autocmd에 이벤트를 AND하는 방법이 있습니까?


21

autocmd 두 이벤트에 대해 트리거하고 싶지만 일반적으로 수행되는 방식이 아닙니다. 즉, 이벤트 중 하나가 발생하면를 트리거합니다 autocmd. 두 이벤트가 모두 발생하면 트리거하고 싶습니다.

예를 들어 :
일반적인 방법

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

이 코드는 BufWrite 또는 BufRead에서 StripTrailingWhiteSpaces ()를 호출합니다.

나는 다음과 같은 것을하고 싶다 :

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

autcmd, 파일 형식이 c, cpp, python 중 하나이고이 버퍼에 대한 쓰기가 발생하면 a를 트리거 합니다.

도움을 주시면 감사하겠습니다.

답변:


14

하나의 이벤트가 발생하면 자동 명령 명령이 실행됩니다. 일련의 이벤트가 발생한 후 명령을 실행하려고합니다. 이를 수행하는 한 가지 방법은 다음과 같습니다.

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

<buffer>패턴은 현재 버퍼가 기록 될 때 자동 명령이 트리거되도록합니다. 만나다

:help autocmd-buflocal

최신 정보

위의 해결책은 매우 간단하며 의견에서 논의 된 결함이 있습니다. 다음은 이러한 결함 중 일부를 해결하는보다 완벽한 솔루션입니다. 자동 명령을 그룹에 넣고 BufWritePre 자동 명령이있는 경우 새 명령을 만들기 전에이를 삭제합니다. 여전히 버퍼 당 하나의 자동 명령을 작성하지만 하나만 작성합니다.

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

lcd047이 게시 한 답변과 비슷한 또 다른 해결책은 FileType 이벤트가 발생하면 'filetype'옵션이 설정되어 있음을 인식하는 것입니다. 그런 다음 다음 예제와 같이 'filetype'값에서 BufWritePost 이벤트에 대한 응답을 조정할 수 있습니다. 하나의 자동 명령 만 작성되는 다른 솔루션보다 이점이 있습니다.

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

현재 열려있는 모든 파일에서 이것을 실행하려면 어떻게해야합니까? 즉 : wa를 실행합니까?
flashburn

파일이 올바른 파일 형식으로 열린 경우 FileType응답 의 autocmd는 파일 BufWritePre을 저장할 때 실행되도록 두 번째 autocmd ( )를 이미 설정 했을 것입니다.
VanLaser

1
FileType위 의 autocmd 는 올바른 파일 형식으로 연 모든 파일 에 대해 실행 되며 해당 파일 각각 에 대해 버퍼 로컬 이벤트를 설정 합니다. 따라서을 실행 하면 vim은 파일에 저장하기 전에 각 버퍼에 대해 등록 된 이벤트를 실행합니다. :wa
VanLaser

1
따라서 5 개의 Python 파일을 열면 autocmd하나의 파일 대신 5 개의 파일이 작성됩니다. 그런 다음 이러한 파일 중 3 개가 숨겨 FileType지고 다시 표시 되면 다시 트리거되어 autocmd쓰기시 3 개를 더 얻습니다 . 이것은 훌륭합니다. 왜이 솔루션을 찾지 못했는지 궁금합니다. :)
lcd047

1
성능에는 문제가 없습니다. stripTrailingWhiteSpaces()동일한 파일에 대해 함수를 여러 번 실행하면 의도하지 않은 결과가 발생할 수 있습니다. 또한 autocmd동일한 파일에 대해 동일한 이벤트에 대해 더 많은 것을 가질수록 실제 경쟁 조건에 처할 가능성이 높아집니다. 아이디어를 얻으려면 vim_dev 아카이브를 검색하십시오. 다시, 내가 무엇을 알고, 그것은 당신을 위해 일할 수도 있습니다.
lcd047

4

더 일반적으로 어떤 이벤트가 먼저 발생하는지 모르는 경우 도우미를 사용하여 각 이벤트가 발생하는 시간을 추적하고 마지막 이벤트가 발생할 때만 명령을 실행할 수 있습니다.

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')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.