Возможное объяснение проблемы
Я думаю, что причина :g/;/jне работает, потому что :gкоманда работает с 2-х проходным алгоритмом:
- во время первого прохода он отмечает строки, содержащие шаблон
;
- во время второго прохода он работает на отмеченных линиях
Во время второго прохода :gсоединяет линию 1;со строкой, 2;потому что 1;был отмечен во время первого прохода. Однако я подозреваю (не уверен) , что он не вступает 1; 2;с , 3;потому что линия 2;больше не существует, его содержание было объединено с линией , 1;которая уже была обработана.
Поэтому :gищет следующую строку, которая была отмечена во время первого прохода ( 3;), и объединяет ее со следующей ( 4;). После того, что проблема повторяется, она не может присоединиться к 3; 4;с , 5;потому что линия 4;больше не существует.
Решение 1 (с vimscript)
Возможно, вы можете вызывать функцию всякий раз, когда ;найдена строка, содержащая строку, чтобы проверить, содержит ли предыдущая строка точку с запятой:
function! JoinLines()
if getline(line('.')-1) =~ ';'
.-1join
endif
endfunction
Затем используйте следующую глобальную команду:
:g/;/call JoinLines()
Или без функции:
:g/;/if getline(line('.')-1) =~ ';' | -j | endif
Решение 2 (без vimscript)
:g/;/.,/^[^;]*$/-1j
Всякий раз, когда глобальная команда :gнаходит шаблон, ;она выполняет команду: .,/^[^;]*$/-1j
Это может быть разбито так:
:g/pattern/a,bj
Куда :
pattern = ;
a = . = number of current line
b = /^[^;]*$/-1 = number of next line without any semicolon minus one
b может быть разбит дальше, как это:
/ = 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это сокращенная форма команды Ex, :joinкоторой, как и большинству других команд Ex, может предшествовать диапазон.
Здесь ему предшествует диапазон: .,/^[^;]*$/-1( a,b)
Диапазон следует за формой, a,bгде aи bобычно представляют собой 2 номера строки, и позволяет вам работать с группой строк, число которых находится между aи bвместо одной.
Таким образом, jкоманда объединяет все строки между текущей ( a) и следующей строкой, которая не содержит точку с запятой минус один ( b).
Для получения дополнительной информации см .:
:help :global
:help :join
:help :range
:g/;/jне работает, потому что это делается в два прохода: сначала сканируется буфер, затем команда применяется к совпадающим строкам.