web-dev-qa-db-fra.com

Collage de code dans la fenêtre du terminal dans vim sur Mac OS X

Lorsque je colle du code dans ma fenêtre de terminal Mac OS X dans vim, il indente chaque ligne. Pour chaque ligne, il ajoute un retrait afin que le texte ressemble à ceci ...

"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."

Ma solution de contournement actuelle consiste à coller d'abord le texte dans l'éditeur de texte TextMate qui conserve la mise en forme correcte. Ensuite, j'enregistre ce fichier et l'ouvre dans vim. Ensuite, j'utilise vim yank pour le coller.
Y a-t-il un paramètre dans mon .vimrc qui pourrait changer ce comportement? Ou s'agit-il d'un problème terminal?

67
eat_a_lemon

Dans vim:

:set paste

Mettez Vim en mode Coller. Ceci est utile si vous souhaitez couper ou copier du texte à partir d'une fenêtre et le coller dans Vim. Cela évitera des effets inattendus.

85
William Pursell

MISE À JOUR: Vim 8 inclut la prise en charge native du mode de collage croisé. Il est activé par défaut. Voir Vim's xterm-bracketed-paste rubrique d'aide. Les utilisateurs n'ont plus rien à faire pour configurer Vim pour prendre en charge cela.

À partir de Mac OS X Lion 10.7, Terminal prend en charge le "mode de collage entre crochets", qui permet à l'émulateur de terminal d'indiquer au programme connecté au terminal lorsque l'utilisateur colle du texte, de sorte que le programme ne l'interprète pas comme des commandes d'édition. Les programmes qui le prennent en charge envoient au terminal une séquence d'échappement pour activer ce mode, dans lequel le terminal entoure le texte collé avec une paire de séquences d'échappement qui identifient le début et la fin.

Pour l'activer dans Vim, mettez le code suivant dans votre fichier ~/.vimrc:

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

Ainsi, lorsque Vim bascule le terminal vers/depuis l'écran alternatif † (t_ti, t_te), il active/désactive le mode de collage entre crochets (ESC [? 2004 h, ESC [? 2004 l). Lorsqu'il reçoit la séquence d'échappement indiquant le début d'un collage (ESC [200 ~), il active le mode Coller (définir le collage) et passe en mode Insertion si nécessaire ("i"). Lorsqu'il reçoit le marqueur de fin de collage correspondant (ESC [201 ~), il désactive le mode Coller (pastetoggle) et reste en mode Insertion. Les commandes cmap permettent à la ligne de commande Vim d'ignorer les séquences d'échappement et d'accepter le texte collé tel quel.

Notez que cela n'active le mode de collage entre crochets que lorsque la valeur $ TERM commence par "xterm…"; si vous définissez $ TERM sur autre chose, vous pouvez réviser ce test pour inclure votre valeur $ TERM. Ou, vous pouvez omettre complètement le test, car il n'est pas strictement nécessaire - il essaie simplement de faire attention de ne pas faire quelque chose qui pourrait être incompatible avec un autre type de terminal.

Dans Terminal, cela fonctionne avec toutes les différentes commandes de collage, ainsi que par glisser-déposer.

† Le terminal possède un écran principal et un écran "alternatif". Chaque écran a son propre contenu et son propre état. Le texte de l'écran secondaire ne défile pas vers le haut dans le journal de défilement. Il est généralement utilisé par les programmes qui prennent le contrôle de tout l'écran et sont donc appelés programmes "plein écran". Cela inclut par exemple vim, emacs, less et top.

105
Chris Page

En plus des autres réponses, si vous voulez un moyen rapide de basculer le mode coller, ajoutez

set pastetoggle=<F2>

à votre .vimrc. Vous pouvez maintenant basculer le mode coller en appuyant sur F2 (ou sur la touche que vous choisissez).

9
dancavallaro

Une autre façon de le faire, en supposant que le presse-papiers de votre système est correctement configuré,

"+p

Cela sera collé depuis le presse-papiers du système.

6
Aaron Jensen

In vim

: définir la pâte

quand tu veux le désactiver

: définir nopaste

6
WenbinWu

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

Cela fonctionne dans Terminal, iTerm2 et tous les terminaux compatibles "modernes" x-term qui prennent en charge le mode de collage entre crochets. 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.

Le plugin est essentiellement une version packagée de la fonctionnalité que @Chris Page a répertorié dans son réponse .

4
studgeek