为 vim 语法折叠添加标记
Adding a marker for vim syntax folding
我通常用 C 编写代码,我的 .vimrc set foldmethod=syntax
中有它,它可以很好地折叠大括号和注释以及所有内容。
但有时我需要折叠大块代码,以免它们妨碍我(例如一组相关函数),我通常使用 set foldmethod=marker
和标记 >>>
和 <<<
.
我一直在尝试添加一个新的同步区域,最近我得到的是:
syn region cFoldMarkers start='>>>' end='<<<' containedin=cComment transparent fold
但这会造成混乱,因为它以某种方式与评论匹配。
有没有办法同时实现这两个目标?还是我应该放弃用语法来做这件事,只为大括号、注释和我的自定义标记设置标记?
提前致谢
好吧,在尝试使用语法折叠大约 5 个小时后,我放弃并改为表达式折叠。
在这个问题之后:LLVM-IR syntax folding for vim我创建了一个折叠函数,它或多或少地做了我想要的:
function! CFold()
let this_line = getline(v:lnum)
" Matching of braces
if match(this_line, '}') >= 0
return 's1'
elseif match(this_line, '{$') >= 0
return 'a1'
" Matching of comments
elseif match(this_line, '/\*') >= 0
if match(this_line, '\*/$') == -1
return 'a1'
" Matching custom folding
elseif match(this_line, '>>>') >= 0
return 'a1'
elseif match(this_line, '<<<') >= 0
return 's1'
endif
elseif match(this_line, '\*/$') >= 0
return 's1'
endif
return '='
endfunction
setlocal foldmethod=expr
setlocal foldexpr=CFold()
插件 syntaxMarkerFold 添加了此功能。
containedin=cComment
表示整个区域(whole fold)包含在单个评论中;我们只希望标记出现在评论中(两个单独的评论)。
令人惊讶的是,它也匹配不属于任何语法组的标记;这对我们来说也是不受欢迎的行为。
只留下
syn region cFoldMarkers start='>>>' end='<<<' transparent fold
它找到区域的开始并折叠它。但是最后运气不好,所以 Vim 只是折叠到文件末尾。
因此我们需要在区域 (\s*//.\{-}
) 的正则表达式中添加匹配的注释,并且出于某些特殊原因,定义 matchgroup=Comment
syn region cFoldMarkers matchgroup=Comment start='\s*//.\{-}>>>' end='\s*//.\{-}<<<' transparent fold
现在它应该折叠在我们想要的地方。
当然,还有更多的边缘情况,需要更多的处理。
我们还希望能够使用任何标记和不同的有效评论,而不仅仅是 //
。
更不用说水平标记折叠(例如 {{{1
)。
看看我的 syntaxMarkerFold 插件的代码,看看我是如何解决这些问题的。
我通常用 C 编写代码,我的 .vimrc set foldmethod=syntax
中有它,它可以很好地折叠大括号和注释以及所有内容。
但有时我需要折叠大块代码,以免它们妨碍我(例如一组相关函数),我通常使用 set foldmethod=marker
和标记 >>>
和 <<<
.
我一直在尝试添加一个新的同步区域,最近我得到的是:
syn region cFoldMarkers start='>>>' end='<<<' containedin=cComment transparent fold
但这会造成混乱,因为它以某种方式与评论匹配。
有没有办法同时实现这两个目标?还是我应该放弃用语法来做这件事,只为大括号、注释和我的自定义标记设置标记?
提前致谢
好吧,在尝试使用语法折叠大约 5 个小时后,我放弃并改为表达式折叠。
在这个问题之后:LLVM-IR syntax folding for vim我创建了一个折叠函数,它或多或少地做了我想要的:
function! CFold()
let this_line = getline(v:lnum)
" Matching of braces
if match(this_line, '}') >= 0
return 's1'
elseif match(this_line, '{$') >= 0
return 'a1'
" Matching of comments
elseif match(this_line, '/\*') >= 0
if match(this_line, '\*/$') == -1
return 'a1'
" Matching custom folding
elseif match(this_line, '>>>') >= 0
return 'a1'
elseif match(this_line, '<<<') >= 0
return 's1'
endif
elseif match(this_line, '\*/$') >= 0
return 's1'
endif
return '='
endfunction
setlocal foldmethod=expr
setlocal foldexpr=CFold()
插件 syntaxMarkerFold 添加了此功能。
containedin=cComment
表示整个区域(whole fold)包含在单个评论中;我们只希望标记出现在评论中(两个单独的评论)。
令人惊讶的是,它也匹配不属于任何语法组的标记;这对我们来说也是不受欢迎的行为。
只留下
syn region cFoldMarkers start='>>>' end='<<<' transparent fold
它找到区域的开始并折叠它。但是最后运气不好,所以 Vim 只是折叠到文件末尾。
因此我们需要在区域 (\s*//.\{-}
) 的正则表达式中添加匹配的注释,并且出于某些特殊原因,定义 matchgroup=Comment
syn region cFoldMarkers matchgroup=Comment start='\s*//.\{-}>>>' end='\s*//.\{-}<<<' transparent fold
现在它应该折叠在我们想要的地方。
当然,还有更多的边缘情况,需要更多的处理。
我们还希望能够使用任何标记和不同的有效评论,而不仅仅是 //
。
更不用说水平标记折叠(例如 {{{1
)。
看看我的 syntaxMarkerFold 插件的代码,看看我是如何解决这些问题的。