Defina a opção de colar, mas apenas para uma inserção

16

Quero ter uma maneira rápida de definir a 'paste'opção Vim , inserir algum texto e reverter para o valor anterior de 'paste'.

Um caso de uso típico insere o conteúdo da área de transferência do SO literalmente, independentemente de qualquer reescrita no modo de inserção que possa estar ativa, como recuo automático e sem alterar o estado do Vim. Outro caso de uso seria permitir que um recurso de macro do SO injete pressionamentos de tecla no Vim e os interprete como texto literal.

Obviamente, isso generaliza para outras opções - a idéia geral é definir algumas opções, mas apenas pela duração de uma viagem pelo modo de inserção.

Basicamente, quero vincular uma sequência de teclas (por exemplo _i) a uma macro que faz isso

:set paste
i…<Esc>
:set nopaste

onde, com i…<Esc>isso, mude para o modo de inserção (como no icomando) e retome a macro ao retornar ao modo de comando, exceto que eu quero terminar com o 'paste'ativo ainda, se estiver ativo anteriormente. Como posso fazer isso?

Nota: O conteúdo da área de transferência do SO é mapeado para o "*registro . Quando isso funciona, a 'paste'opção não é muito útil. O cenário motivador para esta pergunta é para aqueles momentos em que as condições para "*suporte ao registro não são atendidas - o Vim não é compilado com o +xterm_clipboardrecurso ou está sendo executado em um terminal como Screen ou SSH que o isola do servidor X ambiente.

Gilles 'SO- parar de ser mau'
fonte
1
Gosto da sua pergunta (já estive lá muitas vezes). No entanto, não é mais fácil colar do +ou *registrar?
yo '
@yo ' Somente quando eles trabalham . O que, para meus usos do Vim, geralmente não é o caso.
Gilles 'SO- stop be evil'

Respostas:

15

Faça uma tentativa:

function! Paste_Func()
    let s:inPaste = &paste
    if !s:inPaste
        set paste
    endif

    echom s:inPaste
    augroup paste_callback
        autocmd!
        autocmd InsertLeave <buffer> call Paste_End()
    augroup END

    startinsert
endfunction

function! Paste_End()
    augroup paste_callback
        autocmd!
    augroup END
    augroup! paste_callback

    if !s:inPaste
        set nopaste
    endif
endfunction

map _i :call Paste_Func()<cr>

Ele armazena o status atual da pasta na variável inPaste e define a pasta, se ainda não estiver definida. Em seguida, ele configura um autocmd para quando você sai do modo de inserção e o coloca no modo de inserção.

Quando você sai do modo de inserção, ele executa o autocmd, que primeiro remove o autocmd (para que ele não seja executado quando você sai do modo de inserção de qualquer outra maneira) e finalmente define nopaste se você não estava no modo de colar originalmente.

Além disso, se você estiver usando o vim em um terminal, poderá dar uma olhada no vim-bracketed-paste , que usa o recurso de modo de pasta entre colchetes fornecido por vários emuladores de terminal para detectar se você está colando e definir o modo automaticamente.

Editar: corrigido o script

Chade
fonte
Isso parece estar no caminho certo (em particular, eu não tinha ideia de como "colocar um colchete" em um trecho de inserção pelos comandos normais do mundo). Obrigado. No entanto, não está certo e não vejo onde está o problema: depois _i, a pasteopção está desativada, mesmo que estivesse antes.
Gilles 'SO- stop be evil'
Você está certo! Tenho certeza de que havia testado isso, mas devo ter mudado alguma coisa. Eu atualizei o script no post, veja se ele está funcionando para você agora.
Chad
4

exceto que eu quero acabar com o 'paste'ativo ainda, se estiver ativo anteriormente.

'paste'deve estar ativo pelo menor tempo possível. Ele desabilita muitas funcionalidades (incluindo mapas), porque seu único objetivo é evitar interpretar mal o texto que está sendo colado. Como tal, acho que o requisito citado não deveria ser realmente necessário.

Dito isto, é realmente muito fácil colar sem a necessidade de definir 'paste'. Se você estiver executando o gvim ou o +xterm_clipboardconsole vim, poderá simplesmente "+pcolar na área de transferência do sistema operacional.

O problema da indentação automática durante a colagem ocorre apenas em dois cenários. Inserir o conteúdo de um registro enquanto estiver no modo de inserção ( <C-r>+) ou clique com o botão do meio do mouse para colar.

Em vez de inserir o conteúdo de um registro enquanto estiver no modo de inserção, colar do registro no modo normal evitará o problema de reformatação.

Se você deseja clicar com o botão do meio e colar com o mouse, use a 'mouse'opção para permitir que o Vim, em vez do terminal, manipule o clique do meio. O Vim irá inserir o conteúdo literalmente, em vez de interpretar o texto recebido como sendo digitado.

jamessan
fonte
2
Nada disso responde à minha pergunta. Coloquei requisitos explícitos por um motivo! Geralmente, de 'paste'fato, não está ativo de antemão, mas não quero ter que pensar sobre isso. Costumo trabalhar em um Vim que não tem acesso à área de transferência ou mouse do X, porque meu build do Vim não possui o xterm_clipboardrecurso ou porque estou trabalhando, por exemplo, em uma sessão de tela que está atualmente anexada a um Terminal X.
Gilles 'SO- stop be evil'
@Gilles Então você poderia explicar como está colando? São informações relevantes para poder fornecer uma resposta que possa envolver essa ação com o que você deseja fazer.
jamessan
1
Meu caso de uso básico é colar com o botão do meio do mouse ou com Shift + Insert. Isso não é realmente relevante: o núcleo da questão é como definir uma opção, alternar para o modo de inserção (com i, não estou perguntando como parametrizar isso) e restaurar o valor da opção ao retornar do modo de inserção.
Gilles 'SO- stop be evil'
1
@ Gilles O núcleo da sua pergunta, conforme indicado neste comentário, é muito mais claro para mim do que a sua pergunta original. Obrigado.
jamessan
1
@Gilles Não é relevante para você , mas pode ser relevante para futuros visitantes. Portanto, você pode colocá-lo na própria pergunta ("Eu sei que posso usar "*pou "+pcolar nas pranchetas, mas não quero usar as habilidades de colar do sistema") e, em seguida, essa resposta é desnecessária. Ou não, e então acho que essa resposta tem seu lugar aqui.
yo '
4

Pessoalmente, uso a yocombinação de teclas do excelente plug - in sem problemas de Tim Pope por exatamente esse motivo. De sua documentação:

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 yoou yOpara chamar |o|ou |O|com 'colar' já definido. Sair do modo de inserção define 'nopaste' automaticamente.

Pode ser um exagero instalar o plug-in simplesmente para sua pergunta, mas acho que ele também fornece uma variedade de outras combinações de teclas úteis (mais informações no README ).

Andrew Ferrier
fonte
1

Com o Vim 8+ no Linux ou Mac, agora você pode simplesmente usar a pasta nativa do terminal (por exemplo, botão do meio do mouse, ctrl+shift+Vno Gnome, cmd+Vno Mac) se o terminal suportar pasta entre colchetes. Não pressione ipara inserir o modo.

Ele colará o conteúdo da área de transferência do sistema operacional, preservando os espaços e as guias sem adicionar a inserção automática. É equivalente ao velho :set paste, i, ctrl+shift+V, esc, :set nopastemétodo.

Você nem precisa mais dos recursos +clipboardou do +xterm_clipboardvim instalados. Esse recurso é chamado de "pasta entre colchetes". Para obter mais detalhes, consulte /programming/2514445/turning-off-auto-indent-when-pasting-text-into-vim/56781763#56781763

wisbucky
fonte