Recarregar automaticamente um arquivo no VIM assim que ele muda no disco


32

Supondo que um arquivo não tenha alterações não salvas no buffer do VIM, eu gostaria que ele fosse recarregado automaticamente se o arquivo mudar no disco. O caso de uso mais frequente é quando eu atualizo a cópia de trabalho na qual o arquivo reside.

Como posso conseguir isso?


Eu acho que é isso que você quer dizer, mas meu caso de uso específico é quando eu checo uma ramificação git diferente ou confirmamos, quero que o vim recarregue o arquivo.
Nathan Long

Respostas:



11

Isto é o que funcionou para mim

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

A primeira linha não foi suficiente por si só. Você pode colocar em você.vimrc

crédito para Phan Hai Quang


O autocmd não deve ser necessário - o horário da verificação deve ser executado internamente, ao mesmo tempo em que o evento CursorHold é acionado. Em outras palavras, você está apenas fazendo o Vim fazer uma segunda verificação.
Heptite

Para mim é necessário. Melhor solução que encontrei após muitas pesquisas. @ Heptite, você tem capítulo e verso para sua afirmação?
Tom Hale #

1
@TomHale Analisei os documentos do Vim e ele não diz explicitamente, tanto quanto posso dizer, mas " :help timestamp" parece indicar que eu estou com erro e que o Vim realiza apenas a verificação de eventos específicos, portanto, o autocmd pode ser necessário para fazer a verificação com mais frequência.
Heptite 01/08/19

5

A leitura automática não funciona corretamente. O seguinte funciona para mim:

Você precisa primeiro instalar o script a partir daqui .

Eu obtive os melhores resultados chamando a função de instalação diretamente, assim.

let autoreadargs={'autoread':1} 
execute WatchForChanges("*",autoreadargs) 

A razão para isso é que desejo executar uma instalação ipython / screen / vim.

Você pode facilmente converter isso em uma versão aprimorada da visualização.

script do processo ..

mkdir -p ~/bin
cat <<`OUT` > ~/bin/vimviewer
#!/usr/bin/env sh
exec vim -n --cmd "source /home/bryan/.vim/.vimrc.watchforchanges | let autoreadargs={'autoread':1} | execute WatchForChanges('*',autoreadargs)" $@
`OUT`

chmod 755 ~/bin/vimviewer
vimview test.txt

1
Se você estiver usando uma das GUIs do vim, como gVim ou MacVim, o comando autoread se integra perfeitamente ao restante do ambiente. Por exemplo, editar o arquivo em algum outro programa, outro editor ou no controle de origem, e retornar ao vim, lerá automaticamente os arquivos atualizados. O problema parece estar com a integração da versão terminal do vim. A versão do terminal não pode saber quando você alterna entre programas na GUI ou usa multiplexadores de terminal como o tmux, portanto, falha na leitura automática em momentos relevantes. Seria bom se o vim se inscrevesse apenas nos eventos relevantes do sistema de arquivos.
bames53

3

O plugin vim-autoread funcionou para mim até agora:

vim-autoread

Faz com que o vim recarregue automaticamente os arquivos que foram gravados no disco, mas não modificados no buffer desde a última gravação do vim. Isso permite que um arquivo aberto no vim seja editado usando outro aplicativo e salvo. Ao retornar ao vim, desde que você não tenha modificado o arquivo desde a última alteração, o arquivo será atualizado automaticamente para refletir as alterações feitas no disco, como se você tivesse pressionado: e manualmente.


Embora esse link possa responder à pergunta, é melhor incluir aqui as partes essenciais da resposta e fornecer o link para referência. As respostas somente para links podem se tornar inválidas se a página vinculada for alterada. - Da avaliação
Burgi

@Burgi Adicionei uma descrição do plugin que explica como ele resolve o problema.
Wojtek Kruszewski 5/05

Eu tentei, mas tenho que digitar um comando de navegação (como j) para ver a atualização efetiva. Eu criei um problema aqui sobre isso: github.com/djoshea/vim-autoread/issues/3
Martin Delille

3

desta resposta (consultando uma resposta de PhanHaiQuang e um comentário de @flukus)

Pode-se executar este oneliner a partir de ex (dentro do vim) quando necessário (ou colocar cada comando no vimrc, para quando os arquivos de log forem abertos.)

:set autoread | au CursorHold * checktime | call feedkeys("lh")

Explicação:
- autoread : lê o arquivo quando alterado do lado de fora (mas não funciona por si só, não há cronômetro interno ou algo assim. Ele só lerá o arquivo quando o vim executar uma ação, como um comando ex :!
- CursorHold * checktime : quando o cursor não é movido pelo usuário pelo tempo especificado em 'updatetime' (que é de 4000 milissegundos por padrão), o checktime é executado, que verifica alterações fora do arquivo
- chame feedkeys ("lh") : o cursor é movido uma vez, direita e volta à esquerda ... e então nada acontece (... o que significa que o CursorHold é acionado, o que significa que temos um loop )


lhnão faz nada, se o cursor estiver na última posição da linha, lhele mudará sua localização.
Mahmoud Al-Qudsi

Exatamente, esse é o ponto. O arquivo é recarregado com o mínimo de interação ou alterações no arquivo. Você pode pular para a última ou primeira linha, se quiser (basta substituir lh por gg ou G), mas o objetivo aqui é apenas recarregar o arquivo no vim, e é isso que é feito por essa linha única, nada mais. O que você gosta de fazer aqui?
eli

@ MahmoudAl-Qudsi ... ou seja, que "lh" apenas desencadeia a CursorHold - ação (eu mencionei que na explicação), que, em seguida, novamente aciona o Autoread
eli

1

Existem alguns plugins listados aqui que podem funcionar dependendo da sua versão do Vim.

Outra abordagem é enviar periodicamente o checktimecomando ao vim a partir de um processo externo. Aqui está um script ShellJS para fazer isso (requer shelljs-plugin-sleepNeoVim e nvr)

while (true) {
  sleep(15);
  var servernames = exec('nvr --serverlist').trim().split('\n');
  if (!servernames.length || !servernames[0]) {
    continue;
  }
  servernames.forEach(
    (sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}
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.