foldmethod
很棒,但是有时候我只想将注释折叠到源文件中。注释的语法折叠也仅适用于C样式注释,例如:
/*
...
*/
,但不适用于类似以下内容的注释样板:
//
//
// ...
//
甚至对于非C类语言的注释块,例如:
#
#
# ...
#
如何用vim配置它?
#1 楼
使用foldmethod=expr
仅折叠注释非常容易:set foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*'.&commentstring[0]
这将仅检查行是否以任意数量的空格开头,后跟注释字符。请注意,这是非常幼稚的,可能不适用于所有语言,因为
commentstring
可能比单个字符更复杂。因此,您可能想使用autocmd进行更具体的设置:autocmd FileType c setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*//'
autocmd FileType python setlocal foldmethod=expr foldexpr=getline(v:lnum)=~'^\s*#'
有关fold-expr的更多信息,请参见:
:help fold-expr
:help folding-functions
如何编写foldexpr?
通过正则表达式搜索模式进行折叠
使用语法折叠和注释折叠更加复杂;这将需要修改
/usr/share/vim/vim74/syntax/*.vim
中的语法文件,并且将特定于您使用的语言。请注意,某些文件类型已经做到了!例如来自
ruby.vim
:if !exists("ruby_no_comment_fold")
syn region rubyMultilineComment start="\%(\%(^\s*#.*\n\)\@<!\%(^\s*#.*\n\)\)\%(\(^\s*#.*\n\)\{1,}\)\@=" end="\%(^\s*#.*\n\)\@<=\%(^\s*#.*\n\)\%(^\s*#\)\@!" contains=rubyC
syn region rubyDocumentation start="^=begin\ze\%(\s.*\)\=$" end="^=end\%(\s.*\)\=$" contains=rubySpaceError,rubyTodo,@Spell fold
else
syn region rubyDocumentation start="^=begin\s*$" end="^=end\s*$" contains=rubySpaceError,rubyTodo,@Spell
endif
评论
@JackFrost如果您需要告诉某人答案中的代码不起作用,则注释或您自己的答案是更好的选择。 (马丁,建议对其中一组进行转义,以使其逃脱。不确定是否需要,但我怀疑可能是。)
– D. Ben Knoble♦
20年5月8日,0:17
仅使用一个\模式就被忽略了,猜猜我只测试了#在行首的情况。感谢您的编辑!
–马丁·图尔诺伊(Martin Tournoij)
20年5月8日,0:48
@ D.BenKnoble是的,由于:help option-backslash,您需要两个。我倾向于选择定义一个函数并设置将表达式(和autocmds等)用于函数调用的选项,以避免过多的转义。
–filbranden♦
20年5月8日,1:55
#2 楼
我喜欢缩进折叠,但要在折叠中包含注释(我的意思是每个注释的折叠程度与上一行相同)。不幸的是,foldignore关键字仅适用于一行注释。因此,我在vimrc中用expr折叠了:
set foldmethod=expr
set foldexpr=FoldMethod(v:lnum)
function! FoldMethod(lnum)
"get string of current line
let crLine=getline(a:lnum)
" check if empty line
if empty(crLine) "Empty line or end comment
return -1 " so same indent level as line before
endif
" check if comment
let a:data=join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )
if a:data =~ ".*omment.*"
return '='
endif
"Otherwise return foldlevel equal to indent /shiftwidth (like if
"foldmethod=indent)
else "return indent base fold
return indent(a:lnum)/&shiftwidth
endfunction
最后一个块:
indent(a:lnum)/&shiftwidth
返回折叠级别的基数缩进。
另外一个:
join( map(synstack(a:lnum, 1), 'synIDattr(v:val, "name")') )
检查该行的第一个字符是否被视为带有语法的注释。因此,这是将缩进和语法折叠与表达式(最高级的折叠)合并的好方法。
请注意,您还可以根据想要的结果外观来“设置折叠文本”。
#3 楼
您可以使用vac
直观地选择带注释的块,然后创建一个手动折叠zf
。注释文本对象可能是标准vim文本对象集的语言扩展。使用Go语法对其进行了测试。
评论
实际上,交流电不是内置的。但是在tpope的评论中,gc是一个文本对象。因此,最糟糕的解决方案是zfac,zfgc或zfip
– D. Ben Knoble♦
19年7月25日在3:57
评论
您是否要使用语法折叠和注释折叠?还是仅注释折叠?@Carpetsmoker,如果可以说“打开所有折叠(注释除外)”,语法折叠+注释折叠就可以了。否则,不带语法折叠的注释折叠也可以。