Disattivare il rientro automatico quando si incolla il testo in vim


1186

Sto facendo lo sforzo di imparare Vim.

Quando incollo il codice nel mio documento dagli Appunti, ottengo spazi extra all'inizio di ogni nuova riga:

line
  line
    line

So che puoi disattivare il rientro automatico ma non riesco a farlo funzionare perché alcune altre impostazioni sono in conflitto o qualcosa del genere (che sembra abbastanza ovvio nel mio .vimrc ma non sembra importare quando le tolgo).

Come posso disattivare il rientro automatico quando incollo il codice ma ho ancora il rientro automatico vim quando scrivo il codice? Ecco il mio .vimrcfile:

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

4
FWIW, vim 8.0.210 aggiunge il supporto nativo per incolla tra parentesi, in modo da evitare il rientro del testo incollato.
sh1

Per i nuovi file, al fine di evitare di armeggiare con il comando incolla / nopaste di vim, puoi cat > mynewfile.txtpremere Invio , incollare il testo, premere di nuovo Invio , quindi Ctr + D per salvare. Il file è ora creato e puoi modificarlo con vim mynewfile.txt.
ccpizza,

Risposte:


2066

Aggiornamento: migliore risposta qui: https://stackoverflow.com/a/38258720/62202

Per disattivare l'autoindent quando si incolla il codice, esiste una speciale modalità "incolla".

genere

:set paste

Quindi incolla il tuo codice. Si noti che il testo nella descrizione comandi ora dice -- INSERT (paste) --.

Dopo aver incollato il codice, disattiva la modalità incolla, in modo che il rientro automatico durante la digitazione funzioni di nuovo correttamente.

:set nopaste

Tuttavia, l'ho sempre trovato ingombrante. Ecco perché <F3>mappo in modo tale che possa passare tra le modalità incolla e nopaste durante la modifica del testo! Lo aggiungo a.vimrc

set pastetoggle=<F3>

38
Questo non è più facile di quello :set noaiseguito da :set ai. Il suggerimento di :r! catè più breve.
Leopd,

69
Penso che set pastesia più facile, sicuramente. È molto più semantico di noaio addirittura noautoindent, il che è più importante quando si digita "noai" e "incolla" richiede circa la stessa insignificante quantità di tempo quando si è abbastanza abili come un dattilografo touch.
Victor Zamanian,

52
:set noainon funziona sempre, a seconda di come sono configurate le altre impostazioni relative al rientro secondo l'OP. :set pastesembra essere una scorciatoia per diverse impostazioni contemporaneamente.
MarkHu,

13
In ritardo alla festa, ma se set copyindentne occuperà senza problemi.
Matt Ryan

33
:set pastedisabilita anche altre funzionalità come il completamento delle parentesi graffe, che non è nemmeno desiderato quando si incolla il codice.
Manuel Faux,

263

Per evitare effetti indesiderati durante l'incollaggio, è necessario impostare un'opzione:

set paste

Un comando utile da avere nel tuo .vimrc è set pastetoggle=<F10>o qualche altro pulsante, per alternare facilmente tra incolla e nopaste.


13
Finalmente! Ho continuato a scrivere: set paste /: set nopaste, che stupido! Grazie.
imwilsonxu,

4
da un punto di vista pratico, la tua risposta è più utile della risposta accettata
Lynob

8
Un'altra opzione è quella di aggiungere una macro al tuo vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris,

Simpatico suggerimento @Chris - sequenza di tasti singola da incollare senza problemi di rientro!
RichVel,

e se non volessi mai essere in modalità incolla? c'è un modo per disabilitare permanentemente?
maxwell,

132

Di solito uso :r! cate quindi incollo ( shift + insert )il contenuto e CTRL+D.

Non è necessario abilitare e disabilitare l'uso diretto.


Mi piace questa opzione di utilizzo diretto. Sto ancora imparando come leggere la sintassi di VIM sulle pagine Web, però. Cosa significano i tuoi passi? In particolare, supponendo di avere qualcosa negli Appunti di sistema, cosa devo premere per incollarlo in un documento in VIM?
jvriesem,

9
Questa risposta sarebbe più utile con informazioni su perché e come :r! catfunziona.
K Erlandsson,

11
@KErlandsson, :rinserisce il contenuto di un file nel documento corrente. !catdice, esegui cat che essenzialmente apre stdin (* nix shells) (shift + insert)o per alcuni terminali, il tasto destro del mouse incolla il contenuto degli appunti sul terminale CTRL+Dè end-of-file, quindi chiude la :r !catsessione.
Daniel,

Questo è "diretto", davvero? Che impostare un'opzione pastefatta esclusivamente per questo scopo? @jvriesem Questa non è un'opzione 'diretta', se ciò che presumo della tua comprensione di quella parola è corretto.
0xc0de,

È inoltre possibile utilizzare :r! catquindi CTRL+SHIFT+Vper incollare nel terminale (quindi CTRL+D).
Paul Rougieux,

86

Se lavori localmente, puoi incollare dagli appunti di sistema con la sequenza di tasti:

"+p

Questo è un comando vim appropriato, quindi non c'è bisogno di preoccuparsi di entrare in una modalità di inserimento o disattivare prima l'autoindent.

Ovviamente se stai lavorando in remoto (console su SSH, ad esempio), questo non funzionerà e dovresti andare in :set noaimodalità, inserire, incollare in console, lasciare insertmode, :set aiinstradare come descritto altrove.


10
Scrivo questa risposta anni fa. Oggi uso :set pastee :set nopasteinvece perché nonostante sia più lungo, è più facile da ricordare e non devo cercare ogni volta!
thomasrutter,

6
In alcuni sistemi embedded (basati principalmente su busybox) :set pastenon è implementato, quindi :set noaidovrebbe essere usato invece.
jcarballo,

Quando hai un testo di grandi dimensioni da copiare, non è più veloce usare invece il registro +?
Pedromanoel,

1
@pedromanoel che funziona solo quando si lavora localmente. Non funzionerà accedendo a VIM su SSH, ad esempio, se hai copiato qualcosa localmente e vuoi incollarlo in VIM che si trova nella tua sessione SSH.
thomasrutter,

1
@thomasrutter ma l'ho mappato su <leader>p.. molto utile!
Dane,

51

Mentre l'impostazione della modalità incolla con paste/nopaste/pastetoggleva benissimo, devi ancora abilitare manualmente la modalità incolla prima di incollare e disabilitare la modalità incolla dopo averlo incollato. Essendo la persona pigra che sono, di seguito è la migliore soluzione che ho trovato finora, che attiva e disattiva automaticamente la modalità incolla quando si incolla.

Ecco un piccolo trucco che utilizza la modalità incolla tra parentesi del terminale per impostare / disinserire automaticamente la modalità incolla di Vim quando si incolla. Inserisci quanto segue nel tuo .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

Ora puoi incollare senza attivare / disattivare esplicitamente la modalità incolla: viene gestita automaticamente per te.

Fonte: Coderwall

Nota: questa soluzione non funziona in WSL (sottosistema Windows 10 per Linux). Se qualcuno ha una soluzione per WSL, aggiorna questa risposta o aggiungila nei commenti.

Tmux Se si utilizza tmux, è necessario eseguire il doppio escape delle dichiarazioni. Il codice per questo è anche in Coderwall


Questo è geniale. Una cosa però ... Con ogni incolla ottengo un carattere "0" (zero) all'inizio di ogni incolla. Qualche consiglio per quello?
Julius Š.

nota anche se usi tmux allora devi raddoppiare. Il codice per questo è nel link Coderwall in risposta
Daithí,

1
Se sei ancora più pigro e copi incollando il codice sopra nel tuo .vimrc, prenditi cura del rientro della funzione XTermPasteBegin ().
k1133,

Ero curioso di sapere come funzionava, e così ho cercato Paste Bracketing e ho trovato gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing che spiega che le variabili t_SIe t_EIstanno abilitando il bracketing incolla e disabilitandolo. Quando il bracketing incolla è attivo, il testo incollato è preceduto da esc[200~e seguito da esc[201~.
PatS

37

Gli utenti Mac possono evitare la formattazione automatica leggendo direttamente dalla tastiera con:

:r !pbpaste

3
Questa è una risposta fantastica. Quando lo faccio, tuttavia, nasconde il documento (sembra che io sia tornato sulla riga di comando), ma ha il testo negli appunti. Mi chiede di premere invio, quindi lo faccio, e mi riporta al mio documento senza alcuna modifica. Che cosa è successo e come posso fare quello che stai dicendo?
jvriesem,

Se si digita :.!pbpaste, questo dovrebbe funzionare sostituendo la riga corrente con l'output del buffer di incollaggio. In generale, vim consente di reindirizzare i dati presenti nel file corrente a un altro programma e sostituire il testo con l'output del comando. Quindi :1,3!pbpastesostituisce le prime tre righe del file con il buffer di incollaggio. Uso :.!ppjsonuna stringa JSON non formattata molto lunga, formattandola e sostituendo la stringa lunga con l'equivalente formattato. ppjson è solo uno script bash che viene eseguito python -m json.tool.
PatS

19

Ecco un post di qualcuno che ha capito come rimappare l'evento incolla per attivare e riaccendere automaticamente la modalità incolla. Funziona per me in tmux / iTerm su MacOSX.


1
Grazie per il consiglio. Ho anche rintracciato un plugin in cui la persona ha raggruppato funzionalità simili - stackoverflow.com/a/36512548/255961 .
Studgeek

Questo sembra causare una stringa di "eeeeeee" quando inserisco un pezzo di testo dai miei appunti.
John Jiang,

16

Aggiungi questo al tuo ~/.vimrce dovrai solo premere F2 prima e dopo aver incollato:

set pastetoggle=<F2>

12

Ho appena messo set clipboard=unnamed mio .vimrc. Ciò rende il buffer di incollaggio predefinito mappato negli Appunti di X.

Quindi, se segnare un po 'di testo in un terminale, posso semplicemente premere pper incollarlo in VIM. Allo stesso modo, posso trascinare le cose in vim (ad esempio YYper trascinare la linea corrente nel buffer) e fare clic centrale in qualsiasi finestra per incollarla.

Boh. Lo trovo super conveniente.


IMHO, questa è la risposta migliore, non è necessario alternare con F11 (che è preconfigurato di default in vim). Funziona con il sistema Mac OSX, non conosco gli altri.
LightMan,

9

Quando si lavora all'interno di un terminale, il plugin vim vim-bracketed-paste gestirà automaticamente le paste senza la necessità di premere i tasti prima o dopo l'incollaggio.

Funziona rilevando la modalità incolla tra parentesi che è una sequenza di escape inviata da terminali moderni "moderni" come iTerm2, gnome-terminal e altri terminali usando libvte. Come bonus aggiuntivo funziona anche per le sessioni di tmux. Lo sto usando con successo con iTerm2 su un Mac collegandomi a un server Linux e usando tmux.


Fai attenzione a ciò che nota inoltre: Sfortunatamente, ciò significa che eseguiranno anche i contenuti del buffer di input se c'è una nuova riga in qualsiasi cosa incolli nel terminale.
0xc0de,

1
@ 0xc0de, quella citazione non è rilevante qui. Sta parlando di cosa farà una shell quando non supporta la modalità incolla tra parentesi. Questo è il punto in modalità incolla tra parentesi: per impedire che ciò accada.
sh1

Questo ha funzionato molto meglio per me rispetto alle altre soluzioni. Grazie.
jjj

8

Inseriscilo nel tuo ~ / .vimrc e sii felice:

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

Modifica: sulla riflessione, :r !catè un approccio molto migliore poiché è breve, semantico e non richiede vimrc personalizzato. Usa quello invece!


5

Anche se :pastetoggleo :pastee :nopastedovrebbe funzionare bene (se implementato, non sono sempre come possiamo vedere dalla discussione) Consiglio vivamente di incollare usando l'approccio diretto "+po di "*pleggere con "+ro "*r:

Vim ha accesso a dieci tipi di registri ( :help registers) e l'interrogante è interessato alla sezione quotestare quoteplusdalla sezione

  1. Selezione e registri goccia "*, "+e "~

Utilizzare questi registri per archiviare e recuperare il testo selezionato per la GUI. Vedi quotestarequoteplus . Quando gli Appunti non sono disponibili o non funzionano, al suo posto viene utilizzato il registro senza nome. Per i sistemi Unix gli Appunti sono disponibili solo quando è presente la funzione + xterm_clipboard. {non in Vi}

Si noti che esiste solo una distinzione tra "* e" + per i sistemi X11.

:help x11-selectionchiarisce ulteriormente la differenza di *e +:

                                                  quoteplus quote+

Esistono tre selezioni X documentate: PRIMARY (che dovrebbe rappresentare l'attuale selezione visiva - come nella modalità Visual di Vim), SECONDARY (che è mal definito) e CLIPBOARD (che dovrebbe essere usato per le operazioni di taglio, copia e incolla ).

Di questi tre, Vim utilizza PRIMARY durante la lettura e la scrittura del "* registro (quindi quando sono disponibili le selezioni X11, Vim imposta un valore predefinito per" Appunti "di" selezione automatica ") e CLIPBOARD durante la lettura e la scrittura del registro" + ". Vim non accede alla selezione SECONDARIA.

Esempi: (assumendo i valori delle opzioni predefinite)

  • Seleziona un URL in modalità Visual in Vim. Vai al tuo browser e fai clic sul pulsante centrale del mouse nel campo di testo URL. Il testo selezionato verrà inserito (si spera!). Nota: in Firefox è possibile impostare la preferenza middlemouse.contentLoadURL su true in about: config, quindi l'URL selezionato verrà utilizzato quando si preme il pulsante centrale del mouse nella maggior parte dei punti della finestra.

  • Seleziona del testo nel browser trascinandolo con il mouse. Vai a Vim e premi il pulsante centrale del mouse: il testo selezionato viene inserito.

  • Seleziona del testo in Vim ed esegui "+ y. Vai al browser, seleziona un testo in un campo di testo trascinandolo con il mouse. Ora usa il pulsante destro del mouse e seleziona" Incolla "dal menu a comparsa. Il testo selezionato viene sovrascritto da il testo da Vim. Si noti che il testo nel "registro + rimane disponibile quando si effettua una selezione visiva, che rende disponibile altro testo nel registro" *. Ciò consente di sovrascrivere il testo selezionato.

ho notato che l'uso del clic centrale in vim non sembra incasinare il rientro, quindi potrebbe essere un'idea
Fuseteam

4

Questo funziona per me (caso per + register, quello che uso come buffer di scambio tra aps):

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

2

Se sei su un mac, macvim sembra gestirlo bene senza dover attivare e disattivare la pasta.

brew install macvim --override-system-vim


È questo il caso se includi le direttive del PO nel tuo .vimrcfile?
Drew Noakes,


1

Il modo più veloce io sappia rapidamente andare a incollare-insert mode per una pasta one-shot è tpope di intatta , che dispone yoe yO, presumibilmente mnemonici per “si apre”. Sono documentati solo nel suo vimdoc, come:

Non è stato fornito un interruttore per 'incolla' perché il tipico caso d'uso dell'involucro di un inserimento solitario è così dispendioso: si attiva / disattiva due volte, ma si incolla solo una volta (YOPO). Invece, premi yo o yO per invocare oo O con 'incolla' già impostato. L'uscita dalla modalità di inserimento imposta automaticamente 'nopaste'.


1

Un altro modo per incollare è passare <CR>e rilasciare i contenuti del registro (qui il registro globale). Vedi: :h i_ctrl-re h i_CTRL-R_CTRL-O.

Dalla documentazione di aiuto di 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}

Quindi, per incollare i contenuti in Vim senza rientro automatico, utilizzare <CR><CO>*nella maggior parte dei sistemi unix.

Nota: funziona solo se viene compilato vim clipboard .



1

Un'altra risposta che non ho visto fino ad ora:

:se paste noai

1

La pasta nativa / pasta tra parentesi è il modo migliore e più semplice da allora vim 8(rilasciato nel 2016). Funziona anche su SSH! (Il bracketing funziona su Linux e Mac, ma non su Windows Git Bash)

  1. Assicurati di avere vim 8+ (non hai bisogno delle opzioni +clipboardo +xterm_clipboard).

    vim --version | head -1

  2. Basta usare il comando incolla nativo del SO (ad es. ctrl+shift+VO cmd+V) in modalità normale. Non premere iper la modalità di inserimento.


Test

  1. Copia ( ctrl+shift+Co cmd+C) l'output di questo (2 righe con un rientro di tabulazione) negli Appunti di sistema:

    echo -e '\ta\n\tb'

  2. Avvia un vim pulito 8+ con autoindent:

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

  3. Copia dagli appunti di sistema ( ctrl+shift+Vo cmd+V) in modalità normale. Non premere iper la modalità di inserimento. L' ae bdovrebbe essere allineato con un singolo rientro della scheda. Puoi anche farlo mentre stai scrivendo a un computer remoto (il computer remoto avrà bisogno di vim 8+).

  4. Ora prova il vecchio modo, che inserirà automaticamente la seconda riga con una scheda aggiuntiva: premi iper inserire la modalità. Quindi incollare utilizzando ctrl+shift+Vo cmd+V. Gli ae bsono disallineati ora.


Installazione di Vim 8


1
modo migliore e più semplice! Inoltre, Google lo ha suggerito Featured snippetper la mia ricerca 'incolla contenuto senza tabs vim', forse perché, ho usato la parola chiave 'tab', solo in questa risposta menzionata :)
David

0

Purtroppo ho trovato che il plugin vim menzionato non funzionava con iTerm2 3.0.15 (per essere onesti non so se questo si è rotto sulle versioni precedenti) - ma ho trovato invece questo hack.

Mappa command-p per eseguire il comando incolla e usare i tasti vim iTerm2. Ovviamente questo funziona solo per iTerm2.

Come funziona. Uso "jk" per entrare in modalità escape quindi avrai anche bisogno di:

: inoremap jk

nel tuo .vimrc.

Quindi invoca semplicemente P per accedere alla modalità incolla, "+ p per incollare dagli appunti e quindi P per disabilitare la modalità incolla. Hth.

inserisci qui la descrizione dell'immagine


1
Aspetta, cosa usi 'jk' per questo?
0xc0de,

Oh sì, mi ero dimenticato di menzionarlo. Aggiungi ": inoremap jk <esc>" al tuo .vimrc. Per quanto riguarda il motivo per cui utilizzo jk, chiedo a Apple e perché hanno sentito il bisogno di spostarsi e liberarsi della chiave di escape fisica. 8 (
Neil McGill,

A proposito, ci vuole un po 'di allenamento ma dopo un po' jk si sente più veloce e penso di preferirlo ora rispetto alla fuga ... Comunque sarebbe interessante sapere se iTerm2 accetta <ESC> anche qui.
Neil McGill,

Modo di andare Apple!
0xc0de,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.