Vim переключение буфера перезаписывает поведение при удалении
Vim отлично, но, как и многие люди, я очень раздражаюсь, когда хочу скопировать, удалить, а затем вставить - буфер yank перезаписывается действием удаления.
Теперь я знаю, что есть 101 work-arounds и сопоставления, некоторые из которых перечислены в сообщениях, подобных этому: Любой способ удалить в vim без перезаписи вашего последнего yank?
Но у всех этих решений есть недостатки - даже я был буфером-гуру (которого я не знаю). Например, избыточные нажатия клавиш - в то время как я обычно xxxx, чтобы быстро удалить 4 символа (только одно нажатие клавиши, потому что я держу его и жду авторежима), мне небезопасно переключаться на x, x, x, x или независимо от отображения, мне нужно использовать другой буфер.
То, что действительно было бы идеальным, - это просто режим переключения, посредством которого вы можете включать и отключать поведение побочных эффектов клавиш D, d, X и x, чтобы они поочередно выполняли или не записывали свой текст в буфер. Таким образом, я могу просто ввести режим "без побочных эффектов" и удалить его до содержания сердца, а затем вставить, когда я буду готов. При необходимости снова включите побочные эффекты.
Кто-нибудь знает, как это сделать?
[UPDATE: SOLUTION] OK У меня получилось: я написал функцию, которая переключает режим "без побочных эффектов"... отлично работает! См. Мой принятый правильный ответ ниже
[UPDATE # 2] Мое решение все еще отлично работает, и я использую его все время, когда я делаю много удаления и вставки. Но тем временем я также нашел более легкий способ удовлетворить конкретный вариант использования копии, вставки, удаления для простых случаев, когда текст для удаления является смежным.
После нормального поиска текста я затем визуально выделяю текст для удаления с помощью команды v, а затем просто вставляю его с помощью команды p. Это обеспечивает желаемый эффект без какого-либо специального отображения.
Единственная проблема с этим документооборотом заключается в том, что если я захочу вставить снова, оригинальный буфер вставки будет перезаписан актом вставки над выделенным текстом, но это поведение легко изменить с помощью следующего отображения в .vimrc:
vnoremap p "_dp
vnoremap P "_dP
Ответы
Ответ 1
ОК, я понял - этот script в .vimrc позволяет мне эффективно переключать режим "без побочных эффектов", в результате чего ключи d и x больше не перезаписывают буфер, когда режим "без буферных побочных эффектов" активируется.
Добавьте это в .vimrc
function! ToggleSideEffects()
if mapcheck("dd", "n") == ""
noremap dd "_dd
noremap D "_D
noremap d "_d
noremap X "_X
noremap x "_x
echo 'side effects off'
else
unmap dd
unmap D
unmap d
unmap X
unmap x
echo 'side effects on'
endif
endfunction
nnoremap ,, :call ToggleSideEffects()<CR>
Затем для переключения в и из этого режима используйте комбинацию клавиш (две запятые)
Ответ 2
Я думаю, что попытка "выключить" побочные эффекты для каждой команды удаления/изменения будет слишком сложной, если не невозможной. Основные способы решения этой проблемы:
- Используйте регистр черного дыра (
"_
) с помощью команд удаления или изменения. например "_dd
- Используйте регистр
"0
, который содержит самый последний yank с вашими командами вставки. например "0p
- Сохранение текста в названный регистр. например
"ayy
, а затем выполните "ap
Я лично склоняюсь к подходу "0p
, поскольку это соответствует тому, как работает мой ум.
Теперь, увидев, что вы не задали таких обходов, я предоставил некоторые функции, которые изменяют команды вставки для переключения между так называемыми режимами paste_copy
и nopaste_copy
. nopaste_copy
является поведением по умолчанию Vim. Поместите в ~/.vimrc
следующее:
function! PasteCopy(cmd, mode)
let reg = ""
if exists('g:paste_copy') && g:paste_copy == 1 && v:register == '"'
let reg = '"0'
elseif v:register != '"'
let reg = '"' . v:register
endif
let mode = ''
if a:mode == 'v'
let mode = 'gv'
endif
exe "norm! " . mode . reg . a:cmd
endfunction
command! -bar -nargs=0 TogglePasteCopy let g:paste_copy = exists('g:paste_copy') && g:paste_copy == 1 ? 0 : 1<bar>echo g:paste_copy ? ' paste_copy' : 'nopaste_copy'
nnoremap <silent> p :call PasteCopy('p', 'n')<cr>
nnoremap <silent> P :call PasteCopy('P', 'n')<cr>
nnoremap <silent> ]p :call PasteCopy(']p', 'n')<cr>
nnoremap <silent> [p :call PasteCopy('[p', 'n')<cr>
nnoremap <silent> ]P :call PasteCopy(']P', 'n')<cr>
nnoremap <silent> [P :call PasteCopy('[P', 'n')<cr>
vnoremap <silent> p :<c-u>call PasteCopy('p', 'v')<cr>
vnoremap <silent> P :<c-u>call PasteCopy('P', 'v')<cr>
Вы можете переключить режим paste_copy с помощью :TogglePasteCopy
. Вы можете предпочесть отображение таким образом
nnoremap <leader>tp :TogglePasteCopy<cr>
В качестве заключительного совета я бы настоятельно предложил использовать "0p
или использовать именованный регистр для этого подхода, поскольку они являются родными для vim, и есть один менее "режим", о котором можно беспокоиться.