Как оклеить без перезаписи реестра


112

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

Я знаю, что могу решить проблему, всегда вставляя данные из явного регистра. Но печатать - это боль в шее, "xpа не простоp

Ответы:


33

"{register}pне будет работать так, как вы описываете. Он заменит выбор содержимым регистра. Вместо этого вам нужно будет сделать что-то вроде:

" I haven't found how to hide this function (yet)
function! RestoreRegister()
  let @" = s:restore_reg
  return ''
endfunction

function! s:Repl()
    let s:restore_reg = @"
    return "p@=RestoreRegister()\<cr>"
endfunction

" NB: this supports "rp that replaces the selection by the contents of @r
vnoremap <silent> <expr> p <sid>Repl()

Это должно быть хорошо, если вы не используете плагин, у которого есть vmap, отличное от nore, для p, и который ожидает перезаписи регистра.

Этот код доступен как скрипт там . Инго Каркат также определил плагин, решающий ту же проблему.


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

1
Я думаю, что это перебор, я не запомню regtype(линейно?), И что переназначения p на pgvyдостаточно.
Бенуа

2
Это может быть излишним, но у него нет побочных эффектов. На a "xpэто не перезаписывает @"содержимое @xнепохожимpgvy
Люк Эрмитт

1
тогда о чем :xnoremap p pgv@=v:register.'y'<cr>?
Бенуа

1
У меня это не работает. Я тоже пробовал скачать сценарий. Вот список команд, которые я выполняю: сначала я нажимаю v, затем e, чтобы выделить до конца слова, затем y, чтобы выдернуть его. После этого я перехожу к другому слову, которое хочу заменить. Я нажимаю v, e, затем p, чтобы заменить его. Затем я делаю это снова, но на этот раз следующее слово заменяется тем, которое я заменил ранее.
Эдди

41

Мне не нравится поведение Vim по умолчанию копирования всего текста удален с d, D, cили Cв регистре по умолчанию.

Я обошел это путем сопоставления dс "_d, cс "_cи так далее.

Из моего .vimrc:

"These are to cancel the default behavior of d, D, c, C
"  to put the text they delete in the default register.
"  Note that this means e.g. "ad won't copy the text into
"  register a anymore.  You have to explicitly yank it.
nnoremap d "_d
vnoremap d "_d
nnoremap D "_D
vnoremap D "_D
nnoremap c "_c
vnoremap c "_c
nnoremap C "_C
vnoremap C "_C

Какими бы полезными ни были эти сопоставления (я сам делаю нечто подобное), они не отвечают на вопрос OP, p все равно перезапишет то, что вы выдернули, вставив поверх выбранного контента.
Магнус

32

Используйте следующее:

xnoremap p pgvy

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

Изменить: чтобы это работало, "xpвы можете:

xnoremap p pgv"@=v:register.'y'<cr>

v:register расширяется до последнего имени регистра, использованного в команде нормального режима.


На a "xpэтот подход заменяется @"на @x.
Люк Эрмитт,

3
Ваше предложение xnoremap p pgv"@=v:register.'y'<cr>не сработало для меня. Это, однако, делает:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak

Это выглядит интересно. Не могли бы вы добавить строку о том, что gделает? Я такого раньше не видел.
Лондон Роб

4
@LondonRob: gодин ничего не делает. Он предоставляет расширенные многоклавишные команды, например z. Например, goпереходит к n-му байту в буфере gjи gkпереходит к следующей и предыдущей отображаемой строке (отличается от того, jkкогда строки переносятся), gaотображает информацию о символе под курсором, gJобъединяет строки без пробела и gvвосстанавливает последнее визуальное выделение. Вы можете использовать :help gv.
Benoit

6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , я добавил `` `>` `Чтобы восстановить позицию курсора
ROX

19

В твоем .vimrc

xnoremap p "_dP

Я нашел это из ответа в аналогичном потоке, но исходным источником был http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . В нем упоминаются некоторые недостатки, но у меня он работает нормально.


2
Это кажется самым простым решением.
rudolph9

1
Работал у меня. И этот ответ ясен. .vimrc.localтоже ОК.
BaiJiFeiLong

3
Не работает, если ваше выделение продолжается до конца строки.
Джон Фриман

6

Решение Люка Эрмитта работает как шарм. Я использовал его около недели. Затем я обнаружил решение из .vimrc Стива Лоша, которое отлично работает, если YankRing является частью вашей линейки плагинов / пакетов:

function! YRRunAfterMaps()                                                                                                      
    " From Steve Losh, Preserve the yank post selection/put.    
    vnoremap p :<c-u>YRPaste 'p', 'v'<cr>gv:YRYankRange 'v'<cr> 
endfunction  

6

Попробуйте это в своем ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapозначает, что это только для Visualрежима, а не для Visual + Selectрежимов.

  • <expr>означает , что {rhs}по xnoremap {lhs} {rhs}обстановке оценивается как выражение.

  • В этом случае наше выражение 'pgv"'.v:register.'y'используется .для конкатенации.

  • v:register оценивается для регистра, используемого во время выполнения отображения.

Результат "xpбудет оцениваться как pgv"xy, гдеx находится регистр.

Мне помог ответ на этот вопрос о переполнении стека: Vim - отображение с необязательным префиксом регистра в сочетании с ответом Бенуа на этой странице


4

Функция Люка работала у меня хорошо после того, как я внес изменения, поддерживающие тот факт, что у меня есть clipboard = un named set:

function! RestoreRegister()
    let @" = s:restore_reg
    if &clipboard == "unnamed"
        let @* = s:restore_reg
    endif
    return ''
endfunction

1
Для справки: clipboard=unnamedplusэто должно быть @+вместо @*.
Себастьян Бласк

2

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

команда u переключает поведение

let s:putSwap = 1 
function TogglePutSwap()
    if s:putSwap
        vnoremap <silent> <expr> p <sid>Repl()
        let s:putSwap = 0 
        echo 'noreplace put'
    else
        vnoremap <silent> <expr> p p 
        let s:putSwap = 1 
        echo 'replace put'
    endif
    return
endfunction
noremap ,p :call TogglePutSwap()<cr>

Вы также можете изменить s: Repl, чтобы он возвращал «p» вместо «p @ = RestoreRegister () \ <cr>» в зависимости от значения s: putSwap.
Люк Эрмитт,

1
предпочитаю silent! vunmapвместоvnoremap <silent> <expr> p p
Люк Эрмитт

0

программирование изоленты, но у меня работает:

nmap viwp viwpyiw
nmap vi'p vi'pyi'
nmap vi"p vi"pyi"
nmap vi(p vi(pyi(
nmap vi[p vi[pyi[
nmap vi<p vi<pyi<

-4

пытаться -

:set guioptions-=a
:set guioptions-=A

3
Они контролируют добавление выделенного текста в буфер обмена оконной системы (например, X11 или Win32), а не во внутренние регистры копирования Vim.
Роб Кеннеди
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.