In Klammern mit Vim

74

Gibt es eine Möglichkeit, Text in Klammern (oder geschweiften Klammern) in vim einzuschließen?

Mit anderen Worten, wie würden Sie das tun?

Anfangszeichenfolge:

It is sunny outside.

Letzte Zeichenfolge:

It is (sunny) outside.

Lustigerweise habe ich nur gedrückt :w, um diese Frage einzureichen.

Viel Spaß beim Schwimmen, SOCommunity!

Gl
quelle
Es scheint, als könnte ein Makro die Arbeit leicht erledigen, aber ich wage es nicht, eines besonders zu verschreiben - ich bin in VIM immer noch ziemlich grün. Aber so etwas wie "zum Wortanfang gehen, linken Paren einfügen, zum Wortende bewegen, rechten Paren einfügen" klingt wie ein Makro, das in den meisten Fällen funktionieren würde ...
Triptychon
@Triptych - Genau so, wie Sie es vorgeschlagen haben, nur eine Zuordnung anstelle eines Makros. Siehe meine Antwort.
Turm

Antworten:

39

Surround.vim sollte den Trick machen. Wenn Sie dies mit '.' Wiederholen möchten, lesen Sie hier .

mwilson
quelle
82

Für ein Wort habe ich verwendet:

bcw()<Esc>P

Gehen Sie also zum Wortanfang, schneiden Sie das Wort aus und wechseln Sie in den Einfügemodus, geben Sie die Klammern ein, beenden Sie den Einfügemodus und fügen Sie das Wort wieder ein.

Denken Sie daran, dass dies Ihr Ruckregister überschreibt.

Sie können bcw natürlich durch die gewünschten Bewegungs- und Auswahlarten ersetzen

5cc{<Enter>}<Esc>P
Ian Hatch
quelle
22
Ich hasse es, wenn meine Amis überschrieben werden.
d1str0
1
Kein Plugin erforderlich. Toll. Ehrlich gesagt, mit Surround.vim müssen Sie ungefähr die gleiche Anzahl von Tasten drücken. Warum also ein Plugin verwenden?
Hamid
Die Stärke von vim ist die Sprache der Cursorsteuerung! Vielen Dank! Es ist einfach, dies in ein Skript aufzunehmen und daraus ein Makro zu machen. qbcw()<Esc>Pqdann, @qum schnell Wörter zu wiederholen.
Thomson Comer
4
@ d1str0 Sie können immer noch Ihren Ruck im Register finden"0
Bananach
tangential, aber Amis sollten eigentlich zu einem Stapel gemacht worden sein, ähnlich wie rückgängig machen.
Hraban
43

Hier sind Beispiele mit Surround.vim . Platzieren Sie im normalen Vim-Modus den Cursor über dem gewünschten Wort (in diesem Fall sonnig) und geben Sie Folgendes ein:

ysiw

Geben Sie dann ein )

Damit:

Anfangszeichenfolge:

It is sunny outside.

Letzte Zeichenfolge:

It is (sunny) outside.

Zusätzlicher Platz: Verwenden Sie den öffnenden Paren oder die Klammer, ysiw(um ihn mit Parens und einem Leerzeichen zwischen Paren und Anfang + Wortende zu umgeben.

Einfacher im visuellen Modus Rufen Sie den visuellen Modus auf, indem Sie drücken v. Wenn Sie jetzt tippen S(, wird das Wort von Leerzeichen umgeben. Wenn Sie jedoch )stattdessen das Schließen verwenden S), wird es nicht von Leerzeichen umgeben.

Dies gilt für alle Bracket-Pair-Umgebungen <> [] {} (), nicht nur für (). Das Verhalten von S<ist so, dass es ein Tag-Gehäuse erwartet, das nur S>als umgeben kann <>.

Mehr:

Typ , ysiwgefolgt von }den gleichen für curlies zu tun

Hier können Sie noch einige Beispiele hinzufügen:

  • Typ cs('auf [c] hange [s] mgebung von (zu "

  • cs'( von 'Umgebung zu ()

  • ds(.[d] elete ([s] urroundings insgesamt zu elete

Sogar mehr:

Und warum nicht den Rest der Tpope-Seite zitieren, um uns vor dem Klicken auf den Link zu bewahren?

// Zitat beginnen:

Es ist am einfachsten mit Beispielen zu erklären.

Drücken Sie nach cs"'innen

"Hallo Welt!" um es zu ändern

'Hello world!'

- -

Drücken Sie nun cs'<q>, um es zu ändern

<q>Hello world!</q>

- -

Um den Kreis zu schließen, drücken Sie cst", um zu erhalten

"Hello world!"

- -

Drücken Sie, um die Trennzeichen vollständig zu entfernen ds".

Hello world!

- -

Drücken Sie nun mit dem Cursor auf "Hallo" ysiw](iw ist ein Textobjekt).

[Hello] world!

Lassen Sie uns diese Klammern machen und etwas Leerzeichen hinzufügen (verwenden Sie} anstelle von {für kein Leerzeichen): cs]{

{ Hello } world!

- -

Umschließen Sie nun die gesamte Zeile in Klammern mit yssboder yss).

({ Hello } world!)

- -

Zurück zum Originaltext: ds{ds)

Hello world!

- -

Betonen Sie Hallo: ysiw<em>

<em>Hello</em> world!

- -

Lassen Sie uns zum Schluss den visuellen Modus ausprobieren. VDrücken Sie ein Großbuchstaben (für den zeilenweisen visuellen Modus) gefolgt von S<p class="important">.

<p class="important">
  <em>Hello</em> world!
</p>

Dieses Plugin ist sehr leistungsfähig für die HTML- und XML-Bearbeitung, eine Nische, die derzeit in Vim Land unterfüllt zu sein scheint. (Im Gegensatz zum Einfügen von HTML / XML, für das viele Plugins verfügbar sind). Das gleichzeitige Hinzufügen, Ändern und Entfernen von Tagspaaren ist ein Kinderspiel.

Der .Befehl funktioniert mit ds, csund ysswenn Sie installieren repeat.vim .

Danny
quelle
1
Warum brauchen wir das y in ysiw?
Jwan622
8

Sie können eine einfache Zuordnung für diese Art von Dingen definieren. Das sollte es tun. Geben Sie im normalen Modus z ein, um ein Wort in Klammern zu umgeben.

:nnoremap <leader>z viw<esc>a)<esc>hbi(<esc>lel
Turm
quelle
Genial. Einfach 2 Tasten "Leader + Z" drücken. Dies ist meine Lieblingsantwort
Darren Haynes
Warum im Ansichtsmodus übergeben? Die einfacheren Schritte scheinen es zu schaffen :nnoremap <leader>( bi(<esc>eli)<esc>Oder habe ich etwas verpasst? Übrigens sehr gute Antwort.
Titou
7

Warum nicht verwenden :s//( suchen und ersetzen )?

Z.B:

:s/sunny/(&)/

Sie haben wahrscheinlich etwas anderes im Sinn, aber ich kann anhand Ihrer Frage nicht sagen, was es ist.

( &ist eine Abkürzung für den übereinstimmenden Text)

jwd
quelle
5
Da Sie am Ende zweimal ein bereits geschriebenes Wort eingeben, müssen Sie es auswählen und in Klammern setzen.
Titou
2

Sie können die folgenden Befehle verwenden:

cw(<C-r><C-o>")<ESC>

Der Vorteil ist, dass Sie den Punktbefehl verwenden können, um diese Aktion für verschiedene Wörter zu wiederholen. Dies funktioniert auch für benutzerdefinierte Gehäuse, zum Beispiel:

Vor dem Wechsel:

word

Verwenden Sie dann den Befehl:

cw\enquote{<C-r><C-o>"}<ESC>

Endergebnis:

\enquote{word}
vasconssa
quelle
Das ist brilliant. Sie können einen Text auch mit markieren vund dann ganz c(<C-r><C-o>")<ESC>offensichtlich verwenden. Das Einfügen des Standardregisters oder des unbenannten Registers mit dem Text des letzten Löschens oder Ziehens (siehe :help i_^r) an die letzte Position des Cursors ( :help ^o) und das sofortige Einfügen einer schließenden Klammer ist sehr praktisch.
AdamKalisz
1

Ich bevorzuge es, keine Plugins zu verwenden und möchte alles auf meine Punktedateien beschränken, um die Portabilität zu vereinfachen. Der einfachste Weg, den ich mir vorstellen kann, besteht darin, ihn einfach aufzunehmen und wiederzugeben. Wenn Sie vorhaben, es über mehrere Sitzungen hinweg häufiger zu verwenden, können Sie den Schlüssel auch in Ihrem .vimrc zuordnen, aber das musste ich nicht (und ich bin wirklich schlecht darin, herauszufinden, welchem ​​Tastenanschlag ich zuordnen soll).

Angenommen, Sie haben ein Anfängerverständnis für vim. Nehmen wir an, ich habe eine Linie (der Einfachheit halber), die ich mit eckigen Klammern umgeben möchte. z.B

hello world

Gehen Sie in den normalen Modus. q1um die Aufnahme zu starten. Gehen Sie nun wie folgt vor

ESC ^i[ ESC $a] ESC

Dadurch bleibt die aktuelle Zeile in Klammern. Jetzt können Sie eine beliebige Zeile auswählen und drücken @1, um sie zu wiederholen.

Wenn Sie beispielsweise möchten, dass das aktuelle Wort in Klammern gesetzt wird, nehmen Sie einfach das folgende Rezept auf und spielen Sie es ab:

ESC bi[ ESC ea] ESC

Sie können natürlich versuchen, für Tastenanschläge zu optimieren, aber das dient mir vorerst.

zakishaheen
quelle
1

Ich weiß, dass dies eine alte Frage ist, aber eine so komplexe Lösung wie diese wurde hier noch nicht erwähnt und ich bin sicher, dass sie jemandem helfen könnte. In meiner .vimrc- Datei habe ich eine Zeile wie folgt:

xnoremap <silent> ( <ESC>:let p = &paste<CR>:set paste<CR>:let a = line2byte(line('.')) + col('.')<CR>gvc()<ESC>:if getregtype() ==# 'V'<CR>call setreg('"', substitute(@", '\n$', '', ''), 'c')<CR>endif<CR>P:exe "goto ".a<CR>:exe "let &paste=".p<CR>

Es reicht aus, im visuellen Modus Text auszuwählen und zu drücken (. Diese Zuordnung funktioniert auch im zeilenweisen und blockweisen visuellen Modus.

Wie funktioniert es?

<ESC> beendet den visuellen Modus

:let p = &paste<CR>:set paste<CR>...:exe "let &paste=".p<CR> stellt sicher, dass das Makro im Einfügemodus ausgeführt wird (da Autoindent und ähnliche Verbesserungen einige zusätzliche Leerzeichen enthalten können, die wir nicht möchten), während der Einfügestatus nach dem Makro derselbe bleibt wie vor der Ausführung des Makros

:let a = line2byte(line('.')) + col('.')<CR> findet den aktuellen Byte-Offset (1-basiert)

gv wählt den zuvor ausgewählten Text erneut aus

c löscht die Auswahl und bringt uns in den Einfügemodus, um die Auswahl zu ersetzen

()<ESC> wird in die gewünschten Klammern gesetzt und den Einfügemodus verlassen

:if getregtype()==#'V'<CR>call setreg('"',substitute(@",'\n$','',''),'c')<CR>endif<CR>entfernt das Trailing \naus dem "unnamed () -Register und ändert seinen Typ in zeichenweise, jedoch nur, wenn es zuvor zeilenweise war (um das Einfügen aus der Registrierung in Klammern zu ermöglichen).

P fügt zuvor ersetzten Text in die Klammern ein

:exe "goto ".a<CR>bringt den Cursor zurück auf die vorherige Position ( gotoverwendet einen 0-basierten Versatz, sodass wir die zuvor aufgezeichnete Position aufgrund der eingefügten linken Klammer nicht um eins erhöhen müssen).

Eamileann
quelle
0

Für so etwas ist es wahrscheinlich besser, mit Bereichen und Gruppen zu spielen, als externe Plugins zu verwenden:

:%s~\v(\w{5}) ~(\1) ~g

Im obigen Abschnitt wird nach einem Wort mit 5 Buchstaben gefolgt von einem Leerzeichen gesucht, die Übereinstimmung mit () gruppiert und durch umgebende Klammern um die gruppierte Übereinstimmung ersetzt.

gts
quelle
0

Ein weiterer nützlicher Leckerbissen, den ich in anderen Antworten noch nicht gesehen habe:

In einer Abbildung, die Verwendung expand("<cword>")(oder einem anderen ähnlichen <cWORD>, <cexpr>usw.). Dadurch erhalten Sie Zugriff auf das "Wort unter dem Cursor".

So ersetzen Sie beispielsweise alle Vorkommen in der aktuellen Zeile "Wort unter dem Cursor" durch Versionen in Klammern:

nnoremap <leader>( :execute "s!" . expand("<cword>") . "!(&)!g"<CR>

Es gibt einige Nachteile:

  • Wenn <cword>ein Ausrufezeichen darin steht, wird dies unterbrochen (Sie können s///natürlich ein anderes Zeichen auswählen ).
  • Sie können nicht nur das einzelne Wort unter dem Cursor ersetzen . Sie können das erste in einer Zeile (Standardeinstellung) oder alle Vorkommen in einer Zeile (wie oben, mit /gFlag) ausführen. Sie können sogar alle Vorkommen in einer Datei mit ausführen %s....
jwd
quelle