Piegatura secondo il modello di ricerca regex


13

Ho ottenuto un file di testo semplice con colonne di valori separate da spazi bianchi. Come questo:

AU 3030 .... ... ....  
AU 3031 .... ... ....  
AU 3032 .... ... .... 
AU 3033 .... ... .... 
IT 48100 ... .. .....
IT 40100 ... .. .....
IT 48123 ... .. .....
UK 3333 ... ... ..... 
UK 4444 ... ... .....
UK 5555 ... ... .....

Ho anche ottenuto questa regex che corrisponderà a qualsiasi linea adiacente con lo stesso valore nella prima colonna (supponiamo che il file sia ordinato sulla prima colonna) tranne l'ultimo:

/^\(\([A-Z0-9]\+\)\s\+.*\n\)\(\2\)\@=

(o per renderlo meno "peloso"):

/^\v([A-Z0-9]+)\s+.*\n(\1)@=

È possibile piegare le linee sulla linea che non è stata abbinata? Avere questo risultato:

+-- 4 lines AU ....
+-- 3 lines IT ....
+-- 3 lines UK ....

Risposte:


14

Fare set foldmethod=expre usare 'foldexpr'per impostare un'espressione di script vim che definirà i punti di inizio piega.

set foldmethod=expr
set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'='

Questo sembra più complicato di quello che è, perché non possiamo usare facilmente gli spazi in :set, ma con gli spazi e una nuova riga o 2, sembra:

get(split(getline(v:lnum - 1)), 0, '') != get(split(getline(v:lnum)), 0, '')
    \ ? '>1'
    \ : '='

Panoramica

Fondamentalmente questo confronta la prima parola di ogni riga con la riga precedente. Se le parole sono differenti allora la linea è inizio della piega, >1. Altrimenti mantiene lo stesso livello di piegatura, =.

Gloria dei dettagli

  • set foldmethod=expr per dire a Vim di usare un'espressione di script vim per determinare le pieghe
  • 'foldexpr' L'opzione contiene l'espressione dello script vim
  • Valutare la condizione con un ternario che ritorna >1quando dovrebbe iniziare una piega e =quando il livello di piega dovrebbe continuare
  • v:lnumè la riga corrente su cui 'foldexpr'è in esecuzione per aggiornare le pieghe
  • Ottieni il contenuto della riga corrente ( v:lnum) e della riga precedente ( v:lnum - 1) tramitegetline()
  • Dividi ogni riga in parole via split()
  • Utilizzare get()per ottenere il primo indice delle parole appena divise
  • Utilizzare un valore predefinito ''in caso di una riga vuota. per esempioget(words, 0, '')
  • Confronta la prima parola della riga corrente con la prima parola della riga precedente nella porzione condizione del ternario

Nota: questo metodo potrebbe presentare alcuni problemi di prestazioni con documenti molto grandi

Per ulteriori informazioni, consultare:

:h 'foldmethod'
:h 'foldexpr'
:h getline(
:h v:lnum
:h split(
:h get(
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.