Deaktivieren Sie den automatischen Einzug, wenn Sie Text in vim einfügen

1186

Ich bemühe mich, Vim zu lernen.

Wenn ich Code aus der Zwischenablage in mein Dokument einfüge, werden am Anfang jeder neuen Zeile zusätzliche Leerzeichen angezeigt:

line
  line
    line

Ich weiß, dass Sie den automatischen Einzug deaktivieren können, aber ich kann ihn nicht zum Laufen bringen, weil einige andere Einstellungen widersprüchlich sind oder so (die in meiner .vimrc ziemlich offensichtlich aussehen, aber keine Rolle zu spielen scheinen, wenn ich sie herausnehme).

Wie deaktiviere ich das automatische Einrücken, wenn ich Code einfüge, aber beim Schreiben von Code immer noch das automatische Einrücken von vim? Hier ist meine .vimrcDatei:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  
Rimian
quelle
4
FWIW, vim 8.0.210 bietet native Unterstützung für das Einfügen in Klammern, sodass das Einrücken von eingefügtem Text vermieden wird.
Sh1
Für neue Dateien können Sie cat > mynewfile.txtdie Eingabetaste drücken , Ihren Text einfügen, erneut die Eingabetaste drücken und dann Strg + D drücken , um das Speichern zu vermeiden . Die Datei wird jetzt erstellt und Sie können sie mit bearbeiten vim mynewfile.txt.
ccpizza

Antworten:

2065

Update: Bessere Antwort hier: https://stackoverflow.com/a/38258720/62202

Um die automatische Einrückung beim Einfügen von Code zu deaktivieren, gibt es einen speziellen Einfügemodus.

Art

:set paste

Fügen Sie dann Ihren Code ein. Beachten Sie, dass der Text in der QuickInfo jetzt lautet -- INSERT (paste) --.

Nachdem Sie Ihren Code eingefügt haben, deaktivieren Sie den Einfügemodus, damit das automatische Einrücken beim Eingeben wieder korrekt funktioniert.

:set nopaste

Das fand ich jedoch immer umständlich. Deshalb <F3>ordne ich es so zu, dass es beim Bearbeiten des Textes zwischen dem Einfüge- und dem Nopaste-Modus wechseln kann ! Ich füge das hinzu.vimrc

set pastetoggle=<F3>
P Shved
quelle
38
Dies ist nicht einfacher als :set noaigefolgt von :set ai. Der Vorschlag von :r! catist kürzer.
Leopd
68
Ich denke set pasteist definitiv einfacher. Es ist viel semantischer als noaioder sogar noautoindent, was wichtiger ist, wenn Sie "noai" und "paste" eingeben. Dies dauert ungefähr genauso wenig, wenn Sie als Touch-Typist kompetent genug sind.
Victor Zamanian
52
:set noaifunktioniert nicht immer, abhängig davon, wie die anderen einrückungsbezogenen Einstellungen gemäß OP konfiguriert sind. :set pastescheint eine Abkürzung für mehrere Einstellungen gleichzeitig zu sein.
MarkHu
13
Spät zur Party, set copyindentkümmert sich aber nahtlos darum.
Matt Ryan
33
:set pasteDeaktiviert auch andere Funktionen wie die Vervollständigung von Klammern, die auch beim Einfügen von Code nicht erwünscht sind.
Manuel Faux
263

Um unerwünschte Effekte beim Einfügen zu vermeiden, muss eine Option festgelegt werden:

set paste

Ein nützlicher Befehl in Ihrer .vimrc-Datei ist set pastetoggle=<F10>eine andere Schaltfläche, mit der Sie einfach zwischen Einfügen und Nicht-Einfügen wechseln können.

Jacob Rask
quelle
13
Schließlich! Ich tippte weiter: set paste /: set nopaste, wie dumm! Danke.
Imwilsonxu
4
Aus praktischer Sicht ist Ihre Antwort nützlicher als die akzeptierte Antwort
Lynob
8
Eine andere Möglichkeit ist, ein Makro zu Ihrem vimrc hinzuzufügen:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris
Netter Vorschlag @Chris - einzelne Tastenfolge zum Einfügen ohne Einrückungsprobleme!
RichVel
Was ist, wenn ich nie im Einfügemodus sein möchte? Gibt es eine Möglichkeit, dauerhaft zu deaktivieren?
Maxwell
132

Normalerweise benutze ich den Inhalt und :r! catfüge ihn dann ein .( shift + insert )CTRL+D

Keine Notwendigkeit, die direkte Verwendung zu aktivieren und zu deaktivieren.

Der Nerd
quelle
Ich mag diese direkte Nutzungsoption. Ich lerne immer noch, wie man die Vim-Syntax auf Webseiten liest. Was bedeuten deine Schritte? Angenommen, ich habe etwas in der Zwischenablage des Systems. Was drücke ich, um es in ein Dokument in vim einzufügen?
Jvriesem
9
Diese Antwort wäre hilfreicher mit Informationen darüber, warum und wie dies :r! catfunktioniert.
K Erlandsson
11
@KErlandsson :rfügt den Inhalt einer Datei in das aktuelle Dokument ein. !catWenn Sie cat ausführen, die im Wesentlichen stdin (* nix shells) öffnet, (shift + insert)oder bei einigen Terminals, wird der Inhalt der Zwischenablage mit der rechten Maustaste in das Terminal CTRL+Deingefügt, sodass die :r !catSitzung beendet wird.
Daniel
Ist das wirklich "direkt"? Als eine Option einstellen, pastedie ausschließlich für diesen Zweck gemacht wurde? @jvriesem Dies ist keine "direkte" Option, wenn das, was ich von Ihrem Verständnis dieses Wortes annehme, richtig ist.
0xc0de
Sie können auch verwenden , :r! catdann CTRL+SHIFT+Vim Terminal einfügen (dann CTRL+D).
Paul Rougieux
86

Wenn Sie lokal arbeiten, können Sie aus der Systemzwischenablage Folgendes einfügen:

"+p

Dies ist ein richtiger vim-Befehl, sodass Sie sich nicht darum kümmern müssen, zuerst in einen Einfügemodus zu wechseln oder die automatische Einrückung auszuschalten.

Wenn Sie remote arbeiten (z. B. Konsole über SSH), funktioniert dies natürlich nicht. Sie sollten in den :set noaiEinfügemodus wechseln, in die Konsole einfügen, den Einfügemodus verlassen und die :set aiRoute wie an anderer Stelle beschrieben ausführen .

thomasrutter
quelle
10
Ich schreibe diese Antwort vor Ewigkeiten. Heutzutage benutze ich :set pasteund :set nopastestattdessen, weil es trotz der längeren Zeit leichter zu merken ist und ich es nicht jedes Mal nachschlagen muss!
Thomasrutter
6
In einigen eingebetteten Systemen (hauptsächlich basierend auf Busybox) :set pasteist dies nicht implementiert und :set noaisollte stattdessen verwendet werden.
Jcarballo
Wenn Sie einen großen Text kopieren müssen, ist es nicht schneller, stattdessen das + -Register zu verwenden?
Pedromanoel
1
@pedromanoel, das nur funktioniert, wenn lokal gearbeitet wird. Der Zugriff auf vim über SSH funktioniert beispielsweise nicht, wenn Sie etwas lokal kopiert haben und es in vim einfügen möchten, das sich in Ihrer SSH-Sitzung befindet.
Thomasrutter
1
@ Thomasrutter, aber ich habe dies zugeordnet <leader>p.. sehr nützlich!
Dane
51

Während das Einstellen des Einfügemodus mit paste/nopaste/pastetogglevollkommen in Ordnung ist, müssen Sie den Einfügemodus vor dem Einfügen manuell aktivieren und den Einfügemodus nach dem Einfügen deaktivieren. Als die faule Person, die ich bin, ist unten die beste Lösung, die ich bisher gefunden habe, die den Einfügemodus beim Einfügen automatisch umschaltet.

Hier ist ein kleiner Trick, der den Einfügemodus in Klammern des Terminals verwendet, um den Einfügemodus von Vim beim Einfügen automatisch festzulegen / zu deaktivieren. Fügen Sie Folgendes in Ihre .vimrc ein:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

Jetzt können Sie einfügen, ohne den Einfügemodus explizit ein- oder auszuschalten - dies wird automatisch für Sie erledigt.

Quelle: Coderwall

Hinweis: Diese Lösung funktioniert nicht in WSL (Windows 10 Subsystem für Linux). Wenn jemand eine Lösung für WSL hat, aktualisieren Sie diese Antwort oder fügen Sie sie in den Kommentaren hinzu.

Tmux Wenn Sie tmux verwenden, müssen die Deklarationen doppelt maskiert werden. Der Code dafür ist auch in Coderwall

thdoan
quelle
Das ist brillant. Eines jedoch ... Mit jeder Paste bekomme ich zu Beginn jeder Paste einen "0" (Null) -Zeichen. Irgendein Tipp dafür?
Julius Š.
auch beachten , wenn mit tmux dann müssen Sie doppelte Escape. Code dafür ist in Coderwall Link als Antwort
Daithí
1
Wenn Sie noch fauler sind und den obigen Code in Ihre .vimrc-Datei kopieren, achten Sie auf den Einzug der Funktion XTermPasteBegin ().
k1133
Ich war gespannt , wie das funktioniert, und so suchte ich Bracketing für Paste und gefunden gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing , die erklärt , dass die t_SIund t_EIVariablen ermöglichen Paste Bracketing und deaktivieren es. Wenn die Klammer einfügen aktiviert ist, wird eingefügtem Text ein Präfix vorangestellt esc[200~und gefolgt von esc[201~.
PatS
37

Mac-Benutzer können die automatische Formatierung vermeiden, indem sie direkt aus dem Pasteboard lesen mit:

:r !pbpaste
Maniacalrobot
quelle
3
Dies ist eine großartige Antwort. Wenn ich dies tue, wird das Dokument jedoch ausgeblendet (es sieht so aus, als wäre ich wieder in der Befehlszeile), aber der Text befindet sich in meiner Zwischenablage. Es fordert mich auf, die Eingabetaste zu drücken, und kehrt ohne Änderungen zu meinem Dokument zurück. Was ist passiert und wie mache ich das, was du sagst?
Jvriesem
Wenn Sie nur eingeben :.!pbpaste, sollte dies funktionieren, indem Sie die aktuelle Zeile durch die Ausgabe des Einfügepuffers ersetzen. Im Allgemeinen können Sie mit vim Daten aus Ihrer aktuellen Datei an ein anderes Programm weiterleiten und den Text durch die Ausgabe des Befehls ersetzen. So :1,3!pbpasteersetzt die ersten drei Zeilen Ihrer Datei mit dem Paste - Puffer. Ich :.!ppjsonnehme eine sehr lange (unformatierte JSON-Zeichenfolge) und formatiere sie und ersetze die lange Zeichenfolge durch die formatierte Entsprechung. ppjson ist nur ein Bash-Skript, das ausgeführt wird python -m json.tool.
PatS
19

Hier ist ein Beitrag von jemandem, der herausgefunden hat, wie das Einfügeereignis neu zugeordnet werden kann, um den Einfügemodus automatisch ein- und wieder auszuschalten. Funktioniert für mich in tmux / iTerm unter MacOSX.

Von
quelle
1
Danke für den Tipp. Ich habe auch ein Plugin gefunden, in dem die Person ähnliche Funktionen gebündelt hat - stackoverflow.com/a/36512548/255961 .
Studgeek
Dies scheint eine Zeichenfolge von 'eeeeeee' zu verursachen, wenn ich einen Text aus meiner Zwischenablage einfüge.
John Jiang
16

Fügen Sie dies zu Ihrem hinzu ~/.vimrcund Sie müssen nur vor und nach dem Einfügen F2 drücken :

set pastetoggle=<F2>
anh_ng8
quelle
12

Ich habe es gerade gesagt set clipboard=unnamed meine .vimrc eingegeben. Dadurch wird der Standardpuffer in die Zwischenablage von X eingefügt.

Wenn ich also ein Stück Text in einem Terminal markiere, kann ich einfach drücken, pum es in vim einzufügen. Ebenso kann ich Dinge in vim ziehen (z. B. YYum die aktuelle Zeile in den Puffer zu ziehen) und mit der mittleren Maustaste in ein beliebiges Fenster klicken, um sie einzufügen.

Keine Ahnung. Ich finde es super praktisch.

Soren
quelle
IMHO, dies ist die beste Antwort, es ist nicht erforderlich, mit F11 umzuschalten (das in vim standardmäßig vorkonfiguriert ist). Dies funktioniert in Macs OSX-System, ich weiß nicht über die anderen.
LightMan
9

Wenn Sie in einem Terminal arbeiten, verarbeitet das vim-Klammer-Einfügen- Vim-Plugin automatisch Pasten, ohne dass vor oder nach dem Einfügen Tastenanschläge erforderlich sind.

Es erkennt den in Klammern gesetzten Einfügemodus, bei dem es sich um eine Escape-Sequenz handelt, die von "modernen" x-term-kompatiblen Terminals wie iTerm2, gnome-terminal und anderen Terminals mit libvte gesendet wird. Als zusätzlichen Bonus funktioniert es auch für tmux-Sitzungen. Ich verwende es erfolgreich mit iTerm2 auf einem Mac, der eine Verbindung zu einem Linux-Server herstellt und tmux verwendet.

studgeek
quelle
Beachten Sie auch die weiteren Hinweise: Leider bedeutet dies, dass auch der Inhalt des Eingabepuffers ausgeführt wird, wenn in etwas, das Sie in das Terminal einfügen, eine neue Zeile enthalten ist.
0xc0de
1
@ 0xc0de, dieses Zitat ist hier nicht relevant. Hier geht es darum, was eine Shell tun wird, wenn sie den Einfügemodus in Klammern nicht unterstützt. Das ist der Punkt im Einfügemodus in Klammern - um dies zu verhindern.
Sh1
Das hat bei mir viel besser funktioniert als bei den anderen Lösungen. Vielen Dank.
JJJ
8

Steck das in dein ~ / .vimrc und sei glücklich:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'

Bearbeiten: :r !catNach Reflexion ist dies ein weitaus besserer Ansatz, da er kurz und semantisch ist und kein benutzerdefiniertes vimrc erfordert. Verwenden Sie das stattdessen!

Dergachev
quelle
5

Obwohl :pastetoggleoder :pasteund :nopastesollte gut funktionieren (falls implementiert - sie sind nicht immer, wie wir aus der Diskussion sehen können), empfehle ich dringend, das Einfügen mit dem direkten Ansatz "+poder "*pund das Lesen mit "+roder"*r :

Vim hat Zugriff auf zehn Registertypen ( :help registers) und der Fragesteller interessiert sich für quotestarund quoteplusvon Abschnitt

  1. Auswahl und Drop - Register "*, "+und „~

Verwenden Sie diese Register zum Speichern und Abrufen des ausgewählten Textes für die GUI. Siehe quotestarundquoteplus . Wenn die Zwischenablage nicht verfügbar ist oder nicht funktioniert, wird stattdessen das unbenannte Register verwendet. Bei Unix-Systemen ist die Zwischenablage nur verfügbar, wenn die Funktion + xterm_clipboard vorhanden ist. {nicht in Vi}

Beachten Sie, dass bei X11-Systemen nur zwischen "* und" + unterschieden wird.

:help x11-selectionverdeutlicht weiter den Unterschied von *und +:

                                                  quoteplus quote+

Es gibt drei dokumentierte X-Auswahlen: PRIMARY (die voraussichtlich die aktuelle visuelle Auswahl darstellen - wie im visuellen Modus von Vim), SECONDARY (die schlecht definiert ist) und CLIPBOARD (die voraussichtlich zum Ausschneiden, Kopieren und Einfügen verwendet wird ).

Von diesen drei verwendet Vim PRIMARY beim Lesen und Schreiben des Registers "*" (daher legt Vim, wenn die X11-Auswahl verfügbar ist, einen Standardwert für "Zwischenablage" von "Autoselect" fest) und CLIPBOARD beim Lesen und Schreiben des Registers "+". Vim greift nicht auf die SECONDARY-Auswahl zu.

Beispiele: (unter der Annahme der Standardoptionswerte)

  • Wählen Sie in Vim eine URL im visuellen Modus aus. Gehen Sie zu Ihrem Browser und klicken Sie mit der mittleren Maustaste in das URL-Textfeld. Der ausgewählte Text wird eingefügt (hoffentlich!). Hinweis: In Firefox können Sie die Einstellung middlemouse.contentLoadURL in about: config auf true setzen. Die ausgewählte URL wird dann verwendet, wenn Sie an den meisten Stellen im Fenster die mittlere Maustaste drücken.

  • Wählen Sie Text in Ihrem Browser aus, indem Sie mit der Maus ziehen. Gehen Sie zu Vim und drücken Sie die mittlere Maustaste: Der ausgewählte Text wird eingefügt.

  • Wählen Sie einen Text in Vim aus und führen Sie "+ y" aus. Gehen Sie zu Ihrem Browser, wählen Sie einen Text in einem Textfeld durch Ziehen mit der Maus aus. Verwenden Sie nun die rechte Maustaste und wählen Sie "Einfügen" aus dem Popup-Menü. Der ausgewählte Text wird von überschrieben Beachten Sie, dass der Text im Register "+" weiterhin verfügbar ist, wenn Sie eine visuelle Auswahl treffen. Dadurch wird anderer Text im Register "*" verfügbar. Dadurch können Sie ausgewählten Text überschreiben.
Codingdave
quelle
Ich habe festgestellt, dass die Verwendung des mittleren Klicks in vim die Einrückung nicht durcheinander bringt, sodass dies möglicherweise eine Idee ist
Fuseteam
4

Dies funktioniert bei mir (Fall für + Register, was ich als Austauschpuffer zwischen APS verwende):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>
Sergey Vakulenko
quelle
2

Wenn Sie auf einem Mac arbeiten, scheint Macvim gut damit umzugehen, ohne die Paste umschalten zu müssen.

brauen installieren macvim --override-system-vim

Marcus Ericsson
quelle
Ist dies der Fall, wenn Sie die Anweisungen des OP in Ihre .vimrcDatei aufnehmen?
Drew Noakes
2

Native Paste / Paste in Klammern ist der beste und einfachste Weg seit vim 8(veröffentlicht im Jahr 2016). Es funktioniert sogar über ssh! (Das Einfügen in Klammern funktioniert unter Linux und Mac, jedoch nicht unter Windows Git Bash.)

  1. Stellen Sie sicher, dass Sie vim 8+ haben (Sie benötigen die Optionen +clipboardoder nicht +xterm_clipboard).

    vim --version | head -1

  2. Verwenden Sie einfach den nativen Einfügebefehl des Betriebssystems (z. B. ctrl+shift+Voder cmd+V) im normalen Modus. Drücken Sie nicht ifür den Einfügemodus.


Prüfung

  1. Kopieren ( ctrl+shift+Coder cmd+C) der Ausgabe davon (2 Zeilen mit einem Tabulatoreinzug) in die Systemzwischenablage:

    echo -e '\ta\n\tb'

  2. Starten Sie ein sauberes vim 8+ mit autoindent:

    vim -u NONE --noplugin -c 'set autoindent'

  3. Einfügen aus der Systemzwischenablage ( ctrl+shift+Voder cmd+V) im normalen Modus. Drücken Sie nicht ifür den Einfügemodus. Das aund bsollte mit einem einzelnen Tabulatoreinzug ausgerichtet werden. Sie können dies sogar tun, während Sie an einen Remote-Computer senden (der Remote-Computer benötigt vim 8+).

  4. Versuchen Sie nun den alten Weg, bei dem die zweite Zeile automatisch mit einer zusätzlichen Registerkarte eingerückt wird: Drücken Sie für den Einfügemodus i. Dann mit ctrl+shift+Voder einfügen cmd+V. Die aund bsind jetzt falsch ausgerichtet.


Installieren von Vim 8

wisbucky
quelle
1
bester und einfachster Weg! Außerdem schlug Google es Featured snippetfür meine Suche "Inhalt ohne Tabs einfügen vim" vor, möglicherweise weil ich das Schlüsselwort "tab" verwendet habe, nur in dieser Antwort erwähnt :)
David
1

Der schnellste Weg, den ich kenne, um schnell in den Paste-Insert-Modus für eine One-Shot-Paste zu wechseln, ist die unbeeinträchtigte Funktion von tpope , die Funktionen yound yOvermutlich Mnemonik für „you open“ bietet . Sie sind nur in seinem Vimdoc dokumentiert als:

Für "Einfügen" wurde kein Umschalter bereitgestellt, da der typische Anwendungsfall des Umwickelns einer einzelnen Einfügung so verschwenderisch ist: Sie wechseln zweimal um, aber Sie fügen nur einmal ein (YOPO). Drücken Sie stattdessen yo oder yO, um o oder O aufzurufen, wobei 'Einfügen' bereits festgelegt ist. Wenn Sie den Einfügemodus verlassen, wird 'nopaste' automatisch eingestellt.

Micah Elliott
quelle
1

Eine andere Möglichkeit zum Einfügen besteht darin <CR>, den Inhalt des Registers (hier das globale Register) zu löschen und zu löschen. Siehe: :h i_ctrl-rund h i_CTRL-R_CTRL-O.

Aus der vim-Hilfedokumentation:
Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse<MiddleMouse>. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

Verwenden Sie <CR><CO>*in den meisten Unix-Systemen , um Inhalte ohne automatischen Einzug in vim einzufügen .

Hinweis: Dies funktioniert nur, wenn vim mit kompiliert ist clipboard.

TheChetan
quelle
1

Von vim: ]p

Von außen: "*]poder"+]p

Bruno
quelle
1

Eine andere Antwort, die ich bis jetzt nicht gesehen habe:

:se paste noai
sjas
quelle
0

Leider habe ich festgestellt, dass das erwähnte vim-Plugin nicht mit iTerm2 3.0.15 funktioniert (um fair zu sein, ich weiß nicht, ob dies bei älteren Versionen kaputt gegangen ist) - aber ich habe stattdessen diesen Hack gefunden.

Ordnen Sie Befehl-p zu, um das Einfügen und Verwenden der iTerm2-VIM-Tasten durchzuführen. Dies funktioniert natürlich nur für iTerm2.

Wie es funktioniert. Ich benutze "jk", um in den Escape-Modus zu wechseln, sodass Sie auch Folgendes benötigen:

: inoremap jk

in Ihrer .vimrc.

Dann wird einfach P aufgerufen, um in den Einfügemodus zu wechseln, "+ p, um aus der Zwischenablage einzufügen, und dann P, um den Einfügemodus zu deaktivieren. Hth.

Geben Sie hier die Bildbeschreibung ein

Neil McGill
quelle
1
Warten Sie, was, Sie verwenden 'jk' dafür?
0xc0de
Oh ja, das hatte ich vergessen zu erwähnen. Fügen Sie einfach ": inoremap jk <esc>" zu Ihrer .vimrc hinzu. Fragen Sie Apple , warum ich jk verwende und warum sie sich bewegen und den physischen Escape-Schlüssel loswerden müssen. 8 (
Neil McGill
Übrigens braucht es etwas Training, aber nach einer Weile fühlt sich jk schneller an und ich denke, ich ziehe es jetzt der Flucht vor ... Auf jeden Fall wäre es interessant zu wissen, ob iTerm2 auch hier <ESC> akzeptiert.
Neil McGill
Weiter so, Apple!
0xc0de