Vim уже отображает сгибы одной строкой. Однако при indent
сворачивании Vim все линии с одинаковым отступом включаются в сгиб. Таким образом, на скриншоте строки, которые вы называете «заголовками» (например, начинающими collection_base_url
), не находятся в пределах сгиба.
Вы можете добиться чего-то похожего на свертывание Atom, используя 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
Это определяет выражение сгиба (см. :help fold-expr
) Следующим образом:
- Для строк, непосредственно предшествующих отступам, он возвращает отступ следующего блока.
- Для строк с отступом возвращает отступ. (Делится на ширину смещения, поэтому каждый уровень отступа увеличивает возвращаемое значение на 1)
- Для строк в конце блока с отступом возвращает строку
"<N"
, в которой для N задан отступ. Это говорит Vim, что сгиб уровня N заканчивается на этой линии.
Обновить
@alxndr спрашивает в комментариях, возможно ли расширить это, чтобы включить устаревшие end
s Руби в сгибы. Вы можете начать с замены " Calculate indent level
раздела следующим:
if indent_below > indent
return indent_below
elseif getline(a:line_number) =~ '^\s*end\s*$'
return "<" . (indent + 1)
else
return indent
endif
На самом деле это не самое надежное решение (например, оно потерпит неудачу, если end
оператор находится в той же строке после точки с запятой). Вы можете настроить регулярное выражение и окружающий код для решения этой проблемы, но, поскольку вы сейчас находитесь в сфере анализа фактического синтаксиса файла, я подозреваю, что все может стать намного сложнее, прежде чем у вас будет хорошее решение.