Wie bewege ich mich vertikal, bis ich ein Nicht-Leerzeichen erreiche?


27

In einer sehr langen Datei mit (genau-) eingerücktem Code kann es hilfreich sein, direkt zu einer Textzeile über oder unter dem Cursor zu wechseln, die den Einzug begrenzt.

(Eine Möglichkeit hierfür ist die Methode zum Falten von Einrückungen, bei der die aktuelle Einrückungsebene gefaltet wird. Dabei werden die Zeilen, die die Einrückungsebene begrenzen, so zusammengefasst, dass sie nur ein joder knicht vom Cursor entfernt sind. Ich habe jedoch Fälle gefunden, in denen das Falten von Einrückungen nicht erfolgt konnte an dem Gedankenstrich arbeiten, an dem ich interessiert bin.)

Hier ist ein Beispiel, bei dem der Cursor durch den Unterstrich markiert ist _(in der zweiten Zeichenspalte zwischen den Definitionen von class Bazzund class Qux). Stellen Sie sich jedoch vor, dass die Anzahl der Absätze oder Zeilen innerhalb des modules unbekannt oder variabel ist:

module Foo
  # lots of code...
end

module Bar
  class Baz
    # ...
  end

  class Bazz
    # lots of code...
  end
 _
  class Qux
    # ...
  end

  class Quux
    # lots of code...
  end
end

... wie kann ich schnell zu dem ovon module Barüber dem Cursor oder dem nvon endunter dem Cursor in der allerletzten Zeile navigieren ? Beachten Sie, dass die vertikale Spalte Leerzeichen, aber auch keine Zeichen in der zweiten Spalte zwischen den classDefinitionen enthält.


2
verwandt: "Zur nächsten / vorherigen Zeile mit demselben Einzug wechseln
alxndr

Wenn Sie g und dann die Richtungstaste drücken, werden möglicherweise Tabulatoren
vermieden

1
Die Lösung in @ alxndrs Link funktioniert gut, außer wenn der Whitespace schlecht gepflegt ist (z. B. es gibt zufällige Zeilen, die nur Whitespaces enthalten) und Sie den Whitespace ignorieren möchten. superjers lösung unten ist besser, wenn man sich über diesen fall Gedanken macht.
Nukeguy

Antworten:


9

Wie wäre es mit dieser Funktion?

function FloatUp()
    while line(".") > 1
                \ && (strlen(getline(".")) < col(".")
                \ || getline(".")[col(".") - 1] =~ '\s')
        norm k
    endwhile
endfunction

Sie könnten nnoremap gU :call FloatUp()<CR>( gUfür "steigen") und dann mit aufrufen gU.

Hier ist eine Erklärung:

  • Der Code bewegt den Cursor wiederholt nach oben (mit norm k), solange die whileBedingung erfüllt ist.
  • Die whileBedingung gilt, wenn dies nicht die erste Zeile ist ( line(".") > 1) und auch nicht
    • Diese Zeile ist zu kurz (wahrscheinlich leer). oder
    • Das getline(".")Zeichen der aktuellen Zeile ( ) in der aktuellen Spalte ( [col(".") - 1]) ist ein Leerzeichen ( =~ '\s'dh es entspricht dem Leerzeichenmuster).

1
Dies scheint perfekt (und schnell) zu FloatDownfunktionieren und lässt sich auch leicht in eine Funktion umwandeln. In meine .vimrc geht es, danke! github.com/alxndr/dotfiles/commit/0e25a302
alxndr

1
Wir haben gerade festgestellt, dass diese Lösung im visuellen Modus nicht ganz funktioniert (etwas anderes Verhalten, je nachdem, welcher visuelle Modus verwendet wird, bleibt sie entweder an derselben Position oder bewegt sich nur um eine Zeile). Gibt es Hinweise darauf, was dort los ist?
26.

13

Ich verwende gerne die Suche nach diesen Dingen, weil Vims reguläre Ausdrücke eine unglaubliche Menge von Dingen enthalten, nach denen Sie suchen können, z. B. nach bestimmten virtuellen Spaltennummern in diesem Fall:

nnoremap cd /\%<C-R>=virtcol(".")<CR>v\S<CR>

nnoremap cu ?\%<C-R>=virtcol(".")<CR>v\S<CR>

Mit cdrunter und curauf gehen. Ich denke hier "Spalte hoch" und "Spalte runter". Ich bin fast zu 100% davon überzeugt, dass dies standardmäßig No-Ops sind. Oder wählen Sie Ihre eigenen Zuordnungen.

Dies sollte funktionieren, unabhängig davon, ob Sie Tabulatoren oder Leerzeichen oder beides verwenden.


1
Ich habe Probleme beim Parsen dieser Befehle. Würde es Ihnen etwas ausmachen, sie etwas zu erweitern?
Davidlowryduda

1
/ oder ? Um nach unten oder oben zu suchen, begrenzt \% xv die Suche auf die virtuelle Spaltennummer 'x'. In diesem Fall ist das 'x' '<CR> = virtcol (".") <CR>', das den Befehl virtcol ausführt und einfügt Die Nummer der virtuellen Spalte, an der sich der Cursor im Ausdruck befindet. \ S steht für ein beliebiges Nicht-Leerzeichen.
Tschad

1
Danke, dass du Chad erklärt hast. Ich möchte nur hinzufügen, dass <CR> im Einfüge- oder Befehlszeilenmodus den Inhalt eines Registers erfasst. Das =Register ist das Ausdrucksregister, das einen Ausdruck an Ort und Stelle auswertet. Es ist sehr praktisch, wenn nicht ein bisschen komisch aussehend.
Superjer

1
Ein Nachteil dieses Ansatzes besteht darin, dass bei aktivierter Suchmarkierung alle Zeichen in der vertikalen Spalte des Cursors nach dem Aufwärts- oder Abwärtsspaltenmarkieren hervorgehoben werden.
Alxndr

3
Wenn Sie Ihre vorhandene Suche schützen möchten, können Sie sie voranstellen :let searchbak=@/<CR>und anhängen :let @/=searchbak<CR>. Aber zu diesem Zeitpunkt wird es ziemlich lang und unnahbar und sollte vielleicht nur eine Funktion sein.
Superjer

7

Sie können das JumpToVerticalOccurrence- Plugin verwenden (standardmäßig ]|und zugeordnet [|). Es gibt nur wenige, ]V{char}die so funktionieren f, aber vertikal. Sie können sie natürlich nach Bedarf neu zuordnen.


Wenn Sie keine Plugins verwenden möchten, können Sie versuchen, :searchmit zu verwenden virtcol(.), z. B .:

:call search('\%' . virtcol('.') . 'v\S', 'bW')

woher:

  • virtcol('.') gibt Ihnen die aktuelle Spalte,
  • \S steht für non-whitespace
  • bW ist für die Rückwärtssuche

Überprüfen Sie :help search, um mehr zu erfahren.

Um die Verwendung zu vereinfachen, können Sie es zuordnen, z.

:map <C-k> :call search('\%' . virtcol('.') . 'v\S', 'bW')<CR>
:map <C-j> :call search('\%' . virtcol('.') . 'v\S', 'W')<CR>

Alternativ, wenn Sie den Code Klammern enthält, verwenden Sie %zwischen passender sie springen ( zum Beispiel {, }, [, ], etc.) oder benutzen ganzer Absatz springt ( {, }mit , Shiftfalls erforderlich).


Links / Quellen:


Von :h search(): wbedeutet wrap around the end of the fileund Wbedeutet don't wrap around the end of the file. Aber warum hast du sie in der zweiten zusammengefügt :map?
Jair López

@JairLopez Richtig, wsollte nicht da sein, also habe ich es entfernt, danke. Wahrscheinlich war ich durch die Bedeutung der Bewegungstasten verwirrt.
Kenorb

3

Ich verwende eine geänderte Version des Plugins vim-indent-object , um dieses Verhalten bereitzustellen. Meine Änderungen zu sehen sind hier .

Auf diese Weise kann ich abbilden [i, um zum Anfang der aktuellen Einzugsebene und ]izum Ende zu gelangen.


2

Es ist nicht genau das, was Sie gefragt , weil es nicht eine vertikale Bewegung, sondern etwas , das ähnlich ist, schnell und kann gut genug sein für Sie rückwärts 2 Absätze bewegt: {{. Damit gelangen Sie direkt zur vorherigen Zeile module Bar.


2
Stellen Sie sich vor, dass sich zwischen dem Cursor und der obersten moduleZeile eine unbekannte Anzahl von Zeilen und / oder Absätzen befindet. (Insbesondere trat diese Situation auf, als ich kürzlich in mehreren tausend Zeilen langem Code von Drittanbietern mit genauem Einzug, aber ohne Leerzeilen navigierte und versuchte, den äußeren Kontext der Definition eines Moduls zu finden.)
alxndr

Das Springen nach Absätzen ist meine bevorzugte Art, sich zu bewegen, aber es war keine Option: Die gesamte Datei bestand aus einem "Absatz".
3.


1

Ich benutze dafür mein eigenes Plugin move_until_char_changes.vim .

Ich ordne es gKund zu gJ.

Es springt über viele Zeilen mit demselben Zeichen in der aktuellen Spalte (nicht nur über Leerzeichen), was bei Protokolldateien oder SQL-Speicherauszügen mit wiederholten Zeichenfolgen hilfreich sein kann.

Standardmäßig wird zuerst eine Zeile verschoben, bevor das Suchzeichen verwendet wird.

Es funktioniert im visuellen Modus, vorausgesetzt, Sie versuchen nicht, es zweimal zu verwenden, und Sie befinden sich nicht im zeilenweisen oder blockweisen visuellen Modus ... (Fehlerbehebungen erwünscht!)


1

Da ich es hier nicht als Antwort sehe ( Edit hat gerade gemerkt, dass Superjer etwas sehr ähnliches erwähnt hat). Du kannst einfach das / oder? Suche.

Beispielsweise können Sie in der 2. Spalte nach einem Nicht-Leerzeichen wie folgt nach unten suchen:

/\%2v\S

Die Aufteilung ist:

/    "search downward (use ? for upward movement)
\%2v "for the following char in the 2nd virtual column
\S   "any non white space character

Dann können Sie die Suche mit den normalen Operatoren wiederholen.

Weitere Informationen zu diesem Thema finden Sie unter :help \%cund :help \%v.

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.