Da :help 'foldexpr'
:
Viene valutato per ogni riga per ottenere il suo livello di piega
La foldexpr
viene valutata, quindi deve essere il codice VimL; non si fa menzione di "sintassi speciale" o simili. Il risultato di questa valutazione controlla ciò che Vim considera o meno una piega.
I valori possibili sono
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
Questo non è l'elenco completo; solo quelli usati negli esempi della tua domanda. Vedi :help foldexpr
l'elenco completo.
Primo
Il primo è abbastanza semplice una volta aggiunti degli spazi e rimosso le barre rovesciate, dobbiamo farlo funzionare in un :set
comando:
getline(v:lnum)[0] == "\t"
getline(v:lnum)
ottiene l'intera riga.
[0]
ne ottiene il primo personaggio
- e
== "\t"
controlla se si tratta di un carattere di tabulazione.
- VimL non ha "true" o "false", usa solo "0" per false e "1" per true. Quindi, se questa linea inizia con una scheda, viene piegata a livello di piega 1. In caso contrario, non è piegata (0).
Se lo espandessi per contare il numero di schede avresti una piegatura basata sul rientro (almeno, quando expandtab
non è abilitata).
Terzo
Il terzo non è in realtà molto più complicato del primo; come nel primo esempio, vogliamo prima renderlo più leggibile:
getline(v:lnum) =~ '^\s*$' && getline(v:lnum + 1) =~ '\S' ? '<1' : 1
- Otteniamo l'intera riga con
getline(v:lnum)
- Lo abbiniamo come regexp con
=~
to '^\s*$'
; ^
ancore all'inizio, \s
indica qualsiasi carattere di spazio bianco, *
significa ripetere lo zero precedente o più volte e $
ancorare fino alla fine. Quindi questa regexp corrisponde (restituisce vero) per righe vuote o righe con solo spazi bianchi.
getline(v:lnum + 1)
ottiene la riga successiva .
- Abbiniamo questo a
\S
, che corrisponde a qualsiasi carattere non bianco in qualsiasi punto di questa linea.
- Se queste 2 condizioni sono vere, valutiamo a
<1
, in caso contrario, 1
. Questo viene fatto con il "ternario" if
conosciuto da C e alcune altre lingue: condition ? return_if_true : return_if_false
.
<1
significa che una piega termina su questa linea e 1
significa una piega a livello.
Quindi, se si finisce una piega se la linea è vuota e la riga successiva è non vuoto. Altrimenti, siamo al livello 1 o, come :h foldexpr
dice:
Questo renderà un pieghevole di paragrafi separati da linee vuote
Il quarto
Il quarto si comporta come il terzo, ma lo fa in modo leggermente diverso. Espanso, è:
getline(v:lnum - 1) =~ '^\s*$' && getline(v:lnum) =~ '\S' ? '>1' : 1
Se la riga precedente è una riga vuota e la riga corrente è una riga non vuota, iniziamo una piega su questa riga ( >1
), in caso contrario, impostiamo il livello di piegatura su 1.
Epilogo
Quindi la logica di tutti e 3 gli esempi è davvero abbastanza semplice. La maggior parte della difficoltà deriva dalla mancanza di spazi e dall'uso di una barra rovesciata.
Sospetto che chiamare una funzione abbia un certo sovraccarico, e poiché questo viene valutato per ogni linea che si desidera avere prestazioni decenti. Non so quanto sia grande la differenza sulle macchine moderne e consiglierei di usare una funzione (come nel secondo esempio) a meno che tu non abbia problemi di prestazioni. Ricorda The Knuth: "l'ottimizzazione prematura è la radice di tutti i mali" .
Questa domanda è anche su StackOverflow , che ha una risposta leggermente diversa. Ma il mio è ovviamente migliore ;-)