Einfügen von Code in das Terminalfenster in vim unter Mac OS X.

69

Wenn ich Code in mein Mac OS X-Terminalfenster in vim einfüge, wird jede Zeile eingerückt. Für jede Zeile wird ein Einzug hinzugefügt, damit der Text so aussieht ...

"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud        
   ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
        reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
             Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                    deserunt mollit anim id est laborum."

Meine derzeitige Problemumgehung besteht darin, den Text zuerst in den Textmate-Texteditor einzufügen, der die korrekte Formatierung beibehält. Dann speichere ich diese Datei und öffne sie in vim. Dann benutze ich Vim Yank, um es einzufügen.
Gibt es eine Einstellung in meiner .vimrc, die dieses Verhalten ändern könnte? Oder ist das ein Terminalproblem?

eat_a_lemon
quelle
Das Einfügen in Klammern löst dieses Problem, ohne dass andere Befehle wie z :set paste. Das Einfügen in Klammern ist in vim 8 standardmäßig verfügbar. Es wird jedoch nur aktiviert, wenn vim glaubt, dass Sie sich in einem Xterm-kompatiblen Terminal befinden. Es gibt verschiedene Möglichkeiten, diese Antwort auf vi.stackexchange anzuzeigen.
Paul Rougieux

Antworten:

86

Innerhalb von vim:

:set paste

Versetzen Sie Vim in den Einfügemodus. Dies ist nützlich, wenn Sie Text aus einem Fenster ausschneiden oder kopieren und in Vim einfügen möchten. Dadurch werden unerwartete Auswirkungen vermieden.

William Pursell
quelle
1
Ich würde es auf einen Schalter stellen; nämlich; Ich habe dies in meinem vimrc ... set pastetoggle = <F4>
wom
112

UPDATE: Vim 8 bietet native Unterstützung für den Einfügemodus in Klammern . Es ist standardmäßig aktiviert. Siehe das Hilfethema von Vim xterm-bracketed-paste. Benutzer müssen nichts mehr tun, um Vim so zu konfigurieren, dass dies unterstützt wird.

Ab Mac OS X Lion 10.7 unterstützt Terminal den Einfügemodus in Klammern, mit dem der Terminalemulator dem mit dem tty verbundenen Programm mitteilen kann, wenn der Benutzer Text einfügt, sodass das Programm ihn nicht als Bearbeitungsbefehl interpretiert. Programme, die dies unterstützen, senden dem Terminal eine Escape-Sequenz, um diesen Modus zu aktivieren, in dem das Terminal eingefügten Text mit zwei Escape-Sequenzen umgibt, die den Start und das Ende identifizieren.

Um dies in Vim zu aktivieren, fügen Sie den folgenden Code in Ihre ~ / .vimrc-Datei ein:

if &term =~ "xterm.*"
    let &t_ti = &t_ti . "\e[?2004h"
    let &t_te = "\e[?2004l" . &t_te
    function! XTermPasteBegin(ret)
        set pastetoggle=<Esc>[201~
        set paste
        return a:ret
    endfunction
    map <expr> <Esc>[200~ XTermPasteBegin("i")
    imap <expr> <Esc>[200~ XTermPasteBegin("")
    vmap <expr> <Esc>[200~ XTermPasteBegin("c")
    cmap <Esc>[200~ <nop>
    cmap <Esc>[201~ <nop>
endif

Dies führt dazu, dass Vim beim Umschalten des Terminals zum / vom alternativen Bildschirm † (t_ti, t_te) den Einfügemodus in Klammern aktiviert / deaktiviert (ESC [? 2004 h, ESC [? 2004 l). Wenn die Escape-Sequenz empfangen wird, die den Beginn eines Einfügens anzeigt (ESC [200 ~), wird der Einfügemodus aktiviert (Einfügen einstellen) und bei Bedarf in den Einfügemodus umgeschaltet ("i"). Wenn es den passenden Marker für das Ende des Einfügens (ESC [201 ~) erhält, deaktiviert es den Einfügemodus (Pastetoggle) und bleibt im Einfügemodus. Die cmapBefehle sorgen dafür, dass die Vim-Befehlszeile die Escape-Sequenzen ignoriert und den eingefügten Text unverändert akzeptiert.

Beachten Sie, dass dies den Einfügemodus in Klammern nur aktiviert, wenn der Wert $ TERM mit "xterm ..." beginnt. Wenn Sie $ TERM auf etwas anderes setzen, möchten Sie diesen Test möglicherweise überarbeiten, um Ihren $ TERM-Wert einzuschließen. Sie können den Test auch ganz weglassen, da dies nicht unbedingt erforderlich ist. Es wird lediglich versucht, darauf zu achten, dass keine Aktionen ausgeführt werden, die möglicherweise nicht mit einem anderen Terminaltyp kompatibel sind.

In Terminal funktioniert dies mit allen verschiedenen Einfügebefehlen sowie per Drag & Drop.

† Das Terminal verfügt über einen Hauptbildschirm und einen "alternativen" Bildschirm. Jeder Bildschirm hat seinen eigenen Inhalt und Status. Text auf dem alternativen Bildschirm wird nicht in das Scrollback-Protokoll gescrollt. Es wird normalerweise von Programmen verwendet, die die Kontrolle über den gesamten Bildschirm übernehmen und daher als "Vollbild" -Programme bezeichnet werden. Dazu gehören beispielsweise vim, emacs, less und top.

Chris Page
quelle
2
Sie sollten auch eine Zuordnung für den Befehlsmodus hinzufügen (die Sie mit einem Doppelpunkt eingeben). Andernfalls verlieren Sie die Möglichkeit, in die Befehlszeile cmap <Esc>[200~ <nop> cmap <Esc>[201~ <nop>
einzufügen
3
Dies wird jetzt von iTerm2 unterstützt: iterm2.googlecode.com/svn/trunk/appcasts/testing_changes.html
Matt
@ ChrisPage einige Ergänzungen, um das Esc-Mapping zu beschleunigen und es in tmux funktionieren zu lassen: github.com/aaronjensen/vimfiles/blob/master/vimrc#L449-483
Aaron Jensen
6
Diese Antwort wurde in ein Plugin gepackt
Denilson Sá Maia
1
Wenn Sie den alternativen Bildschirm nicht verwenden, können Sie ihn im (nur) Einfügemodus aktivieren, indem Sie t_SIund t_EIanstelle von t_tibzw. t_teändern.
Rampion
9

Fügen Sie zusätzlich zu den anderen Antworten hinzu, wenn Sie den Einfügemodus schnell umschalten möchten

set pastetoggle=<F2>

zu Ihrem .vimrc. Jetzt können Sie den Einfügemodus durch Drücken von F2 (oder einer beliebigen Taste) umschalten.

Dancavallaro
quelle
Ich habe auch einen Pastetoggle auf <F2> gesetzt, aber dazu muss F2 eine Funktion aufrufen. Das liegt daran, dass ich im Einfügemodus auch möchte, dass vim "showbreak" deaktiviert, damit ich die Kopie aus dem Editorfenster bereinigen kann.
Anthony
Hinweis: Ich verwende auch "listchars" (Umschalten mit set "list"), sodass ich am Ende der Zeile Leerzeichen, Tabulatoren und zusätzliche Leerzeichen sehen kann, wenn ich mich nicht im Einfügemodus befinde. Diese normalerweise versteckten Charaktere verursachen mir viel Greif und Listchars lassen mich wissen, dass sie ihre sind. Es gibt auch eine Reihe anderer versteckter Unicode-Leerzeichen, die vim nicht "anzeigt".
Anthony
9

Eine andere Möglichkeit, dies zu tun, vorausgesetzt, Sie haben Ihre System-Zwischenablage ordnungsgemäß eingerichtet, ist dies

"+p

Dies wird aus der System-Zwischenablage eingefügt.

Aaron Jensen
quelle
3
"*poder "+p. Das *Register ist die primäre X11-Auswahl und +die Zwischenablage. Ich weiß nicht, ob Mac OS X das gleiche Konzept wie X11 hat.
Denilson Sá Maia
6

In vim

: Einfügen einstellen

wenn Sie es deaktivieren möchten

: Nopaste setzen

WenbinWu
quelle
2
Oder :set paste!um es umzuschalten.
Denilson Sá Maia
5

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.

Dies funktioniert in Terminal, iTerm2 und allen "modernen" x-term-kompatiblen Terminals, die den Einfügemodus in Klammern unterstützen. 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.

Das Plugin ist im Grunde eine verpackte Version der Funktionalität, die @Chris Page in seiner Antwort aufgeführt hat .

studgeek
quelle
Vim-8 hat es eingebaut. ABER macht auch ein Einfügen-Einfügen, wenn Sie versuchen, im Befehlsmodus vorbei zu gehen. Das heißt, Sie können keine vim-Befehle mehr einfügen! Etwas, das ich seit mehr als 30 Jahren mache (von damals in den Tagen 'vi' und 'elvis')
Anthony
In Vim 8 ist es integriert ... aus Patch 8.0.0210, aber Debians aktueller Stall Stretch enthält diesen Patch nicht, sondern nur ausgewählte Patches nach 0197 .
Martin Dorey