Desativando o recuo automático ao colar texto no vim


1186

Estou fazendo um esforço para aprender o Vim.

Quando colo o código no meu documento a partir da área de transferência, obtenho espaços extras no início de cada nova linha:

line
  line
    line

Eu sei que você pode desativar o recuo automático, mas não consigo fazê-lo funcionar porque tenho outras configurações conflitantes ou algo assim (que parece bastante óbvio no meu .vimrc, mas não parece importar quando as tiro).

Como desativo o recuo automático quando colo o código, mas ainda tenho o recuo automático do vim quando estou escrevendo o código? Aqui está o meu .vimrcarquivo:

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

4
O FWIW, vim 8.0.210 adiciona suporte nativo à pasta entre colchetes, para evitar recuar o texto colado.
— Sh1

Para novos arquivos, a fim de evitar mexer com a pasta / nopaste do vim, cat > mynewfile.txtpressione Enter , cole seu texto, pressione Enter novamente e, em seguida , pressione Ctr + D para salvar. O arquivo agora está criado e você pode editá-lo com vim mynewfile.txt.
— Ccpizza # 6/19

Respostas:


2066

Atualização: Melhor resposta aqui: https://stackoverflow.com/a/38258720/62202

Para desativar o autoindent ao colar o código, existe um modo especial "colar".

Tipo

:set paste

Em seguida, cole seu código. Observe que o texto na dica de ferramenta agora diz -- INSERT (paste) --.

Depois de colar o código, desative o modo de colar, para que o recuo automático ao digitar funcione corretamente novamente.

:set nopaste

No entanto, eu sempre achei isso complicado. É por isso <F3>que mapeio para que ele possa alternar entre os modos colar e nopaste durante a edição do texto! Eu adiciono isso a.vimrc

set pastetoggle=<F3>

38
Isso não é mais fácil do que :set noai seguido por :set ai. A sugestão de :r! caté mais curta.
— Leopd

69
Eu acho que set pasteé mais fácil, definitivamente. É muito mais semântico do que noaiou mesmonoautoindent , o que é mais importante ao digitar "noai" e "paste" e leva a mesma quantidade insignificante de tempo quando você é proficiente o suficiente como datilógrafo.
— Victor Zamanian

52
:set noainem sempre funciona, dependendo de como as outras configurações relacionadas ao recuo são definidas de acordo com o OP. :set pasteparece ser uma abreviação para várias configurações ao mesmo tempo.
— MarkHu

13
Tarde para a festa, mas set copyindentvai cuidar disso para você sem problemas.
— Matt Ryan

33
:set pastetambém desativa outros recursos, como conclusão de chaves, que também não são desejados ao colar código.
— Manuel Faux

263

Para evitar efeitos indesejados ao colar, existe uma opção que precisa ser definida:

set paste

Um comando útil para ter em seu .vimrc é set pastetoggle=<F10>ou algum outro botão, para alternar facilmente entre colar e nopaste.


13
Finalmente! Continuei digitando: set paste /: set nopaste, que idiota! Valeu.
— imwilsonxu

4
a partir de um ponto de vista prático, a sua resposta é mais útil do que a resposta aceita
— Lynob

8
Outra opção é adicionar uma macro para seu vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
— Chris

Boa sugestão @ Chris - sequência de teclas simples para colar sem problemas de recuo!
— RichVel

e se eu nunca quiser estar no modo colar? existe uma maneira de desativar permanentemente?
— Max24

132

Normalmente, uso :r! cate colo ( shift + insert )o conteúdo e CTRL+D.

Não há necessidade de ativar e desativar o uso direto.


Eu gosto dessa opção de uso direto. Ainda estou aprendendo a ler a sintaxe do vim em páginas da web. O que seus passos significam? Em particular, supondo que eu tenha algo na área de transferência do sistema, o que pressiono para colá-lo em um documento no vim?
— Jvriesem #

9
Esta resposta seria mais útil com informações sobre por que e como :r! catfunciona.
— K Erlandsson #

11
@KErlandsson, :rinsere o conteúdo de um arquivo no documento atual. !catdiz, execute cat que essencialmente abre stdin (* nix shells) (shift + insert)ou, para alguns terminais, o clique com o botão direito do mouse colará o conteúdo da área de transferência no terminal que CTRL+Destá no final do arquivo e, portanto, fechará a :r !catsessão.
— Daniel Daniel

Isso é 'direto', realmente? Do que definir uma opção pastefeita exclusivamente para esse fim? @jvriesem Esta não é uma opção 'direta', se o que eu presumo de sua compreensão dessa palavra está correto.
— 0xc0de 31/10

Você também pode usar :r! cat, em seguida, CTRL+SHIFT+Vpara colar no terminal (então CTRL+D).
— Paul Rougieux

86

Se você estiver trabalhando localmente, poderá colar da área de transferência do sistema com a sequência de teclas:

"+p

Este é um comando vim adequado, portanto, não é necessário se preocupar em entrar no modo de inserção ou desativar o autoindent primeiro.

Obviamente, se você estiver trabalhando remotamente (console por SSH, por exemplo), isso não funcionará e você deve ir para o :set noaimodo de inserção, colar no console, deixar o modo de inserção, :set airota conforme descrito em outro lugar.


10
Escrevo esta resposta há séculos. Hoje em dia eu uso :set pastee, :set nopasteem vez disso, porque apesar de ser mais longo, é mais fácil lembrar e não preciso procurar sempre!
— thomasrutter

6
Em alguns sistemas embarcados (principalmente no busybox) :set pastenão é implementado, portanto :set noaideve ser usado.
— jcarballo

Quando você tem um texto grande para copiar, não é mais rápido usar o registro +?
— Pedromanoel

1
@pedromanoel que só funciona quando se trabalha localmente. Não funcionará acessando o vim pelo SSH, por exemplo, se você copiou algo localmente e deseja colá-lo no vim que está na sua sessão SSH.
— thomasrutter

1
@ thomasrutter mas mapeei isso para <leader>p.. muito útil!
— Dane

51

Enquanto definir o modo de colar com paste/nopaste/pastetoggleestiver perfeitamente correto, você ainda precisará ativar manualmente o modo de colar antes de colar e desativar o modo de colar após colar. Sendo a pessoa preguiçosa que sou, abaixo está a melhor solução que encontrei até agora, que alterna automaticamente o modo de colar quando você cola.

Aqui está um pequeno truque que usa o modo de colar entre parênteses do terminal para definir / desabilitar automaticamente o modo de colar do Vim quando você cola. Coloque o seguinte em seu arquivo .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

Agora você pode colar sem ativar / desativar explicitamente o modo de colar - ele é tratado automaticamente para você.

Fonte: Coderwall

Nota: Esta solução não funciona no WSL (Windows 10 Subsystem for Linux). Se alguém tiver uma solução para WSL, atualize esta resposta ou adicione-a nos comentários.

Tmux Se você estiver usando o tmux, as declarações precisam ser escapadas duas vezes. O código para isso também está em Coderwall


Isso é brilhante. Uma coisa é ... Com cada pasta, recebo um caractere "0" (zero) no início de cada pasta. Alguma dica para isso?
— Julius Š.

Observe também que , se estiver usando o tmux , você precisará escapar duas vezes. O código para isso está no link Coderwall em resposta
— Daithí 17/02/19

1
Se você é ainda mais preguiçoso e copia a cola acima do código no seu .vimrc, cuide da indentação da função XTermPasteBegin ().
— precisa saber é o seguinte

Fiquei curioso para saber como isso funcionava e, então, procurei Colar Bracketing e encontrei gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing, que explica que as variáveis t_SIe t_EIestão ativando e desabilitando o bracketing de pasta. Quando o bracketing de colagem está ativado, o texto colado é prefixado esc[200~e seguido por esc[201~.
— PatS 01/04

37

Os usuários de Mac podem evitar a formatação automática lendo diretamente a partir da área de transferência com:

:r !pbpaste

3
Esta é uma resposta impressionante. Quando faço isso, no entanto, ele oculta o documento (parece que estou de volta à linha de comando), mas tem o texto na minha área de transferência. Ele solicita que eu pressione enter, assim o faço e me retorna ao meu documento sem nenhuma alteração. O que aconteceu e como faço o que você está dizendo?
— Jvriesem #

Se você digitar :.!pbpaste, isso funcionará substituindo a linha atual pela saída do buffer de colagem. Em geral, o vim permite canalizar dados que estão no seu arquivo atual para outro programa e substituir o texto pela saída do comando. Portanto, :1,3!pbpastesubstitui as três primeiras linhas do seu arquivo pelo buffer de colagem. Eu uso :.!ppjsonpara pegar uma muito longa (string JSON não formatada) e formatá-la e substituir a longa com o equivalente formatado. O ppjson é apenas um script bash que é executado python -m json.tool.
— PatS 01/04

19

Aqui está uma postagem de alguém que descobriu como remapear o evento de colar para ativar e ativar o modo de colar automaticamente. Funciona para mim no tmux / iTerm no MacOSX.


1
Obrigado pela dica. Também localizei um plug-in no qual a pessoa agrupou funcionalidades semelhantes - stackoverflow.com/a/36512548/255961 .
— precisa saber é o seguinte

Isso parece causar uma sequência de 'eeeeeee' quando insiro um pedaço de texto da minha área de transferência.
— John Jiang

16

Adicione isso ao seu ~/.vimrce você só precisará pressionar F2 antes e depois de colar:

set pastetoggle=<F2>

12

Acabei de colocar set clipboard=unnamedno meu .vimrc. Isso faz com que o buffer de colagem padrão seja mapeado para a área de transferência do X.

Portanto, se eu marcar um pouco de texto em um terminal, posso simplesmente pressionar ppara colá-lo no vim. Da mesma forma, posso arrancar as coisas no vim (por exemplo,YY para puxar a linha atual para o buffer) e clicar com o botão do meio em qualquer janela para colá-la.

Não sei. Acho super conveniente.


IMHO, esta é a melhor resposta, sem necessidade de alternar com o F11 (que é pré-configurado por padrão no vim). Isso funciona no sistema OSX macs, eu não sei sobre os outros.
— LightMan 29/07

9

Ao trabalhar dentro de um terminal, a pasta vim-bracketed-paste plugin vim manipulará automaticamente pastas sem a necessidade de pressionar as teclas antes ou depois da pasta.

Ele funciona detectando o modo de colar entre colchetes, que é uma sequência de escape enviada por terminais "modernos" compatíveis com o termo x, como iTerm2, gnome-terminal e outros terminais usando a libvte. Como um bônus adicional, ele também funciona para sessões tmux. Estou usando-o com sucesso com o iTerm2 em um Mac conectado a um servidor Linux e usando o tmux.


Cuidado com o que ele também observa: Infelizmente, isso significa que eles também executarão o conteúdo do buffer de entrada se houver uma nova linha em qualquer coisa que você colar no terminal.
— 0xc0de 31/10

1
@ 0xc0de, essa citação não é relevante aqui. Isso está falando sobre o que um shell fará quando não suporta o modo de colar entre colchetes. Esse é o ponto no modo de colar entre parênteses - para impedir que isso aconteça.
— sh1

Isso funcionou muito melhor para mim do que as outras soluções. Obrigado.
— Jjj #

8

Cole isso em seu ~ / .vimrc e seja feliz:

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

Edit: na reflexão, :r !caté uma abordagem muito melhor, pois é curta, semântica e não requer vimrc personalizado. Use isso em vez disso!


5

Embora :pastetoggleor :pastee :nopastedeva estar funcionando bem (se implementado - eles nem sempre são como podemos ver na discussão), recomendo fortemente colar usando a abordagem direta "+pou "*pe lendo com "+rou "*r:

Vim tem acesso aos tipos de dez dos registos ( :help registers) e o questionador está interessado em quotestare quoteplusda seção

  1. Seleção e registros queda "*, "+e "~

Use esses registros para armazenar e recuperar o texto selecionado para a GUI. Veja quotestare quoteplus. Quando a área de transferência não está disponível ou não está funcionando, o registro sem nome é usado. Para sistemas Unix, a área de transferência está disponível apenas quando o recurso + xterm_clipboard está presente. {não no Vi}

Observe que há apenas uma distinção entre "* e" + para sistemas X11.

:help x11-selectionesclarece ainda mais a diferença *e +:

                                                  quoteplus quote+

Existem três seleções X documentadas: PRIMARY (que deve representar a seleção visual atual - como no modo Visual do Vim), SECONDARY (que está mal definido) e CLIPBOARD (que deve ser usado para operações de recortar, copiar e colar) )

Desses três, o Vim usa PRIMARY ao ler e gravar o registro "* (portanto, quando as seleções X11 estão disponíveis, o Vim define um valor padrão para 'área de transferência' de" seleção automática ") e o CLIPBOARD ao ler e gravar o registro" +. O Vim não acessa a seleção SECUNDARY.

Exemplos: (assumindo os valores da opção padrão)

  • Selecione uma URL no modo Visual no Vim. Vá para o seu navegador e clique no botão do meio do mouse no campo de texto da URL. O texto selecionado será inserido (espero!). Nota: no Firefox, você pode definir a preferência middlemouse.contentLoadURL como true em about: config; o URL selecionado será usado ao pressionar o botão do meio do mouse na maioria dos locais da janela.

  • Selecione algum texto no seu navegador, arrastando com o mouse. Vá para o Vim e pressione o botão do meio do mouse: O texto selecionado é inserido.

  • Selecione algum texto no Vim e faça "+ y. Vá para o seu navegador, selecione algum texto em um campo de texto arrastando com o mouse. Agora use o botão direito do mouse e selecione" Colar "no menu pop-up. O texto selecionado é substituído por o texto do Vim. Observe que o texto no registro "+ permanece disponível ao fazer uma seleção Visual, que disponibiliza outro texto no registro" *. Isso permite substituir o texto selecionado.

Eu notei que usar o clique do meio no vim não parece atrapalhar o recuo, então isso pode ser uma idéia.
— Fuseteam

4

Isso funciona para mim (caso para + register, o que eu uso como buffer de troca entre aps):

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

2

Se você estiver em um mac, o macvim parece lidar bem com isso sem precisar alternar a pasta.

brew install macvim --override-system-vim


É esse o caso se você incluir as diretrizes do OP em seu .vimrcarquivo?
— de Drew Noakes


1

A maneira mais rápida que eu conheço de ir rapidamente para o modo colar-inserir para uma pasta de um tiro é perfeita do tpope , que apresenta yoe yO, presumivelmente, mnemônicos para "você abre". Eles estão documentados apenas em seu vimdoc, como:

Não foi fornecida uma alternância para 'colar' porque o caso de uso típico de empacotar uma inserção solitária é um desperdício: você alterna duas vezes, mas cola apenas uma vez (YOPO). Em vez disso, pressione yo ou yO para chamar o ou O com 'colar' já definido. Sair do modo de inserção define 'nopaste' automaticamente.


1

Outra maneira de colar é via <CR>e soltando o conteúdo do registro (aqui o registro global). Veja: :h i_ctrl-re h i_CTRL-R_CTRL-O.

Na documentação de ajuda do 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}

Portanto, para colar o conteúdo no vim sem recuo automático, use <CR><CO>*na maioria dos sistemas unix.

Nota: isso só funciona se o vim for compilado clipboard.



1

Outra resposta que não vi até agora:

:se paste noai

1

Pasta nativa / pasta entre colchetes é a melhor e mais simples maneira desde vim 8(lançada em 2016). Até funciona sobre ssh! (A pasta entre colchetes funciona no Linux e Mac, mas não no Windows Git Bash)

  1. Verifique se você possui o vim 8+ (não precisa das opções +clipboardou +xterm_clipboard).

    vim --version | head -1

  2. Basta usar o comando colar nativo do SO (por exemplo, ctrl+shift+Vou cmd+V) no modo normal. Não pressione ipara inserir o modo.


Teste

  1. Copie ( ctrl+shift+Cou cmd+C) a saída disso (2 linhas com recuo de tabulação) na área de transferência do sistema:

    echo -e '\ta\n\tb'

  2. Inicie um vim limpo 8+ com autoindent:

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

  3. Cole na área de transferência do sistema ( ctrl+shift+Vou cmd+V) no Modo Normal. Não pressione ipara inserir o modo. O ae bdeve estar alinhado com um único recuo da guia. Você pode fazer isso enquanto faz o ssh em uma máquina remota (a máquina remota precisará do vim 8+).

  4. Agora tente da maneira antiga, que indentará automaticamente a segunda linha com uma guia extra: Pressione ipara inserir o modo. Em seguida, cole usando ctrl+shift+Vou cmd+V. O ae bestá desalinhado agora.


Instalando o Vim 8


1
melhor e mais simples maneira! Além disso, o Google sugere-nos Featured snippetpara a minha pesquisa 'colar conteúdo não tabulações vim', talvez porque, eu usei 'guia' palavra-chave, só nesta resposta mencionado :)
— David

0

Infelizmente, achei que o plugin vim mencionado não estava funcionando com o iTerm2 3.0.15 (para ser justo, não sei se isso ocorreu em versões mais antigas) - mas encontrei esse hack.

Mapeie command-p para colar e use as chaves do iTerm2 vim. Obviamente, isso funciona apenas para o iTerm2.

Como funciona. Eu uso "jk" para entrar no modo de escape, assim você também precisará:

: inoremap jk

no seu .vimrc.

Depois, basta chamar P para entrar no modo de colar ", + p para colar na área de transferência e depois P para desativar o modo de colar. Hth.

insira a descrição da imagem aqui


1
Espere, você usa 'jk' para isso?
— 0xc0de 31/10/19

Ah sim, eu tinha esquecido de mencionar isso. Basta adicionar ": inoremap jk <esc>" ao seu .vimrc. Quanto ao motivo pelo qual uso o jk, pergunte à Apple e por que eles sentiram a necessidade de se mover e se livrar da tecla de escape físico. 8 (
— Neil McGill

BTW, é preciso algum treinamento, mas depois de um tempo o jk parece mais rápido e acho que agora prefiro que escape ... Enfim, seria interessante saber se o iTerm2 também aceita <ESC> aqui.
— Neil McGill

Muito bem Apple!
— 0xc0de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.