Существует ли специальный способ объединения двух блоков текста путем чередования строк, например, переходя от этого:
a1
a2
a3
a4
b1
b2
b3
b4
к тому, что:
a1
b1
a2
b2
a3
b3
a4
b4
в нескольких командах?
РЕДАКТИРОВАТЬ : Мне очень нравится решение Сато Кацура , вот как я его реализовал:
function! Interleave()
" retrieve last selected area position and size
let start = line(".")
execute "normal! gvo\<esc>"
let end = line(".")
let [start, end] = sort([start, end], "n")
let size = (end - start + 1) / 2
" and interleave!
for i in range(size - 1)
execute (start + size + i). 'm' .(start + 2 * i)
endfor
endfunction
" Select your two contiguous, same-sized blocks, and use it to Interleave ;)
vnoremap <pickYourMap> <esc>:call Interleave()<CR>
vimscript
formatting
merge
Яго-лито
источник
источник
scroll-binding
двух окнах Vim.b1
, затем нажимаю,vip
чтобы выбрать весь кусок, а затем,it
- это<map-I've-Picked>
. Разве это не работает на вашей стороне?Ответы:
Нет специального способа сделать это (насколько я знаю), но да, это можно сделать с помощью нескольких команд:
Вы можете запустить его с
:call Interleave(5, 8, 1)
. Первый параметр - это первая строка для перемещения, вторая - последняя строка, а третий - куда их перемещать. Вы, вероятно, хотите включить номера строк, чтобы увидеть, что вы делаете (:set number
).Это предполагает, что блоки не перекрываются. Смотрите
:help :move
и:help range()
понимайте, как работает функция.Вероятно, есть более эффективные способы подобрать два блока. Вокруг плавающего плагина, который должен поменять местами два блока. Я не могу вспомнить название плагина, но автор (возможно, знаменитый доктор Чип?) Уделил больше внимания поиску интерфейса, чем я. :)
источник
start
иsize
. С функцией доморощенного, которая извлекает эти значения из выбора, это будет просто идеально. Я работаю над этим. :)Вот еще одна альтернатива:
Сначала скопируйте строки, расположенные на 4 строки ниже, после текущей строки (
:h :t
), затем удалите последовательные строки b (:h :d
)Еще лучше эта команда:
Это означает, что для каждой строки, начинающейся с поиска, найдите следующую строку, начинающуюся с 'b', и переместите ее ниже текущей строки.
источник
.+,$d
вместо этого, и это сработало (как сделал.+,.+4d
)./^\s*b
на другой:range
. Например: выбрать 1-й блок, выполнить'<,'>g/^/'>+1m.
'>+1
помечает начало 2-го блока.Если вы хотите немного повеселиться с макросами и метками, вы можете попробовать что-то вроде этого:
Сначала поставить знак (здесь
a
) на строке , содержащейa1
сma
Перейти к строке, содержащей
b1
и пометить ееmb
Начните запись макроса в регистр, который вы хотите (здесь регистр
q
) сqq
Вставьте следующее в ваш макрос:
ddmb'apjma'b
Прекратить запись макроса с
q
Играйте в нее столько раз, сколько необходимо, с
X@q
указаниемX
количества времени, которое вы можете воспроизвести.Чтобы детализировать макрос:
Редактировать Как упоминал Лаго-Лито в комментариях, этот метод будет перезаписывать метки и буферы.
Что касается отметок, я не думаю, что это реальная проблема: я редко использую все 26 отметок в буфере, и я думаю, что большую часть времени можно найти 2 свободных отметки.
Для буфера можно сохранить его во временной переменной: перед записью макроса используйте
:let saveReg=getreg('"')
для сохранения регистра, а после завершения действия используйте:call setreg('"', saveReg)
для возврата регистра в его предыдущее состояние.В любом случае я должен признать, что это решение является быстрым обходным путем и не оптимальным: по моему мнению , ответ Кристана является лучшим и должен быть принят, потому что он не мешает с буферами и метками, не заставляет пользователя создавать функция и показывает силу глобальной команды.
источник
getreg()
иsetreg()
сохранить буфер. Но я согласен, что это не оптимальное решение :-)Я только что видел другой подобный вопрос, и решение состоит из:
Перейти к середине плюс один:
И запустить:
источник