Recarga automática de un archivo en VIM tan pronto como cambie en el disco


33

Suponiendo que un archivo no tiene cambios no guardados en el búfer VIM, me gustaría que se vuelva a cargar automáticamente si el archivo cambia en el disco. El caso de uso más frecuente para esto es cuando actualizo la copia de trabajo en la que reside el archivo.

¿Cómo puedo conseguir esto?


Creo que esto es lo que quieres decir, pero mi caso de uso específico es cuando reviso una rama o commit de git diferente, quiero que vim vuelva a cargar el archivo.
Nathan Long

Respuestas:


32

En su ~/.vimrc:

set autoread

99
En general autoread, solo se activará después de ejecutar un comando externo. Esta respuesta detalla las soluciones.
Tom Hale

Esto no funciona Siga el enlace @TomHale para obtener una respuesta detallada que sí lo hace
JonnyRaa

11

Esto es lo que funcionó para mí.

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

La primera línea no era suficiente por sí sola. Puedes poner en ti.vimrc

crédito a Phan Hai Quang


El autocmd no debería ser necesario: se supone que checktime se ejecuta internamente al mismo tiempo que se activa el evento CursorHold. En otras palabras, solo estás haciendo que Vim haga un segundo control.
Heptita

Para mi es necesario. La mejor solución que he encontrado después de mucha investigación. @Heptite, ¿tienes capítulo y versículo para tu afirmación?
Tom Hale

1
@TomHale He revisado los documentos de Vim y no dice explícitamente, por lo que puedo decir, pero " :help timestamp" parece indicar que soy el que está equivocado, y que Vim solo realiza la verificación de eventos específicos, por lo tanto, el autocmd podría ser necesario para que se verifique con más frecuencia
Heptita

5

La lectura automática no funciona correctamente. Lo siguiente funciona para mí:

Primero debe instalar el script desde aquí .

Obtuve los mejores resultados llamando directamente a la función de configuración, así.

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

La razón de esto es que quiero ejecutar una configuración de ipython / screen / vim.

Puede convertir esto fácilmente en una versión mejorada de la vista.

guión del proceso ..

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
Si está utilizando una de las GUI de vim, como gVim o MacVim, el comando autoread se integra bien con el resto del entorno. Por ejemplo, editar el archivo en algún otro programa, otro editor o desde el control de origen, luego volver a vim leerá automáticamente los archivos actualizados. El problema parece estar en cómo se integra la versión terminal de vim. La versión del terminal no puede indicar cuándo cambia entre programas en la GUI o usando multiplexores de terminal como tmux, por lo que no se puede leer automáticamente en los momentos relevantes. Sería bueno que vim se suscribiera a eventos relevantes del sistema de archivos.
bames53

3

El complemento vim-autoread me ha funcionado hasta ahora:

vim-autoread

Hace que vim vuelva a cargar automáticamente los archivos que se han escrito en el disco pero que no se han modificado en el búfer desde la última escritura desde vim. Esto permite editar un archivo abierto en vim usando otra aplicación y guardarlo. Al regresar a vim, siempre que no haya modificado el archivo desde el último cambio, el archivo se actualizará automáticamente para reflejar los cambios realizados en el disco, como si hubiera presionado: e manualmente.


Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden volverse inválidas si la página vinculada cambia. - De la opinión
Burgi

@ Burgi He agregado la descripción del complemento que explica cómo resuelve el problema.
Wojtek Kruszewski

Lo intenté pero tengo que escribir un comando de navegación (como j) para ver la actualización efectiva. Creé
Martin Delille

3

de esta respuesta (refiriéndose a una respuesta de PhanHaiQuang y un comentario de @flukus)

Uno puede ejecutar este oneliner desde ex (dentro de vim) cuando sea necesario (o poner cada comando en vimrc, para cuando se abren los archivos de registro).

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

Explicación:
- autoread : lee el archivo cuando se cambia desde el exterior (pero no funciona por sí solo, no hay un temporizador interno o algo así. Solo leerá el archivo cuando vim realice una acción, como un comando en ex :!
- CursorHold * checktime : cuando el usuario no mueve el cursor durante el tiempo especificado en 'updatetime' (que es 4000 milisegundos por defecto) se ejecuta checktime, que verifica los cambios desde fuera del archivo
- llame a las teclas de alimentación ("lh") : el cursor se mueve una vez, hacia la derecha y hacia la izquierda, y luego no pasa nada (... lo que significa que se activa CursorHold, lo que significa que tenemos un bucle )


lhno hace nada, si el cursor está en la última posición de la línea, lhcambiará su ubicación.
Mahmoud Al-Qudsi

Exactamente, ese es el punto. El archivo se vuelve a cargar con el mínimo de interacción o cambios en el archivo. Puede saltar a la última o primera línea si lo desea (solo reemplace lh con gg o G), pero el objetivo aquí es simplemente volver a cargar el archivo en vim, y eso es lo que se hace con esta línea, nada más. ¿Qué te gusta hacer aquí?
eli

@ MahmoudAl-Qudsi ... lo que significa que "lh" solo activa el CursorHold - acción (mencioné eso en la Explicación), que luego activa nuevamente la lectura automática
eli

1

Hay algunos complementos enumerados aquí que pueden funcionar dependiendo de su versión de Vim.

Otro enfoque es enviar periódicamente el checktimecomando a vim desde un proceso externo. Aquí hay un script de ShellJS para hacer esto (requiere shelljs-plugin-sleep, NeoVim y 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}`) );
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.