Wyłączanie automatycznego wcięcia podczas wklejania tekstu do vima


1186

Staram się nauczyć Vima.

Kiedy wklejam kod do mojego dokumentu ze schowka, dostaję dodatkowe spacje na początku każdej nowej linii:

line
  line
    line

Wiem, że możesz wyłączyć automatyczne wcięcie, ale nie mogę go uruchomić, ponieważ mam inne sprzeczne ustawienia lub coś takiego (które wyglądają dość oczywiste w moim .vimrc, ale nie wydają się mieć znaczenia, gdy je wyjmę).

Jak wyłączyć automatyczne wcięcie podczas wklejania kodu, ale nadal mam automatyczne wcięcie vim podczas pisania kodu? Oto mój .vimrcplik:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  

4
FWIW, vim 8.0.210 dodaje natywne wsparcie dla wklejania w nawiasach, dzięki czemu uniknie wcięcia wklejonego tekstu.
sh1

W przypadku nowych plików, aby uniknąć majstrowania przy wklejaniu / wklejaniu vima, możesz cat > mynewfile.txtnacisnąć Enter , wkleić tekst, ponownie nacisnąć Enter , a następnie Ctr + D, aby zapisać. Plik jest teraz utworzony i możesz go edytować za pomocą vim mynewfile.txt.
ccpizza

Odpowiedzi:


2065

Aktualizacja: lepsza odpowiedź tutaj: https://stackoverflow.com/a/38258720/62202

Aby wyłączyć autoindent podczas wklejania kodu, istnieje specjalny tryb „wklejania”.

Rodzaj

:set paste

Następnie wklej swój kod. Zauważ, że tekst w etykiecie narzędzia mówi teraz -- INSERT (paste) --.

Po wklejeniu kodu wyłącz tryb wklejania, aby automatyczne wcięcie podczas pisania działało poprawnie.

:set nopaste

Jednak zawsze uważałem to za kłopotliwe. Dlatego <F3>mapuję tak, aby podczas edytowania tekstu mógł przełączać się między trybami wklejania i nopaste ! Dodaję to do.vimrc

set pastetoggle=<F3>

38
To nie jest łatwiejsze niż :set noaipóźniej :set ai. Sugestia :r! catjest krótsza.
Leopd

68
Zdecydowanie set pastełatwiej. Jest o wiele bardziej semantyczny niż, noaia nawet noautoindent, co jest ważniejsze, gdy wpisujesz „noai” i „wklej” zajmuje tyle samo mało czasu, gdy jesteś wystarczająco biegły jako maszynistka dotykowa.
Victor Zamanian

52
:set noainie zawsze działa, w zależności od konfiguracji innych ustawień związanych z wcięciem zgodnie z OP. :set pastewydaje się być skrótem dla kilku ustawień jednocześnie.
MarkHu

13
Późno na imprezę, ale set copyindentzałatwi to za Ciebie bezproblemowo.
Matt Ryan

33
:set pastewyłącza również inne funkcje, takie jak uzupełnianie nawiasów klamrowych, co również nie jest pożądane podczas wklejania kodu.
Manuel Faux

263

Aby uniknąć niepożądanych efektów podczas wklejania, należy ustawić opcję:

set paste

Przydatnym poleceniem w twoim .vimrc jest set pastetoggle=<F10>lub inny przycisk, aby łatwo przełączać się między wklejaniem a nopaste.


13
Wreszcie! Wciąż pisałem: set paste /: set nopaste, jakie głupie! Dzięki.
imwilsonxu

4
z praktycznego punktu widzenia twoja odpowiedź jest bardziej przydatna niż odpowiedź zaakceptowana
Lynob

8
Inną opcją jest dodanie makra do vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris

Dobra sugestia @Chris - pojedyncza sekwencja klawiszy do wklejenia bez problemów z wcięciami!
RichVel

co jeśli nigdy nie chcę być w trybie wklejania? Czy istnieje sposób na trwałe wyłączenie?
maxwell

132

Zwykle używam, :r! cata następnie wklejam ( shift + insert )treść, i CTRL+D.

Nie ma potrzeby włączania i wyłączania bezpośredniego użycia.


Podoba mi się ta opcja bezpośredniego użycia. Jednak wciąż uczę się, jak czytać składnię vima na stronach internetowych. Co oznaczają twoje kroki? W szczególności, zakładając, że mam coś w schowku systemowym, co mam nacisnąć, aby wkleić to do dokumentu w vimie?
jvriesem,

9
Ta odpowiedź byłaby bardziej pomocna w przypadku informacji o tym, dlaczego i jak :r! catdziała.
K Erlandsson,

11
@KErlandsson, :rwstawia zawartość pliku do bieżącego dokumentu. !catmówi, uruchom cat, który zasadniczo otwiera stdin (* powłoki nix) (shift + insert)lub dla niektórych terminali, kliknięcie prawym przyciskiem myszy wklei zawartość schowka do terminala na CTRL+Dkońcu pliku, więc zamknie :r !catsesję.
Daniel

Czy to naprawdę „bezpośrednie”? Niż ustawienie opcji pastewykonanej wyłącznie w tym celu? @jvriesem Nie jest to opcja „bezpośrednia”, jeśli zakładam, że rozumiesz to słowo.
0xc0de,

Możesz także użyć :r! catnastępnie, CTRL+SHIFT+Vaby wkleić terminal (wtedy CTRL+D).
Paul Rougieux,

86

Jeśli pracujesz lokalnie, możesz wkleić ze schowka systemowego sekwencję klawiszy:

"+p

Jest to poprawne polecenie vim, więc nie musisz się martwić wejściem w tryb wstawiania lub wyłączeniem autoindent.

Oczywiście, jeśli pracujesz zdalnie (na przykład konsola przez SSH), to nie zadziała i powinieneś przejść do :set noaitrybu wstawiania, wkleić do konsoli, opuścić tryb wstawiania, :set aitrasy jak opisano w innym miejscu.


10
Piszę tę odpowiedź wieki temu. Obecnie używam :set pastei :set nopastezamiast tego, ponieważ pomimo tego, że jest dłuższy, łatwiej jest zapamiętać i nie muszę za każdym razem sprawdzać!
thomasrutter

6
W niektórych systemach wbudowanych (opartych głównie na busyboksie) :set pastenie jest zaimplementowany, dlatego :set noainależy go użyć.
jcarballo,

Kiedy masz duży tekst do skopiowania, czy nie jest szybsze skorzystanie z rejestru +?
pedromanoel

1
@pedromanoel, który działa tylko podczas pracy lokalnej. Nie będzie działać z dostępem do vima przez SSH, na przykład, jeśli skopiowałeś coś lokalnie i chcesz wkleić go do vima, który jest w twojej sesji SSH.
thomasrutter

1
@ thomasrutter, ale zamapowałem to na <leader>p... bardzo przydatne!
Dane

51

Mimo że ustawienie trybu wklejania paste/nopaste/pastetogglejest w porządku, nadal musisz ręcznie włączyć tryb wklejania przed wklejeniem i wyłączyć tryb wklejania po wklejeniu. Będąc leniwą osobą, którą jestem, poniżej jest najlepsze rozwiązanie, jakie do tej pory znalazłem, które automatycznie przełącza tryb wklejania podczas wklejania.

Oto mała sztuczka, która używa trybu wklejania w nawiasach terminalu, aby automatycznie ustawić / wyłączyć tryb wklejania Vima podczas wklejania. Umieść w swoim .vimrc:

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

Teraz możesz wklejać bez jawnego włączania / wyłączania trybu wklejania - jest on obsługiwany automatycznie.

Źródło: Coderwall

Uwaga: to rozwiązanie nie działa w WSL (Windows 10 Subsystem for Linux). Jeśli ktoś ma rozwiązanie dla WSL, zaktualizuj tę odpowiedź lub dodaj ją w komentarzach.

Tmux Jeśli używasz tmux, to deklaracje muszą być podwójnie zmienione. Kod do tego znajduje się również w Coderwall


To jest genialne. Jedno jest pewne ... Z każdą pastą uzyskuję znak „0” (zero) na początku każdej pasty. Masz na to jakąś wskazówkę?
Julius Š.

Zauważ też, że jeśli używasz Tmux , musisz podwójnie uciec. Kod do tego znajduje się w linku Coderwall w odpowiedzi
Daithí

1
Jeśli jesteś bardziej leniwy i skopiuj wklejanie powyższego kodu do swojego .vimrc, zajmij się wcięciem funkcji XTermPasteBegin ().
k1133

Byłem ciekawy, jak to działa, więc poszukałem Bracketingu Wklej i znalazłem gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing, który wyjaśnia, że zmienne t_SIi t_EIumożliwiają włączanie braketingu wklejania i wyłączanie go. Gdy włączone jest braketing wklejania, wklejany tekst jest poprzedzany przez, esc[200~a następnie esc[201~.
PatS

37

Użytkownicy komputerów Mac mogą uniknąć automatycznego formatowania, czytając bezpośrednio z pulpitu za pomocą:

:r !pbpaste

3
To niesamowita odpowiedź. Kiedy to robię, ukrywa jednak dokument (wygląda na to, że wróciłem do wiersza poleceń), ale ma tekst w moim schowku. Skłania mnie do naciśnięcia klawisza Enter, więc robię to, i wraca do mojego dokumentu bez żadnych zmian. Co się stało i jak mam zrobić to, co mówisz?
jvriesem,

Jeśli tylko wpiszesz :.!pbpaste, powinno to działać, zastępując bieżący wiersz danymi wyjściowymi bufora wklejania. Zasadniczo vim pozwala przesyłać dane znajdujące się w bieżącym pliku do innego programu i zamieniać tekst na wynik polecenia. :1,3!pbpasteZastępuje więc pierwsze trzy wiersze pliku buforem wklejania. Używam, :.!ppjsonaby wziąć bardzo długi (niesformatowany ciąg JSON) i sformatować go i zastąpić długi ciąg sformatowanym odpowiednikiem. ppjson to tylko uruchamiany skrypt bash python -m json.tool.
PatS

19

Oto post kogoś, kto wymyślił, jak ponownie przypisać zdarzenie wklejania, aby automatycznie włączyć tryb wklejania, a następnie wyłączyć. Działa dla mnie w tmux / iTerm na MacOSX.


1
Dzięki za wskazówkę. Wyśledziłem również wtyczkę, w której osoba ma podobne funkcje - stackoverflow.com/a/36512548/255961 .
studgeek 9.04.16

Wydaje się, że powoduje to ciąg „eeeeeee”, gdy wstawiam kawałek tekstu ze schowka.
John Jiang

16

Dodaj to do swojego, ~/.vimrca będziesz musiał nacisnąć F2 tylko przed i po wklejeniu:

set pastetoggle=<F2>

12

Właśnie włożyłem set clipboard=unnamedmój .vimrc. To sprawia, że ​​domyślna mapa bufora wklejania jest umieszczona w schowku X.

Tak więc, jeśli zaznaczę trochę tekstu w terminalu, mogę po prostu nacisnąć, paby wkleić go w vimie. Podobnie, mogę zaciągać rzeczy w vimie (np. YYWciągać bieżącą linię do bufora) i klikać środkowym przyciskiem w dowolnym oknie, aby je wkleić.

Dunno. Uważam to za bardzo wygodne.


IMHO, to najlepsza odpowiedź, nie trzeba przełączać z F11 (który jest wstępnie skonfigurowany w vimie). Działa to w systemie Mac OSX, nie wiem o innych.
LightMan

9

Podczas pracy wewnątrz terminala wtyczka vim z nawiasami klamrowymi automatycznie obsługuje wklejanie bez potrzeby naciskania klawiszy przed lub po wklejeniu.

Działa poprzez wykrywanie trybu wklejania w nawiasach, który jest sekwencją ucieczki wysyłaną przez „nowoczesne” terminale kompatybilne z X-term, takie jak iTerm2, gnome-terminal i inne terminale używające libvte. Jako dodatkowy bonus działa również w sesjach Tmux. Z powodzeniem używam go z iTerm2 na komputerze Mac łączącym się z serwerem Linux i korzystającym z tmux.


Uważaj również na to, co zauważa dalej: Niestety, oznacza to, że będą również uruchamiać zawartość bufora wejściowego, jeśli w terminalu pojawi się nowa linia.
0xc0de,

1
@ 0xc0de, ten cytat nie ma tutaj znaczenia. To mówi o tym, co zrobi powłoka , gdy nie będzie obsługiwać trybu wklejania w nawiasach. To jest punkt w trybie wklejania w nawiasach - aby temu zapobiec.
sh1

To działało dla mnie znacznie lepiej niż inne rozwiązania. Dzięki.
jjj

8

Umieść to w swoim ~ / .vimrc i ciesz się:

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

Edycja: po refleksji :r !catjest znacznie lepszym podejściem, ponieważ jest krótkie, semantyczne i nie wymaga niestandardowego vimrc. Użyj tego zamiast tego!


5

Chociaż :pastetogglelub :pastei :nopastepowinny działać dobrze (jeśli są zaimplementowane - nie zawsze są, jak widać z dyskusji), bardzo polecam wklejanie przy użyciu bezpośredniego podejścia "+plub "*pczytanie za pomocą "+rlub "*r:

Vim ma do niego dostępu do dziesięciu typy rejestrów ( :help registers) i pytający jest zainteresowany quotestari quoteplusz sekcji

  1. Wybór i rejestrów spadek "*, "+a „~

Użyj tych rejestrów do przechowywania i wyszukiwania wybranego tekstu dla GUI. Zobacz quotestari quoteplus. Gdy schowek jest niedostępny lub nie działa, zamiast niego używany jest rejestr bez nazwy. W systemach Unix schowek jest dostępny tylko wtedy, gdy jest dostępna funkcja + xterm_clipboard. {not in Vi}

Zauważ, że istnieje tylko różnica między „*” i „+ dla systemów X11.

:help x11-selectiondodatkowo wyjaśnia różnicę *i +:

                                                  quoteplus quote+

Istnieją trzy udokumentowane wybory X: PODSTAWOWY (który ma reprezentować bieżący wybór wizualny - jak w trybie wizualnym Vima), WTÓRNY (który jest źle zdefiniowany) i SCHOWEK (który ma być używany do operacji wycinania, kopiowania i wklejania) ).

Z tych trzech Vim używa PODSTAWOWEJ podczas odczytu i zapisu rejestru „* (stąd, gdy dostępne są wybory X11, Vim ustawia domyślną wartość dla„ schowka ”„ automatycznego wyboru ”) oraz SCHOWEK podczas odczytu i zapisu rejestru„ +. Vim nie ma dostępu do wyboru WTÓRNEGO.

Przykłady: (zakładając domyślne wartości opcji)

  • Wybierz adres URL w trybie Visual w Vimie. Przejdź do przeglądarki i kliknij środkowy przycisk myszy w polu tekstowym adresu URL. Wybrany tekst zostanie wstawiony (mam nadzieję!). Uwaga: w Firefoksie możesz ustawić preferencję middlemouse.contentLoadURL na true w about: config, wówczas wybrany adres URL zostanie użyty po naciśnięciu środkowego przycisku myszy w większości miejsc w oknie.

  • Zaznacz tekst w przeglądarce, przeciągając myszą. Przejdź do Vima i naciśnij środkowy przycisk myszy: wybrany tekst zostanie wstawiony.

  • Zaznacz tekst w Vimie i zrób „+ y. Przejdź do przeglądarki, zaznacz tekst w polu tekstowym, przeciągając myszką. Teraz użyj prawego przycisku myszy i wybierz„ Wklej ”z menu podręcznego. Wybrany tekst zostanie zastąpiony przez tekst z Vima. Zauważ, że tekst w rejestrze „+ pozostaje dostępny podczas dokonywania selekcji wizualnej, co powoduje udostępnienie innego tekstu w rejestrze„ *. Pozwala to na zastąpienie zaznaczonego tekstu.

zauważyłem, że użycie środkowego kliknięcia w vimie nie wydaje się zepsuć wcięć, więc może to być pomysł
Fuseteam

4

To działa dla mnie (przypadek na rejestr +, co używam jak bufor wymiany między aps):

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

2

Jeśli korzystasz z komputera Mac, macvim wydaje się radzić sobie dobrze bez konieczności przełączania wklejania.

brew install macvim --override-system-vim


Czy tak jest, jeśli do .vimrcakt dołączasz dyrektywy PO ?
Drew Noakes,

2

Pasta natywna / nawias klamrowy jest najlepszym i najprostszym sposobem od vim 8(wydanym w 2016 r.) Działa nawet na ssh! (Wklej wklejany działa w systemach Linux i Mac, ale nie w Windows Git Bash)

  1. Upewnij się, że masz vima 8+ (nie potrzebujesz opcji +clipboardlub +xterm_clipboard).

    vim --version | head -1

  2. Wystarczy użyć natywnego polecenia wklejania systemu operacyjnego (np. ctrl+shift+VLub cmd+V) w trybie normalnym. Nie naciskaj, iaby przejść do trybu wstawiania.


Test

  1. Skopiuj ( ctrl+shift+Club cmd+C) wynik tego (2 wiersze z wcięciem tabulatora) do schowka systemowego:

    echo -e '\ta\n\tb'

  2. Uruchom czysty vim 8+ z autoindent:

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

  3. Wklej ze schowka systemowego ( ctrl+shift+Vlub cmd+V) w trybie normalnym. Nie naciskaj, iaby przejść do trybu wstawiania. aI bpowinny być zgodne z jednym akapicie tab. Możesz to zrobić nawet podczas ssh-shingu na zdalnej maszynie (zdalna maszyna będzie potrzebowała vim 8+).

  4. Teraz wypróbuj stary sposób, który automatycznie włączy drugi wiersz z dodatkową zakładką: Naciśnij, iaby przejść do trybu wstawiania. Następnie wklej za pomocą ctrl+shift+Vlub cmd+V. aI bsą przesunięte teraz.


Instalowanie Vima 8


1
najlepszy i najprostszy sposób! Ponadto Google zasugerował to Featured snippetdla mojego wyszukiwania „wklej treść bez kart vim”, być może dlatego, że użyłem słowa kluczowego „tab”, tylko w tej wspomnianej odpowiedzi :)
David


1

Najszybszym sposobem, w jaki jestem świadomy, aby szybko przejść do trybu wklejania dla wklejenia za jednym razem, jest nienaruszony tpope , który oferuje yoi yO, prawdopodobnie, mnemonikę dla „otwierasz”. Są one udokumentowane tylko w jego vimdoc, jako:

Nie podano przełącznika dla „wklejania”, ponieważ typowy przypadek użycia owijania pojedynczego wstawienia jest tak marnotrawny: Przełączasz dwa razy, ale wklejasz tylko raz (YOPO). Zamiast tego naciśnij yo lub yO, aby wywołać o lub O z ustawionym „wklejaniem”. Opuszczenie trybu wstawiania powoduje automatyczne ustawienie „nopaste”.


1

Innym sposobem wklejenia jest <CR>i usunięcie zawartości rejestru (tutaj rejestr globalny). Zobacz: :h i_ctrl-ri h i_CTRL-R_CTRL-O.

Z dokumentacji pomocy vim:
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}

Aby wkleić zawartość do vima bez automatycznego wcięcia, użyj go <CR><CO>*w większości systemów uniksowych.

Uwaga: działa to tylko wtedy, gdy vim jest skompilowany clipboard.



1

Kolejna odpowiedź, której nie widziałem do tej pory:

:se paste noai

0

Niestety, znalazłem wspomnianą wtyczkę vim, która nie działa z iTerm2 3.0.15 (uczciwie nie wiem, czy to się zepsuło w starszych wersjach) - ale zamiast tego znalazłem hack.

Mapuj polecenie-p, aby wkleić i używając kluczy vim iTerm2. Oczywiście działa to tylko w przypadku iTerm2.

Jak to działa. Używam „jk”, aby przejść do trybu ucieczki, więc będziesz również potrzebować:

: inoremap jk

w twoim .vimrc.

Następnie po prostu wywołuje P, aby przejść do trybu wklejania, „+ p, aby wkleić ze schowka, a następnie P, aby wyłączyć tryb wklejania. Hth.

wprowadź opis zdjęcia tutaj


1
Zaraz, używasz do tego „jk”?
0xc0de,

O tak, zapomniałem o tym wspomnieć. Wystarczy dodać „: inoremap jk <esc>” do swojego .vimrc. Aby dowiedzieć się, dlaczego używam jk, zapytaj Apple i dlaczego czuli potrzebę poruszenia się i pozbycia się fizycznego klucza ucieczki. 8 (
Neil McGill

BTW wymaga trochę treningu, ale po chwili jk czuje się szybciej i myślę, że wolę teraz niż ucieczkę ... W każdym razie byłoby interesujące wiedzieć, czy iTerm2 akceptuje również <ESC> tutaj.
Neil McGill

Droga do Apple!
0xc0de,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.