Posible explicación del problema.
Creo que la razón por la :g/;/jque no funciona es porque el :gcomando funciona con un algoritmo de 2 pasos:
- durante la primera pasada marca las líneas que contienen el patrón
;
- durante la segunda pasada opera en las líneas marcadas
Durante la segunda pasada, :gune la línea 1;con la línea 2;porque 1;se marcó durante la primera pasada. Sin embargo, sospecho (no estoy seguro) que no se une 1; 2;con 3;ya que la línea 2;ya no existe, su contenido se ha fusionado con la línea 1;que ya ha sido procesado.
Entonces :gbusca la siguiente línea que se marcó durante el primer pase ( 3;) y la une con la siguiente ( 4;). Después de eso se repite el problema, no pueden unirse 3; 4;con 5;porque la línea 4;no existe más.
Solución 1 (con vimscript)
Tal vez podría llamar a una función siempre que ;se encuentre una línea que contenga para verificar si la línea anterior también contiene un punto y coma:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
Luego use el siguiente comando global:
:g/;/call JoinLines()
O sin una función:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
Solución 2 (sin vimscript)
:g/;/.,/^[^;]*$/-1j
Cada vez que el comando global :gencuentra el patrón ;, ejecuta el comando: .,/^[^;]*$/-1j
Se puede desglosar así:
:g/pattern/a,bj
Dónde :
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b puede desglosarse más de esta manera:
/ = 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
jes la forma abreviada del comando Ex :joinque, como la mayoría de los otros comandos Ex, puede ir precedida de un rango.
Aquí está precedido por el rango: .,/^[^;]*$/-1( a,b)
Un rango sigue la forma a,bdonde ay bgeneralmente son números de 2 líneas, y le permite operar en un grupo de líneas cuyo número está entre ay b, en lugar de solo uno.
Entonces, el jcomando une todas las líneas entre la actual ( a) y la siguiente que no contiene punto y coma menos uno ( b).
Para más información, ver:
:help :global
:help :join
:help :range
:g/;/jno funciona porque se realiza en dos pasadas: primero se escanea el búfer, luego se aplica el comando a las líneas coincidentes.