Possibile spiegazione del problema
Penso che il motivo per cui :g/;/jnon funziona sia perché il :gcomando 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, :gunisce 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 :gcerca 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 :gtrova 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 :joinche 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,bdove ae bsono generalmente 2 numeri di riga, e permette di operare su un gruppo di linee cui numero è compreso tra ae b, invece di uno solo.
Quindi il jcomando 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/;/jnon funziona perché viene eseguito in due passaggi: prima viene scansionato il buffer, quindi il comando viene applicato alle righe corrispondenti.