我最近意识到,我的vimrc现在已经超过400行了(IMO太多了,我会尽量减少它),并且为了使其更易于浏览,阅读和编​​辑,我决定研究一下vim中折叠的概念(我不熟悉)。


我尝试将折叠方法设置为indent,但我不喜欢结果(它太乱了,主要是因为我的很大一部分vimrc并非真正缩进)。
我也尝试将foldmethod设置为exprsyntax,但是我无法正确折叠任何东西。
这里使用diff作为折叠方法似乎并不重要。 (或者如果我不明白如何使用它)
所以现在我使用的是marker方法,由于我在其中发现了“嘈杂”的"{{{"}}}标记,这并不完全令我满意。该文件。

所以我想知道是否存在有关正确折叠vimrc的最佳实践或通用准则。

注1:众所周知,这不是一个论坛,也不是为了收集个人意见,而这并不是我所要寻找的:当然,我想有些人会有自己的偏好,但我想知道为什么使用标记(例如)比使用indent可以提高可读性。

注2:我的主要目的是使vimrc尽可能清晰,以便采用其他最佳做法存在,可以创建一个很好的vimrc,对此我感到很好奇。

编辑1:我应该明确指出,我的vimrc已被细分为几个部分(有时甚至是几个子部分),主要部分是


常规选项
映射
导航(还包含小节)
颜色...

正是这种结构让我想到了折叠:我觉得能够只在特定点上只输出我感兴趣的部分非常方便。

编辑2:回答在几个文件中提及vimrc的细分是有效的,但出于个人喜好,我宁愿使用折叠,因为我认为在git repo中仅保存一个包含我的dotfile的文件比较容易。那只是个人喜好,我知道也可以使用这种方法,但是我更喜欢使用折叠。

评论

我认为使用“ {{{是最像'vim''的方式”,solarized插件使用了这种方式,尽管它可能很嘈杂,但它为您提供了设置手动折叠的最标准方式

#1 楼

我在vimrc的底部有以下模式行,这些行是从表格的作者Godlygeek复制而来的: "越多,折痕越深。这使您可以根据需要细分部分。
更新:如第二个Modeline下面的注释中所述,现在会导致Vim错误。这是引入此更改的补丁的注释:

补丁8.1.1366
问题:在modeline中使用表达式是不安全的。除非设置了
'modelineexpr'选项。

不,您不能从modeline设置"!您可以尝试在autocmd中如上所述设置'modelineexpr'(例如'fde')。我(B层)没有对此进行测试,但是我确实对其进行了手动测试。您需要对autocmd Filetype vim ...进行转义。
"" vim:fdm=expr:fdl=0
"" vim:fde=getline(v\:lnum)=~'^""'?'>'.(matchend(getline(v\:lnum),'""*')-2)\:'='


评论


我目前无法测试,但这似乎是我的理想解决方案!感谢分享!

–statox♦
15年7月3日在17:15

一些解释:getline(v:lnum)返回由行号(v:lnum)给出的行的字符串; =〜表示正则表达式匹配; '^“”'表示所有行均以两个“ s”开头; matchend(getline(v:lnum),'“” *')-2计数额外的“”,这意味着“”“将折叠为1级, “”“将以第2级折叠,依此类推; getline(v:lnum)=〜'^”“'返回true或false,具体取决于以两个”或否“开头的v:lnum行;如果为true,则将fde设置为>“(在此行<后面的数字位于起始级别)或” =”(使用前一行的级别)的额外编号,其含义可以在fold-expr中找到

–van abel
17年8月27日在7:24

在最近的vim更新8.1.1517之后),使用此配置,我收到“在处理模式行时检测到错误”。

–阿波罗
19年6月12日在13:33

你们已经有一年了,可能有些人已经弄清楚了,但是我用有关破损的信息更新了答案。

– B层
20年8月29日在19:01

#2 楼

最好先在.vimrc中定义自己的类别(如带有子列表和子子列表的列表),然后将所有插件/设置/功能添加到相应的类别中。结合自定义折叠功能,可以很好地发挥作用:它使用以下自定义的折叠设置:

""""""""""""""""""""""""
"  THIS IS A CATEGORY  "
""""""""""""""""""""""""
"" Autofolding .vimrc
" see http://vimcasts.org/episodes/writing-a-custom-fold-expression/
""" defines a foldlevel for each line of code
function! VimFolds(lnum)
  let s:thisline = getline(a:lnum)
  if match(s:thisline, '^"" ') >= 0
    return '>2'
  endif
  if match(s:thisline, '^""" ') >= 0
    return '>3'
  endif
  let s:two_following_lines = 0
  if line(a:lnum) + 2 <= line('$')
    let s:line_1_after = getline(a:lnum+1)
    let s:line_2_after = getline(a:lnum+2)
    let s:two_following_lines = 1
  endif
  if !s:two_following_lines
      return '='
    endif
  else
    if (match(s:thisline, '^"""""') >= 0) &&
       \ (match(s:line_1_after, '^"  ') >= 0) &&
       \ (match(s:line_2_after, '^""""') >= 0)
      return '>1'
    else
      return '='
    endif
  endif
endfunction

""" defines a foldtext
function! VimFoldText()
  " handle special case of normal comment first
  let s:info = '('.string(v:foldend-v:foldstart).' l)'
  if v:foldlevel == 1
    let s:line = ' ◇ '.getline(v:foldstart+1)[3:-2]
  elseif v:foldlevel == 2
    let s:line = '   ●  '.getline(v:foldstart)[3:]
  elseif v:foldlevel == 3
    let s:line = '     ▪ '.getline(v:foldstart)[4:]
  endif
  if strwidth(s:line) > 80 - len(s:info) - 3
    return s:line[:79-len(s:info)-3+len(s:line)-strwidth(s:line)].'...'.s:info
  else
    return s:line.repeat(' ', 80 - strwidth(s:line) - len(s:info)).s:info
  endif
endfunction

""" set foldsettings automatically for vim files
augroup fold_vimrc
  autocmd!
  autocmd FileType vim 
                   \ setlocal foldmethod=expr |
                   \ setlocal foldexpr=VimFolds(v:lnum) |
                   \ setlocal foldtext=VimFoldText() |
     "              \ set foldcolumn=2 foldminlines=2
augroup END


使用以下语法定义自己的类别和子类别:

""""""""""""""
"  Category  "
""""""""""""""
"" Subcategory
""" Subsubcategory
" Just a comment, gets ignored no matter where


如果使用vim代码片段(例如,使用UltiSnips),则可以非常容易地创建顶级类别:只需扩展vim代码片段提供的.vimrcbox代码片段(编写bboxbox,然后按展开触发器)即可。 br />
通过两次按空格键可以更快地打开和关闭折叠:

let mapleader = "\<space>"
" Toggle folds
nnoremap <silent> <leader><Space> @=(foldlevel('.')?'za':"\<Space>")<CR>
vnoremap <leader><space> zf


这样,您就可以轻松浏览结构良好的bbox

评论


+1为精美的动画gif :)很好奇,您用来显示键入的键是什么?

–mMontu
16-2-22在11:25

@mMontu:我使用screenkey来显示按键,并使用gtk-recordmydesktop对其进行记录(均在Debian存储库中)。使用5fps时,45秒的剪辑比MiB少。然后将其在线转换为gif(这是图片质量完美之前失真的来源)。

–cbaumhardt
16-2-22在12:48

#3 楼

我将我的主要vimrc用作指向其他几个分类文件的链接,并根据需要进行采购,例如一个文件中的Vim选项,另一个文件中的插件设置。

"--- Vim Options
source ~/.vim/config/vim_options.vim

"--- Here Be Functions!
" (need to be sourced before stuff that uses 'em)
runtime! functions/*.vim

"--- Key Mapping
source ~/.vim/config/key_mapping.vim

"--- Folding
source ~/.vim/config/folding.vim

"--- Autocmds
source ~/.vim/config/autocmds.vim

"--- We Are Plugged In!
source ~/.vim/config/plugins.vim

" vim: ft=vim fdm=marker


作为对OP问题的更直接回答,我确实使用了标记方法,但是在右边以空格隔开,并且类别比个人多大部分。我会分别做每个插件。

评论


我在我的问题中忘记了精确性:我不喜欢将vimrc“分离”到不同的文件中,因为(IMO)会增加复杂性并使其更难维护。关于折叠,您所说的“以一定的间距向右侧移动”是什么意思?

–statox♦
15年7月3日在13:54

我的意思是“ {{{,其中的空格与您的文本宽度一样多,因此标记位于右边缘附近。我在folding.vim文件中也具有个性化的FoldText函数。我更喜欢单独的文件,因此我的git repo仅一个每次提交的mod类型。

–彗星
2015年7月3日15:39



#4 楼

您可能会说“最佳实践”主要是个见解,:)但是有两种方法(1)显而易见,并且(2)可以应用于所有配置文件,不仅限于Vim:按逻辑部分折叠和小节(或者更深的部分,如果您觉得很勇敢),并将您的配置分成几个较小的文件,然后对其进行:source -ing。给我一些层次。最内层的折叠函数和autocmd也是一个好主意,因为它们构成了“自然的”逻辑单元。 marker折叠对此最有意义,因为逻辑层次结构不一定会反映到缩进级别或语法突出显示中。我还增加了foldcolumn,这给了我我所在位置的视觉提示:



对IIRC的Drew Neil的类似功能进行的修改对我来说比默认值更有意义:

# vim: filetype=vim foldmethod=marker foldlevel=0 foldcolumn=3

查找内容,然后从一个文件切换到另一个文件。解决这两个问题的一种非常不错的方法是使用诸如CtrlSF,CtrlP之类的插件。但是无论如何,您可能已经在使用其中之一了。

评论


所以你去标记。确实,自定义折叠柱是一件不错的事情,我将看看哪种值最适合我的需求。另外,我也分享了您对拆分文件的看法,但我不知道CtrlSF,即使我对CtrlP感到非常满意,也还是会看一下。

–statox♦
15年7月3日在14:30

还可以请您说明如何使用自定义折叠方法吗?我试图将fdm设置为foldtext和MyFoldText(),但似乎这不是使用它的正确方法。

–statox♦
2015年7月3日14:39

@statox CtrlSF最适合与grep或ack一起使用,这是grep的专门版本。 foldtext不是自定义的折叠方法,而是一种用于更改折叠文本外观的功能。我的代码片段的最后一行显示了它的用法:set foldtext = MyFoldText()。

–lcd047
2015年7月3日14:54



#5 楼

最佳基本做法:



分为以下部分:


插件
设置
重新绑定


评论每个部分/重新绑定
(将您的.vimrc_vimrc备份到Github上)

我个人喜好。也许没有太多帮助。

评论


我个人不使用折叠功能,而您则不需要。只要组织您的vimrc,一切都应该很好。

–古斯塔夫·布洛姆奎斯特(Gustav Blomqvist)
2015年7月3日在13:48



我的vimrc已经按部分进行了组织(常规选项,插件,映射,导航,颜色等)。能够折叠一个部分(或子部分)的事实实际上可以很好地集中于您正在编辑/寻找的内容。

–statox♦
15年7月3日在13:51

好的。对不起,不好的回答。

–古斯塔夫·布洛姆奎斯特(Gustav Blomqvist)
15年7月3日在14:18

那不是一个不好的答案,我也因没有给出足够详细的问题而内gui,无需后悔;-)

–statox♦
15年7月3日,14:26

#6 楼

受@PeterRincker的回答启发,我精心设计了以下内容以使用ATX样式标头。将其添加到.vimrc

"# Folding

" Fold with ATX style headers - "# is H1, "## is H2, and so on
" vim:fdm=expr:fdl=0
" vim:fde=getline(v\:lnum)=~'^"#'?'>'.(matchend(getline(v\:lnum),'"#*')-1)\:'='

的末尾

#7 楼

如果您有像我这样的大型函数,则可以使用它来折叠函数:

fun! MyFoldLevel(linenum)
    if ! exists('w:nextline')
        let w:nextline = 0
        let w:insideafun = 0
    endif

    if w:nextline == 1
        let w:nextline = 0
        let w:insideafun = 0
    endif

    let l:line = getline(a:linenum)

    if l:line =~# '^[[:space:]]*fun'
        let w:insideafun = 1
        return '>1'
    elseif l:line =~# '^[[:space:]]*endf'
        let w:nextline = 1
        return '<1'
    endif

    if w:insideafun == 1
        return 1
    else
        return 0
    endif
endfun


将此模型添加到您的vimrc中:

" vim:fde=MyFoldLevel(v\:lnum):fdm=expr:


#8 楼

扩展了@Peter Rincker和@ go2null的想法。如果不想在Vim modeline中设置折叠选项。您可以使用以下autocmd来设置折叠方法和折叠表达式。

augroup vim_folding
    autocmd!
    autocmd FileType vim set foldmethod=expr foldlevel=0
    " note that double quote in foldexpr has to be escaped with backslash
    autocmd FileType vim set foldexpr=getline(v:lnum)=~'^\"#'?'>'.(matchend(getline(v:lnum),'\"#*')-1):'='
augroup END


我做了一些小的修改,以使原始答案成为常规的vim命令(不需要转义冒号,但需要转义双引号)。

如果您不喜欢长的foldexpr字符串,我们可以为此定义一个函数:

function! VimFolds(lnum)
    let s:cur_line = getline(a:lnum)

    if s:cur_line =~ '^"#'
        return '>' . (matchend(s:cur_line, '"#*')-1)
    else
        return '='
    endif

endfunction


然后将大约foldexpr的autocmd线替换为

autocmd FileType vim set foldexpr=VimFolds(v:lnum)