So fügen Sie ein, ohne das Register zu überschreiben


112

Kennt jemand eine Möglichkeit, einen visuell ausgewählten Bereich einzufügen, ohne dass die Auswahl in das Standardregister eingefügt wird?

Ich weiß, dass ich das Problem lösen kann, indem ich immer aus einem expliziten Register einfüge. Aber es ist ein Schmerz im Nacken, "xpstatt nur zu tippenp

Antworten:


33

"{register}pwird nicht funktionieren, wie Sie beschreiben. Die Auswahl wird durch den Inhalt des Registers ersetzt. Sie müssen stattdessen Folgendes tun:

" 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()

Dies sollte in Ordnung sein, solange Sie kein Plugin verwenden, dessen vmap nicht zu p gehört und das erwartet, dass ein Register überschrieben wird.

Dieser Code ist als ein Skript zur Verfügung gibt . Ingo Karkat hat auch ein Plugin definiert , das das gleiche Problem löst.


Eigentlich gab es zwar eine gute Möglichkeit, das verwendete Register abzurufen, konnte mich aber nicht erinnern, wie. Daher die Komplexität der Funktion.
Luc Hermitte

1
Ich denke, dass dies ein Overkill ist, ich werde mich nicht an das erinnern regtype(zeilenweise?) Und dass eine Neuzuordnung von p zu pgvyausreichend ist.
Benoit

2
Es kann übertrieben sein, hat aber keine Nebenwirkungen. Auf einem "xpüberschreibt dies nicht den @"Inhalt mit @xanders alspgvy
Luc Hermitte

1
was ist dann mit :xnoremap p pgv@=v:register.'y'<cr>?
Benoit

1
Es funktioniert nicht bei mir. Ich habe auch versucht, das Skript herunterzuladen. Hier ist die Liste der Befehle, die ich mache: Zuerst drücke ich v, dann e, um bis zum Ende des Wortes auszuwählen, dann y, um es zu ziehen. Danach gehe ich zu einem anderen Wort, das ich ersetzen möchte. Ich drücke v, e und dann p, um dieses zu ersetzen. Dann mache ich es noch einmal, aber dieses Mal wird das nächste Wort durch das Wort ersetzt, das ich zuvor ersetzt habe.
Eddy

41

Ich weiß nicht , wie das Standard - vim Verhalten des Kopierens der gesamten Textes gelöscht mit d, D, c, oder Cin das Standardregister.

Ich habe es umgangen, indem ich dauf "_d, czu "_cund so weiter abgebildet habe .

Aus meiner .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

So nützlich diese Zuordnungen auch sind (ich mache selbst etwas Ähnliches), sie beantworten nicht die Frage von OP. P überschreibt dennoch, was Sie über ausgewählte Inhalte eingefügt haben.
Magnus

32

Verwenden Sie Folgendes:

xnoremap p pgvy

Dadurch wird der im visuellen Modus eingefügte Text erneut ausgewählt und erneut gezogen.

Bearbeiten: Damit dies funktioniert "xp, können Sie Folgendes tun:

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

v:register wird auf den letzten Registernamen erweitert, der in einem normalen Modusbefehl verwendet wird.


Auf a "xpüberschreibt dieser Ansatz @"mit @x.
Luc Hermitte

3
Ihr Vorschlag von xnoremap p pgv"@=v:register.'y'<cr>hat bei mir nicht funktioniert. Dies tut jedoch:xnoremap <expr> p 'pgv"'.v:register.'y'
mrak

Das sieht interessant aus. Könnten Sie eine Zeile darüber hinzufügen, was gfunktioniert? Ich habe es noch nie gesehen.
LondonRob

4
@ LondonRob: gallein macht nichts. Es bietet erweiterte Befehle mit mehreren Tasten, wie z z. Geht beispielsweise gozum n-ten Byte im Puffer gjund gkzur nächsten und vorherigen angezeigten Zeile (unterscheidet sich vom Zeilenumbruch jk), gazeigt Informationen zum Zeichen unter dem Cursor an, gJverbindet Zeilen ohne Leerzeichen und gvstellt hier die letzte visuelle Auswahl wieder her. Sie können verwenden :help gv.
Benoit

6
@mark :xnoremap <expr> p 'pgv"'.v:register.'y`>' , ich habe `` `>` `hinzugefügt, um die Cursorposition wiederherzustellen
rox

19

In deinem .vimrc

xnoremap p "_dP

Ich fand dies aus einer Antwort in einem ähnlichen Thread, aber die ursprüngliche Quelle war http://vim.wikia.com/wiki/Replace_a_word_with_yanked_text . Es werden einige Nachteile erwähnt, aber es funktioniert gut für mich.


2
Dies scheint die einfachste Lösung zu sein.
Rudolph9

1
Hat für mich gearbeitet. Und diese Antwort ist klar. .vimrc.localist auch in Ordnung.
BaiJiFeiLong

3
Funktioniert nicht, wenn Ihre Auswahl bis zum Ende der Zeile reicht.
John Freeman

6

Die Lösung von Luc Hermitte wirkt wie ein Zauber. Ich habe es ungefähr eine Woche lang benutzt. Dann habe ich eine Lösung aus Steve Loshs .vimrc entdeckt , die gut funktioniert, wenn YankRing Teil Ihrer Plugin / Bundle-Reihe ist:

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

Versuchen Sie dies in Ihrem ~/.vimrc:

xnoremap <expr> p 'pgv"'.v:register.'y'
  • xnoremapbedeutet, dass dies nur für den VisualModus gilt, nicht für den Modus Visual + Select.

  • <expr>bedeutet, dass {rhs}die xnoremap {lhs} {rhs}Einstellung als Ausdruck ausgewertet wird.

  • In diesem Fall unser Ausdruck 'pgv"'.v:register.'y'verwendet .für Verkettung.

  • v:register wird anhand des Registers ausgewertet, das während der Erfüllung des Mappings verwendet wird.

Das Ergebnis von "xpwürde auswerten pgv"xy, wo xsich das Register befindet.

Eine Antwort auf diese Frage zum Stapelüberlauf hat mir geholfen: Vim - Mapping mit einem optionalen Registerpräfix in Verbindung mit Benoits Antwort auf dieser Seite


4

Lucs Funktion funktionierte gut für mich, nachdem ich eine Änderung vorgenommen hatte, um die Tatsache zu unterstützen, dass ich Zwischenablage = unbenanntes Set habe:

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

1
Als Referenz: Verwenden Sie clipboard=unnamedplusdies @+anstelle von @*.
Sebastian Blask

2

Luc Hermitte hat es geschafft! Wirklich gut. Hier ist seine Lösung in einer Umschaltfunktion, so dass Sie zwischen normalem Verhalten und Put ohne Register wechseln können.

Mit dem Befehl schaltet u das Verhalten um

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>

Sie können s: Repl auch so ändern, dass "p" anstelle von "p @ = RestoreRegister () \ <cr>" zurückgegeben wird, abhängig vom Wert von s: putSwap.
Luc Hermitte

1
lieber silent! vunmapalsvnoremap <silent> <expr> p p
Luc Hermitte

0

Klebebandprogrammierung, funktioniert aber bei mir:

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

Versuchen -

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

3
Diese steuern, ob ausgewählter Text in die Zwischenablage des Fenstersystems (z. B. X11 oder Win32) und nicht in die internen Kopierregister von Vim eingefügt wird.
Rob Kennedy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.