45 Stimmen

Wie kann man verhindern, dass der Cursor beim Verlassen des Einfügemodus in Vim ein Zeichen zurückgeht?

Ist es möglich, dieses Verhalten rückgängig zu machen?

Eine Aufgabe für zusätzliche Punkte: Finden Sie einen Weg, Vim zu zwingen, die Cursorposition sofort nach dem Verlassen des Einfügemodus zu aktualisieren.

9 Stimmen

Interessante Frage. Ich frage mich, was der Grund für dieses Verhalten ist. Ich habe es einfach akzeptiert.

5 Stimmen

Ich habe es versucht. Es ist ein bisschen unbequem. Wenn ich den Cursor bewege, könnte ich siehe wenn ich den Bearbeitungsmodus verlasse.

1 Stimmen

@StefanoBorini Es gibt einen Teil der Erklärung in diese Frage hier auf SO. So wie ich es verstehe: Wenn Sie den Einfügemodus verlassen, weiß vi nicht, ob Sie den Modus mit a o i und nimmt daher an a . Und wirklich: Der Cursor "rutscht" nicht weg, wenn Sie a und Esc wiederholt.

30voto

ib. Punkte 26240

Allerdings würde ich nicht empfehlen, die Standard-Cursor-Mechanik zu ändern, eine Möglichkeit, das fragliche Verhalten zu erreichen, ist die Verwendung der folgenden Einfügemodus-Zuordnung.

:inoremap <silent> <Esc> <Esc>`^

Hier wird die Esc Taste ist im Einfügemodus überladen, um zusätzlich die `^  Befehl, der den Cursor an die Stelle bewegt, an der er an die Stelle bewegt, an der er sich beim letzten Verlassen des Einfügemodus befunden hat. Da er in dieser Abbildung sofort nach dem Verlassen des Einfügemodus ausgeführt wird, mit Esc , wird der Cursor um ein Zeichen nach rechts verschoben im Vergleich zu seiner Position beim Standardverhalten.

Im Gegensatz zu einigen anderen Umgehungslösungen erfordert diese nicht, dass Vim kompiliert werden mit dem +ex_extra Funktion.

2 Stimmen

Ja, und ich glaube, es ist auch kohärenter. Anhängen bedeutet bereits, den Cursor um ein Zeichen nach rechts zu bewegen, unabhängig davon, ob Sie Zeichen eingegeben haben oder nicht.

0 Stimmen

@ib +1, ich wechsle, stelle um und bereite neue Maschinen vor eine Menge und dieser Ansatz hat sich für mich millionenfach ausgezahlt. (Ich spreche bei weitem nicht nur von vim.) Aber dennoch: für weniger "nomadische" Menschen kann der Aufbau einer super-bequemen Umgebung sicherlich ein besserer Ansatz sein.

2 Stimmen

@NathanNeff, das ist die beste Lösung, die ich je gesehen habe und übertrifft bei weitem die eigentliche Antwort, auf die Sie geantwortet haben.

17voto

DrAl Punkte 67029

Es gibt zwar Tricks, um damit umzugehen (z. B. die ESC Mappings, die in den beiden vorangegangenen Beiträgen erwähnt wurden), gibt es keine einheitliche Methode, dies zu tun. Der Grund dafür ist, dass es keine Möglichkeit gibt, die Methode zu bestimmen, mit der der Einfügemodus aufgerufen wurde. Genauer gesagt, wenn die Zeichenfolge abcDefg mit dem Cursor auf dem Feld D :

  • Wenn Sie die Taste i befindet sich die Position des Einfügemodus zwischen den c y D . A normal ESC setzt den Cursor auf c ; <C-O>:stopinsert<CR> (oder die Backtick-Methode) setzt den Cursor auf D .

  • Wenn Sie die Taste a befindet sich die Position des Einfügemodus zwischen den D y e . A normal ESC setzt den Cursor auf D ; <C-O>:stopinsert<CR> setzt den Cursor auf e .

Wenn Sie das WIRKLICH wollen, können Sie es mit so etwas wie dem Folgenden überspielen:

let insert_command = "inoremap <ESC> <C-O>:stopinsert<CR>"
let append_command = "iunmap <ESC>"
nnoremap i :exe insert_command<CR>i
nnoremap a :exe append_command<CR>a

ABER: Denken Sie daran, dass dies nur für folgende Fälle gilt i y a als Eingabemethoden: wenn Sie den visuellen Blockmodus verwenden, I , oder A oder was auch immer, müssen Sie sich neue Befehle ausdenken, die dazu passen (und davon gibt es viele). Daher würde ich Ihnen dringend empfehlen, dies nicht zu tun.

Ich persönlich würde empfehlen, sich an das Standardverhalten zu gewöhnen. Sie können es leicht logisch machen für i OR logisch für a . Wenn Sie den Standardwert auf logisch ändern für i auf Kosten der Logik für a Wenn Sie eine normale vi/vim-Installation verwenden, werden Sie nur verwirrt sein.

12voto

Mikel Punkte 23574

Basierend auf Nathan Neffs Kommentar Der beste Ansatz, den ich gefunden habe, ist

autocmd InsertLeave * :normal! `^
set virtualedit=onemore

autocmd bewegt den Cursor an die Stelle zurück, an der er sich zum Zeitpunkt der Beendigung des Einfügemodus befand (d. h. einen Schritt vorwärts im Vergleich zur Standardeinstellung).

virtualedit sorgt dafür, dass es am Ende der Zeile konsistent agiert (es kann also ein Zeichen vor dem letzten Zeichen in der Zeile sein).

(Bearbeitet: normal! um rekursive Zuordnungen zu vermeiden)

7voto

tur1ng Punkte 2891
inoremap <silent> <Esc> <C-O>:stopinsert<CR>

in Ihrem .vimrc .

0 Stimmen

Diese Zuordnung macht es logisch, wenn Sie den Einfügemodus mit i aber unlogisch, wenn Sie den Einfügemodus mit a .

2 Stimmen

Nun, man könnte den normalen Modus umstellen i um ein Flag zu setzen und dann den Einfügemodus neu zuzuordnen <Esc> um dieses Flag zu überprüfen, und wenn es gesetzt ist, verwenden Sie <C-O>:stopinsert<CR> und löschen Sie dann die Markierung in beiden Fällen.

2 Stimmen

Ich bin nicht überzeugt, dass dies völlig unlogisch ist, denn a . Im Allgemeinen bin ich nach jeder Änderung, wenn ich diese verlasse, mit dieser Änderung fertig, und die nächste Sache, die ich tun möchte, wird wahrscheinlich eine andere Änderung beinhalten. Wenn ich also den Einfügemodus verlasse (egal wie ich ihn betreten habe), ist es mir im Allgemeinen lieber, wenn sich der Cursor auf dem nächsten Zeichen befindet, damit ich für meine nächste Änderung bereit bin, als dass ich bereit bin, das zu ändern, was ich gerade eingefügt habe. (größtenteils von meinem Kommentar hier kopiert: unix.stackexchange.com/a/11403/38050 )

4voto

Steven Lu Punkte 38883

Ich glaube, die richtige Vorgehensweise ist

au InsertLeave * call cursor([getpos('.')[1], getpos('.')[2]+1])

1 Stimmen

Bei der ersten Spalte verhält sich dies jedoch nicht korrekt. einfügen if (getpos('.')[2] > 1) | vor dem call um es zu reparieren. (Außerdem sollte es Teil eines augroup um kumulative Vorwärtssprünge beim Nachladen einer .vimrc die diesen Autocommand enthält).

0 Stimmen

Können Sie ein Beispiel dafür geben, wie man die augroup Sache? Danke

0 Stimmen

Dies funktionierte bei mir am besten, aber ich musste 'set timeoutlen=100' verwenden, da das InsertLeave-Ereignis eine ganze Sekunde dauerte, bevor es ausgelöst wurde

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X