Mapping mit Bewegung


12

Ich versuche zu verstehen, wie ich einen Operator mit anschließender Bewegung in einem Mapping verwenden kann. Beispielsweise:

nmap /c c{here we pending for a motion}/<C-r>"<CR>

Die Karte sollte Folgendes tun:

  1. Aktivieren Sie den cBediener und warten Sie auf die nächste Bewegung.
  2. ZB kann ich hier eingeben, t,um alles vor dem nächsten Komma zu ändern;
  3. Gehen Sie in den Einfügemodus und löschen Sie alles zwischen Cursor und Komma.
  4. Gelöschter Text wird automatisch als Muster gesucht

Einfach ausgedrückt, nachdem der Bewegungstext entfernt wurde, wird der Einfügemodus mit hervorgehobenen Vorkommen des gelöschten Texts beendet. Ich wäre sehr dankbar, wenn mir jemand helfen würde, diesen Fall zu klären.

AKTUALISIEREN

Die Antworten sind fast das, was ich will. Aber! Wenn ich drücke /cw, tippe etwas anstelle des Wortes und drücke dann <Esc>. Danach gehe ich davon aus, dasselbe bei den nächsten Ereignissen zu tun. Nach dem Drücken von n(gehe zum nächsten Vorkommen) und .(wiederhole den letzten Befehl) wird nur der zuletzt eingegebene Text vorangestellt, anstatt ihn zu ersetzen. Das Hauptziel des Mappings ist es, es mit n/Nund .zu wiederholen. Habe ich etwas verpasst

Antworten:


9

vim unterstützt Operator-Mapping :h map-operator.

Was Sie brauchen, ist ein operatorfuncund ein Mapping. Für Ihre Bedürfnisse funktionieren die folgenden Codes. Nun, es ist nur ein Beispiel, das Sie weiter verfeinern.

nmap  <silent> /c :set opfunc=SpecialChange<CR>g@
function! SpecialChange(type)
    silent exec 'normal! `[v`]d'    
    silent exec 'let @/=@"' 
    startinsert
endfunction

Beachten Sie, dass exec 'let @/=@"'nur zum Hervorheben der Codes im Puffer. Wenn Sie die Hervorhebung nicht sofort sehen möchten, können Sie einfachlet @/=@"


Ich habe meine Frage aktualisiert. Es sieht so aus, als ob Ihre Antwort meinen Bedürfnissen am nächsten kommt, aber beim nächsten Auftreten ist es nicht dasselbe. Deshalb habe ich diesen Moment in der Frage erläutert.
Timur Fayzrakhmanov

Sie haben zwei Operatoren (die /cund i) vim .wiederholt nur die letzte. Wenn Sie es erweitern möchten, überprüfen Sie das repeatPlugin. @ TimurFayzrakhmanov gibt es auch :gund :sBefehle, kann Ihnen auch helfen.
Kent

Enthält "Ihr Code einen ungeraden Code 'let @/=@""'? Ich dachte , es ist möglich, zum Beispiel silent exec 'normal! [v ]c', weil cBediener tun , was ich erwarten, außer es nicht den geänderten Text zu dem Suchmuster hinzufügt.
Timur Fayzrakhmanov

1
@ TimurFayzrakhmanov das "" war ein Tippfehler .. fix .. Ich kam auch mit c, aber es fügte ein Leerzeichen hinzu, weil es einen Moduswechsel gibt, n-i-n-idenke ich ... mache einen Test, den du sehen wirst.
Kent

@ TimurFayzrakhmanov Sie können es wiederholbar machen, ohne ein Plugin durch Ändern dvon yund startinsertzu call feedkeys("cgn", 'n')(siehe meine Antwort unten)
Jerome Dalbert

4

Es ist einfacher, komplexe Zuordnungen mithilfe von Funktionen zu implementieren (und zu dokumentieren):

function! DoMagic()
   execute "normal! d".input("enter motion: ")
   let @/=@"
   startinsert
endfunction

Dann rufen Sie in Ihrem Mapping diese Funktion auf:

nmap /c :call DoMagic()<CR>

Bearbeiten:

Wenn Ihre Absicht durchführen zu suchen ist und Ersetzen in einer großen Anzahl von Orten sollten Sie den Ersatz - Befehl versuchen: :s. Sie können Ihre Zuordnung ändern, um die visuelle Auswahl in das Suchmuster zu kopieren:

function! DoMagic2()
   normal! gv"ay
   return @a
endfunction

vmap /c :<c-w>%s/<C-r>=DoMagic2()<CR>//gc<left><left><left>

1
Dies funktioniert sogar mit einer "netten" Benutzeroberfläche, die für die Anforderungen von OPs geeignet ist und je nach Eingabe "mehr" als erwartet sein kann. ZB wenn man sieht enter motion:, gab er: t,ggVGJZZ ^ _ ^ Es ist ein häufiges Problem für die Befehlsverkettung
Kent

Das ist fast das, was ich will. ZB: Ich drücke /cwdann etwas anstelle des Wortes und drücke dann <Esc>. Nachdem ich das gleiche mit den nächsten Vorkommnissen machen möchte. Nach dem Drücken von n(gehe zum nächsten Vorkommen) und .(wiederhole den letzten Befehl) wird nur der zuletzt eingegebene Text vorangestellt, anstatt ihn zu ersetzen. Das Hauptziel des Mappings ist es, es mit n/Nund .zu wiederholen. Habe ich etwas verpasst
Timur Fayzrakhmanov

1
Diese Funktion dient zur Verdeutlichung der Verwendung von Funktionen bei Problemen mit komplexen Zuordnungen. Sie sollten es an Ihre Bedürfnisse anpassen. Versuchen Sie, Kents Rat zu befolgen, um den .Befehl zu wiederholen.
16.

Danke für die Antwort. Es ist zu nützlich, aber ich die @Kent ist eine akzeptieren, weil es Bewegung tun sofort , nachdem ich sie eingeben (ohne anhängig <CR>aus input()).
Timur Fayzrakhmanov

1
@ TimurFayzrakhmanov Sie könnten auch den Ersatz versuchen, wie im Update erläutert.
MMontu

1

Diese Lösung funktioniert mit "Letzten Befehl wiederholen" (aka .):

nmap <silent> /c :set opfunc=ChangeOccurence<CR>g@

function! ChangeOccurence(type)
  exec 'normal! `[v`]y'
  let @/ = @"
  call feedkeys('cgn', 'n')
endfunction

Wenn Sie das wiederholen, brauchen Sie es nicht einmal zu verwenden n, Sie können es nur verwenden ., um das nächste Vorkommen direkt abzurufen und zu ersetzen, wenn Sie schneller gehen möchten.

Wenn Sie Hervorhebungen der übereinstimmenden Wörter wünschen, können Sie diese optional 'cgn'durch ersetzen 'n``cgn'.

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.