Vim đã hiển thị các nếp gấp như một dòng duy nhất. Tuy nhiên, trong cách indent
gấp của Vim , tất cả các dòng có cùng một vết lõm được bao gồm trong một nếp gấp. Vì vậy, trong ảnh chụp màn hình của bạn, các dòng bạn đang gọi là "tiêu đề" (ví dụ: dòng bắt đầu collection_base_url
) không nằm trong các nếp gấp.
Bạn có thể đạt được thứ gì đó tương tự như cách gấp của Atom bằng cách sử dụng Vim foldexpr
foldmethod
:
" Finds the indent of a line. The indent of a blank line is the indent of the
" first non-blank line above it.
function! FindIndent(line_number, indent_width)
" Regular expression for a "blank" line
let regexp_blank = "^\s*$"
let non_blank_line = a:line_number
while non_blank_line > 0 && getline(non_blank_line) =~ regexp_blank
let non_blank_line = non_blank_line - 1
endwhile
return indent(non_blank_line) / a:indent_width
endfunction
" 'foldexpr' for Atom-style indent folding
function! AtomStyleFolding(line_number)
let indent_width = &shiftwidth
" Find current indent
let indent = FindIndent(a:line_number, indent_width)
" Now find the indent of the next line
let indent_below = FindIndent(a:line_number + 1, indent_width)
" Calculate indent level
if indent_below > indent
return indent_below
elseif indent_below < indent
return "<" . indent
else
return indent
endif
endfunction
set foldexpr=AtomStyleFolding(v:lnum)
set foldmethod=expr
Điều này định nghĩa một biểu thức gấp (xem :help fold-expr
) như sau:
- Đối với các dòng ngay trước dòng thụt lề, nó trả về độ thụt của khối theo sau.
- Đối với các dòng thụt lề, nó trả về thụt lề. (Được chia theo độ rộng dịch chuyển để mỗi cấp độ thụt đầu dòng tăng giá trị được trả về 1)
- Đối với các dòng ở cuối một khối các dòng thụt lề, nó trả về một chuỗi
"<N"
, trong đó N được đặt thành thụt lề. Điều này nói với Vim rằng một cấp độ N kết thúc trên dòng đó.
Cập nhật
@alxndr hỏi trong các nhận xét liệu có thể mở rộng điều này để bao gồm các lỗi thời của Ruby end
trong các nếp gấp hay không. Bạn có thể bắt đầu bằng cách thay thế " Calculate indent level
phần bằng cách sau:
if indent_below > indent
return indent_below
elseif getline(a:line_number) =~ '^\s*end\s*$'
return "<" . (indent + 1)
else
return indent
endif
Vì nó là, đây không phải là giải pháp mạnh mẽ nhất (ví dụ: nó sẽ thất bại nếu end
câu lệnh nằm trên cùng một dòng, sau dấu chấm phẩy). Bạn có thể điều chỉnh biểu thức chính quy và mã xung quanh để giải quyết vấn đề này, nhưng vì bây giờ bạn đang ở trong lĩnh vực phân tích cú pháp thực tế của tệp, tôi nghi ngờ mọi thứ có thể phức tạp hơn nhiều trước khi bạn có giải pháp tốt.