¿Cómo puedo ejecutar un autocmd cuando inicio Vim sin archivo, un archivo no existente o un archivo en blanco (pero no cuando empiezo con un archivo existente)?

11

Me gustaría ejecutar un autocmd en los siguientes escenarios cuando inicio Vim:

  • Sin nombre de archivo especificado.
  • Cuando el archivo es nuevo.
  • Cuando el archivo existe pero está completamente en blanco.

En todos los tres casos anteriores, me gustaría ejecutar un autocmd; específicamente, me gustaría comenzar el modo de inserción automáticamente solo para los escenarios anteriores (y no cuando estoy abriendo un archivo que ya existe y no está en blanco).


ACTUALIZAR:

Intenté colocar lo siguiente en mi _vimrc, pero no tuve suerte (además, no estoy seguro de si hay una función en vim que cuente el número de caracteres en un archivo (para ver si es cero) antes de abrirlo:

if @% == "" || filereadable(@%)
  autocmd BufRead,BufNewFile * startinsert
endif
John Sonderson
fuente
No, esto no es un duplicado. Quiero que vi comience en modo de inserción SOLO PARA LOS TRES ESCENARIOS QUE HE MENCIONADO.
John Sonderson
3
OK, LO SIENTO, PERO REALMENTE PARECÍA COMO UN DUPLICADO. ;-) He editado su pregunta un poco para aclarar las diferencias.
Martin Tournoij
2
@JohnSonderson el primer enlace le dice cómo encontrar si no se proporciona un nombre de archivo, el segundo se puede adaptar usando en normallugar de exec.
muru
1
El archivo vimrc se lee solo una vez : cuando se inicia Vim. El contenido de autocmd se ejecuta cada vez que se activa. Por lo tanto, la ifdeclaración no debe estar alrededor del autocmd, si debe estar dentro del autocmd, por lo que se ejecutará cada vez que se active el autocmd.
Martin Tournoij

Respuestas:

10

Esto funciona para los 3 de sus casos para mí:

function InsertIfEmpty()
    if @% == ""
        " No filename for current buffer
        startinsert
    elseif filereadable(@%) == 0
        " File doesn't exist yet
        startinsert
    elseif line('$') == 1 && col('$') == 1
        " File is empty
        startinsert
    endif
endfunction

au VimEnter * call InsertIfEmpty()

Probablemente, esto podría condensarse en la última verificación de un archivo que está vacío, ya que ningún nombre de archivo o un archivo que no existe generalmente comienzan como buffers vacíos. Sin embargo, es probable que algún otro complemento complete previamente algunas cosas en uno de los primeros dos casos (como algunos complementos de plantilla), por lo que es mejor verificar los tres.

La primera prueba que ya te hiciste.

La segunda prueba necesita verificar filereadablecontra el valor de cero (no existe) para decidir si es nuevo (opuesto a lo que tenía).

La última prueba verifica que el número de la última línea en el archivo es 1 (que también es la primera línea, lo que significa que solo hay una línea), y que el número de columna del final de la línea (columna después del último carácter en la línea) es 1, lo que significa que hay 0 caracteres. Si solo hay 1 línea con 0 caracteres, el archivo debe estar vacío.

Una nota final: la forma en que tiene sus declaraciones en la pregunta puede dar algunos resultados sorprendentes. Es decir, está configurando BufReady BufNewFilesolo si se cumplen las condiciones al inicio, pero esos comandos automáticos existen para el resto de su sesión. Entonces, si tuviera que comenzar en un archivo vacío, que establece estos comandos, cada archivo subsiguiente abierto (nuevo o no, vacío o no) comenzaría en modo de inserción.

El autocomando VimEnterse ejecuta al final del inicio de Vim y solo una vez durante toda la sesión. De esta manera, sus pruebas solo se ejecutan cuando inicia Vim y no en cualquier otro momento.

John O'M.
fuente