Possibile spiegazione del problema
Penso che il motivo per cui :g/;/j
non funziona sia perché il :g
comando funziona con un algoritmo a 2 passaggi:
- durante il primo passaggio segna le linee che contengono il motivo
;
- durante il secondo passaggio opera sulle linee segnate
Durante il secondo passaggio, :g
unisce la linea 1;
con la linea 2;
perché è 1;
stata contrassegnata durante il primo passaggio. Tuttavia ho il sospetto (non sono sicuro) che non si unisce 1; 2;
con 3;
perché la linea 2;
non esiste più, il suo contenuto è stata fusa con la linea 1;
, che è già stato elaborato.
Quindi :g
cerca la riga successiva che è stata contrassegnata durante il primo passaggio ( 3;
) e si unisce a quella successiva ( 4;
). Dopo di che le ripetizioni problema, non possono partecipare 3; 4;
con 5;
perché la linea 4;
non esiste più.
Soluzione 1 (con vimscript)
Forse potresti chiamare una funzione ogni volta che ;
viene trovata una riga contenente per verificare se la riga precedente contiene anche un punto e virgola:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
Quindi utilizzare il seguente comando globale:
:g/;/call JoinLines()
O senza una funzione:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
Soluzione 2 (senza vimscript)
:g/;/.,/^[^;]*$/-1j
Ogni volta che il comando globale :g
trova il modello ;
esegue il comando: .,/^[^;]*$/-1j
Può essere suddiviso in questo modo:
:g/pattern/a,bj
Dove :
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b
può essere ulteriormente suddiviso in questo modo:
/ = look for the number of the next line matching the following pattern
^ = a beginning of line
[^;] = then any character except a semicolon
* = the last character can be repeated 0 or more times
$ = an end of line
/ = end of pattern
-1 = removes one to the number you just got
j
è la forma abbreviata del comando Ex :join
che come la maggior parte degli altri comandi Ex può essere preceduta da un intervallo.
Qui è preceduto dalla catena: .,/^[^;]*$/-1
( a,b
)
Una gamma segue la forma a,b
dove a
e b
sono generalmente 2 numeri di riga, e permette di operare su un gruppo di linee cui numero è compreso tra a
e b
, invece di uno solo.
Quindi il j
comando unisce tutte le linee tra quella corrente ( a
) e quella successiva che non contiene punti e virgola meno uno ( b
).
Per ulteriori informazioni, vedere:
:help :global
:help :join
:help :range
:g/;/j
non funziona perché viene eseguito in due passaggi: prima viene scansionato il buffer, quindi il comando viene applicato alle righe corrispondenti.