我试图为大型降价文件创建一个简单,快速的折叠方法。我在vim中使用fold-expr
方法。例如,如果我想在H1
和H2
降价条目上开始折叠,我的vimscript代码为:
function! MarkdownLevel()
if getline(v:lnum) =~ '^# '
" begin a fold of level one here
return ">1"
elseif getline(v:lnum) =~ '^## '
" begin a fold of level two
return ">2"
else
return "="
endif
endfunction
这很有效,我得到了嵌套的折叠。但是,当我有一个大的降价文件时,vim会大大减慢。这并不奇怪,事实上,在vim的fold-expr帮助中表明了这一点。这是因为=
符号告诉vim在文件中向后扫描,直到找到带有明确定义的 foldlevel的第一行;这可能是数千行。
我尝试用
替换最后一行 else
" set foldlevel to foldlevel of previous line
return foldlevel(v:lnum-1)
endif
但这并不像预期的那样奏效。有谁知道如何解决这一问题?很清楚我不理解foldlevel函数是如何工作的,或者是如何实现vim中的折叠算法。
答案 0 :(得分:1)
您是否考虑过使用Drew Nelstrom的vim-markdown-folding插件?
您可能还想查看Vimcast剧集:Profiling Vimscript performance。这一集实际上是关于折叠降价的。
警示性想法
我无法肯定,因为我没有对您的代码进行分析(并且您应该真正地分析您的代码),但是每当重新绘制内容时,每行都会调用fold表达式,这对Vim来说非常沉重。一些猜测:
=
这样的相对折叠表达式意味着我们需要计算前一行,以便您可以想象这可能会成为问题。如果可以的话,尝试使用精确的深度而不计算其他线条。getline()
两次zi
答案 1 :(得分:1)
我想出了如何解决减速问题,并了解了fold-expr
在vim中的工作原理。我在3000行md文件上测试了性能问题。
我依赖于fold-expr
应该具有的以下自动折叠功能:如果当前行的foldlevel小于下一个的foldlevel,它将开始折叠。如果当前行的foldlevel大于下一行的foldlevel,它结束折叠。事实证明,据我所知,这不符合预期。
使用return ">1"
明确告诉vim折叠开始此处,其中1
被相应的数字替换。
在学习了如何从@PeterRinker中分析vim脚本之后,我发现return "="
语句在我编辑行(例如)3000时被评估了很多次。
这是我的修复:如果当前行的foldlevel没有落入任何标题类型和中,前一行的foldlevel已经定义,那么当前行应该只继承上一行的折叠级别。这是一个显而易见的解决方案,但如果我使用上面的return "1"
代替return ">1"
,那么无效。它需要第一遍的return "="
语句才能找出foldlevel。
所以我的启动时间对于3000行文件来说有点大(大约1秒),但现在编辑非常流畅。以下是完成的,简单的代码。其他更精细的降价项目没有这种有用的简化。
function! MarkdownLevel()
let theline = getline(v:lnum)
let nextline = getline(v:lnum+1)
if theline =~ '^# '
" begin a fold of level one here
return ">1"
elseif theline =~ '^## '
" begin a fold of level two here
return ">2"
elseif theline =~ '^### '
" begin a fold of level three here
return ">3"
elseif nextline =~ '^===*'
" elseif the next line starts with at least two ==
return ">1"
elseif nextline =~ '^---*'
" elseif the line ends with at least two --
return ">2"
elseif foldlevel(v:lnum-1) != "-1"
return foldlevel(v:lnum-1)
else
return "="
endif
end
答案 2 :(得分:0)
这是可以预料到的,因为Vim必须为每一行计算你的表达。在:h fold-expr
Note: Since the expression has to be evaluated for every line,
this fold method can be very slow!
Try to avoid the "=", "a" and "s" return values, since Vim often
has to search backwards for a line for which the fold level is
defined. This can be slow.