Désactivation du retrait automatique lors du collage de texte dans vim

1186

Je fais l'effort d'apprendre Vim.

Lorsque je colle du code dans mon document depuis le presse-papiers, j'obtiens des espaces supplémentaires au début de chaque nouvelle ligne:

line
  line
    line

Je sais que vous pouvez désactiver le retrait automatique, mais je ne peux pas le faire fonctionner car j'ai d'autres paramètres en conflit ou quelque chose (qui semblent assez évidents dans mon .vimrc mais ne semblent pas avoir d'importance lorsque je les supprime).

Comment désactiver la mise en retrait automatique lorsque je colle du code, mais que la mise en retrait automatique de vim est toujours active lorsque j'écris du code? Voici mon .vimrcdossier:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  
Rimian
la source
4
FWIW, vim 8.0.210 ajoute la prise en charge native de la coller entre crochets, ce qui évite de mettre en retrait le texte collé.
sh1
Pour les nouveaux fichiers afin d'éviter de tripoter le collage / nopaste de vim, vous pouvez cat > mynewfile.txtappuyer sur Entrée , coller votre texte, appuyer à nouveau sur Entrée , puis Ctr + D pour enregistrer. Le fichier est maintenant créé et vous pouvez le modifier avec vim mynewfile.txt.
ccpizza

Réponses:

2067

Mise à jour: meilleure réponse ici: https://stackoverflow.com/a/38258720/62202

Pour désactiver l'indentation automatique lorsque vous collez du code, il existe un mode spécial "coller".

Type

:set paste

Collez ensuite votre code. Notez que le texte de l'infobulle indique maintenant -- INSERT (paste) --.

Après avoir collé votre code, désactivez le mode collage, afin que l'indentation automatique lorsque vous tapez fonctionne à nouveau correctement.

:set nopaste

Cependant, j'ai toujours trouvé cela lourd. C'est pourquoi je mappe de <F3>telle sorte qu'il puisse basculer entre les modes coller et nopaste tout en éditant le texte! J'ajoute ceci à.vimrc

set pastetoggle=<F3>
P Shved
la source
38
Ce n'est pas plus facile que :set noaisuivi :set ai. La suggestion de :r! catest plus courte.
Leopd
69
Je pense que set pastec'est plus facile, certainement. C'est beaucoup plus sémantique que noaiou même noautoindent, ce qui est plus important lorsque vous tapez "noai" et "paste" prend environ le même temps insignifiant lorsque vous êtes assez compétent en tant que dactylographe.
Victor Zamanian
52
:set noaine fonctionne pas toujours, selon la façon dont les autres paramètres liés au retrait sont configurés conformément à l'OP. :set pastesemble être un raccourci pour plusieurs paramètres à la fois.
MarkHu
13
En retard à la fête, mais set copyindentvous vous en occuperez sans problème.
Matt Ryan
33
:set pastedésactive également d'autres fonctionnalités telles que l'achèvement des accolades, ce qui n'est pas non plus souhaité lors du collage de code.
Manuel Faux
263

Pour éviter les effets indésirables lors du collage, une option doit être définie:

set paste

Une commande utile à avoir dans votre .vimrc est set pastetoggle=<F10>ou un autre bouton, pour basculer facilement entre coller et nopaste.

Jacob Rask
la source
13
Finalement! J'ai continué à taper: set paste /: set nopaste, comme c'est stupide! THX.
imwilsonxu
4
d'un point de vue pratique, votre réponse est plus utile que la réponse acceptée
Lynob
8
Une autre option consiste à ajouter une macro à votre vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Chris
Belle suggestion @Chris - séquence de touches unique à coller sans problèmes d'indentation!
RichVel
que faire si je ne veux jamais être en mode collage? existe-t-il un moyen de désactiver définitivement?
maxwell
132

J'utilise :r! catet colle habituellement ( shift + insert )le contenu, puis CTRL+D.

Pas besoin d'activer et de désactiver, utilisation directe.

le geek
la source
J'aime cette option d'utilisation directe. Cependant, j'apprends toujours à lire la syntaxe vim sur les pages Web. Que signifient vos étapes? En particulier, en supposant que j'ai quelque chose dans le presse-papiers du système, sur quoi dois-je appuyer pour le coller dans un document dans vim?
jvriesem
9
Cette réponse serait plus utile avec des informations sur pourquoi et comment cela :r! catfonctionne.
K Erlandsson
11
@KErlandsson, :rinsère le contenu d'un fichier dans le document actuel. !catdit, exécutez cat qui ouvre essentiellement stdin (shells * nix) (shift + insert)ou pour certains terminaux, un clic droit de la souris collera le contenu du presse-papiers au terminal en CTRL+Dfin de fichier, donc il fermera la :r !catsession.
Daniel
Est-ce vraiment «direct»? Que de définir une option pastefaite uniquement à cette fin? @jvriesem Ce n'est pas une option "directe", si ce que je suppose de votre compréhension de ce mot est correct.
0xc0de
Vous pouvez également utiliser :r! catensuite CTRL+SHIFT+Vpour coller dans le terminal (puis CTRL+D).
Paul Rougieux
86

Si vous travaillez localement, vous pouvez coller à partir du presse-papiers du système avec la séquence de touches:

"+p

Il s'agit d'une commande vim appropriée, donc pas besoin de s'inquiéter d'entrer dans un mode d'insertion ou de désactiver d'abord l'indentation automatique.

Bien sûr, si vous travaillez à distance (console sur SSH, par exemple), cela ne fonctionnera pas et vous devez passer en :set noaimode d'insertion, coller dans la console, quitter le mode d'insertion, :set aiacheminer comme décrit ailleurs.

thomasrutter
la source
10
J'écris cette réponse il y a longtemps. De nos jours j'utilise :set pasteet à la :set nopasteplace parce qu'en dépit d'être plus long, c'est plus facile à retenir et je n'ai pas besoin de le chercher à chaque fois!
thomasrutter
6
Dans certains systèmes embarqués (basés principalement sur busybox) :set pasten'est pas implémenté, :set noaidoit donc être utilisé à la place.
jcarballo
Lorsque vous avez un gros texte à copier, n'est-il pas plus rapide d'utiliser le registre + à la place?
pedromanoel
1
@pedromanoel qui ne fonctionne que lorsque vous travaillez localement. Cela ne fonctionnera pas d'accéder à vim via SSH, par exemple, si vous avez copié quelque chose localement et que vous souhaitez le coller dans vim qui se trouve dans votre session SSH.
thomasrutter
1
@thomasrutter mais j'ai mappé ceci à <leader>p.. très utile!
Dane
51

Bien que le réglage du mode de paste/nopaste/pastetogglecollage avec soit parfaitement correct, vous devez toujours activer manuellement le mode de collage avant de coller et désactiver le mode de collage après le collage. Étant la personne paresseuse que je suis, voici la meilleure solution que j'ai trouvée jusqu'à présent, qui bascule automatiquement le mode de collage lorsque vous collez.

Voici une petite astuce qui utilise le mode de collage entre crochets du terminal pour définir / désactiver automatiquement le mode de collage de Vim lorsque vous collez. Mettez ce qui suit dans votre .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

Maintenant, vous pouvez coller sans activer / désactiver explicitement le mode coller - il est géré automatiquement pour vous.

Source: Coderwall

Remarque: Cette solution ne fonctionne pas dans WSL (sous-système Windows 10 pour Linux). Si quelqu'un a une solution pour WSL, veuillez mettre à jour cette réponse ou l'ajouter dans les commentaires.

Tmux Si vous utilisez tmux, les déclarations doivent être à double échappement. Le code pour cela est également dans Coderwall

thdoan
la source
C'est brillant. Une chose cependant ... Avec chaque pâte, j'obtiens un caractère "0" (zéro) au début de chaque pâte. Une astuce pour ça?
Julius Š.
Notez également que si vous utilisez tmux, vous devez double-échapper. Le code pour cela est dans le lien Coderwall en réponse
Daithí
1
Si vous êtes encore plus paresseux et copiez le collage ci-dessus dans votre .vimrc, prenez soin de l'indentation de la fonction XTermPasteBegin ().
k1133
J'étais curieux de savoir comment cela fonctionnait, et j'ai donc recherché Paste Bracketing et trouvé gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing, ce qui explique que les variables t_SIet activent le t_EIbracketing et le désactivent. Lorsque le collage entre parenthèses est activé, le texte collé est précédé esc[200~et suivi de esc[201~.
PatS
37

Les utilisateurs de Mac peuvent éviter le formatage automatique en lisant directement à partir de la table de montage avec:

:r !pbpaste
maniacalrobot
la source
3
Ceci est une réponse impressionnante. Quand je fais cela, cependant, il cache le document (il semble que je sois de retour sur la ligne de commande), mais a le texte dans mon presse-papiers. Il m'invite à appuyer sur Entrée, alors je le fais, et il me renvoie à mon document sans aucune modification. Que s'est-il passé et comment faire ce que vous dites?
jvriesem
Si vous tapez simplement :.!pbpaste, cela devrait fonctionner en remplaçant la ligne actuelle par la sortie du tampon de collage. En général, vim vous permet de diriger les données qui se trouvent dans votre fichier actuel vers un autre programme et de remplacer le texte par la sortie de la commande. Remplace donc :1,3!pbpasteles trois premières lignes de votre fichier par le tampon de collage. J'utilise :.!ppjsonpour prendre une très longue (chaîne JSON non formatée) et la formater et remplacer la longue chaîne par l'équivalent formaté. ppjson est juste un script bash qui s'exécute python -m json.tool.
PatS
19

Voici un article de quelqu'un qui a compris comment remapper l'événement de collage pour activer et désactiver automatiquement le mode de collage. Fonctionne pour moi dans tmux / iTerm sur MacOSX.

Von
la source
1
Merci pour le conseil. J'ai également retrouvé un plugin où la personne a regroupé des fonctionnalités similaires - stackoverflow.com/a/36512548/255961 .
studgeek
Cela semble provoquer une chaîne de «eeeeeee» lorsque j'insère un morceau de texte de mon presse-papiers.
John Jiang
16

Ajoutez ceci à votre ~/.vimrcet vous n'aurez qu'à appuyer sur F2 avant et après le collage:

set pastetoggle=<F2>
anh_ng8
la source
12

Je viens de mettre set clipboard=unnamedmon .vimrc. Cela fait la carte par défaut du tampon de collage dans le presse-papiers de X.

Donc, si je marque un peu de texte dans un terminal, je peux simplement appuyer sur ppour le coller dans vim. De même, je peux extraire des choses dans vim (par exemple YYpour extraire la ligne actuelle dans le tampon) et cliquer avec le bouton central dans n'importe quelle fenêtre pour la coller.

Je ne sais pas. Je trouve ça super pratique.

Soren
la source
À mon humble avis, c'est la meilleure réponse, pas besoin de basculer avec F11 (qui est préconfiguré par défaut dans vim). Cela fonctionne dans le système macs OSX, je ne connais pas les autres.
LightMan
9

Lorsque vous travaillez à l'intérieur d'un terminal, le plug-in vim-bracketed-paste vim gèrera automatiquement les pâtes sans avoir besoin de touches avant ou après la pâte.

Il fonctionne en détectant le mode de collage entre parenthèses qui est une séquence d'échappement envoyée par des terminaux compatibles x-term "modernes" comme iTerm2, gnome-terminal et d'autres terminaux utilisant libvte. En prime, il fonctionne également pour les sessions tmux. Je l'utilise avec succès avec iTerm2 sur un Mac se connectant à un serveur Linux et utilisant tmux.

studgeek
la source
Méfiez-vous de ce qu'il note également: Malheureusement, cela signifie qu'ils exécuteront également le contenu du tampon d'entrée s'il y a une nouvelle ligne dans tout ce que vous collez dans le terminal.
0xc0de
1
@ 0xc0de, cette citation n'est pas pertinente ici. Cela parle de ce qu'un shell fera lorsqu'il ne prend pas en charge le mode de collage entre crochets. C'est le point en mode de collage entre parenthèses - pour empêcher cela de se produire.
sh1
Cela a fonctionné beaucoup mieux pour moi que les autres solutions. Merci.
jjj
8

Collez-le dans votre ~ / .vimrc et soyez heureux:

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

Edit: à la réflexion, :r !catest une bien meilleure approche car elle est courte, sémantique et ne nécessite aucun vimrc personnalisé. Utilisez-le à la place!

Dergachev
la source
5

Bien que :pastetoggleou :pasteet :nopastedevrait fonctionner correctement (si mis en œuvre - ils ne sont pas toujours comme nous pouvons le voir dans la discussion) je recommande fortement de coller en utilisant l'approche directe "+pou "*pet de lire avec "+rou "*r:

Vim a accès à dix types de registres ( :help registers) et l'intervenant est intéressé par quotestaret quoteplusdepuis la section

  1. Sélection et registres goutte "*, "+et « ~

Utilisez ces registres pour stocker et récupérer le texte sélectionné pour l'interface graphique. Voir quotestaret quoteplus. Lorsque le presse-papiers n'est pas disponible ou ne fonctionne pas, le registre sans nom est utilisé à la place. Pour les systèmes Unix, le presse-papiers n'est disponible que lorsque la fonction + xterm_clipboard est présente. {pas à Vi}

Notez qu'il n'y a qu'une distinction entre "* et" + pour les systèmes X11.

:help x11-selectionclarifie davantage la différence *et +:

                                                  quoteplus quote+

Il existe trois sélections X documentées: PRIMARY (qui devrait représenter la sélection visuelle actuelle - comme dans le mode visuel de Vim), SECONDARY (qui est mal défini) et CLIPBOARD (qui devrait être utilisé pour les opérations de couper, copier et coller ).

Parmi ces trois, Vim utilise PRIMARY lors de la lecture et de l'écriture du registre "* (donc lorsque les sélections X11 sont disponibles, Vim définit une valeur par défaut pour" presse-papiers "de" sélection automatique "), et CLIPBOARD lors de la lecture et de l'écriture du registre" +. Vim n'accède pas à la sélection SECONDAIRE.

Exemples: (en supposant les valeurs d'option par défaut)

  • Sélectionnez une URL en mode visuel dans Vim. Accédez à votre navigateur et cliquez sur le bouton central de la souris dans le champ de texte URL. Le texte sélectionné sera inséré (espérons-le!). Remarque: dans Firefox, vous pouvez définir la préférence middlemouse.contentLoadURL sur true dans about: config, puis l'URL sélectionnée sera utilisée lorsque vous appuyez sur le bouton central de la souris dans la plupart des endroits de la fenêtre.

  • Sélectionnez du texte dans votre navigateur en le faisant glisser avec la souris. Accédez à Vim et appuyez sur le bouton central de la souris: le texte sélectionné est inséré.

  • Sélectionnez du texte dans Vim et faites "+ y. Allez dans votre navigateur, sélectionnez du texte dans un champ de texte en le faisant glisser avec la souris. Utilisez maintenant le bouton droit de la souris et sélectionnez" Coller "dans le menu contextuel. Le texte sélectionné est écrasé par le texte de Vim. Notez que le texte dans le registre "+ reste disponible lorsque vous effectuez une sélection visuelle, ce qui rend les autres textes disponibles dans le registre" *. Cela permet d'écraser le texte sélectionné.
codingdave
la source
j'ai remarqué que l'utilisation du clic du milieu dans vim ne semble pas gâcher l'indentation, ce qui pourrait être une idée
Fuseteam
4

Cela fonctionne pour moi (cas pour + registre, ce que j'utilise comme tampon d'échange entre aps):

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

Si vous êtes sur un mac, macvim semble bien le gérer sans avoir à basculer la pâte.

installer brew macvim --override-system-vim

Marcus Ericsson
la source
Est-ce le cas si vous incluez les directives du PO dans votre .vimrcdossier?
Drew Noakes du
1

La façon la plus rapide que je suis au courant de passer rapidement en mode coller-insertion pour une pâte one-shot est de tpope intact , qui présente yoet yO, probablement mnémoniques pour « vous ouvrez ». Ils sont uniquement documentés dans son vimdoc, comme:

Une bascule n'a pas été fournie pour la «pâte» car le cas d'utilisation typique de l'emballage d'une insertion solitaire est si inutile: vous basculez deux fois, mais vous ne collez qu'une seule fois (YOPO). Au lieu de cela, appuyez sur yo ou yO pour appeler o ou O avec 'coller' déjà défini. Le fait de quitter le mode d'insertion définit automatiquement «nopaste».

Micah Elliott
la source
1

Une autre façon de coller est via <CR>et de supprimer le contenu du registre (ici le registre global). Voir: :h i_ctrl-ret h i_CTRL-R_CTRL-O.

Dans la documentation d'aide de 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}

Donc, pour coller du contenu dans vim sans retrait automatique, utilisez-le <CR><CO>*dans la plupart des systèmes Unix.

Remarque: cela ne fonctionne que si vim est compilé avec clipboard.

TheChetan
la source
1

De vim: ]p

De l'extérieur: "*]pou"+]p

Bruno
la source
1

Une autre réponse que je n'ai pas vue jusqu'à présent:

:se paste noai
sjas
la source
1

La pâte native / pâte entre crochets est la meilleure et la plus simple depuis vim 8(sortie en 2016). Cela fonctionne même sur ssh! (La pâte entre crochets fonctionne sur Linux et Mac, mais pas sur Windows Git Bash)

  1. Assurez-vous d'avoir vim 8+ (vous n'avez pas besoin des options +clipboardou +xterm_clipboard).

    vim --version | head -1

  2. Utilisez simplement la commande de collage natif du système d'exploitation (par exemple ctrl+shift+Vou cmd+V) en mode normal. N'appuyez pas ipour le mode d'insertion.


Tester

  1. Copiez ( ctrl+shift+Cou cmd+C) la sortie de ceci (2 lignes avec un retrait de tabulation) dans le presse-papiers du système:

    echo -e '\ta\n\tb'

  2. Lancez un vim propre 8+ avec autoindent:

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

  3. Coller à partir du presse-papiers du système ( ctrl+shift+Vou cmd+V) en mode normal. N'appuyez pas ipour le mode d'insertion. Le aet bdoit être aligné avec un seul retrait de tabulation. Vous pouvez même le faire en effectuant un transfert vers une machine distante (la machine distante aura besoin de vim 8+).

  4. Essayez maintenant l'ancienne méthode, qui induira automatiquement la deuxième ligne avec un onglet supplémentaire: Appuyez sur ipour le mode Insertion. Collez ensuite à l'aide de ctrl+shift+Vou cmd+V. Le aet bsont désalignés maintenant.


Installation de Vim 8

wisbucky
la source
1
meilleur et plus simple moyen! En outre, Google l'a suggéré Featured snippetpour ma recherche 'coller du contenu sans onglets vim', peut-être parce que j'ai utilisé le mot clé 'tab', uniquement dans cette réponse mentionnée :)
David
0

Malheureusement, j'ai trouvé que le plugin vim mentionné ne fonctionnait pas avec iTerm2 3.0.15 (pour être honnête, je ne sais pas si cela s'est cassé sur les anciennes versions) - mais j'ai trouvé ce hack à la place.

Mappez la commande-p pour faire le collage et utiliser les clés vim iTerm2. Évidemment, cela ne fonctionne que pour iTerm2.

Comment ça fonctionne. J'utilise "jk" pour entrer en mode d'échappement, vous aurez donc également besoin:

: inoremap jk

dans votre .vimrc.

Ensuite, il appelle simplement P pour entrer en mode Coller, "+ p pour coller à partir du presse-papiers, puis P pour désactiver le mode Coller. Hth.

entrez la description de l'image ici

Neil McGill
la source
1
Attendez, quoi, vous utilisez 'jk' pour ça?
0xc0de
Oh ouais, j'avais oublié de le mentionner. Ajoutez simplement ": inoremap jk <esc>" à votre .vimrc. Quant à savoir pourquoi j'utilise jk, demandez à Apple et pourquoi ils ont ressenti le besoin de bouger et de se débarrasser de la touche d'échappement physique. 8 (
Neil McGill
BTW ça prend un peu de formation mais après un certain temps jk se sent plus vite et je pense que je le préfère maintenant plutôt que de s'échapper ... Quoi qu'il en soit, il serait intéressant de savoir si iTerm2 accepte <ESC> ici aussi.
Neil McGill
Bravo Apple!
0xc0de