В Vim есть способ удалить без внесения текста в реестр?
-
09-06-2019 - |
Вопрос
Используя Vim, мне часто хочется заменить блок кода блоком, который я только что дернул.
Но когда я удаляю блок кода, который нужно заменить, этот блок сам попадает в регистр, который стирает блок, который я только что выдернул.Итак, у меня появилась привычка выдергивать, затем вставлять, а затем удалять то, что мне не нужно, но с большими блоками кода это становится беспорядочным, пытаясь сохранить вставленный блок и блок, который нужно удалить, отдельно.
Так какой же самый простой и быстрый способ заменить текст в Vim?
- есть ли способ удалить текст не занося его в реестр?
- есть ли способ сказать, например?«заменить следующее слово» или «заменить до следующего абзаца»
- или это лучший способ как-то использовать функцию нескольких регистров?
Решение
Чтобы удалить что-либо, не сохраняя это в реестре, вы можете использовать «регистр черной дыры»:
"_d
Конечно, вы также можете использовать любой другой регистр, который не содержит ничего, что вас интересует.
Другие советы
Ага.Это немного более запутанно, чем сначала удалить «старый» текст, но:
Я начинаю с..
line1
line2
line3
line4
old1
old2
old3
old4
я сдвиг+в выберите строку 1, строку 2, 3 и 4 и удалите их с помощью кнопки д команда
Затем таким же образом удаляю старые 1-4 строки.
Затем сделайте
"2p
Это вставит предпоследние выдернутые строки (строки 1-4). "3p
сделаю третье от последнего и так далее..
Итак, я получаю
line1
line2
line3
line4
Документы ВИМ: Пронумерованный регистр 0 содержит текст из самой последней команды YANK, если только команда не указала другой регистр с ["x].
Например.мы выдергиваем «foo» и удаляем «bar» — реестр 0 все еще содержит «foo»!Следовательно, «foo» можно вставить, используя "0p
Удобно иметь простое сопоставление, которое позволяет заменить текущий выбор буфером.
Например, когда вы поместите это в свой .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
Я поместил следующее в свой 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
Теперь я извлекаю и помещаю из регистра буфера обмена, и меня не волнует, что происходит с регистром по умолчанию.Дополнительным преимуществом является то, что я могу вставлять данные из других приложений с минимальными трудностями.Я знаю, что теряю некоторые функциональные возможности, но в любом случае я просто не могу отслеживать более одного регистра/буфера обмена.
В конкретном примере, который вы привели, если я понимаю вопрос, это может сработать:
*Highlight what you want to put somewhere else
*delete (d)
*Highlight the code that you want it to replace
*paste (p)
Все операции извлечения и удаления по умолчанию записываются в безымянный регистр.Однако самое последнее копирование и самое последнее удаление всегда сохраняются (отдельно) в пронумерованных регистрах.Регистр 0
содержит самый последний рывок.Регистры 1-9
хранить 9 последних удалений (с 1
является самым последним).
Другими словами, удаление перезаписывает самую последнюю запись в безымянном регистре, но она все еще находится в 0
регистр. Трюк с регистром черной дыры ("_dd
), упомянутый в других ответах, работает, потому что предотвращает перезапись безымянного регистра, но в этом нет необходимости.
Вы ссылаетесь на регистр, используя двойные кавычки, поэтому вставку последнего извлеченного текста можно выполнить следующим образом:
"0p
Это отличная ссылка:
Чтобы подчеркнуть то, что ЭБГрин сказал:
Если вы вставляете текст при выделении текста, выделенный текст заменены с вставленным текстом.
Если вы хотите скопировать текст, а затем вставить его в несколько мест, используйте "0p
вставить.Нумерованный регистр 0 содержит текст последней команды извлечения.
Также вы можете перечислить содержимое всех ваших регистров:
:registers
Эта команда упрощает определение того, какой регистр вам нужен, когда вы делаете что-то вроде ответ дбр.Вы также увидите регистры /,%,#.(Смотрите также :help registers
)
И, наконец, проверьте cW
и cW
изменить слово, включая и не включая конечный пробел.(Использование капитала W
включает знаки препинания.)
Если вы используете 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
:вставить (при выборе двух последних строк он заменит эти строки всем, что есть в буфере - в данном случае двумя первыми строками)
Это имеет небольшое неудобство, заключающееся в том, что последний блок помещается в буфер, поэтому повторная вставка одного и того же объекта почему-то нежелательна, поэтому вам нужно сохранить исходный код в именованный буфер с помощью чего-то вроде "ay
(в буфер с именем «a») и вставьте что-то вроде "ap
(но тогда, если вы программируете, вам, вероятно, не нужно вставлять несколько раз, а нужно создать функцию и вызвать ее, верно? ВЕРНО?).
Если вы используете только vi, вам придется использовать невидимые метки вместо визуального режима. :he mark
подробнее об этом, извините, но я не очень хорошо разбираюсь в этой штуке с невидимыми метками, я сильно запутался в визуальном режиме.
Для «заменить слово» попробуйте cw
в обычном режиме.
Для «заменить абзац» попробуйте cap
в обычном режиме.
Минимально инвазивное решение для ленивых:
регистр 0
всегда содержит последний рывок (так как Рафаэль, Алекс2к8 и Идбри уже упоминали).К сожалению, выбор регистрации 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: Команда вырезания теперь "0d
вместо того, чтобы просто d
.Но поскольку я ленив, для меня это слишком долго;) Поэтому я использую следующее отображение:
noremap <LEADER>d "0d
noremap <LEADER>D "0D
Ключ лидера – это \
по умолчанию, поэтому вы можете легко вырезать текст, набрав \d
или \D
.
Подсказка 2: Тайм-аут по умолчанию для сопоставлений нескольких клавиш довольно короткий.Возможно, вы захотите увеличить его, чтобы иметь больше времени при выборе регистра.Видеть :help timeoutlen
для подробностей я использую:
set timeout timeoutlen=3000 ttimeoutlen=100
Ну, сначала выполните эту команду:
:h d
Тогда вы поймете, что можете удалить в определенный регистр.Таким образом, вы не будете изменять то, что находится в реестре по умолчанию.
Текст, удаленный в режиме вставки, не попадает в регистр по умолчанию.
Два решения, которые я использую в правильных контекстах:
- выделите то, что вы хотите заменить, используя Vims
VISUAL
mode, затем вставьте реестр.
Я использую это в основном по привычке, так как второе решение я нашел только намного позже, например
yiw " yank the whole word
viwp " replace any word with the default register
- ЯнкРинг.С помощью этого плагина вы можете использовать привязку клавиш
<ctrl>+<p>
чтобы заменить предыдущий пронумерованный регистр на тот, который вы только что вставили.
По сути, вы выполняете вставку, как обычно, но когда вы понимаете, что с тех пор вы перезаписали регистр по умолчанию, потеряв тем самым то, что вы на самом деле хотели вставить, вы можете <C-P>
найти и заменить из истории YankRing!
У одного из них должны быть плагины...
Я нашел очень полезное сопоставление для вашей цели:
xnoremap p "_dP
Удаленный текст помещается в «регистр черной дыры», а выдернутый текст остается.
Источник: http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text
В версии для Windows (вероятно, и в Linux) вы можете выполнить рывок в системный буфер копирования/вставки, используя "*y
(т.е.перед командой yank используйте двойные кавычки и звездочку).
Затем вы можете удалить заменяемые строки обычным способом и вставить скопированный текст, используя "*p
.
Я часто делаю ошибку, выполняя команды «y'ank, затем '»_d'elete в черную дыру, а затем 'p'aste.Я предпочитаю «отменить», затем удалить, как мне нравится, затем «0p» из регистра 0, куда помещается последний скопированный текст.
Моя ситуация:в Normal
режиме, когда я удаляю символы с помощью x
нажатия клавиши, эти удаления перезаписывают мой последний регистр, что усложняет редактирование, когда я хочу удалить символы, используя x
и вставьте что-нибудь из моего последнего реестра (например,вставка одного и того же текста в двух или более местах).
Я попробовал предложение в принятом ответе ("_d
), но это не сработало.
Однако из принятого ответа/комментариев на https://vi.stackexchange.com/questions/122/performing-certain-operations-without-clearing-register, я добавил это в свой ~/.vimrc
, что работает (возможно, вам придется перезапустить Vim):
nnoremap x "_x
То есть теперь я могу делать свое обычное дерганье(y
), удалить (d
) и вставьте (p
) команды - и символы, которые я удаляю с помощью x
больше не заполняют самые последние регистры.
Для пользователей Дворжака один очень удобный метод — просто удалить ненужный текст в регистр «1» вместо регистра «_ черной дыры», хотя бы потому, что вы можете нажать « + 1 тем же сдвигом и быстрым движением мизинца, поскольку 1 — это клавиша непосредственно над " у Дворжака (PLUS d находится в другой руке, что делает всю команду чертовски быстрой).
Тогда, конечно, регистр «1» можно использовать и для других целей из-за его удобства, но если у вас нет более общей цели, чем замена текста, я бы сказал, что это довольно хорошее использование регистра.
Для тех из вас, кто в первую очередь заинтересован в том, чтобы не перезаписывать безымянный регистр при замене текста с помощью виртуального выделения и вставки.
Вы можете использовать следующее решение, которое просто и лучше всего подходит для меня:
xnoremap <expr> p 'pgv"'.v:register.'y'
Это из ответов (и комментариев) здесь:Как вставить без перезаписи регистра
Сначала он проходит мимо выделения, затем снова выделяется выделение с новым текстом (gv).Теперь регистр, который последний раз использовался в визуальном режиме (обычно это безымянный регистр, но он также работает без побочных эффектов, если вы используете другой регистр для вставки).А затем снова занесите новое значение в регистр.
ПС:Если вам нужен более простой вариант, который также работает с плагином intellj idea vim-simulation, вы можете выбрать этот (недостаток:перезаписать безымянный регистр, даже если для вставки был указан другой регистр):
vnoremap p pgvy
Для пользователей emacs-evil функция (evil-paste-pop)
может быть запущен после вставки и циклически перебирает предыдущие записи в списке уничтожений.Предполагая, что вы связали его с <C-p>
(по умолчанию в Spacemacs), вы должны нажать p
за которым следует столько же <C-p>
по мере необходимости.