De :help 'foldexpr'
:
Se evalúa para cada línea para obtener su nivel de plegado
Se foldexpr
evalúa, por lo que debe ser un código VimL; no se menciona la "sintaxis especial" o similar. El resultado de esta evaluación controla lo que Vim considera un pliegue o no.
Los valores posibles son
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
Esta no es la lista completa; solo los utilizados en los ejemplos en su pregunta. Ver :help foldexpr
para la lista completa.
primero
El primero es bastante simple una vez que agregamos algunos espacios y eliminamos las barras diagonales inversas que necesitamos para que esto funcione en un :set
comando:
getline(v:lnum)[0] == "\t"
getline(v:lnum)
Obtiene toda la línea.
[0]
obtiene el primer personaje de eso
- y
== "\t"
comprueba si ese es un carácter de tabulación.
- VimL no tiene "verdadero" o "falso", solo usa "0" para falso y "1" para verdadero. Entonces, si esta línea comienza con una pestaña, se pliega en el nivel de plegado 1. Si no lo hace, no está en un pliegue (0).
Si expandiera esto para contar el número de pestañas, tendría un plegado basado en sangría (al menos, cuando expandtab
no esté habilitado).
Tercero
El tercero no es realmente mucho más complicado que el primero; Como con el primer ejemplo, primero queremos que sea más legible:
getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
- Obtenemos toda la línea con
getline(v:lnum)
- Hacemos coincidir eso como una expresión regular con
=~
to '^\s*$'
; ^
ancla al inicio, \s
significa cualquier carácter de espacio en blanco, *
significa repetir el cero anterior o más veces y $
ancla al final. Entonces, esta expresión regular coincide (devuelve verdadero) para líneas en blanco o líneas con solo espacios en blanco.
getline(v:lnum + 1)
Obtiene la siguiente línea.
- Hacemos coincidir esto con
\S
, que coincide con cualquier carácter que no sea un espacio en blanco en cualquier lugar de esta línea.
- Si se cumplen estas condiciones 2, evaluamos a
<1
, de lo contrario, 1
. Esto se hace con la "ternaria" if
conocido de C y algunos otros idiomas: condition ? return_if_true : return_if_false
.
<1
significa que un pliegue termina en esta línea, y 1
significa un pliegue de nivel uno.
Así pues, si nos terminamos un pliegue si la línea está en blanco y la siguiente línea es no blanco. De lo contrario, estamos en el nivel 1. o, como :h foldexpr
dice:
Esto hará un pliegue de párrafos separados por líneas en blanco
Cuarto
El cuarto se comporta igual que el tercero, pero lo hace de una manera ligeramente diferente. Ampliado, es:
getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1
Si la línea anterior es una línea en blanco, y la línea actual es una línea no en blanco, comenzamos un pliegue en esta línea ( >1
), si no, estableceremos el nivel de pliegue en 1.
Epílogo
Entonces la lógica en los 3 ejemplos es realmente bastante simple. La mayor parte de la dificultad viene por la falta de espacios y parte del uso de la barra invertida.
Sospecho que llamar a una función tiene algo de sobrecarga, y dado que esto se evalúa para cada línea que desea tener un rendimiento decente. Sin embargo, no sé cuán grande es la diferencia en las máquinas modernas, y recomendaría que use una función (como en el segundo ejemplo) a menos que tenga problemas de rendimiento. Recuerde The Knuth: "la optimización prematura es la raíz de todo mal" .
Esta pregunta también está en StackOverflow , que tiene una respuesta ligeramente diferente. Pero el mío es, por supuesto, mejor ;-)