Wie bewege ich mich zum letzten Zeichen in einem Satz?

9

Im normalen Modus (und )Umzug in den vorherigen oder nächsten ersten Zeichen im Satz ist. Wie bewege ich mich zum allerletzten Charakter?

Wenn alle meine Sätze mit einem Punkt enden, den ich verwenden kann )T.(erstes Zeichen des nächsten Satzes, dann rückwärts zum ersten Punkt), möchte ich jedoch eine robustere Lösung für ein Makro.

Ich weiß über asund isim visuellen Modus Bescheid , also vis<ESC>funktioniert es (visueller Modus, dann innerhalb des Satzes auswählen, dann visuellen Modus verlassen), aber das scheint mir ziemlich hässlich und ich kann es nicht als Bewegung mit anderen Befehlen verwenden.

Ich bin ratlos. Hilfe!

bsmith89
quelle
Warum zwei <esc>? Du brauchst nur einen.
Türknauf
Hoppla, ich war gerade durcheinander, weil vim verspätet reagiert hat. Ich werde die Frage bearbeiten.
bsmith89
1
Ich kann nur vorschlagen )gE. Ich weiß, dass Sie gesagt haben, Sie beenden Sätze immer mit einem Punkt, aber es ist besser, das nicht einmal annehmen zu müssen.
Superjer
Beachten Sie auch, dass asund isnicht nur im visuellen Modus arbeiten. Sie können dasim normalen Modus einen Satz löschen.
Superjer

Antworten:

10

Aus meiner Forschung dazu müssen Sie mindestens zwei benutzerdefinierte Bewegungen definieren. Der erste dient nur zum Bewegen des Cursors und der zweite zum Verwenden in Operatoren. Für ein voll funktionsfähiges Setup ist es viel komplizierter, und ich würde empfehlen, den Code in CamelCaseMotion von Ingo Karkat zu betrachten, der deutlich mehr Überlegungen dazu enthält, dies richtig zu machen als unten. Der größte Teil meiner Antwort basiert auf schnellen Informationen in der Vim-Hilfe und im Experimentieren.

In den folgenden Beispielen werde ich die )und (Bewegungen neu zuordnen , um jedes Ende eines Satzes zu machen. Sie können andere Zeichen verwenden, indem Sie das Beispiel ändern. Ich gehe auch auf Ihr Beispiel vis<ESC>als die robustere Option (im Vergleich zu )T.). Wenn Sie sich dabei bereits am Ende eines Satzes befinden, bleiben Sie am Ende, anstatt aufgrund der Funktionsweise zum Ende zu gelangen is. Sie können versuchen, es durch aszu ersetzen, um unterschiedliche Ergebnisse zu erzielen. Dies sollte tatsächlich funktionieren, um beide Seiten eines Textobjekts in eine Bewegung umzuwandeln.

Erstens die Bewegung im normalen Modus

Hinweis Dies funktioniert nicht im visuellen Modus oder im anhängigen Bedienermodus

function! MoveToEnd(type, ...)
    exe "normal `]"
endfunction
map <silent> \) :set opfunc=MoveToEnd<CR>g@
nmap ) \)is

Zuerst definieren wir eine neue Funktion namens, MoveToEndderen einzige Aufgabe darin besteht, den Cursor auf das "letzte Zeichen des zuvor geänderten oder gezogenen Textes" zu setzen, das die ]Markierung ist (siehe :help ']).

Als nächstes erstellen wir einen benutzerdefinierten Operator \), der unsere MoveToEndFunktion für jede Bewegung aufruft , die ihm gegeben wird. Auf diese Weise wird die ]Marke zum Ende der Auswahl, die unserem neuen Bediener gegeben wird. (siehe :help map-operator)

Schließlich ordnen wir )unseren benutzerdefinierten Operator mit der isMehrheit zu, wodurch effektiv das Äquivalent von angegeben wird, vis<ESC>ohne die letzte visuelle Auswahl zu ändern und ohne die Modi zu ändern.

Das Gegenteil ist ähnlich, nur mit den anderen Richtungen:

function! MoveToBeginning(type, ...)
    exe "normal `["
endfunction
map <silent> \( :set opfunc=MoveToBeginning<CR>g@
:nmap ( \(is

Zweitens die Bedienerbewegung

Dieser ist schwieriger. Unsere Bewegung oben zerstört die Startposition, sodass Bediener wie 'd' gegen nichts arbeiten. Was wir brauchen, ist in der Lage zu sein, unsere Startposition zu speichern und die Endposition hinzuzufügen. :help omap-info(Operator Pending Mapping) gibt einen Tipp dazu, nämlich den visuellen Modus zu verwenden.

Dann speichern wir unsere Position an einem Ende des visuellen Auswahlregisters, verwenden unsere Bewegung im normalen Modus von oben, stellen das andere visuelle Auswahlregister ein und aktivieren dann den visuellen Modus:

function! SelectToEnd()
    normal m<  "Set start point of visual selection
    normal )   "Move to end of sentance (relies on mapping from earlier)
    normal m>  "Set end point of visual selection
    normal gv  " 'Go Visual' activate visual mode using selection marks
endfunction
omap ) :call SelectToEnd()<CR>

Und für unsere Rückenbewegung:

function! SelectToBeginning()
    normal m>  "Set end point to current position (since we are moving backwards)
    normal (   "Move to beginning of sentence (relies on mapping from earlier)
    normal m<  "Set start point
    normal gv  "Activate visual mode based on our new marks
endfunction
omap ( :call SelectToBeginning()

Mit dieser Option können Sie d)bis zum Ende des Satzes löschen (anstelle des Originals bis zum Anfang des nächsten Satzes). Alle anderen Bediener sollten ebenfalls funktionieren.

John O'M.
quelle
4

Ninja Füße

Ich habe ein Plugin namens ninja-feet.vim geschrieben , das bei diesem Problem helfen soll.

Bewegliche Operatoren

Es definiert einige bewegliche Operatoren 1 , mit denen Sie Text von Ihrem Cursor bis zu einem Ende eines Textobjekts bearbeiten können . Die Verwendung von [oder ]zwischen dem Operator und dem Textobjekt bewirkt, dass der Operator Text vom Cursor bis zur linken bzw. rechten Grenze des Textobjekts bearbeitet.

Es gibt auch Normalmodus Operatoren zum Starten Insert - Modus am Anfang oder Ende eines Textobjekts: z[und z], respectively.

Beispiel 1: Wechseln Sie von hier zum Ende der Zeichenfolge

In diesem Beispiel bezeichnen wir |die Cursorposition.

foo("This is a string| with superfluous text at the end", bar);

Durch Eingabe d]i"wird dies geändert in:

foo("This is a string", bar);
  1. d: Verwenden Sie den Löschoperator
  2. ]: bis zum Ende des folgenden Textobjekts
  3. i": zitiertes String-Textobjekt

Beispiel 2: Beginnen Sie mit dem Einfügen nach dem aktuellen Satz

Wiederum bezeichnen wir |die Cursorposition.

Here is |some sentence. And here is another.

Durch Eingabe z]iswird der Einfügemodus am Ende des ersten Satzes gestartet.

  1. z]: Starten Sie den Einfügemodus nach dem folgenden Textobjekt
  2. is: Satztextobjekt

Vorsichtsmaßnahmen

  • Diese Zuordnungen sind mit nicht wiederholbar .. Es ist ziemlich knifflig und ich versuche es richtig zu machen.
  • Die Operatoren [und ](zwischen Operator und Textobjekt verwendet) funktionieren nur für Textobjekte, die mit ioder beginnen a. Technisch gesehen , das ist , weil sie wirklich Karten für [i, ]i, [aund ]a. Ich würde das gerne verbessern, aber es ist auch sehr schwierig.
  • Es gibt keine Bewegungen im Normalmodus, mit denen Sie den Cursor einfach an ein Ende eines Textobjekts bewegen können. Ich habe es zum Laufen gebracht, aber zum Preis der Bewegung, die tatsächlich ein Operator ist (was bedeutet, .dass die Bewegung wiederholt wird). Ich finde dieses Verhalten nicht akzeptabel.

1 Ich nenne sie bewegliche Operatoren, weil sie Operatoren sind, die im Operator-Pending-Modus zugeordnet sind. Dies ist der Modus, in dem Sie zwischen der Eingabe eines Operators und einer Bewegung (z. B. zwischen dund win dw) liegen.

tommcdo
quelle