Wie erstelle ich automatisch passende Klammern in vim?
Es sollte wie folgt funktionieren: Wenn ich eine offene Klammer eingebe, sollte die schließende automatisch erscheinen und der Cursor dazwischen stehen. Zum Herausspringen aus dem Zahnspangenpaar wird die Kombination Ctrl-jverwendet.
Es gibt viele Plugins, die das automatische Einfügen von Klammern ermöglichen. Aber sie
- Verwenden Sie entweder eine andere Tastenkombination als Ctrl-j, um aus dem Klammerpaar zu springen, oder
- stören die UltiSnips- Tastenkombinationen.
Das Folgende funktioniert wie erwartet
:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a
Aber mit diesen Einstellungen funktionieren die UltiSnips-Snippets nicht mehr. Also habe ich UltiSnips verwendet, um die schließende Klammer einzufügen:
inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>
Das funktioniert fast. Die passende Klammer wird eingefügt und ich kann die schließende mit überspringen Ctrl-j. Dies funktioniert jedoch nur, wenn vor der geöffneten Klammer ein Leerzeichen vorhanden ist.
main () // works, the closing parentheses is added
main( // fails without a space
Meine Lösungen erfordern entweder eine andere Schlüsselbindung, um über die schließende Klammer zu springen, oder erfordern ein Leerzeichen vor der offenen. Wie kann man das beheben?
Hinweis: Als Beispiel habe ich Klammern verwendet. Es sollte mit Klammern, Klammern, Klammern und Kleinbuchstaben funktionieren und das UltiSnips-Plugin nicht beeinträchtigen.
)
, eine Neuzuordnungc-j
könnte funktionieren.Antworten:
Dieses Problem ist nicht trivial, wie Sie sehen werden. Die einfache Antwort lautet: Verwenden Sie ein Plugin wie Autoclose oder Smartinput . Durch einfaches Neuzuordnen der Tasten ([..] erhalten Sie Edgecases in mehreren Zeilen. Deshalb werden diese Plugins erstellt und sind normalerweise recht komplex (wenn sie gut sind).
Sie könnten dies stattdessen versuchen (was sich von meinem ursprünglichen Vorschlag unterscheidet):
Wobei UltiSnips die Linie aufteilt,
(
anstatt siemain
in das Match einzubeziehen . Das Problem bei der Verwendung eines Snippet-Plugins besteht darin, dass es (normalerweise) kein Verschachteln unterstützt, sodass Sprungpositionen beim Einfügen des nächsten (verschachtelten) Snippets vergessen werden.Sie können entweder Ctrl-jfür UltiSnips oder das in Konflikt stehende Plugin eine Neuzuordnung vornehmen. Wenn die Zuordnungen nicht in der Dokumentation aufgeführt sind, können Sie sie
:map/imap/nmap <key>
anzeigen. Wenn Sie Ctrl-jbeide Plugins auswählen und ausführen möchten , fragen Sie nach:Betrachten Sie diese Bash-Schleife:
In diesem Fall müssen Sie Ctrl-jfünfmal drücken , um zum Loop-Body zu gelangen. Wenn Sie die schließenden Klammern verwenden, um aus einem entsprechenden Paar zu springen, können Sie viel besser steuern, wo sich der Cursor tatsächlich bewegen soll. Sie könnten einen Stapel implementieren, um eingefügte Paare zu verfolgen und Ctrl-jzum Platzieren und Verschieben zu verwenden, aber dann treten Probleme auf, wenn Sie beginnen, Klammern manuell zu löschen, ohne sie aus dem Stapel zu entfernen. Also werden Sie anfangen, Probleme zu lösen, die die Klammer-Plugins zu lösen versuchen. Das Rad ist schwer neu zu erfinden.
Wenn Sie dies erweitern, können Sie das bekommen, wonach Sie ursprünglich gefragt haben, indem Sie Ctrl-jaus geschweiften Klammern und Auszügen springen . Wenn Sie einen Dummy-Wert verwenden, um die Schnipselpositionen darzustellen, und diese zusätzlich zu den schließenden Klammern auf den Stapel schieben, wobei die dynamische Neuzuordnung der Ctrl-jÜbergabe von Schnipsel oder Klammern entspricht. Dann müssen Sie jedoch einige recht fortgeschrittene Heuristiken implementieren, um herauszufinden, was mit Magie geschehen soll, da Sie im Wesentlichen zwei Probleme gleichzeitig angehen, die derzeit von den Entwicklern der Plugins zum Einfügen von Snippets und zum Anpassen von Klammern separat gelöst werden Lösen Sie diese Probleme erneut, zusätzlich zu ihren Lösungen, um Bequemlichkeit und Magie zu erreichen.
Es kommt auf die Kontrolle gegen die Bequemlichkeit an. Ich denke, die Steuerung wird Ihnen in diesem Fall bessere Dienste leisten. Das bedeutet, Sie sollten diese Probleme und die zugehörigen Plugins und Tastenzuordnungen voneinander trennen. Wenn Sie noch Bequemlichkeit wünschen, ist es machbar, aber es ist schwer.
quelle
Ich denke, delimitMate macht das, was Sie brauchen.
Es schließt automatisch Klammern oder Anführungszeichen und setzt den Cursor dazwischen. Springen aus einem Klammerpaar (während im Einfügemodus ist) würden Sie tun Ctrl-g+ , gaber Sie können diese neu zuordnen sein , Ctrl-jindem Sie diese in Ihrem
vimrc
:quelle
Ich habe festgestellt, dass Autoclose ein wenig Verzögerung hinzufügt und auch mein Setup stört (Ultisnips und Supertab), aber ich mag seinen Ansatz, Eclipse CDT zu emulieren.
Ich verwende delimitMate mit den folgenden Karten, um die Navigation und das Einrücken zu erleichtern, und versuche, die gleichen Ergebnisse zu erzielen :
Ich benutze es so: Füge die Öffnung ein
{ <CR><CR><C-K>
und beginne, in die eingerückte innere Zeile zu schreiben.quelle
Persönlich benutze ich smartinput zum automatischen Einfügen von Klammern und Anführungszeichen. Wenn Sie beispielsweise
{
irgendwo tippen , wird{}
der Cursor in der Mitte angezeigt. Um die{
Klammergruppe zu verlassen , geben Sie einfach den}
Zeitpunkt neben dem eingefügten ein}
.Dies unterstützt jedoch Ihre Anforderungen an Tabstopps und das Springen nach außerhalb der Klammer. Es wird auch kein neuer zwischen Ihren Klammern erstellt, aber Sie benötigen dafür nur einen zusätzlichen Schlüssel -
<CR>
.Sie können eine Karte
<C-J>
erstellen, um zur nächsten Zeile nach unten zu springen:oder wenn Sie zum Anfang der nächsten Zeile springen wollten:
quelle
So etwas könnte für Sie funktionieren.
quelle
Eigentlich kann Ultisnips das fast perfekt (dies könnte neu sein). Die oben gegebenen Antworten leicht modifizierend, habe ich guten Erfolg damit
inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>
Man muss eingeben,
()
was man besser findet, aber das kann man auch ändern(
. Dann sind die zusätzlichen optionalen ArgumenteUltiSnips#Anon
eine Beschreibung und der Modifikator,i
der die In-Word-Erweiterung ermöglicht.Mit
<c-j>
Werken aus den Klammern springen , auch verschachtelt in anderen Ausschnitten. Das Aufrufen verschachtelter()
Klammern scheint diese Funktion jedoch zu beeinträchtigen, was keine große Sache ist.quelle