Wie springe ich zurück zur Cursorposition, bevor ich in den Einfügemodus gewechselt bin?

7

Ich versuche, normale Moduszuordnungen einzurichten, um das Hinzufügen von Leerzeichen um den Cursor zu vereinfachen:

<C-h>fügt rechts vom Cursor ein Leerzeichen hinzu;
<C-j>fügt unten eine neue Zeile hinzu;
<C-k>fügt oben eine neue Zeile hinzu;
<C-l>fügt rechts vom Cursor ein Leerzeichen hinzu; und
<C-Enter>fügt an der aktuellen Cursorposition eine neue Zeile hinzu.

Ich möchte auch, dass sich die Cursorposition während des Befehls nicht bewegt. Für links, rechts und Zeilenumbruch ist dies einfach:

nnoremap <C-h> i <Esc>l
nnoremap <C-l> a <Esc>h
nnoremap <C-^M> i<CR><Esc><Backspace>

aber für oben und unten die entsprechenden Befehle

nnoremap <C-j> o <Esc>k
nnoremap <C-k> O <Esc>j

bringt mich wieder in die richtige Zeile, aber nicht zurück zu derselben Spalte, in der ich vorher war.

Gibt es eine Möglichkeit, zu der Cursorposition zurückzukehren, an der ich mich kurz vor dem Aufrufen des Einfügemodus befand? Mein bestes Google-Fu hat nur Verweise auf ''& double-backtick (kann nicht herausfinden, wie der Markdown dort formatiert werden soll) und :jumps/ <C-O>& erwähnt <C-I>, von denen keines so zu funktionieren scheint, wie ich es gerne hätte.

Kann dies ohne Vimscript gelöst werden? Kann es überhaupt mit Vimscript gelöst werden ?

Ryan Lue
quelle

Antworten:

7

Sie können eine lokale Markierung an der Stelle setzen, an der Sie sich befinden, bevor Sie eine neue Zeile öffnen, und anschließend zu dieser Markierung zurückkehren.

Sie können einen beliebigen Buchstaben für die Marke auswählen, zum Beispiel x:

nnoremap <C-k> mxO<esc>`x
nnoremap <C-j> mxo<esc>`x
  • mxSetzt die Markierung, xin der sich der Cursor befindet
  • `x Bewegt den Cursor zurück zur Markierungsposition x

Sie können sich auch ansehen, was tpope in seinem unbeeinträchtigten Plugin geschrieben hat, und den folgenden Code in Ihr vimrc einfügen:

set nostartofline

function! s:BlankUp(count) abort
  put!=repeat(nr2char(10), a:count)
  ']+1
endfunction

function! s:BlankDown(count) abort
  put =repeat(nr2char(10), a:count)
  '[-1
endfunction

nnoremap <c-k> :<c-u>call <SID>BlankUp(v:count1)<cr>
nnoremap <c-j> :<c-u>call <SID>BlankDown(v:count1)<cr>

Der Vorteil dieser Lösung gegenüber der vorherigen besteht darin, dass sie eine Zählung akzeptiert und keine Ihrer Noten ändert.
Um beispielsweise 2 Zeilen über der aktuellen einzufügen, drücken Sie 2<C-k>3 Zeilen darunter 3<C-j>.

PS: Um einen doppelten Backtick in Ihren Beitrag zu schreiben, verwenden Sie vorher und nachher dreifache Backticks (und setzen Sie Leerzeichen vor und nach dem doppelten Backtick): ``

Bearbeiten
Ich habe gerade bemerkt, dass Sie im Fall der zweiten Lösung die Option deaktivieren müssen, wenn der Cursor zu derselben Spalte zurückkehren soll, in der er sich vor dem Einfügen einer neuen Zeile befand 'startofline':set nostartofline

Wenn diese Option deaktiviert ist, bleibt die Spaltennummer des Cursors gleich nach verschiedenen Befehlen wie mit <C-d>, gg, dd, >>, :bnext, :25.
Siehe :help 'startofline'für weitere Informationen.

saginaw
quelle
6

Hier ist kein Vimscript erforderlich. Die folgenden Zuordnungen machen genau das, was Sie verlangen:

nnoremap <C-j> m`o<Esc>``
nnoremap <C-k> m`O<Esc>``
  • m` wird verwendet, um die "vorherige Kontextmarke" zu setzen,
  • o<Esc> macht was du erwartest,
  • `` springt zurück zur vorherigen Kontextmarke.
romainl
quelle
Beachten Sie auch, dass Sie auch m'und ''anstelle von m`und``
EvergreenTree
2
@EvergreenTree, ''springt nicht zur rechten Spalte, sondern nur zur rechten Zeile.
Romainl
Ah, das habe ich nicht bemerkt.
EvergreenTree