Возможное объяснение проблемы
Я думаю, что причина :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
не работает, потому что это делается в два прохода: сначала сканируется буфер, затем команда применяется к совпадающим строкам.