diff --git a/autoload/ale/events.vim b/autoload/ale/events.vim index f8020a16..f740fdaa 100644 --- a/autoload/ale/events.vim +++ b/autoload/ale/events.vim @@ -12,3 +12,22 @@ function! ale#events#SaveEvent() abort call ale#Queue(0, 'lint_file') endif endfunction + +function! s:LintOnEnter() abort + if g:ale_enabled && g:ale_lint_on_enter && has_key(b:, 'ale_file_changed') + call remove(b:, 'ale_file_changed') + call ale#Queue(0, 'lint_file') + endif +endfunction + +function! ale#events#EnterEvent() abort + call s:LintOnEnter() +endfunction + +function! ale#events#FileChangedEvent(buffer) abort + call setbufvar(a:buffer, 'ale_file_changed', 1) + + if bufnr('') == a:buffer + call s:LintOnEnter() + endif +endfunction diff --git a/doc/ale.txt b/doc/ale.txt index 9d07a51d..2a760ba1 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -407,6 +407,10 @@ g:ale_lint_on_enter *g:ale_lint_on_enter* desired, this variable can be set to `0` in your vimrc file to disable this behaviour. + The |FileChangedShellPost| and |BufEnter| events will be used to check if + files have been changed outside of Vim. If a file is changed outside of + Vim, it will be checked when it is next opened. + g:ale_lint_on_filetype_changed *g:ale_lint_on_filetype_changed* diff --git a/plugin/ale.vim b/plugin/ale.vim index 5901187f..a42eb50b 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -209,6 +209,10 @@ function! ALEInitAuGroups() abort autocmd! if g:ale_enabled && g:ale_lint_on_enter autocmd BufWinEnter,BufRead * call ale#Queue(300, 'lint_file') + " Track when the file is changed outside of Vim. + autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand(''))) + " If the file has been changed, then check it again on enter. + autocmd BufEnter * call ale#events#EnterEvent() endif augroup END diff --git a/test/test_ale_init_au_groups.vader b/test/test_ale_init_au_groups.vader index 7cc3e6a6..42dd763e 100644 --- a/test/test_ale_init_au_groups.vader +++ b/test/test_ale_init_au_groups.vader @@ -112,12 +112,14 @@ Execute (g:ale_lint_on_enter = 0 should bind no events): AssertEqual [], CheckAutocmd('ALERunOnEnterGroup') -Execute (g:ale_lint_on_enter = 1 should bind no BufReadPost and BufWinEnter): +Execute (g:ale_lint_on_enter = 1 should bind the required events): let g:ale_lint_on_enter = 1 AssertEqual [ + \ 'BufEnter * call ale#events#EnterEvent()', \ 'BufReadPost * call ale#Queue(300, ''lint_file'')', \ 'BufWinEnter * call ale#Queue(300, ''lint_file'')', + \ 'FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('''')))', \], CheckAutocmd('ALERunOnEnterGroup') Execute (g:ale_lint_on_filetype_changed = 0 should bind no events): diff --git a/test/test_lint_on_enter_when_file_changed.vader b/test/test_lint_on_enter_when_file_changed.vader new file mode 100644 index 00000000..ff4e7dd5 --- /dev/null +++ b/test/test_lint_on_enter_when_file_changed.vader @@ -0,0 +1,77 @@ +Before: + Save &filetype + Save g:ale_buffer_info + Save g:ale_lint_on_enter + let g:buf = bufnr('') + let g:ale_lint_on_enter = 1 + let g:ale_run_synchronously = 1 + + function! TestCallback(buffer, output) + return [{ + \ 'lnum': 1, + \ 'col': 3, + \ 'text': 'baz boz', + \}] + endfunction + + call ale#linter#Define('foobar', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'true', + \ 'command': 'true', + \}) + +After: + Restore + unlet! g:buf + let g:ale_run_synchronously = 0 + delfunction TestCallback + call ale#linter#Reset() + call setloclist(0, []) + +Execute(The file changed event function should set b:ale_file_changed): + if has('gui') + new + else + e test + endif + + call ale#events#FileChangedEvent(g:buf) + close + + " We should set the flag in the other buffer + AssertEqual 1, getbufvar(g:buf, 'ale_file_changed') + +Execute(The file changed event function should lint the current buffer when it has changed): + set filetype=foobar + call ale#events#FileChangedEvent(bufnr('')) + + AssertEqual [{ + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'baz boz', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }], getloclist(0) + +Execute(The buffer should be checked after entering it after the file has changed): + let b:ale_file_changed = 1 + + set filetype=foobar + call ale#events#EnterEvent() + + AssertEqual [{ + \ 'bufnr': bufnr(''), + \ 'lnum': 1, + \ 'vcol': 0, + \ 'col': 3, + \ 'text': 'baz boz', + \ 'type': 'E', + \ 'nr': -1, + \ 'pattern': '', + \ 'valid': 1, + \ }], getloclist(0)