29

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

blah1
newtext
blah2
wrong1
blah3
wrong2
blah4

Предположим , что я визуальный знак newtext и y апк его. Теперь я выбираю wrong1 (который может быть что угодно, не обязательно просто слово) и p Aste newtext Однако, если я теперь сделаю то же самое с wrong2 он будет заменен wrong1 вместо newtext .

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

Редактировать 1

Хотя мне очень нравятся предложения по повторной регистрации (я думаю, что я начну больше использовать регистры, теперь, когда я обнаружил команду :dis ), я собираюсь изменить ответ jinfield , потому что я не использую режим обмена.

vnoremap p "0p
vnoremap P "0P
vnoremap y "0y
vnoremap d "0d

делает трюк отлично.

Редактировать 2

Я был слишком быстр; Решение romainl - это именно то, что я искал, без взлома в Edit 1.
На самом деле, vnoremap p "_dP достаточно!
Итак, меняем принятый ответ.

9 ответов9

15

У меня есть эти сопоставления в моем .vimrc:

" delete without yanking
nnoremap <leader>d "_d
vnoremap <leader>d "_d

" replace currently selected text with default register
" without yanking it
vnoremap <leader>p "_dP

"_ - это" регистр черной дыры ", согласно :help "_:

«При записи в этот регистр ничего не происходит. Это может быть использовано для удаления текста, не затрагивая обычные регистры. При чтении из этого регистра ничего не возвращается. {не в Vi} "

10

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

"dyy - вставить текущую строку в буфер d.
"a7yy - Янкинуть следующие семь строк в буфер a.
"dP - поместить содержимое буфера d перед курсором.
"ap - поместить содержимое буфера после курсора

Еще одна крутая вещь, если вы используете заглавную букву вместо нижнего регистра, то есть "Dyy текущая строка будет добавлена к буферу d вместо его замены. Подробнее в книге О`Рейли: http://docstore.mik.ua/orelly/unix/vi/ch04_03.htm

4

При использовании 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
3

Когда вы вставляете текст в безымянный регистр *, копия также помещается в регистр 0. Каждый раз, когда вы заменяете выделенный текст, вы можете просто вставить из регистра 0. Увидеть

:help registers

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

:help single-repeat

* Места хранения, в которые вы вставляете и кладете, называются регистрами. Буфер - это то, что вы редактируете, обычно это копия файла с диска.

3

Важно знать вставку из "0 регистра, но вы часто хотите заменить много раз. Если вы делаете повторяемое действие, вы можете использовать . оператор, на что ссылается Гариджон. Это объясняется на вики-сайте vim:

yiw     yank inner word (copy word under cursor, say "first". Same as above).
...     Move the cursor to another word (say "second").
ciw<C-r>0   select "second", then replace it with "first" If you are at the start of the word then cw<C-r>0 is sufficient.
...     Move the cursor to another word (say "third").
.   select "third", then replace it with "first". 
1

Мне нужно это так часто, я написал для этого плагин: ReplaceWithRegister.

Этот плагин предлагает команду gr два в одном», которая заменяет текст, покрытый {motion}, всю строку (строки) или текущий выбор, содержимым регистра; старый текст удаляется в регистр черной дыры, т.е.

1

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

Примечание. Код, представленный здесь, сокращен. Полный список с возможностью отладки, а также другие комментарии и отзывы см .: http://pastebin.com/aBEsm5mV

function! SmartCut()
    execute 'normal! gv"+c'

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " Note: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif
endfunction

function! SmartCopy()
    execute 'normal! gv"+y'

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " Note: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif
endfunction

function! SmartPaste()
    let mode = 'gv'

    let delete = '"_d'

    let reg = '"+'

    let currentLine = line(".")
    let lastLineOfBuffer = line("$")
    let selectionEndLine = line("'>")
    let selectionEndLineLength = len(getline(selectionEndLine))
    let nextLineLength = len(getline(currentLine + 1))
    let selectionEndColumn = col("'>")

    " If selection does not include or go beyond the last visible character of the line (by also selecting the invisible EOL character)
    if selectionEndColumn < selectionEndLineLength
        let cmd = 'P'

    " If attempting to paste on a blank last line
    elseif selectionEndLineLength == 0 && selectionEndLine == lastLineOfBuffer
        let cmd = 'P'

    " If selection ends after the last visible character of the line (by also selecting the invisible EOL character) and next line is not blank and not the last line
    elseif selectionEndColumn > selectionEndLineLength && nextLineLength > 0 && selectionEndLine != lastLineOfBuffer
        let cmd = 'P'

    " If selection ends after the last visible character of the line (by also selecting the invisible EOL character), or the line is visually selected (Shift + V), and next line is the last line
    elseif selectionEndColumn > selectionEndLineLength && selectionEndLine == lastLineOfBuffer
        let cmd = 'p'
        call append(selectionEndLine, "")

    else
        let cmd = 'p'
    endif

    if visualmode() != "\<C-v>" " If not Visual-Block mode
        " Trim the last \r\n | \n | \r character in the '+' buffer
        " Note: This messes up Visual-Block pasting.
        let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
    endif

    try
        execute 'normal! ' . mode . delete . reg . cmd
    catch /E353:\ Nothing\ in\ register\ +/
    endtry

    " Move caret one position to right
    call cursor(0, col(".") + 1)
endfunction

Использование:

" p or P delete to black hole register before pasting
vnoremap <silent>p :<C-u>call SmartPaste()<CR>
vnoremap <silent>P :<C-u>call SmartPaste()<CR>

" MiddleMouse delete to black hole register before pasting
nmap <MiddleMouse> "+p " Changes default behavior from 'P' mode to 'p' mode for normal mode middle-mouse pasting
vmap <silent><MiddleMouse> :<C-u>call SmartPaste()<CR>
imap <MiddleMouse> <C-r><C-o>+

" Disable weird multi-click things you can do with middle mouse button
map <2-MiddleMouse> <Nop>
imap <2-MiddleMouse> <Nop>
map <3-MiddleMouse> <Nop>
imap <3-MiddleMouse> <Nop>
map <4-MiddleMouse> <Nop>
imap <4-MiddleMouse> <Nop>


if os !~ "mac" " NOTE: MacVim provides Command+C|X|V|A|S and undo/redo support and also can Command+C|V to the command line by default
    " Copy and paste for the command line 
    cmap <C-c> <C-y>
    cmap <C-v> <C-r>+
    " TODO: Is their a select-all for the command line???

    vmap <silent><C-x> :<C-u>call SmartCut()<CR>
    vmap <silent><C-c> :<C-u>call SmartCopy()<CR>
    vmap <silent><C-v> :<C-u>call SmartPaste()<CR>
    imap <C-v> <C-r><C-o>+

    " Select-all support for normal, visual, and insert mode
    " http://vim.wikia.com/wiki/Using_standard_editor_shortcuts_in_Vim
    nmap <C-a> ggVG
    vmap <C-a> ggVG
    imap <C-a> <Esc>ggVG

    " Save file support for normal, visual, and insert mode
    " If the current buffer has never been saved, it will have no name,
    " call the file browser to save it, otherwise just save it.
    command -nargs=0 -bar Update if &modified |
                                \    if empty(bufname('%')) |
                                \        browse confirm write |
                                \    else |
                                \        confirm write |
                                \    endif |
                                \endif
    nmap <C-s> :update<CR>
    vmap <C-s> <Esc>:update<CR>V
    imap <C-s> <C-o>:update<CR>

    " Undo and redo support for normal, visual, and insert mode
    nmap <C-z> <Esc>u
    nmap <C-y> <Esc><C-r>

    vmap <C-z> <Esc>uV
    vmap <C-y> <Esc><C-r>V

    imap <C-z> <Esc>uI
    imap <C-y> <Esc><C-r>I

    " Find and Find/Replace support for normal, visual, and insert mode
    nmap <C-f> :promptfind<CR>
    nmap <C-h> :promptrepl<CR>

    vmap <C-f> <Esc>:promptfind<CR>
    vmap <C-h> <Esc>:promptrepl<CR>

    imap <C-f> <C-o>:promptfind<CR>
    imap <C-h> <C-o>:promptrepl<CR>
endif
0

Поскольку что-то вроде vnoremap p "_dP(я также пробовал x или c) имеет проблемы с началом и концом строки, я закончил этим: vnoremap p :<C-U>let @p = @+<CR>gvp:let @+ = @p<CR> который я нашел проще, чем существующие плагины (которые также не работали с set clipboard=unnamedplus из коробки). Итак, что он делает:

  • переключиться в командный режим
  • удалить диапазон (C-U)
  • резервное копирование + регистрация (из-за неназванного плюса, альтернативы " и * зависимости от вашей конфигурации) для p
  • восстановить выделение и вставить
  • снова переключиться в командный режим
  • восстановить регистр
-1

tl; dr - vnoremap p "_c *

Вот список моих полных сопоставлений:
"Исправление копирования / вставки регистра
nnoremap DD "* dd
без карты D "* d
Внокарта Д " Д
нет карты d "_d
nnoremap dd "_dd
vnoremap d "_d
nnoremap s "_s
vnoremap s "_s
без карты c "_c
vnoremap c "_c
nnoremap x "_x
vnoremap x "_x
vnoremap p "_c

"Вставить на новую строку
nnoremap, p op
без карты, P Op

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .