Ändern Sie den 2-Leerzeichen-Einzug in vim in 4-Leerzeichen

90

Ich habe einige aus dem Internet kopierte Codes mit 2-Leerzeichen-Einrückung und möchte sie in 4-Leerzeichen-Einrückung ändern. Ich frage mich, ob es eine kurze vim-Routine gibt, um die Aufgabe zu erledigen, ohne ein vim-Skript schreiben zu müssen. So mache ich es derzeit mit einer HTML-Datei:

  • Zeichnen Sie ein Makro auf
  • Gehen Sie zum Anfang einer Zeile
  • Wählen Sie alle Leerzeichen bis zum ersten Auftreten von "<" visuell aus.
  • Ziehen Sie alle Leerzeichen heraus und fügen Sie sie ein (im Grunde genommen, um sie zu verdoppeln).
  • Wiederholen Sie das Makro bis zum Ende der Datei

Zusamenfassend qa0vt<yp<esc>jq

Tücken:

Das Makro schlägt für eine leere Zeile oder eine Zeile fehl, die nicht mit "<" beginnt. Und ich habe keine Ahnung, wie ich diese Lösung auf Nicht-HTML-Dateien erweitern kann.

Lim H.
quelle

Antworten:

169

Eine allgemeine Methode zum Ändern des Einzugs besteht darin, den Tabstop zu ändern:

Fügen Sie Ihre Datei in einen leeren Puffer ein und folgen Sie dann:

:set ts=2 sts=2 noet
:retab!

Dies ändert sich alle 2 Leerzeichen in ein TAB-Zeichen. Dann:

:set ts=4 sts=4 et
:retab

Dies ändert jede TAB in 4 Leerzeichen.

Der Vorteil dieser Methode ist, dass Sie sie auch umgekehrt verwenden können, um beispielsweise 4 in 2 Leerzeichen zu konvertieren.

Daan Bakker
quelle
16
@ XavierT.Ich denke tatsächlich, dass diese Antwort ziemlich einfach zu verstehen ist. Und vielleicht wird es klarer, wenn der kurze Befehlsname durch den vollständigen Namen ersetzt wird :: ts= tabstop, sts: = softtabstopund [no]et: = [no]expandtab.
YaOzI
In welcher Situation wäre retabdas Argument nützlich und warum können wir es nicht für diese Aufgabe verwenden?
Joeytwiddle
@joeytwiddle Wie ich es verstehe, Sie könnten das verwenden und die gleiche Wirkung wie diese Antwort erreichen durch die Verwendung :set sts=2 noetund :retab! 2so wäre es ein bisschen kürzer sein (wenn auch vielleicht weniger lesbar) auf diese Weise.
Daan Bakker
Diese Methode ändert auch 2-Leerzeichen in 4-Leerzeichen innerhalb von Zeichenfolgenliteralen und anderen Stellen und nicht nur den Zeilenanfang.
Nacitar Sevaht
2
Fügen Sie sie alle zusammen: :set ts=2 sts=2 noet | retab! | set ts=4 sts=4 et | retab!und verwenden Sie sie dann @:in verschiedenen Dateien, um schnell dieselbe Aktion anzuwenden.
Lynnard
57

Es kann mit :set shiftwidth=4und möglich sein gg=G.

perreal
quelle
Wenn dies nicht funktioniert, ist möglicherweise ein Modus aktiviert, der einen anderen Einfluss auf die Einrückung hat.
Dav Clark
1
Obwohl es sich bei der Frage nicht um eine allgemeine Lösung handelt, beachten Sie bitte, dass dies nicht immer funktioniert, insbesondere bei Python-Code.
0xc0de
5
Was gg=Gbedeutet genau? Ich verstehe, dass ggdies "zu 1,1 verschieben" und G"zur letzten Zeile verschieben" bedeutet.
Jonathon Reinhart
4
@JonathonReinhart =nicht einrücken, so dass er nur Mittel zum Einzug von Anfang bis Ende des Textes
alex
funktionierte besser als %retab, wodurch Leerzeichen, die in String-Literale eingebettet waren, falsch konvertiert wurden.
Alnitak
32

Was ich mache, ist den Ansätzen von esneider und cforbish sehr ähnlich, aber etwas schneller zu tippen:

:%s/^\s*/&&

Ersetzt einfach das führende Leerzeichen (Leerzeichen oder Tabulatoren) durch doppelt so viel führendes Leerzeichen ( &wird durch den übereinstimmenden Ausdruck ersetzt).

spro
quelle
2
Dies ist praktisch, da es mit der visuellen Auswahl (V) funktioniert. Lassen Sie einfach die Taste fallen %.
Trevor Robinson
1
Ich mag dieses auch b / c es es nicht mit irgendeiner manuellen Ausrichtung von Tabellen, die ich in Kommentaren usw. habe,
durcheinander bringt
@TrevorRobinson Die beiden wichtigsten Antworten beziehen sich auch auf Bereiche.
Brian McCutchon
Dies hat auch den zusätzlichen Vorteil, dass Sie es erweitern können, um es zu verwenden sedund auf alle Dateien in einem Verzeichnis
anzuwenden.
3

Dies ist eine sehr alte Frage, aber alle Antworten sind ... falsch ... Vim hat eine sehr einfache Möglichkeit, die gesamte Datei neu zu indentieren. Ich habe das gelernt, nachdem ich meine eigene Funktion dazu geschrieben habe, also bin ich im selben Boot der Unwissenheit;)

Art

gg=G

Dies setzt voraus, dass Sie Ihren Tabstop auf das eingestellt haben, was Sie möchten (für das OP wäre es also ts = 4).

Ich habe dies von http://vim.wikia.com/wiki/Fix_indentation gelernt , in dem erwähnt wird

Im normalen Modus wird durch Eingabe von gg = G die gesamte Datei erneut eingerückt. Dies ist ein Sonderfall; = ist ein Operator. Genau wie d oder y wirkt es auf jeden Text, den Sie mit einem Cursorbewegungsbefehl verschieben. In diesem Fall positioniert gg den Cursor in der ersten Zeile und dann = G rückt von der aktuellen Cursorposition bis zum Ende des Puffers wieder ein.

Chase Vasic
quelle
2
1. Wenn Sie ganz nach unten scrollen, wird eine Antwort mit gg = G angezeigt. 2. Es funktioniert nicht immer.
Lim H.
2

Ich habe diesen regulären Ausdruck verwendet (er verdoppelt die Anzahl der führenden Leerzeichen):

%s;^\(\s\+\);\=repeat(' ', len(submatch(0))*2);g
cforbish
quelle
macht nicht %s/\s\+/&&/das gleiche? Übrigens denke ich, dass die gFlagge unnötig ist (zum einen würde es nur 1 Übereinstimmung mit ^patternin jeder Zeile geben, nein?)
doubleDown
Vielen Dank für den Hinweis auf '&'. Ich habe eine leichte Korrektur an Ihrer, hauptsächlich weil Sie vergessen haben, dass das '^' %s/^\s\+/&&/gnäher ist.
cforbish
Dies ähnelt der Antwort von spro, aber ich schätze die Antwort, da Sie sie einfacher tweeken können, wenn Sie etwas etwas komplizierteres tun müssen.
Stephenmm
1

Ähnlich (aber etwas einfacher) wie die Antwort von cforbish dupliziert dieser Regex die führenden Leerzeichen

:%s/^\( \+\)/\1\1

Oder Sie können diesen anderen regulären Ausdruck verwenden, um 2-Leerzeichen in 4-Leerzeichen umzuwandeln, wobei einzelne Leerzeichen (und ungerade Beträge im Allgemeinen) erhalten bleiben.

:%s/^\(\(  \)\+\)/\1\1

Das ist,

  • 1 Feld ⇢ 1 Feld
  • 2 Felder ⇢ 4 Felder
  • 3 Felder ⇢ 5 Felder
  • 4 Felder ⇢ 8 Felder
esneider
quelle
0

Dies ist eine Variante der Regex-basierten Antworten.

Ich habe ein Bash-Skript in meinem lokalen bin-Verzeichnis, das die Anzahl der Leerzeichen am Zeilenanfang verdoppelt. Die Eingabe kann stdin oder eine Datei sein:

$ cat ~/bin/dblsp
#!/bin/bash

file=${1--}

while IFS= read -r line; do
    echo "$line" | sed 's/\s*/&&/'
done < <(cat -- "$file")

Ich verwende dies in vim, indem ich eine Zeile visuell auswähle und den folgenden Befehl gebe:

:'<,'>!dblsp

Dies erspart mir die Notwendigkeit, den regulären Ausdruck einzugeben (oder sich daran zu erinnern).

Ich benutze es auch in Karten wie den folgenden:

nnoremap <leader>] `[V`]!dblsp<CR>

Dadurch wird es auf einen Block kürzlich eingefügten Textes angewendet. Normalerweise verwende ich die folgende Karte zum Einfügen anstatt:set paste

nnoremap <leader>p :r !xclip -o<CR>

Mein üblicher Workflow ist:

  • Code-Snippet auswählen (z. B. der Beispielcode auf dieser Seite besteht aus 2 Leerzeichen, aber ich möchte 4)
  • Code-Snippet einfügen (, p)
  • Abstand ändern (,])

oder einfach den Einzug auf gezogenen Blöcken ändern, die aus einem anderen Puffer eingefügt wurden.

htaccess
quelle
0

Zusätzlich zu der Antwort von @ spro habe ich dies in meine .vimrc

command! -range=% Format :<line1>,<line2>s/^\s*/&&

Geben Sie einfach ein :Format.

Bei der visuellen Auswahl werden nur die ausgewählten Linien formatiert.

Ohne visuelle Auswahl wird die gesamte Datei formatiert.

Eli
quelle