В соответствии с :help fold-create-marker
, автоматическая вставка маркера складывания
не работает должным образом, когда:
- Строка уже содержит маркер с номером уровня. Vim тогда не
знать, что делать.
- Складки рядом используют номер уровня в своем маркере, который мешает.
- Строка внутри комментария,
commentstring
не пустая и не вложенная
комментарии не работают. Например с C: добавление /* {{{ */
внутри
комментарий урезает существующий комментарий.
Таким образом, невозможно изменить поведение zf
по умолчанию, изменив
commentstring
настройка.
Однако можно создать собственную версию команды zf
, которая
будет принимать во внимание, что начало или конец (или оба) строки
складка может иметь комментарии. Например, рассмотрим следующие отображения, один
для маркировки складки путем визуального выбора, другой для использования с движением
команда.
nnoremap <silent> <leader>zf :set opfunc=CreateMarkerFold<cr>g@
vnoremap <silent> <leader>zf :<c-u>call CreateMarkerFold(visualmode(), 1)<cr>
function! CreateMarkerFold(vt, ...)
let range = map(['[<', ']>'], 'line("''".v:val[a:0])')
let mark = split(&foldmarker, ',')
let pat = escape(&commentstring, '\')
let pat = '\V' . substitute(pat, '\\\@<!%s', '\\zs\\ze\\.\\{-}', '')
for i in [1, 0]
let line = getline(range[i])
if line =~ pat
let line = substitute(line, pat, escape(mark[i], '\'), '')
else
let line .= printf(&commentstring, mark[i])
endif
call setline(range[i], line)
endfor
endfunction
Оба отображения следуют одной и той же процедуре. Перед добавлением запуска и
заканчивая складывание маркеров, он отдельно проверяет, является ли первый и последний
линии блока для сгиба соответствуют шаблону commentstring
. Для каждого из
два, которые совпадают, он вставляет соответствующий маркер внутри первого найденного
комментарий, в самом начале своего текста. В противном случае маркер
оформлен по шаблону commentstring
и добавлен в конце
линия.
Если в последнем случае предпочтительнее разделить маркер на отдельной строке,
можно изменить цикл for, как показано ниже.
for i in [1, 0]
let line = getline(range[i])
if line =~ pat
let line = substitute(line, pat, escape(mark[i], '\'), '')
call setline(range[i], line)
else
call append(range[i] - !i, printf(&commentstring, mark[i]))
endif
endfor
В отличие от предыдущей версии цикла, порядок обработки двух
линии важны: конечная линия маркера должна быть добавлена первой, если
необходимо, потому что вставка строки для начального маркера сместит
следующие строки меняют свои номера.