Vim: замена строки на другую, которую выдернули ранее

113

Хотя бы раз в день бывает такая ситуация:

A: This line should also replace line X
...
X: This is line should be replaced

Я считаю, что не выполняю эту задачу эффективно.

Что я делаю:

  • Перейти к строке A: AG
  • Линия янки A: yy
  • Перейти к строке X: XG
  • Вставить строку A: P
  • Перейти к старой строке: j
  • Удалить старую строку: dd

Это имеет дополнительный недостаток , что линия X в настоящем время в реестре по умолчанию, которая раздражает , если я найду другую линию , которая должна быть заменена А. дергать , чтобы и наклеивая от дополнительного регистра ( «его , » аР ) делает эту простую задачу даже менее эффективны.

Мои вопросы:

  • Пропустил ли я встроенную команду Vim для замены ранее удаленной строки?
  • Если нет, как я могу привязать свою собственную команду, которая оставляет (или восстанавливает) извлеченную строку в регистре по умолчанию?
хрустящие
источник
2
Это моя самая большая проблема с моделью редактирования Vim. Я хотел бы узнать решение. Редактор CUA различает вырезание и удаление, поэтому вы просто вырезаете текст, а затем можете удалить и вставить все, что хотите. С Vim любое удаление, которое вы делаете, приводит к уничтожению вырезанного текста. В итоге вы используете гораздо больше нажатий клавиш, чем другой редактор.
Грязь
3
ЯнкРинг
аджреал
@Mud узнать :moveи черная дыра регистр ( _) (или на самом деле, только регистры)
sehe
2
@sehe Я прекрасно знаю регистры, но это добавляет 4 нажатия клавиш на операцию вырезания / вставки и требует большей предусмотрительности. Когда вы много редактируете, это быстро складывается.
Mud
Есть ли преимущество в использовании регистра черной дыры по сравнению с любым другим регистром, кроме экономии нескольких байтов памяти? Я бы сказал, что любой регистр может быть регистром черной дыры, если вы не читаете его обратно.
sleblanc

Ответы:

91

Что бы я сделал:

  1. aG
  2. Y
  3. xG
  4. Vp

Вам не нужно выходить из нормального режима, но это действительно дергает линию. Однако вы можете использовать, V"0pкоторый всегда будет дергать линию на шаге 2.

icecrime
источник
11
@duddle: да, Yэто синонимyy
icecrime
8
Шаги 1 и 2 можно комбинировать с помощью: ay [например, 20y], за которым следует Vp. Вам не нужно идти к линии, чтобы дергать ее.
Bharad
2
Если вы перезаписываете дополнительные строки ccCTRL + r0ESC вместо V "0p, тогда все следующие строки можно заменить на just. (Повторитель)
Джордан Моррис
Yявляется синонимом для yy, но я предлагаю изменить его y$на соответствие Dи C.
золото
Ознакомьтесь с ответом Джордана Морриса stackoverflow.com/users/970673/jordan-morris ниже - действительно использует команды vim в полной мере, позволяя вам повторять команду несколько раз.
JESii
106

Vp: выберите строку, вставьте то, что было выдернуто

Дориан
источник
3
VPработает так же хорошо, что удобно, потому что вы можете удерживать Shift на протяжении всей последовательности.
Джордж Хиллиард
24
очень хороший трюк, хотя стоит отметить (возможно) существенное предостережение: это приводит к обновлению регистра yank содержимым перезаписываемой строки, поэтому он может плохо работать с некоторыми задачами - например, если вы хотите перезаписать одна и та же линия на несколько пунктов назначения.
underscore_d
8
@underscore_d, он отлично играет, если вы это делаете V"0p, который вставляет из последнего извлеченного регистра.
timblaktu
@timblaktu Вы можете объяснить, что V"0pделает? V переходит в режим визуальной линии, а p - для вставки. Что "и 0 для Thanks?
theprogrammer
43

Это имеет дополнительный недостаток, заключающийся в том, что строка X теперь находится в регистре по умолчанию, что раздражает, если я нахожу другую строку, которую следует заменить на A.

Чтобы удалить текст, не затрагивая обычные регистры, вы можете использовать регистр черной дыры "_:

"_dd
Евгений Ярмаш
источник
10
Я добавил некоторые отображения в моей .vimrc сделать dи ddвсегда использовать черную дыру, а xи xxвыполнять то , что большинство редакторов назвали бы «вырезать» (удалить и сохранить в регистре по умолчанию):noremap x d noremap xx dd noremap d "_d noremap dd "_dd
IMSoP
2
Я опасаюсь переназначения вещей в VIM, потому что это может быть непросто на других компьютерах или в плагинах в стиле VIM для IDE. Также дизайнеры VIM, как правило, решают проблемы с отображениями по умолчанию, если вы действительно копаете.
Джордан Моррис
15

Основываясь на ответах, предлагающих использовать Vpили VPвставить строку - чтобы избежать изменения содержимого регистра восстановления, я считаю, что наиболее эргономичная команда проста:

VPY

RichardW
источник
Это простейшее решение, при котором содержимое восстановления остается неизменным. Большое спасибо!
heylookltsme
14
  1. уу
  2. j (перейдите к строке, которую хотите заменить), а затем
  3. Vp (верхний регистр v, а затем p, заменит извлеченное содержимое)
Мариано Анайя
источник
здорово! Действительно, очень короткий и позволяет легко выбрать несколько строк в визуальном режиме. Это также сохраняет буфер пасты в целости. Досадно, когда dd перезаписывает этот буфер ...
Актау
@Aktau это не оставляет буфер нетронутым.
Джордан Моррис,
9

Я бы использовал режим командной строки (Ex) и выполнил следующие две команды

:XmA
:Ad

Это просто перемещает линию X чуть ниже A, затем удаление A перемещает эту линию вверх

Например

:7m3
:3d
Эрикгамлиэль
источник
Вы можете привести пример? Когда я нажимаю, например, 50Gm30G, Vim переходит к строке 50, а затем вниз, и все. Также: реклама ничего не делает для A = 50 или A = 50G
хрустящий
7
  1. Перейти к началу первой строки.

  2. y, $- скопировать строку без разрыва строки в конце

  3. Перейти к началу целевой линии.

    1. V, p- заменить только одну целевую строку

    2. c, c, Ctrlr, 0, Esc- заменить целевую строку с оригинальным рывком

  4. Перейти к началу следующей целевой линии.

  5. . - повторяет команду п. 4.2.

Ноты:

  • 4.1 y, $потому что если вы делаете y, yили Yвы будете копировать разрыв строки, и Ctrlr,  на 0самом деле добавляет разрыв строки ниже вашей целевой линии.

  • 4.2 заменяет V p, что не работает с повтором, потому что технически последним действием является удаление, поэтому .будет просто удалить строку.

  • Если кто-нибудь знает, как выполнить команду «заменить текущую строку регистром» из режима EX (командная строка), я хотел бы услышать от вас (и узнать, где вы нашли документацию). Может быть повторяемая команда EX, которая быстрее, чем 4.2 и / или не имеет предупреждения о переносе строки.

Джордан Моррис
источник
1
Шаг 4.2 здесь убийственный, так как теперь вы можете повторить весь процесс с помощью команды dot, как в 4.3 - вот что такое vim!
JESii
1
Я этого не понимаю. «AG» помещает мой производитель в конец строки, переходит в режим вставки и входит в «G». Что я не понимаю?
gustafbstrom,
@gustafbstrom справедливая критика - извините, A должен был представлять номер строки, но я не смог указать на это. Ред.
Джордан Моррис,
5

Вот что бы я сделал

  • Переместить начало строки A AG(где A, очевидно, номер строки)
  • Вернуть строку в какой-либо регистр, например, a (без новой строки). Тип"ay$
  • Перейти к строке вставки, XG
  • Подстановочная строка, S
  • Вставить из регистра а, Ctrl-Ra
Брайан Расмуссен
источник
4

Вы можете использовать это в визуальном режиме.

  • Перейти к строке A: AG
  • Выберите строку с визуальным режимом: VESC
  • перейти к строке X: XG
  • Войдите в режим замены для строки: S
  • Вставьте скопированную строку: shift+ insert(или что-то еще, что вы назначили для вставки из буфера обмена).
Натан Феллман
источник
Ах. Не знаю , о V и S . Однако ваши действия не работают для меня, поскольку я не дергаюсь за буфер обмена своей ОС, который является единственным, к которому я могу получить доступ в режиме вставки. Так что сначала мне придется выйти из режима вставки.
хрустящий
3

Вы также можете:

Vy (in normal mode at the line you want to copy)
Vp (in normal mode at the line you want to replace)
  • Не создает пробелов или концов строк.
  • Курсор помещается в начало скопированного текста.

Одни и те же клавиши могут использоваться для вставки / вставки более чем одной строки.

V (in normal mode at what you want to yank)
(use jk to move the selection)
y (to yank the selection)
V (in normal mode at where you want to paste)
(use jk to move the selection)
p (to replace the selection with the yanked lines)
Козьмонавт
источник
2

Вы можете использовать эти команды в нормальном режиме:

:AmX | Xd

mкоманда для m[ove], которая перемещает номер строки А после строки с номером X, если вы хотите скопировать , а не переместить линию, использование co[py]. dкоманда для d[elete].

Вы можете перемещать (копировать с помощью co) диапазон строк, используя

:start,end m X
Нафаа Бутефер
источник
2

В свете недавнего комментария cicld (спасибо!) Я вижу, что не полностью понял исходную проблему. Перемещение строки не подходит, но копирование возможно (поскольку строка дергается). Поэтому я бы изменил его так:

:1t20:20d_
  1. Скопируйте 1-ю строку ( :tкоманда является псевдонимом для :copy) после строки 20 (поместит ее в строку 21)

  2. Удалите строку 20, поместив удаленную строку в регистр 'черной дыры' ( _) (т.е. не затрагивая текущий буфер восстановления)

Как упоминалось в недавнем комментарии, это не повлияет на текущую позицию курсора.

nkalvi
источник
1
  1. : ay (где a - номер строки. Пример: 20y). Это дергает строку (каламбур).
  2. Вп
Bharad
источник
1

Я считаю, что для этого проще использовать команду Ex; ех. чтобы переместить строку 9 на 46:

 :46|9m.|-1d

Это переместит курсор на строку 46, переместит строку 9 ниже текущей, затем удалит предыдущую строку (поскольку перемещенная строка является текущей).

Или используя метку (метки), используя метку 'a':

:46ma a|9m'a|'ad
nk3181544
источник
Прелесть команд EX в том, что вы можете запускать их, где бы ни находился курсор (в обычном режиме). Я предпочитаю :1m20|.+1d(переместите строку 1 в строку 20 и удалите следующую строку, т. Е. Текст, который ранее был в строке 20). Та же идея!
около
1

Мне часто приходится использовать Y одну строку и заменять ее в нескольких местах, каждое из которых имеет другое значение (что означает, что я не могу выполнять регулярное выражение).

Y чтобы выдернуть желаемую исходную строку

а затем в каждой строке, которую вы хотите заменить, VpzeroY

Рон
источник
0

Я бы просто использовал регистр «Черная дыра»:

дано:

nnoremap <Cd> "_dd

решение было бы:

<Cd> гг

j5shi
источник