В Vim есть способ удалить без внесения текста в реестр?


470

Используя Vim, я часто хочу заменить блок кода блоком, который я только что дернул.

Но когда я удаляю блок кода, который должен быть заменен, этот блок сам попадает в регистр, который стирает блок, который я только что дернул. Таким образом, у меня есть привычка дергать, затем вставлять, затем удалять то, что я не хотел, но с большими блоками кода это становится беспорядочным, пытаясь сохранить вставленный блок и блок для удаления отдельно.

Так какой же самый простой и быстрый способ заменить текст в Vim?

  • Есть ли способ удалить текст без внесения его в реестр?
  • Есть ли способ сказать, например, «заменить следующее слово» или «заменить до следующего абзаца»
  • или это лучший способ как-то использовать функцию мультирегистрации?

1
vim-easyclip ( github.com/svermeulen/vim-easyclip ) предназначен для решения именно этой проблемы
Стив Вермёлен

1
Я задал вопрос, неосознанно (в то время) дубликат вашей реальной проблемы , но не так много заглавного вопроса. TL; DR - заменить тем, что вы дернули, используя viwp(для word).
OJFord

Ответы:


429

Чтобы удалить что-то без сохранения в реестре, вы можете использовать «регистр черной дыры»:

"_d

Конечно, вы также можете использовать любые другие регистры, которые не содержат ничего, что вас интересует.


4
Сначала я думал, что эта команда не работает должным образом. Затем я понял, что использую версию американской клавиатуры «мертвые клавиши». С этой раскладкой клавиатуры я должен печатать "<space>_d. Пространство необходимо, чтобы на самом деле набрать ".
Себастьян Гриньоли

4
Любые идеи делать это выборочно только на пустых строках? (Если я ddна пустой строке, то он уходит в черную дыру, в противном случае это ddкак обычно).
Джонатан Думайн

6
Чтобы удалить одного персонажа, попробуйте:"_x
kenorb

54
Это одна из областей, где выигрывает стандартный текстовый редактор. Вы просто нажимаете клавишу удаления.
Винс Пануччо

22
Вы также можете нажать что-нибудь с помощью yyили '3yy' (или что-то еще), что помещает это в неназванный регистр, но также и в 0. Вы можете затем продолжить вставлять это "0p, несмотря на то, что использовали dпосле этого.
Halfgaar

102

Ага. Это немного сложнее, чем сначала удалить «старый» текст, но:

Я начинаю с ..

line1
line2
line3
line4

old1
old2
old3
old4

Я shift+ vвыбираю строку 1, строку 2, 3 и 4 и удаляю их dкомандой

Затем я удаляю старые 1-4 строки таким же образом.

Затем сделать

"2p

Это вставит вторую последнюю строчку (строки 1-4). "3pбудет делать третий из последних, и так далее ..

Так что я в конечном итоге

line1
line2
line3
line4

Справка: Vim документация по нумерованному регистру


Если вы выбираете строки с помощью <Shift-v>, вы удаляете их просто с помощью d, а не dd
Хейкки Наски

31
От 1 до 9 работает для удалений. Чтобы вставить последнюю вещь, действительно выдернутую (с 'y'), вы должны использовать "0p. Это полезно в тех случаях, когда вы сначала дергаете что-то, намеревающееся заменить что-то другое, но затем что-то другое перезаписывает регистр вставки по умолчанию.
Рафаэль де Ф. Феррейра

Для дополнительной проверки отмены утонченности из в Гундо (графический отмен) сценария .
Луми

@ RafaeldeF.Ferreira: Ваш комментарий не является ответом на этот вопрос, но на самом деле он, вероятно, решает реальную проблему, которая привела к тому, что ОП задала вопрос. Для меня это было настоящей проблемой.
0xc0de

76

Документы VIM: пронумерованный регистр 0 содержит текст самой последней команды yank, если в команде не указан другой регистр с ["x].

Например, мы дергаем «foo» и удаляем «bar» - реестр 0 по-прежнему содержит «foo»! Следовательно, «foo» можно вставить с помощью"0p


53

Удобно иметь простое сопоставление, которое позволяет заменить текущий выбор буфером.

Например, когда вы положите это в свой .vimrc

vmap r "_dP       // it's a capital 'p' on the end

затем, после копирования чего-либо в регистр (то есть с помощью «y»), вы можете просто выбрать текст, который вы хотите заменить, и просто нажать «r» на клавиатуре. Выбор будет заменен вашим текущим регистром.

Объяснение:

vmap - mapping for visual mode
"_d - delete current selection into "black hole register"
P - paste

1
Для более продвинутой версии, проверьте: stackoverflow.com/questions/290465/…
Люк Эрмитт

Я хотел бы использоватьvmap <C-P> "_dP
Гарри Ли

7
Вы можете просто поместить текст, не удаляя выделение. Например, Vpзаменяет вашу текущую строку на выдернутую сразу.
Бобби Маринофф,

Это решение не устраняет проблему d, которая часто используется для удаления.
Виктор Ярема

35

Я вставил следующее в мой vimrc:

noremap  y "*y
noremap  Y "*Y
noremap  p "*p
noremap  P "*P
vnoremap y "*y
vnoremap Y "*Y
vnoremap p "*p
vnoremap P "*P

Теперь я возвращаюсь к регистру буфера обмена и вставляю его, и мне нет дела до того, что происходит с регистром по умолчанию. Дополнительным преимуществом является то, что я могу вставлять из других приложений с минимальными хлопотами. Я теряю некоторые функциональные возможности, я знаю, но я все равно не могу отслеживать более одного регистра / буфера обмена.


6
Вместо всех этих переназначений вы могли бы также set clipboard=unnamedили set clipboard=unnamedplus, что изменяет буфер обмена по умолчанию на *или +, соответственно.
Стив

5
@ Steve Если вы сделаете это, то d также перезапишет последний рывок в регистр буфера обмена, чего и пытается избежать вопрос.
79E09796

1
@ 79E09796, я не имел в виду, что так и будет; Я комментировал этот ответ, а не оригинальный вопрос.
Стив

1
Я положил их в свой .vimrc, и теперь дергание не работает. Есть идеи почему?
TBA

2
@tba замените noremap на nnoremap (два n), и он должен работать нормально.
meain

24

Для конкретного примера, который вы привели, если я понимаю вопрос, тогда это может сработать:

*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)

6
Это работает хорошо, за исключением случаев, когда вы хотите вставить несколько вариантов.

23

Все операции удаления и удаления по умолчанию записываются в безымянный регистр. Тем не менее, самые последние янки и самые последние удаления всегда сохраняются (отдельно) в пронумерованных регистрах. В реестре 0хранятся самые последние янки. Регистры 1-9содержат 9 самых последних удалений ( 1причем самые последние).

Другими словами, удаление перезаписывает самый последний рывок в неназванном регистре, но он все еще там в 0регистре. Уловка blackhole-register ( "_dd), упомянутая в других ответах, работает, потому что она предотвращает перезапись безымянного регистра, но это не обязательно.

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

"0p

Это отличная ссылка:


16

Чтобы подчеркнуть, что EBGreen сказал :

Если вы вставляете текст при выделении текста, выделенный текст заменяется вставленным текстом.

Если вы хотите скопировать текст, а затем вставить его в нескольких местах, используйте "0pдля вставки. Нумерованный регистр 0 содержит текст самой последней команды yank.


Также вы можете перечислить содержимое всех ваших регистров:

:registers

Эта команда облегчает определение того, какой регистр вы хотите, когда делаете что-то вроде ответа dbr . Вы также увидите регистры /,%, #. (См. Также :help registers)


И, наконец, проверить cWи cWизменить слово, включая и не включая завершающий пробел. (Использование заглавных Wбукв включает пунктуацию.)


10

Если вы используете Vim, то у вас будет визуальный режим, который подобен выбору, но с разделением режимов, который является основой vi / vim.

То, что вы хотите сделать, это использовать визуальный режим, чтобы выбрать источник, затем нажать, затем снова использовать визуальный режим, чтобы выбрать область назначения, а затем вставить текст в буфер по умолчанию.

Пример:

В текстовом файле с:

1 | Qwer
2 | ASDF
3 | zxcv
4 | poiu

со следующей последовательностью: ggVjyGVkpвы закончите с:

1 | Qwer
2 | ASDF
3 | qewr
4 | ASDF

Разъяснение:

  • gg: перейти к первой строке
  • V: запустить визуальный режим с целыми строками
  • j: перейти на одну строку вниз (при выборе, начатом на предыдущих строках, это увеличивает выделение на одну строку вниз)
  • y: вернуть в буфер по умолчанию (две выбранные строки, и он автоматически выходит из визуального режима)
  • G: перейти к последней строке
  • V: запустить визуальный режим (как и раньше)
  • k: перейти на одну строку вверх (как и раньше, при включенном визуальном режиме выделение увеличивается на одну строку вверх)
  • p: paste (с выделением на двух последних строках, он заменит эти строки тем, что есть в буфере - в этом случае 2 первые строки)

Это немного неудобно, так как последний блок помещается в буфер, так что он как-то нежелателен для повторных вставок одной и той же вещи, поэтому вы захотите сохранить источник в именованный буфер с чем-то вроде "ay(в буфер, называемый "a ") и вставьте что-то вроде "ap(но тогда, если вы программируете, вы, вероятно, не хотите вставлять несколько раз, но создаете функцию и вызываете ее, верно? ВПРАВО ?).

Если вы используете только vi, тогда вам придется использовать невидимые метки вместо визуального режима, но :he markоб этом, извините, но я не очень хорош в этом невидимом знаке, я довольно загрязнен визуальным режимом.


10

Для «заменить слово», попробуйте cwв обычном режиме.

Для «замены абзаца» попробуйте capв обычном режиме.


1
Для «заменить до следующего абзаца» попробуйте c}в обычном режиме.
Джабирали

Почему «кепка» это делает? Разве «а» и «р» не означают «добавить» и «вставить»?
WiSaGaN

2
@WiSaGaN «ap» означает «абзац»: vimhelp.appspot.com/motion.txt.html#object-select
Swaroop CH

9

Минимально инвазивное решение для ленивых:

Регистр 0всегда содержит последний янки (как уже упоминали Рафаэль , alex2k8 и idbrii ). К сожалению, выбор регистрации 0все время может быть довольно раздражающим, поэтому было бы неплохо, если бы он pиспользовался "0по умолчанию. Это может быть достигнуто путем добавления следующих строк в ваш .vimrc:

noremap p "0p
noremap P "0P
for s:i in ['"','*','+','-','.',':','%','/','=','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
    execute 'noremap "'.s:i.'p "'.s:i.'p'
    execute 'noremap "'.s:i.'P "'.s:i.'P'
endfor

Первая строка отображает каждый pштрих "0p. Однако это предотвращает pдоступ к любым другим регистрам. Поэтому все pштрихи с явно выбранным регистром отображаются в эквивалентное выражение командной строки внутри цикла for. То же самое сделано для P.

Таким образом стандартное поведение сохраняется, за исключением неявного pи Pштрихов, которые теперь используют регистр 0по умолчанию.

Подсказка 1: команда cut теперь "0dвместо just d. Но так как я ленив, это слишком долго для меня;) Поэтому я использую следующее отображение:

noremap <LEADER>d "0d
noremap <LEADER>D "0D

Клавиша-лидер \по умолчанию, поэтому вы можете легко вырезать текст, набрав \dили \D.

Подсказка 2: время ожидания по умолчанию для многоключевых сопоставлений довольно короткое. Возможно, вы захотите увеличить его, чтобы иметь больше времени при выборе регистра. Подробности :help timeoutlenсмотрите, я использую:

set timeout timeoutlen=3000 ttimeoutlen=100

7

Ну, сначала выполните эту команду:

:h d

Тогда вы поймете, что можете удалить в конкретный реестр. Таким образом, вы не будете изменять то, что находится в вашем регистре по умолчанию.


1
["x]d{motion} Delete text that {motion} moves over [into register x]- Вим:h d
Уэс Тёрнер

5

Моя ситуация: в Normalрежиме, когда я удаляю символы с помощью xнажатия клавиши, эти удаления перезаписывают мой последний регистр - затрудняет редактирование, когда я хочу удалить символы, используя xи вставляя что-то, что у меня есть в моем последнем регистре (например, вставляя один и тот же текст в два или больше мест).

Я попробовал предложение в принятом ответе ( "_d), но оно не сработало.

Однако из принятого ответа / комментариев по адресу /vi/122/performing-~/.vimrc sure-operations-without-clearing-register я добавил это в свой список , который работает (возможно, вам придется перезапустить Vim ):

nnoremap x "_x

То есть теперь я могу выполнять свои обычные команды yank ( y), delete ( d) и paste ( p) - и символы, которые я удаляю, xбольше не заполняют самые последние регистры.


4

Текст, удаленный в режиме вставки, не попадает в регистр по умолчанию.


2
но удаление любого значительного объема текста в режиме по умолчанию - МЕДЛЕННО
Хэмиш Даунер

3

Два решения, которые я использую в правильном контексте:

  • выделите то, что вы хотите заменить в VISUALрежиме Vims, затем вставьте регистр.

Я использую это в основном по привычке, так как я нашел второе решение намного позже, например

yiw   " yank the whole word
viwp  " replace any word with the default register
  • ЯнкРинг . С этим плагином вы можете использовать связывание клавиш, <ctrl>+<p>чтобы заменить предыдущий пронумерованный регистр на тот, который вы только что вставили.

По сути, вы продолжаете вставлять как обычно, но когда вы понимаете, что с тех пор вы перезаписали регистр по умолчанию, теряя то, что вы на самом деле хотели вставить, вы можете <C-P>найти и заменить из истории YankRing!

Один из них должен иметь плагины ...



2

В версии для Windows (возможно, и в Linux) вы можете войти в системный буфер копирования / вставки, используя "*y (т.е. перед вашей командой yank двойные кавычки и звездочку).

Затем вы можете удалить заменяемые строки как обычно и вставить скопированный текст, используя "*p.


2

Я часто ошибаюсь, когда следую командам 'y'ank затем' '_d' удалить в черную дыру, а затем 'p'aste. Я предпочитаю' y'ank, затем удалить, как мне нравится, затем '' 0p 'из регистр 0, куда помещается последний скопированный текст.


2

Для злых пользователей emacs эта функция (evil-paste-pop)может быть запущена после вставки и циклически повторять предыдущие записи в kill-ring. Предполагая, что вы привязали его к <C-p>(по умолчанию в Spacemacs), вы должны нажать pстолько, <C-p>сколько вам нужно.


1

Для пользователей Dvorak, один очень удобный способ - просто удалить ненужный текст в регистр «1» вместо «_ регистр черной дыры», хотя бы потому, что вы можете нажать «+ 1 с тем же нажатием Shift и быстрым движением мизинца, поскольку ключ сразу над "в Двораке" (плюс d в другой руке, что делает всю команду быстрой, как ад).

Тогда, конечно, регистр "1" может использоваться для других целей из-за его удобства, но если у вас нет более общей цели, чем замена текста, я бы сказал, что это довольно хорошее использование регистра.


1

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

Вы можете использовать следующее решение, которое легко и лучше всего работает для меня:

xnoremap <expr> p 'pgv"'.v:register.'y'

Это из ответов (и комментариев) здесь: Как вставить без перезаписи регистра

Сначала он проходит после выделения, затем снова выбирается выделение с новым текстом (gv). Теперь регистр, который последний раз использовался в визуальном режиме (обычно это неназванный регистр, но он работает также без побочных эффектов, если вы используете другой регистр для вставки). А затем снова введите новое значение в регистр.

PS: Если вам нужен более простой вариант, который работает также с vim-имитацией плагина intellj idea, вы можете воспользоваться этим (недостаток: перезаписать безымянный регистр, даже если для вставки был задан другой регистр):

vnoremap p pgvy


1

Для тех, кто использует JetBrans IDE (PhpStorm, WebStorm, IntelliJ IDEA) с IdeaVim. Возможно, у вас возникли проблемы с переназначением, например, nnoremap d "_dс использованием его для удаления строки dd. Возможное решение для вас:nnoremap dd "_dd

Есть проблемы на вашем треке, пожалуйста, проголосуйте за них: https://youtrack.jetbrains.com/issue/VIM-1189 https://youtrack.jetbrains.com/issue/VIM-1363


0

Случайное предпочтение Vim сложности по сравнению с практичностью обременяет пользователя применением регистров для копирования / удаления действий - когда чаще всего нужно просто вставить то, что было скопировано, и «забыть», что было удалено.

Однако вместо того, чтобы бороться со сложными регистрами vim, сделайте их более удобными: выберите регистр «по умолчанию» для хранения вашего последнего удаления. Например, отправьте удаления в регистр d (оставив переменную открытой для специального использования; d - хорошая мнемоника):

nnoremap d "dd           "send latest delete to d register
nnoremap D "dD           "send latest delete to d register 
nnoremap dd "ddd         "send latest delete to d register
nnoremap x "_x           "send char deletes to black hole, not worth saving
nnoremap <leader>p "dp   "paste what was deleted
nnoremap <leader>P "dP   "paste what was deleted

Этот подход предотвращает удаление удалений янки, НО не теряет регистрацию удаления - можно вставить (вернуть) то, что было удалено, вместо того, чтобы потерять его в черной дыре (как в принятом ответе). В приведенном выше примере это повторение выполняется с помощью двух отображений лидера p. Преимущество этого подхода заключается в том, что он дает вам возможность выбрать, что вставлять: (a) что было только что выдернуто или (b) что было только что удалено.


0

регистр от 0 до 9 - это последние события, которые вы ударили или вырезали и т. д., НЕ включайте удаленные элементы и т. д. Поэтому, если вы что-то дергаете / вырезаете, это также входит в регистр 0, даже если вы говорите, что удалили весь день после этого, зарегистрируйте 0 все еще последний материал, который вы дернули

yiw # идет как в регистр по умолчанию, так и в регистр 0

он дергает слово, в котором находится курсор

удаленные вещи и т. д. будут идти в регистр по умолчанию, но НЕ регистрироваться 0

в стандартном режиме:

"0p # введите содержимое регистра 0

в режиме вставки:

ctrl-r 0 # вывести содержимое регистра 0

У меня также был друг, который всегда дергал / разрезал, чтобы зарегистрировать х лол.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.