Como eu passaria o conteúdo de um registrador Vim para um script externo?

1

Essencialmente eu quero criar um operador em um script Vim que envie o texto selecionado para um script externo (Python). Ele deve se comportar como um normalmente esperaria um operador, se o texto é selecionado no modo visual ou usando um movimento. Isso se mostrou mais difícil para mim do que eu esperava, e uma limitação divertida é que o operador precisa trabalhar nas versões do Vim de 6.3 para 7.0. Estou usando a versão de console do Vim, em vez do GVim, pois é mais fácil para meu fluxo de trabalho pessoal.

Minha motivação: Eu quero copiar texto para a área de transferência do sistema do Vim (sem usar o mouse), para que eu possa colá-lo em outra guia do terminal. Frustrantemente, nos sistemas com os quais eu trabalho, o Vim foi compilado sem suporte à área de transferência, então os registros "+ e" * não me ajudarão. É bastante fácil juntar um script Python rápido para colocar texto arbitrário na área de transferência, mas o problema é passar o texto para o script do Vim.

O que eu tentei: Meu primeiro pensamento foi arrancar o texto, criar um novo buffer, colocar o texto lá, salvá-lo como um arquivo em / tmp e executar um comando como "cat / tmp / stuff | clipboard.py" da função. Mais especificamente: usei let scratchFile = system("mktemp") para criar um arquivo temporário, badd para adicionar o arquivo como um buffer e buffer para alternar para o novo buffer. Em seguida, coloco o texto em que estou operando no buffer, escrevo-o e, em seguida, faço silent execute "!cat % | clipboard.py" seguido por bd para me livrar do buffer. Isso realmente não funciona. (Isso estraga a maneira como o Vim desenha o conteúdo do arquivo original na tela, de modo que eu tenho que destacar o arquivo no modo Visual para fazer com que o texto apareça novamente. :redraw não corrige o problema.)

Existe uma abordagem melhor para resolver este problema?

Editar para adicionar meu script em andamento:

nnoremap <C-y> :set operatorfunc=<SID>CopyClipboard<cr>g@
vnoremap <C-y> :<c-u>call <SID>CopyClipboard(visualmode())<cr>

function! s:CopyClipboard(type)
    let saved_register = @@

    if a:type ==? 'v'
        normal! '<v'>y
        let scratchFile = system("mktemp")
        execute "badd " . scratchFile
        execute "buffer " . scratchFile
        normal! P
        write
        silent execute "!cat % | clipboard.py"
        execute "bd! " . scratchFile
    elseif a:type ==# 'char'
        normal! '[v']y
    else
        return
    endif

    let @@ = saved_register
endfunction
    
por user108471 07.12.2011 / 03:00

2 respostas

1

:buffer abrirá um novo arquivo temporário em vez do buffer atual. Use a função writefile() . Também pode ajudar com os problemas de redesenho.

    
por 08.12.2011 / 10:46
0

Eu diria que há mais de uma maneira "certa" de fazer isso, mas suas etapas podem ser simplificadas, dependendo da sua implementação.

Primeiro, você pode gravar diretamente um intervalo de texto em um arquivo sem precisar: badd it. Se você tiver texto visualmente selecionado, basta pressionar: e ele irá inserir automaticamente o intervalo apropriado para você. Continue digitando " w somefile ". O Vim gravará no arquivo (criando-o, se necessário) apenas as linhas especificadas pelo intervalo para esse arquivo. Então você pode enviar o texto para o seu programa externo.

Em segundo lugar, você pode até escrever texto diretamente em um pipe, em vez de gravar em um arquivo e, em seguida, chamar um comando usando " :w !command ". (Não se esqueça do seu alcance, quando necessário.)

Essas duas opções, no entanto, terão problemas com a manipulação de linhas completas do Vim, em vez de parcial, em intervalos na linha: -command que você provavelmente encontrará, além do fato de que não cobrirá (facilmente) todos de seus casos de uso declarados e implícitos, então eu diria que sua abordagem original pode ser mais apropriada. Sem ver sua implementação real, não consigo encontrar uma razão sólida para explicar o que está acontecendo com a apresentação de Vim - tenho ideias, mas elas são mais difíceis de explicar de maneira abstrata do que se houvesse exemplos para trabalhar.

    
por 07.12.2011 / 06:24