Atualização 25/06/2015 :
- Eu descartei o método "shell", pois era muito disfuncional. Parou o modo de inserção e deixou os processos zumbis. Veja o histórico de revisões deste post e você realmente deseja vê-lo de qualquer maneira.
- Eu criei um plugin com isso: auto_autoread.vim . No momento, é efetivamente o mesmo que o código abaixo, mas eu recomendo que você use o plug-in, pois é provável que ele receba atualizações.
O que autoread
faz?
Para responder a essa pergunta, precisamos primeiro entender o que a autoread
opção faz e, mais importante, o que ela não faz.
Infelizmente :help 'autoread'
, não há muitas informações sobre isso, apenas diz que "um arquivo foi detectado como alterado fora do Vim" . Como o Vim detecta que um arquivo foi alterado? Em determinadas ações, o Vim verifica a hora da modificação do arquivo.
Quando:
:checktime
é usado;
- um buffer é inserido;
:diffupdate
é usado;
:e
é emitido para um arquivo que já possui um buffer;
- executando um comando externo com
!
;
- retornando para o primeiro plano (
^Z
, fg
, somente se o shell tem controle de trabalho);
para o gVim, isso também é feito quando:
- fechar o menu "clique com o botão direito" (selecionando algo ou apenas fechando);
- o foco é alterado (é isso que você já percebeu);
- fechando a caixa de diálogo dos navegadores de arquivos exibida se você usar "arquivo -> abrir", "arquivo -> salvar como" no menu (assim como em outros locais).
Reuni essas informações da fonte Vim, localizando todas as chamadas para
buf_check_timestamp()
, check_timestamps()
funções e locais em que
need_check_timestamps
está definido TRUE
.
Posso ter perdido alguns eventos, mas o principal a lembrar é que o Vim apenas verifica se o arquivo foi modificado em um conjunto muito limitado de circunstâncias . Certamente não "pesquisa" o arquivo em busca de alterações a cada n segundos, que é basicamente o que você procura .
Portanto, para o seu propósito, set autoread
não é suficiente.
Usando Python
Isso programa um thread Python para ser executado em segundo plano; ele será executado a
:checktime
cada n segundos. Se autoread
estiver ativado , isso recarregará o buffer do disco, caso contrário, apenas avisará.
Isto requer que Vim tem +python
ou +python3
em :version
. Ele deve funcionar em todas as plataformas (incluindo Windows).
fun! AutoreadPython()
python << EOF
import time, vim
try: import thread
except ImportError: import _thread as thread # Py3
def autoread():
vim.command('checktime') # Run the 'checktime' command
vim.command('redraw') # Actually update the display
def autoread_loop():
while True:
time.sleep(1)
autoread()
thread.start_new_thread(autoread_loop, ())
EOF
endfun
Você pode iniciar isso usando :call AutoreadPython()
; é claro que você pode fazer isso em um autocmd; por exemplo:
autocmd *.c call AutoreadPython()
Posfácio
Na verdade, existem mais métodos, por exemplo, você pode usar uma ferramenta como
entr
o Python inotify
ou o gamin
módulo para monitorar um arquivo em busca de alterações, :checktime
também verifica todos os buffers se não houver argumentos, isso pode ser aprimorado apenas com a verificação de um único buffer ou um determinado arquivo.
No entanto, essa resposta já é bastante longa :-) Esse método deve (espero!) Funcionar bem para a maioria dos cenários ou deve ser facilmente adaptável ao seu cenário.
PS. Também tentei usar o Ruby, mas infelizmente os threads do Ruby (usando Thread
) não são executados em segundo plano como o Python, então não pude fazer isso funcionar (talvez haja outra maneira?)
CursorHold
evento? Se o Vim não tiver foco, ele deve ser acionado a cada n segundos.