Como executar comandos shell dentro do Vim como Gary Bernhardt faz em seus screencasts?

Dec 13 2020

Estou assistindo os screencasts de Destroy All Software, de Gary Bernhardt , especificamente A Compiler from Scratch . Lá, ele executa comandos de shell sem sair do Vim. Estou quase certo de que ele está apenas usando a sintaxe normal do Vim, por exemplo, sobre a marca de 1 minuto: :!chmod u+x compiler.rb. Se eu fizer isso no meu computador, a janela mudará para executar o comando shell e, em seguida, tenho que pressionar Enter para voltar ao editor. Esse é, eu acho, o comportamento normal do Vim, e outras pessoas já perguntaram isso antes, mas não acho que nenhuma resposta faça as coisas da maneira que Gary faz.

Olhei para o .vimrcarquivo dele , especificamente a última versão antes do upload do screencast, mas não consegui descobrir o que ele pode ter alterado para obter o comportamento que procuro. Eu baixei, mas ainda não estou obtendo o comportamento certo, então obviamente estou faltando alguma coisa. Nenhum de seus plug-ins parece estar relacionado a isso, então geralmente os ignorei.

Tenho quase certeza que eu não estou procurando uma solução que usa tmux, ou coisas, como :split, :term, :below terminal, ou :silent. Nem estou procurando uma resposta que use algo diferente do Vim, acredito que Gary está apenas usando o Vim e alguns plug-ins.

Eu assisti aos screencasts de Gary onde ele fala especificamente sobre o Vim, mas ele não respondeu a essa pergunta (ou eu não entendi), então se alguém descobriu como usar :! <shell command>sem sair do editor de texto, eu realmente apreciaria se você pode me ajudar a resolver isso. Eu testei as opções que mencionei antes no Mac e no Linux, mas nada funcionou como eu gostaria, e ficaria feliz com uma solução que funcione em qualquer plataforma.

Respostas

3 filbranden Dec 13 2020 at 12:02

O vídeo passa rápido, mas eu pausei e parece que o vi digitar o seguinte:

:!chmod u+x %

O que então produz esta saída:

:!chmod u+x compiler.rb
[No write since last change]
"compiler.rb" 5L, 42C
Press ENTER or type command to continue

Então, na verdade, Vim faz alerta para "pressionar ENTER" depois que o comando está completo, mas parece que ele apertou-a tão rapidamente (talvez ele estava esperando por isso já? Ou talvez ele começou pressionando os seguintes comandos?) Que parece que a mensagem foi pulado.

Existem duas configurações que são relevantes aqui, a primeira para evitar a mudança da tela alternativa durante a execução do comando e a segunda para recarregar automaticamente o arquivo assim que ele for alterado pelo comando externo (embora apenas as permissões tenham mudado).

Olhando para o repositório de dotfiles do GitHub, podemos ver as duas configurações no vimrc em 29/06/2017 (que é quando o vídeo foi publicado).

  1. Configurar o Vim para não mudar da tela alternativa é configurado com este trecho :
" Prevent Vim from clobbering the scrollback buffer. See
" http://www.shallowsky.com/linux/noaltscreen.html
set t_ti= t_te=
  1. Configurando o Vim para recarregar automaticamente o arquivo após uma operação externa ser feita com esta configuração :
set autoread

Com essas duas configurações ativadas, posso reproduzir quase exatamente o mesmo efeito, exceto que não recebo a [No write since last change]mensagem. Não tenho muita certeza de onde está vindo, já que pelo que posso dizer, ele acabou de escrever o arquivo antes do chmodcomando. (Como evidência, a linha de status não mostra um [+]próximo ao nome do arquivo, o que denotaria um buffer que foi modificado.)

Talvez seja outra coisa de seu vimrc ... Em teoria, deveria ser possível obtê-lo no GitHub e tentar o mesmo. Parece que o vídeo está usando o Vim 7.4, então isso também pode fazer parte.

Ainda olhando para seu repositório dotfiles do GitHub, parece que ele voltou a permitir que o Vim destruísse o buffer de rolagem , então ele mudou de ideia sobre essa parte.

Se essa parte ainda interessar a você, você pode dar uma olhada no plug-in vim-altscreen , que implementa esse comportamento, com alguns controles em torno dele. Veja também a discussão sobre a questão "Diferença entre :!{cmd}e em :w !{cmd}relação à tela alternativa" , em particular a resposta excepcional de @ user938271 .