It is evaluated for each line to obtain its fold level
foldexpr is evaluated, so it needs to be VimL code; there is no mention of "special syntax" or the like. The result of this evaluation controls what Vim considers a fold or not.
Possible values are
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
This is not the full list; just the ones used in the examples in your question. See
:help fold-expr for the full list.
The first one is fairly simple once we add some spaces and remove the backslashes we need to get this working in a
getline(v:lnum) == "\t"
getline(v:lnum) gets the entire line.
 gets the first character of that
== "\t" checks if that is a tab character.
- VimL doesn't have "true" or "false", it just uses "0" for false, and "1" for true. So if this line starts with a tab, it's folded at foldlevel 1. If it doesn't, it's not in a fold (0).
If you would expand this to count the number of tabs you would have indentation-based folding (at least, when
expandtab isn't enabled).
The third one is really not that much more complicated as the first one; as with the first example, we first want to make it more readable:
getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
- We get the entire line with
- We match that as a regexp with
^ anchors to the start,
\s means any whitespace character,
* means repeat the previous zero or more times, and
$ anchors to the end. So this regexp matches (returns true) for blank lines or lines with only whitespace.
getline(v:lnum + 1) gets the next line.
- We match this to
\S, which matches any non-whitespace character anywhere on this line.
- If these 2 conditions are true, we evaluate to
1. This is done with the "ternary"
if known from C and some other languages:
condition ? return_if_true : return_if_false.
<1 means a fold ends on this line, and
1 means foldlevel one.
So, If we end a fold if the line is blank and the next line is not blank. Otherwise, we're at foldlevel 1. Or, as
:h fold-expr says it:
This will make a fold out of paragraphs separated by blank lines
The fourth behaves the same as the third one, but does it in a slightly different way. Expanded, it's:
getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1
If the previous line is a blank line, and the current line is a non-blank line, we start a fold on this line (
>1), if not, we're setting the foldlevel to 1.
So the logic on all 3 examples is really quite simple. Most of the difficulty comes in the lack of spaces and some of the backslash usage.
I suspect that calling a function has some overhead, and since this is evaluated for every line you want to have a decent performance. I don't know how great the difference is on modern machines though, and would recommend that you use a function (as in the 2nd example) unless you have performance problems. Remember The Knuth: "premature optimisation is the root of all evil".
This question is also on StackOverflow, which has a slightly different answer. But mine is of course better ;-)