Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could someone explain a particular use case of ‘foldexpr’ syntax in Vim?

Tags:

vim

folding

Could anyone please provide an explanation of the syntax in the following example, or post me a link where there is a more general explanation of the individual symbols used in this expression? I found Vim help to be incomplete in this regard.

:set foldexpr=getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1

What is unclear to me is the following.

  1. Why are strings enclosed in single quotes instead of double quotes? Is it a matter of choice?
  2. What does the explanation mark mean in =~'\\S'?'<1':1?
  3. What does the expression 'string1'string2'string3 mean?
  4. What does :1 mean?
like image 716
xralf Avatar asked May 12 '11 12:05

xralf


1 Answers

The foldexpr option supposed to contain an expression that evaluates into an integer or a string of particular format that specifies the folding level of the line which number is stored in the v:lnum global variable at the moment of evaluation.

Let us follow the logic of this foldexpr example from top to bottom.

getline(v:lnum)=~'^\\s*$'&&getline(v:lnum+1)=~'\\S'?'<1':1

At the top level, the whole expression is an instance of the ternary operator A ? B : C. The result of the operator is the value of the B expression if A evaluates to non-zero, and the value of the C expression otherwise (see :help expr1). In this case, B is the string literal '<1', and C is the number 1 (for meaning of '<1' and 1 as fold level specifiers see :help fold-expr).

The A expression consists of two conditions joined by the && operator:

getline(v:lnum) =~ '^\\s*$' && getline(v:lnum+1) =~ '\\S'

Both conditions have the same form:

getline(N) =~ S

The getline function returns contents of the line (in the current buffer) that is referenced by the line number passed as an argument (see :help getline). When the foldexpr is evaluated, the v:lnum variable contains number of the line for which folding level should be calculated.

The =~ operator tests whether its left operand matches a regular expression given by its right string operand, and returns boolean value (see :help expr4, in particular, near the end of the expr4 section). Thus, the A condition is intended to check that the v:lnum-th line matches the '^\\s*$' pattern, and the line following that v:lnum-th line matches the '\\S' pattern.

The regular expression patterns are specified in the expression as string literals. String literals have two syntactic forms and can be quoted using double or single quotes. The difference between these forms is that double quoted string could contain various control sequences which start with backslash. That sequences allow to specify special characters that cannot be easily typed otherwise (double quote, for example—it writes \"). Single quoted strings, at the other hand, do not allow such backslash-sequences. (For complete description of single and double quoted strings see :help expr-string and :help literal-string.)

The notable consequence of the double quoted strings syntax is that backslash symbol itself must be escaped (\\). That is why single quoted strings are often used to specify regular expressions: there is no need to escape constantly demanded backslash symbol. One can notice, though, that backslashes are nevertheless escaped in those patterns above. This is due to that some symbols (including backslash) have special meaning when in Ex commands (including :set, of course). When you hit Enter to start the command

:set foldexpr=...

Vim interprets some character sequences first (see :help cmdline-special). In particular, the \\ sequence is treated as a single backslash.

Putting it all together, the expression tests whether the line number v:lnum contains only blank characters and whether the following line (number v:lnum+1) has any non-blank character (see :help pattern to grasp the meaning of the patterns). If so, the expression evaluates to the string '<1', otherwise it evaluates to the number 1.

like image 158
ib. Avatar answered Oct 03 '22 16:10

ib.