:h fold-expr
)的帮助页面,但没有解释表达式中使用的语法。有四个示例:
:set foldexpr=getline(v:lnum)[0]==\"\t\"
:set foldexpr=MyFoldLevel(v:lnum)
:set foldexpr=getline(v:lnum)=~'^\s*$'&&getline(v:lnum+1)=~'\S'?'<1':1
:set foldexpr=getline(v:lnum-1)=~'^\s*$'&&getline(v:lnum)=~'\S'?'>1':1
我知道
v:lnum
是需要缩进级别的行,表达式2是对函数的调用。 1,3和4?有人可以给我解释一下吗?#1 楼
从:help 'foldexpr'
开始:对每条线进行评估以获得折叠水平
对
foldexpr
进行评估,因此它需要是VimL代码;没有提及“特殊语法”等。此评估的结果控制着Vim认为是折叠还是不折叠。可能的值是
0 the line is not in a fold
1, 2, .. the line is in a fold with this level
"<1", "<2", .. a fold with this level ends at this line
">1", ">2", .. a fold with this level starts at this line
只是问题示例中使用的那些。有关完整列表,请参见
:help foldexpr
。第一个
第一个非常简单,一旦我们添加了一些空格并删除了反斜杠,我们就可以开始工作了。一个
:set
命令:getline(v:lnum)[0] == "\t"
getline(v:lnum)
获得整行。[0]
获得该行的第一个字符和
== "\t"
检查这是否是制表符。VimL没有“ true”或“ false”,它只将“ 0”表示为false,将“ 1”表示为true。因此,如果此行以制表符开头,则以foldlevel 1折叠。如果不是,则它不在fold(0)中。
如果要扩展它以计算制表符的数量将具有基于缩进的折叠(至少在未启用
expandtab
时)。第三
第三个实际上并没有那么复杂第一个;与第一个示例一样,我们首先要使其更具可读性:
getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
我们用
getline(v:lnum)
整行得到我们将其作为正则表达式与
=~
匹配到'^\s*$'
; ^
锚定到开头,\s
表示任何空格字符,*
表示重复前一个零或更多次,$
锚定到结尾。因此,此正则表达式匹配(返回true)空白行或仅包含空格的行。getline(v:lnum + 1)
获取下一行。这条线。如果这两个条件为真,则求值为
\S
,否则为<1
。这是通过C和其他一些语言已知的“三元” 1
完成的:if
。因此,如果我们在一行是空白而下一行不是空白的情况下结束折叠。否则,我们将处于折叠级别1。或者,正如condition ? return_if_true : return_if_false
所说的那样: /> 第四次
第四次与第三次的行为相同,但是方式略有不同。展开后,它是:
getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1
如果前一行是空白行,而当前行是非空白行,则在该行上开始折叠(
<1
),如果没有,我们将折叠级别设置为1。后缀
因此,所有3个示例的逻辑都非常简单。大多数困难在于缺少空格和一些反斜杠使用。 。我不知道现代机器上的差别有多大,除非您有性能问题,否则建议您使用一个函数(如第二个示例中所示)。请记住The Knuth:“过早的优化是万恶之源”。
这个问题也在StackOverflow上,答案略有不同。但是我的当然更好;-)
#2 楼
您本质上是在问这些表达式中的其他元素是什么,可以依次调用:help
来找到它们:v:lnum: the line being evaluated
getline(): get the line of text for a line number
==: equals
=~: matches
<cond>?<if-true>:<if-false>: evaluates to <if-true> if <cond> is true, else to <if-false>
我已经分解了以下这些表达式的各个部分有助于说明其含义:
1将以制表符开头的所有行返回1,其他行返回0:
v:lnum the current line number
getline(v:lnum) the text of the current line
getline(v:lnum)[0] the first character of the current line
getline(v:lnum)[0]==\"\t\" the first char of the current line is 'tab'
3在以下段落之后的空白行上结束折页:
getline(v:lnum)=~'^\s*$' current line is only spaces
getline(v:lnum+1)=~'\S' next line has non-space
(getline(v:lnum)=~'^\s*$' && getline(v:lnum+1)=~'\S') ? '<1' if both of these: <1
:1 otherwise: 1
(getline(v:lnum)=~'^\s*$' && getline(v:lnum+1)=~'\S') ? '<1':1
4在以下段落开始的空白行上进行折行:
(getline(v:lnum-1)=~'^\s*$' previous line only spaces
getline(v:lnum)=~'\S' this line has non-space
(getline(v:lnum-1)=~'^\s*$' && getline(v:lnum)=~'\S') ? '>1' if both of these: >1
:1 otherwise: 1
(getline(v:lnum-1)=~'^\s*$' && getline(v:lnum)=~'\S') ? '>1':1
<1
,>1
等的含义就在:help fold-expr
中这些表达式的正下方#3 楼
不小心将我的答案发表为评论,并提早提交。 Darn mobile。我的理解是表达式应返回一个数字,该数字将用于确定给定行将在哪一级折叠。 0不折叠,1是最外面的折叠,2是嵌套在1级折叠内部的折叠,依此类推。
示例中的表达式看起来像它们的值为true或false。 VimScript没有正确的布尔类型,因此它实际上是1或0,这是有效的折叠级别。
您可以使用VimScript编写自己的表达式,就像返回1或0一样简单,或更复杂,允许嵌套折叠。
评论
仅使用数字即可工作,但值得注意的是foldexpr可以求值其他特殊值,例如=,a1,s1,> 1,<1,-1
–马特·博姆(Matt Boehm)
15年2月24日在19:03
评论
我的理解是该表达式应返回一个数字,并且该数字将用于确定给定行将在哪一级折叠。 0不折叠,1是最外面的折叠,2是嵌套在1级折叠内部的折叠,依此类推