Вопрос или проблема
Я обычно копирую текст из одной точки в другую, перезаписывая старый текст, куда вставляется новый:
blah1
newtext
blah2
wrong1
blah3
wrong2
blah4
Предположим, я выделяю newtext
и копирую его. Теперь я выбираю wrong1
(что может быть чем угодно, не обязательно словом) и вставляю newtext
. Однако, если я сделаю то же самое с wrong2
, он будет заменён на wrong1
вместо newtext
.
Так как мне сохранить текст, который находится в буфере, чтобы он не был заменён текстом, который я сейчас перезаписываю?
Правка 1
Хотя мне довольно нравятся предложения регистров (думаю, что начну больше использовать регистры, теперь, когда я обнаружил команду :dis
), я воспользуюсь модификацией ответа jinfield, потому что я не использую режим обмена.
vnoremap p "0p
vnoremap P "0P
vnoremap y "0y
vnoremap d "0d
это работает идеально.
Правка 2
Я был слишком спешным; romainl‘s решение – это именно то, что я искал, без хаков из Правки 1.
На самом деле, vnoremap p "_dP
достаточно!
Итак, меняю принятие ответа.
У меня есть следующие привязки в моем .vimrc:
" удаление без копирования
nnoremap <leader>d "_d
vnoremap <leader>d "_d
" заменить текущий выделенный текст на текст по умолчанию
" без копирования
vnoremap <leader>p "_dP
"_
это “регистратор черной дыры”, согласно :help "_
:
“При записи в этот регистратор ничего не происходит. Это можно использовать для удаления текста, не влияя на обычные регистры. При чтении из этого регистра ничего не возвращается. {не в Vi}”
Используйте P
, чтобы вставить без копирования удаленного текста.
С
P
неназванный регистр не изменяется (так же как и выделение или буфер обмена), вы можете повторить то же самое изменение.
Это поведение было введено в v8.2.4242 (2022-01-28) и уточнено в v8.2.4881 (2022-05-06).
Или если ваша мышечная память слишком сильна:
xnoremap p P
В дополнение к стандартному буферу, вы можете копировать текст в именованные буферы, а затем вставлять из этих именованных буферов. Вы можете использовать до 26 именованных буферов (по одному для каждой буквы). Используйте двойные кавычки и букву, чтобы получить доступ к именованному буферу.
Примеры:
"dyy
– Копировать текущую строку в буфер d.
"a7yy
– Копировать следующие семь строк в буфер a.
"dP
– Вставить содержимое буфера d перед курсором.
"ap
– Вставить содержимое буфера a после курсора
Еще одна интересная вещь: если вы используете заглавную букву вместо строчной, то есть "Dyy
, текущая строка будет добавлена в буфер d, вместо того, чтобы заменять его. Более подробная информация в книге O’Reilly: http://docstore.mik.ua/orelly/unix/vi/ch04_03.htm
При использовании put
в визуальном режиме текст, который вы заменяете, wrong1
, перезаписывается содержимым ‘неназванного’ регистра.
На самом деле это работает, “вставляя” регистр после выделения, а затем удаляя выделение. Проблема в том, что это удаление сейчас сохраняется в unnamed
регистре и будет использовано для следующего действия put
.
Решение, согласно :h v_p
, состоит в том, чтобы копировать в именованный регистр, такой как "0y
, затем вставить, используя "0p
столько раз, сколько вам нужно. Может быть полезно сопоставить <leader>y
и <leader>p
для использования именованного регистра, если вы часто это делаете.
:map <leader>y "0y
:map <leader>p "0p
для получения дополнительной помощи см.:
:help v_p
:help map
Вставка из регистра "0
важна для знания, но вы часто хотите заменить много раз. Если вы сделаете это повторяемым действием, вы можете использовать оператор .
, как упоминал garyjohn. Это объясняется на вики vim:
yiw копирует внутреннее слово (копирует слово под курсором, скажем "первое". То же самое, что и выше).
... Переместите курсор к другому слову (скажем "второе").
ciw<C-r>0 выберите "второе", затем замените его на "первое". Если вы находитесь в начале слова, тогда достаточно cw<C-r>0
.
... Переместите курсор к другому слову (скажем "третье").
. выберите "третье", затем замените его на "первое".
Когда вы копируете текст в неназванный регистр*, копия также помещается в регистр 0. Каждый раз, когда вы заменяете выделенный текст, вы можете просто вставлять из регистра 0. Смотрите
:help registers
Кроме того, если вы заменяете несколько слов одним и тем же словом, вы можете просто переместиться к началу слова, подлежащего замене, и ввести .
. Это повторит последнюю операцию редактирования. Смотрите
:help single-repeat
* Места хранения, в которые вы копируете и из которых вставляете, называются регистрами. Буфер – это то, что вы редактируете, обычно копия файла с диска.
Я использую clipboard=unnamedplus
, поэтому я обнаружил, что многие из решений здесь не работали, потому что вставка помещала перезаписанный текст в "+
вместо ""
. Я также нашел, что "_dP
имел проблемы в конце строк.
Однако я выяснил, что использование c
сработало.
set clipboard=unnamedplus " Используйте системный буфер обмена.
" Не помещайте вставленный контент в буфер обмена.
vnoremap p "_c<C-r><C-o>+<Esc>
Это по сути cменяет текст и использует вставку в режиме ввода (<C-r><C-o>+
) неназванного регистра. Поскольку курсор в режиме вставки может находиться после последнего символа строки, это не вызывает проблем в конце строк.
Возможные корректировки:
- Если вы не хотите переопределять обычную команду
p
, просто используйте<Leader>p
. - Если вы используете другой регистр буфера обмена, замените
+
на"
или*
.
Поскольку что-то вроде vnoremap p "_dP
(я также пробовал x
или c
) имеет проблемы с началом и концом строки, я в конце концов сделал следующее: vnoremap p :<C-U>let @p = @+<CR>gvp:let @+ = @p<CR>
, что я нашел проще, чем существующие плагины (которые также не работали с set clipboard=unnamedplus
изначально).
Что он делает:
- переключается в командный режим
- удаляет диапазон (
C-U
) - резервирует
+
регистр (из-за неназванного регистра, альтернативы –"
и*
в зависимости от вашей конфигурации) вp
- восстанавливает выделение и вставляет
- снова переключается в командный режим
- восстанавливает регистр
Выделите текст и вставьте с помощью P
(заглавной).
Пример:
viwP
Смотрите h: v_P
для получения дополнительной информации.
Мне это нужно так часто, что я написал для этого плагин: ReplaceWithRegister.
Этот плагин предлагает команду gr
, которая заменяет текст, покрытый {движением}, целыми строками или текущим выделением содержимым регистра; старый текст удаляется в регистр черной дыры, т.е. он исчезает.
Следующее может сработать во многих случаях: c+CtrlR+0+Esc.
Возможно, вам придется сделать
:set paste
перед этим, чтобы отключить автоотступ.
Это то, что я использую для поведения вырезания Control + X/копирования Control + C/вставки Control + V/сохранения Control + S/поиска Control + F/замены Control + H в стиле Windows.
Функция SmartPaste() должна содержать то, что вы ищете, т.е. способ вставки поверх выделенного текста без одновременного копирования выбранного.
" Общие сочетания клавиш Windows и поведение вставки {{{
" Рекомендуемые настройки vimrc:
" Установите буфер обмена так:
" ЗАМЕТКА: Используйте ^=, чтобы добавить значение к списку, разделенному запятыми. См. :h set^=
" set clipboard^=unnamedplus " Работает в Linux, но есть проблемы с копированием в Windows.
" set clipboard^=unnamed,unnamedplus " Работает в Linux и Windows (а, вероятно, MacVim, который нуждался в неназванном опции в последний раз, когда я использовал его).
"
" Установите мышь так:
" set mouse=a " Гарантирует, что бинды мыши работают во всех режимах.
"
" Отключите автоматический выбор:
" ЗАМЕТКА: Это заставляет щелчки средней мыши в других программах вставлять содержимое буфера Vim's "+ неназванный регистр вместо "* регистра выбранного текста. См. :h go-a
" set guioptions-=a
" set guioptions-=A
" Функции {{{
" Раскомментируйте, чтобы включить отладку.
" Проверьте вывод отладки с :messages
" let s:debug_smart_cut = 1
" let s:debug_smart_copy = 1
" let s:debug_smart_paste = 1
function! SmartCut() " {{{
if !has('clipboard')
echoerr 'Поддержка буфера обмена требуется для использования этой функции.'
return
endif
let clipboard_register="+"
" Восстановите визуальное выделение с 'gv' и удалите выделение в буфер обмена.
" ЗАМЕТКА: 'd' (удаление) лучше, чем 'c' (копирование), потому что он перемещает каретку вправо.
execute 'normal! gv"' . clipboard_register . 'd'
" Войти в режим вставки.
startinsert
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_cut')
echomsg "SmartCut"
echomsg " содержимое буфера: " . getreg(clipboard_register)
endif
endfunction " }}}
function! SmartCopy() " {{{
if !has('clipboard')
echoerr 'Поддержка буфера обмена требуется для использования этой функции.'
return
endif
let clipboard_register="+"
" Восстановите визуальное выделение с 'gv' и копируйте выделение в буфер обмена.
execute 'normal! gv"' . clipboard_register . 'y'
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_copy')
echomsg "SmartCopy"
echomsg " содержимое буфера: " . getreg(clipboard_register)
endif
endfunction " }}}
function! SmartPaste() " {{{
if !has('clipboard')
echoerr 'Поддержка буфера обмена требуется для использования этой функции.'
return
endif
if !&modifiable
return
endif
" См. :help '> для получения дополнительной информации. Подсказка: если вы выделите текст и нажмёте ':' вы увидите :'<,'>
" ИСТОЧНИК: http://superuser.com/questions/723621/how-can-i-check-if-the-cursor-is-at-the-end-of-a-line
" ИСТОЧНИК: http://stackoverflow.com/questions/7262536/vim-count-lines-in-selected-range
" ИСТОЧНИК: https://git.zug.fr/config/vim/blob/master/init.vim
" ИСТОЧНИК: https://git.zug.fr/config/vim/blob/master/after/plugin/zzzmappings.vim
let currentColumn = col(".")
let currentLine = line(".")
let lastVisibleLetterColumn = col("$") - 1
let lastLineOfBuffer = line("$")
let selectionEndLine = line("'>")
let selectionEndLineLength = strchars(getline(selectionEndLine))
let nextLineLength = strchars(getline(currentLine + 1))
let selectionStartColumn = col("'<")
let selectionEndColumn = col("'>")
" Если выделение не включает или не выходит за последний видимый символ строки (также включая невидимый символ конца строки).
if selectionEndColumn < selectionEndLineLength
let pee="P"
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_paste')
echomsg "SmartPaste специальный случай #1"
endif
" Если пытаетесь вставить на пустую последнюю строку.
elseif selectionEndLineLength == 0 && selectionEndLine == lastLineOfBuffer
let pee="P"
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_paste')
echomsg "SmartPaste специальный случай #2"
endif
" Если выделение заканчивается после последнего видимого символа строки (также включая невидимый символ конца строки),
" или строка визуально выбрана (Shift + V),
" и следующая строка не пустая,
" и выделение не заканчивается на последней строке.
elseif selectionEndColumn > selectionEndLineLength && nextLineLength > 0 && selectionEndLine != lastLineOfBuffer
let pee="P"
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_paste')
echomsg "SmartPaste специальный случай #3"
endif
else
let pee="p"
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_paste')
echomsg "SmartPaste случай по умолчанию"
endif
endif
let clipboard_register="+"
" Получает значение, если оно существует, в противном случае возвращает 0.
if get(s:, 'debug_smart_paste')
echomsg "SmartPaste"
echomsg " содержимое буфера: " . getreg(clipboard_register)
echomsg " currentColumn: " . currentColumn
echomsg " currentLine: " . currentLine
echomsg " lastVisibleLetterColumn: " . lastVisibleLetterColumn
echomsg " lastLineOfBuffer: " . lastLineOfBuffer
echomsg " selectionEndLine: " . selectionEndLine
echomsg " selectionEndLineLength: " . selectionEndLineLength
echomsg " nextLineLength: " . nextLineLength
echomsg " selectionStartColumn: " . selectionStartColumn
echomsg " selectionEndColumn: " . selectionEndColumn
echomsg " pee: " . pee
echomsg " границы выделения" . string([getpos("'<")[1:2], getpos("'>")[1:2]])
echomsg " visualmode(): " . visualmode()
echomsg " mode(): " . mode()
echomsg " getpos('.'): " . string(getpos('.'))
endif
try
" Войти в режим вставки.
" ЗАМЕТКА: Это предотвращает повторное выполнение автокоманд InsertCharPre для каждого символа в вставленной строке.
set paste
" Резервирование буфера обмена.
let clipboard_contents = getreg(clipboard_register)
let clipboard_type = getregtype(clipboard_register)
" Если тип буфера обмена построчный.
if clipboard_type[0] == 'V'
" Изменить регистр буфера обмена на побуквенный режим.
call setreg(clipboard_register, clipboard_contents, 'v')
endif
" Восстановите визуальное выделение с 'gv' и вставьте содержимое буфера обмена туда.
execute 'normal! gv"' . clipboard_register . pee
" Восстановите буфер обмена.
call setreg(clipboard_register, clipboard_contents, clipboard_type)
catch /E353:\ Nothing\ in\ register/
finally
" Выйти из режима вставки.
set nopaste
endtry
endfunction " }}}
function! SmartFind() " {{{
let wordUnderCursor = expand('<cword>')
if wordUnderCursor == ''
execute 'promptfind'
else
execute 'promptfind' wordUnderCursor
endif
endfunction " }}}
function! SmartReplace() " {{{
let wordUnderCursor = expand('<cword>')
if wordUnderCursor == ''
execute 'promptrepl'
else
execute 'promptrepl' wordUnderCursor
endif
endfunction " }}}
function! SmartSaveFile() " {{{
" ИСТОЧНИК: http://vim.wikia.com/wiki/Map_Ctrl-S_to_save_current_or_new_files
" Если файл сохранён.
if !&modified
return
endif
try
" Если у текущего буфера нет имени.
if empty(bufname('%'))
" Отобразите диалог сохранения, чтобы пользователь мог указать имя файла.
browse confirm write
else
" Принудительное сохранение, даже если файл с таким именем уже существует.
confirm write
endif
catch /E212:\ Can't\ open\ file\ for\ writing/
if has("win32") || has("win64")
echomsg "ОШИБКА: У вас нет разрешения на запись для этого каталога или имя файла недопустимо."
else
" ЗАМЕТКА: Вызов [browse confirm write] выше установит имя файла в случае пустого буфера.
try
" Хак, который использует tee для вывода буфера в % имя файла с правами sudo.
" ИСТОЧНИК: https://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work
execute("w !sudo tee %")
if v:shell_error
throw 'Не удалось сохранить файл.'
else
" Перезагрузите файл, иначе vim обнаружит, что файл изменился, и спросит вас о разрешении на перезагрузку файла.
silent edit!
" Очистите командную строку и уберите подсказку 'Нажмите ENTER или введите команду, чтобы продолжить'.
" ИСТОЧНИК: https://vim.fandom.com/wiki/Avoiding_the_%22Hit_ENTER_to_continue%22_prompts
redraw!
endif
catch /.*/
echomsg 'SmartSaveFile() Необработанное исключение: ' . v:exception
endtry
endif
endtry
endfunction " }}}
function! SmartCopyMessageHistory() " {{{
redir @+
silent execute(':messages')
redir END
endfunction " }}}
" }}} Функции
" Привязки {{{
" Вставка для средней мыши в обычном, визуальном и режиме вставки {{{
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
nnoremap <silent> <MiddleMouse> <C-v>:<C-u>call SmartPaste()<CR>
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
vnoremap <silent> <MiddleMouse> :<C-u>call SmartPaste()<CR>
" Побуквенная вставка для режима вставки.
" ИСТОЧНИК: https://vim.fandom.com/wiki/Pasting_registers
" ЗАМЕТКА: выполняет команду нормального режима, не покидая режима вставки. См. :help ins-special-special
" ЗАМЕТКА: + вставляет содержимое неназванного регистра во время вставки. См. :h i_CTRL-R
" ЗАМЕТКА: + не работает для столбцов текста, вырезанных и вставленных с Ctrl-v. Он принудительно вставляет выборки побуквенно. + работает.
" [плохо, срабатывает InsertCharPre для каждой вставленной буквы] inoremap <silent> <MiddleMouse> <C-r><C-r>+
" [работает] inoremap <silent> <MiddleMouse> <C-o>"+<MiddleMouse>
" [работает, но, думаю, нет необходимости в режиме вставки, потому что он не вызывает события InsertCharPre для каждой вставленной буквы] inoremap <silent> <MiddleMouse> <C-o>:set paste<CR><C-r><C-o>+<C-o>:set nopaste<CR>
inoremap <silent> <MiddleMouse> <C-r><C-o>+
" Отключите странные многократные нажатия, которые вы можете сделать с помощью средней кнопки мыши.
" ИСТОЧНИК: http://vim.wikia.com/wiki/Mouse_wheel_for_scroll_only_-_disable_middle_button_paste
nnoremap <2-MiddleMouse> <Nop>
inoremap <2-MiddleMouse> <Nop>
vnoremap <2-MiddleMouse> <Nop>
nnoremap <3-MiddleMouse> <Nop>
inoremap <3-MiddleMouse> <Nop>
vnoremap <3-MiddleMouse> <Nop>
nnoremap <4-MiddleMouse> <Nop>
inoremap <4-MiddleMouse> <Nop>
vnoremap <4-MiddleMouse> <Nop>
" }}} Вставка для средней мыши в обычном, визуальном и режиме вставки
" Если ОС не mac.
if system('uname') !~ 'Darwin' " ЗАМЕТКА: MacVim предоставляет функциональность Command+C|X|V|A|S и отмены/повтора, а также может по умолчанию Command+C|V на командную строку.
" Копирование, вставка и выбрать все функции для командной строки {{{
" ИСТОЧНИК: https://opensource.apple.com/source/vim/vim-62.41.2/runtime/macmap.vim.auto.html
" ЗАМЕТКА: только копирование и вставка возможны в командной строке, насколько я могу судить.
" На написанный текст в командной строке нет отмены, и вы не можете вставить текст на выделение текста, чтобы заменить его.
cnoremap <C-c> <C-y>
cnoremap <C-v> <C-r>+
" Все, похоже, связывают это. Нет способа выделить все, но мы можем переместить каретку в самую левую часть командной строки. Ура.
cnoremap <C-A> <Home>
" Копировать историю сообщений в буфер обмена.
" ЗАМЕТКА: Это обходной путь для того, чтобы нельзя было выделить все.
nnoremap <silent> <Leader>m :<C-u>call SmartCopyMessageHistory()<CR>
" }}} Копирование, вставка и выбор всех функций для командной строки
" Вырезание, копирование и вставка функции для визуального и режима вставки {{{
" Вырезать, копировать и вставлять в визуальном режиме.
" ИСТОЧНИК: http://superuser.com/questions/10588/how-to-make-cut-copy-paste-in-gvim-on-ubuntu-work-with-ctrlx-ctrlc-ctrlv
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
vnoremap <silent> <C-x> :<C-u>call SmartCut()<CR>
vnoremap <silent> <C-c> :<C-u>call SmartCopy()<CR>
vnoremap <silent> <C-v> :<C-u>call SmartPaste()<CR>
" Побуквенная вставка для режима вставки.
" ИСТОЧНИК: https://vim.fandom.com/wiki/Pasting_registers
" ЗАМЕТКА: выполняет команду нормального режима, не покидая режима вставки. См. :help ins-special-special
" ЗАМЕТКА: + вставляет содержимое неназванного регистра во время вставки. См. :h i_CTRL-R
" ЗАМЕТКА: + не работает для столбцов текста, вырезанных и вставленных с Ctrl-v. Он принудительно вставляет выборки побуквенно. + работает, однако.
" [работает, но, думаю, нет необходимости в режиме вставки, потому что он не вызывает события InsertCharPre для каждой вставленной буквы] inoremap <silent> <C-v> <C-o>:set paste<CR><C-r><C-o>+<C-o>:set nopaste<CR>
inoremap <silent> <C-v> <C-r><C-o>+
" }}} Вырезание, копирование и вставка функции для визуального и режима вставки
" Функция выбора всего для обычного, визуального и режима вставки {{{
" ИСТОЧНИК: http://vim.wikia.com/wiki/Using_standard_editor_shortcuts_in_Vim
nnoremap <C-a> ggVG
vnoremap <C-a> ggVG
inoremap <C-a> <Esc>ggVG
" }}} Функция выбора всего для обычного, визуального и режима вставки
" Функция сохранения для обычного, визуального и режима вставки {{{
nnoremap <silent> <C-s> :call SmartSaveFile()<CR>
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
vnoremap <silent> <C-s> :<C-u>call SmartSaveFile()<CR>gv
" ЗАМЕТКА: выполняет команду нормального режима, не покидая режима вставки. См. :help ins-special-special
inoremap <silent> <C-s> <C-o>:call SmartSaveFile()<CR>
" }}} Функция сохранения для обычного, визуального и режима вставки
" Функции отмены и повтора для обычного, визуального и режима вставки {{{
nnoremap <C-z> <Esc>u
nnoremap <C-y> <Esc><C-r>
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
vnoremap <C-z> :<C-u>uV
vnoremap <C-y> :<C-u><C-r>V
inoremap <C-z> <Esc>uI
inoremap <C-y> <Esc><C-r>I
" Отключить клавиши отмены/повтора в нормальном режиме Vim.
" Иметь одну клавишу для отмены - это несчастный случай, который ждет, когда произойдет, особенно когда 'u' и 'U' также используются как переключатели регистра в режиме визуального.
" ИСТОЧНИК: https://stackoverflow.com/questions/57714401/vi-vim-remap-or-unmap-built-in-command-the-u-key-in-visual-mode
nnoremap u <NOP>
nnoremap <C-r> <NOP>
" }}} Функции отмены и повтора для обычного, визуального и режима вставки
" Функция поиска и замены для обычного, визуального и режима вставки {{{
nnoremap <silent> <C-f> :call SmartFind()<CR>
nnoremap <silent> <C-h> :call SmartReplace()<CR>
" ЗАМЕТКА: удаляет выделение из командной строки. См. :h c_CTRL-u
vnoremap <silent> <C-f> :<C-u>call SmartFind()<CR>
vnoremap <silent> <C-h> :<C-u>call SmartReplace()<CR>
" ЗАМЕТКА: выполняет команду нормального режима, не покидая режима вставки. См. :help ins-special-special
inoremap <silent> <C-f> <C-o>:call SmartFind()<CR>
inoremap <silent> <C-h> <C-o>:call SmartReplace()<CR>
" }}} Функция поиска и замены для обычного, визуального и режима вставки
endif
" }}} Привязки
" }}} Общие сочетания клавиш Windows и поведение вставки
if has('patch-8.2.4881')
xnoremap p P
xnoremap P p
else
xnoremap P p
xnoremap p "_dp
endif
это работает для меня, чтобы поменять местами p и P
vnoremap p "_c<C-r>*<Esc>
Вот список моих полных привязок:
" Исправить копирование/вставку регистра
nnoremap DD "*dd
nnoremap D "*d
vnoremap D "*d
nnoremap d "_d
nnoremap dd "_dd
vnoremap d "_d
nnoremap s "_s
vnoremap s "_s
nnoremap c "_c
vnoremap c "_c
nnoremap x "_x
vnoremap x "_x
vnoremap p "_c<C-r>*<Esc>
" Вставка на новой строке
nnoremap ,p o<Esc>p
nnoremap ,P O<Esc>p
Ответ или решение
Чтобы заменить текст, выделенный в Vim, вставленной текстовой строкой без сохранения удаленных строк в буфер обмена, вы можете использовать «черную дырку» (black hole register) и специальные сопоставления. Рассмотрим поэтапно, как это сделать, а также объясним, почему это важно для более эффективной работы в редакторе Vim.
Почему это важно?
При копировании и вставке в Vim вы можете столкнуться с нежелательными последствиями: когда вы удаляете текст, он помещается в общий буфер обмена, что может вызвать путаницу при следующей операции вставки. Это может быть особенно проблематично, если вы многократно заменяете один текст другим. Использование черной дыры помогает избежать этого и обеспечивает более чистый подход.
Установка маппинга для черной дыры
Вы можете добавить следующую конфигурацию в ваш .vimrc
файл, чтобы создать удобные сопоставления для этих операций:
" Настройка удаления и замены с использованием черной дыры
vnoremap p "_dP " Вставка нового текста, не захватывая удаленный
vnoremap P "_dP " Вставка нового текста перед текущим курсором
Объяснение конфигурации
-
vnoremap p "_dP
:- При выделении текста в визуальном режиме и нажатии
p
, Vim удаляет выделенный текст без записи его в общий буфер, добавляя его в черную дыру. ЗатемP
вставляет содержимое, находящееся в неименованном регистре, что означает, что вы вставляете текст, который вы скопировали ранее.
- При выделении текста в визуальном режиме и нажатии
-
vnoremap P "_dP
:- Данное сопоставление аналогично первому, но оно используется, когда вы хотите вставить текст перед текущим курсором.
Дополнительные настройки
Если вы часто нуждаетесь в этой функции, возможно, вам также стоит рассмотреть возможность использования других регистров. К примеру, использование именованных регистров может быть пригодится для копирования и вставки между множественными строками:
vnoremap y "0y " Копировать текст в регистр 0
vnoremap p "0p " Вставить текст из регистра 0
Альтернативные способы
Для большей гибкости вы можете использовать следующие комбинации:
ciw<C-r>0
: Обрезает текущее слово и вставляет из регистра 0 (если вы предварительно сохранили текст, который хотите вставить).<C-r><C-o>+
: Это сочетание в режиме вставки позволяет вам вставлять текст из системного буфера обмена, не затрагивая другие действия.
Заключение
Данная настройка позволяет вам работать в Vim гораздо эффективнее, избегая нежелательной потери текста при замене. Использование черной дыры и регистров обеспечит вам большую гибкость и контроль над процессом замены текста. Тщательное планирование вашего ~/.vimrc файла с учетом этих настроек может значительно повысить вашу продуктивность и сделать работу с Vim более интуитивной.