Como invocar o editor vim e a saída do pipe para o bash

26

Às vezes eu preciso escrever texto e depois canalizar esse texto para outro comando. Meu fluxo de trabalho usual é algo assim:

vim
# I edit and save my file as file.txt
cat file.txt | pandoc -o file.pdf # pandoc is an example 
rm file.txt

Eu acho isso complicado e procurando aprender bash scripting Eu gostaria de tornar o processo muito mais simples escrevendo um comando que abre um editor e quando o editor fecha a saída do editor para stdout. Então eu seria capaz de executar o comando como quickedit | pandoc -o file.pdf .

Não sei como isso funcionaria. Eu já escrevi uma função para automatizar isso, seguindo o fluxo de trabalho exato acima, além de algumas adições. Ele gera uma string aleatória para atuar como um nome de arquivo e passa para o vim quando a função é invocada. Quando o usuário sai do vim salvando o arquivo, a função imprime o arquivo no console e, em seguida, exclui o arquivo.

function quickedit {
    filename="$(cat /dev/urandom | env LC_CTYPE=C tr -cd 'a-f0-9' | head -c 32)"
    vim $filename
    cat $filename
    rm $filename
}
# The problem:
# => Vim: Warning: Output is not to a terminal

O problema que eu logo encontrei é que quando eu faço algo como quickedit | command vim em si não pode ser usado como um editor porque toda a saída é restrita ao pipe.

Eu estou querendo saber se há alguma solução alternativa para isso, para que eu pudesse canalizar a saída da minha função quickedit . A alternativa sub-ótima é abrir um editor separado, digamos um texto sublime, mas eu realmente quero ficar no terminal.

    
por theideasmith 10.05.2016 / 23:29

4 respostas

34

vipe é um programa para edição de pipelines:

command1 | vipe | command2

Você obtém um editor com a saída completa de command1 e, quando você sai, o conteúdo é passado para command2 pelo canal.

Nesse caso, não há command1 . Então, você poderia fazer:

: | vipe | pandoc -o foo.pdf

Ou:

vipe <&- | pandoc -o foo.pdf

vipe pega as variáveis EDITOR e VISUAL , então você pode usá-las para abrir o Vim.

Se você não instalou, vipe está disponível no pacote moreutils ; sudo apt-get install moreutils , ou seja qual for o seu equivalente ao sabor.

    
por 11.05.2016 / 01:00
20

Você pode fazer isso de dentro do Vim:

:w !pandoc -o file.pdf

Ou até mesmo escreva o buffer em um pipeline complexo:

:w !grep pattern | somecommand > file.txt

E então você pode sair do Vim sem salvar:

:q!

No entanto, considerando seu caso de uso específico, provavelmente há uma solução melhor usando vi como seu editor de linha de comando. Supondo que você use bash :

set -o vi

Isso define suas combinações de teclas como vi . Assim, você pode editar seus comandos diretamente na linha de comando com atalhos de teclado vi pressionando <Esc> e digitando vi comandos como x , cw , etc. (Você pode voltar no modo de inserção pressionando i .)

Melhor ainda, e mais relevante para esta questão, você pode abrir o Vim para criar seu conteúdo de linha de comando diretamente. Basta digitar <Esc>v e você receberá um buffer Vim vazio. Quando você salva e sai, esse é o comando em sua linha de comando e é imediatamente executado. Isso é muito mais flexível do que editar diretamente na linha de comando, já que você pode escrever um mini-script inteiro, se quiser.

Então, por exemplo, se você quiser escrever algum texto complicado e colocá-lo em pandoc imediatamente, você pode simplesmente digitar:

<Esc>v

Em seguida, edite o buffer do Vim até ter algo como:

cat <<EOF | pandoc -o file.pdf
stuff for pandoc
more stuff for pandoc
EOF

Em seguida, salve e saia (com :x ) e a coisa toda será executada como um comando shell.

Ele também estará disponível no histórico de comandos do seu shell.

    
por 11.05.2016 / 00:49
15

Executando em um pipeline

Tente:

quickedit() (  trap 'rm ~/temp$$' exit; vim ~/temp$$ >/dev/tty; cat ~/temp$$ )

A chave é que, para poder usar vim normalmente, vim precisa de stdout para ser o terminal. Nós conseguimos isso aqui com o redirecionamento >/dev/tty .

Para fins de segurança, eu coloco o arquivo temporário no diretório pessoal do usuário. Para mais informações, acesse Perguntas frequentes de Greg, Pergunta 062 . Isso elimina a necessidade de usar um nome de arquivo obscuro.

Exemplo:

Quando vim for aberto, eu digito This function succeeded. e salve o arquivo. O resultado na tela se parece com:

$ quickedit | grep succeeded
This function succeeded.

Mesmo que a saída de quickedit seja redirecionada para um pipeline, vim ainda funciona normalmente porque fornecemos acesso direto a /dev/tty .

Executando um programa dentro do vim

Como mencionei nos comentários, o vim pode enviar um arquivo para um comando. De dentro do vim, por exemplo, emita o comando :w !pandoc -o file.pdf (Nota: o espaço entre w e! É essencial).

    
por 10.05.2016 / 23:58
5

Certifique-se de que vim esteja definido como seu editor padrão (por exemplo, export EDITOR=vim no seu .bash_profile ou .bashrc . Então, em qualquer prompt, você pode digitar Ctrl - X seguido por Ctrl - E . Isto irá abrir a sua linha de comandos atual no seu editor configurado (ex. vim ). Faça as suas edições, salve e exit, e o comando será executado como se você tivesse digitado na linha de comando, incluindo pipelines e afins.

    
por 11.05.2016 / 00:40

Tags