atualizar o conteúdo alterado do arquivo aberto no vi (m)

362

Eu tenho um arquivo de configuração que mantenho aberto no vim, mas que às vezes é alterado no disco, sem que essas alterações sejam refletidas no terminal. Posso atualizar o conteúdo na tela sem fechar e reabrir o arquivo? Se sim, como?

twan163
fonte
1
Relacionado: Como recarregar todos os buffers de uma só vez? em Vim SE
kenorb
Conclusão: todas as respostas até agora são do estilo "Enquete" em vez do estilo "Push". Ou seja, em vez de receber um evento de alteração de arquivo externo, como foi feito pelos recursos similares de outros softwares, essas respostas dependem do vim pesquisar ativamente a alteração do arquivo, manualmente ou acionada por uma ação do usuário ou um temporizador. O resultado final é que você não verá as alterações atualizadas na tela instantaneamente.
Penghe Geng 01/07

Respostas:

464

Você pode usar o :editcomando, sem especificar um nome de arquivo, para recarregar o arquivo atual. Se você fez modificações no arquivo, pode usar :edit!para forçar o recarregamento do arquivo atual (você perderá as modificações).

O comando :editpode ser abreviado por :e. A edição forçada pode ser feita por:e!

Thushi
fonte
2
O "!" estava me tropeçando, mas agora está claro.
precisa saber é o seguinte
107
Nota: normalmente é abreviado para :e!.
Stéphane Chazelas
31
@StephaneChazelas: Sim, isso está correto :) @ twan163: Em vez de :edite :edit!você pode usar :ee :e!respectivamente.
Thushi 8/08/14
11
Perder modificações, sim e não. Crucialmente, você ainda pode encontrar uo :e!.
gerrit
5
Além disso, se você quiser recarregar todos os seus buffers, execute::bufdo e
pkout 4/16
193

Além de atualizar manualmente o arquivo :edit, você pode colocar em seu~/.vimrc

:set autoread

para fazer com que o Vim atualize automaticamente todos os arquivos que não foram editados pelo Vim. Veja também :checktime.

Ingo Karkat
fonte
2
Cuidado com o comprador - se você estiver trabalhando em um novo código e git pullestiver ciente de que pode perder as alterações não salvas na tela de maneira não intencional.
Azatar 16/06/16
5
@toszter Não, o Vim atualiza apenas buffers inalterados . Em caso de alterações, ainda haverá uma consulta: Manter ou carregar?
Ingo Karkat
10
NB a leitura automática não funciona exatamente automaticamente. Você precisa usar gvimou executar comandos externos.
Sparhawk
3
Aqueles que usam o vim dentro do tmux podem obter eventos de foco usando github.com/tmux-plugins/vim-tmux-focus-events . Caso contrário Autoread não vai ajudar no terminal a menos que você de alguma forma chamar:checktime
Karl Bartel
3
autoreadpode ser disparado automaticamente X segundos após o cursor parar de se mover, veja esta resposta .
Tom Hale #
57

TL; DR

Pule para o Wrap-upcabeçalho das vimrclinhas a serem adicionadas para tornar sua vida melhor.

Manualmente

Corre :checktime

Verifique se algum buffer foi alterado fora do Vim. Isso verifica e avisa se você terminaria com duas versões de um arquivo.

Automaticamente

Para carregar automaticamente as alterações, adicione vimrc:

set autoread

Quando for detectado que um arquivo foi alterado fora do Vim e não foi alterado dentro do Vim, leia-o automaticamente novamente. Quando o arquivo foi excluído, isso não é feito.

Esta resposta adiciona uma ressalva:

A leitura automática não recarrega o arquivo, a menos que você execute algo como executar um comando externo (como !lsou !shetc)

Leia sobre soluções.

Disparar quando o cursor parar de se mover

Adicione ao seu vimrc:

au CursorHold,CursorHoldI * checktime

Por padrão, CursorHold é acionado após o cursor permanecer parado por 4 segundos e é configurável via hora de atualização .

Gatilho na alteração do buffer ou no foco do terminal

Adicione o seguinte ao seu vimrcgatilho autoreadao alterar buffers enquanto estiver dentro do vim:

au FocusGained,BufEnter * :checktime

Captura do foco da janela do terminal dentro do vim comum

Para que FocusGained(veja acima) funcione no vim simples, dentro de um emulador de terminal (Xterm, tmux, etc) instale o plugin: vim-tmux-focus-events

Nas versões tmux> 1.9, você precisará adicionar .tmux.conf:

set -g focus-events on

Embrulhar

Notificações quando autoreadgatilhos também são possíveis .

Aqui estão minhas vimrclinhas para implementar todas as opções acima:

" Triger `autoread` when files changes on disk
" https://unix.stackexchange.com/questions/149209/refresh-changed-content-of-file-opened-in-vim/383044#383044
" https://vi.stackexchange.com/questions/13692/prevent-focusgained-autocmd-running-in-command-line-editing-mode
autocmd FocusGained,BufEnter,CursorHold,CursorHoldI * if mode() != 'c' | checktime | endif
" Notification after file change
" https://vi.stackexchange.com/questions/13091/autocmd-event-for-autoread
autocmd FileChangedShellPost *
  \ echohl WarningMsg | echo "File changed on disk. Buffer reloaded." | echohl None

Obrigado a ErichBSchulz por me apontar na direção certa comau CursorHold .

Tom Hale
fonte
2
excelente post! Se sente como uma daquelas coisas em que este deve ser o comportamento padrão
JonnyRaa