¿Hay alguna forma de eventos AND en el autocmd?


21

Me gustaría activar un autocmd en dos eventos, pero no de la forma en que generalmente se hace, es decir, si alguno de los eventos sucedió, entonces active un autocmd. Quiero activarlo si sucedieron ambos eventos.

Por ejemplo:
la forma habitual de hacerlo

autocmd BufWrite,BufRead *.c *.py *.h :call StripTrailingWhitespaces()

Este código llamará a StripTrailingWhiteSpaces () en BufWrite o BufRead

Me gustaría hacer algo como:

autocmd Filetype c,cpp,python AND BufWrite :call StripTrailingWhiteSpaces()

En otras palabras, desencadenan un autcmdcuando el tipo de archivo es uno de c, cpp, python y ocurre la escritura en este búfer.

Cualquier ayuda es apreciada.

Respuestas:


14

Un comando de autocomando se ejecuta cuando ocurre un evento. Desea que se ejecute un comando después de que se haya producido una secuencia de eventos. Una forma de hacerlo es así:

autocmd FileType c,cpp,python
    \ autocmd BufWritePre <buffer> call StripTrailingWhiteSpaces()

El <buffer>patrón hace que el autocomando se active cuando se escribe el búfer actual. Ver

:help autocmd-buflocal

Actualizar

La solución anterior es bastante simple y tiene algunos defectos que se discutieron en los Comentarios. Aquí hay una solución más completa que aborda algunos de esos defectos. Pone los comandos automáticos en un grupo y elimina el comando automático BufWritePre, si existe, antes de crear uno nuevo. Todavía crea un autocomando por búfer, pero solo uno.

augroup TrailSpace
    autocmd FileType c,cpp,python
        \ autocmd! TrailSpace BufWritePost <buffer> call SkipTrailingWhiteSpaces()
augroup END

Otra solución, similar a la respuesta publicada por lcd047, ahora eliminada, es reconocer que cuando ocurre el evento FileType, se establece la opción 'tipo de archivo'. Luego puede condicionar la respuesta al evento BufWritePost en el valor de 'tipo de archivo', como en el siguiente ejemplo. Tiene la ventaja sobre las otras soluciones de que solo se crea un autocomando.

autocmd BufWritePre * if count(['c','cpp','python'],&filetype)
    \ | call SkipTrailingWhiteSpaces()
    \ | endif

¿Qué sucede si quiero ejecutar esto en todos los archivos que están abiertos actualmente, es decir, ejecuto: wa?
flashburn

Si los archivos se abrieron con el tipo de archivo correcto, el FileTypeautocmd en la respuesta ya habría configurado el segundo autocmd ( BufWritePre) para que se dispare cuando los guarde.
VanLaser

1
El FileTypeautocmd anterior se activará para cada archivo que abra con el tipo de archivo correcto y configurará un evento local de búfer para cada uno de esos archivos. Entonces, si ejecuta :wa, vim ejecutará eventos registrados para cada búfer, antes de guardar en el archivo.
VanLaser

1
Entonces, si abre 5 archivos de Python, tendrá 5 autocmds en lugar de uno solo, todo en escritura. Entonces, si, por ejemplo, 3 de estos archivos se ocultan, luego se muestran nuevamente, FileTypese vuelven a activar para que obtenga 3 autocmds más , también en escritura. Esto es brillante, me pregunto por qué no se me ocurrió esta solución. :)
lcd047

1
El rendimiento no es un problema. Sin stripTrailingWhiteSpaces()embargo, ejecutar la función varias veces contra el mismo archivo puede tener consecuencias no deseadas. Además, cuanto más autocmdtenga para el mismo evento para el mismo archivo, más probabilidades tendrá de encontrarse con algunas condiciones realmente de carrera. Intente buscar archivos vim_dev para tener una idea. Por otra parte, qué sé, podría funcionar para ti, ¿verdad?
lcd047

4

En términos más generales, si no sabe qué evento sucederá primero, puede usar un ayudante para rastrear cuándo se dispara cada uno y solo ejecutar su comando cuando se dispara el último:

function StripTrailingWhiteSpacesIfReady(event) abort
  if !exists('b:events_for_whitespace')
    let b:events_for_whitespace = {}
  endif
  let b:events_for_whitespace[a:event] = 1
  if has_key(b:events_for_whitespace, 'FileType') && has_key(b:events_for_whitespace, 'Buf')
    " Strip trailing whitespace
    %s/\m\s\+$//
  endif
endfunction
autocmd Filetype c,cpp,python call StripTrailingWhiteSpacesIfReady('FileType')
autocmd BufWrite,BufRead * StripTrailingWhiteSpacesIfReady('Buf')
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.