diff --git a/autoload/ale/events.vim b/autoload/ale/events.vim index efae11c1..1992b1ee 100644 --- a/autoload/ale/events.vim +++ b/autoload/ale/events.vim @@ -1,8 +1,15 @@ " Author: w0rp +function! ale#events#QuitEvent(buffer) abort + " Remember when ALE is quitting for BufWrite, etc. + call setbufvar(a:buffer, 'ale_quitting', 1) +endfunction + function! ale#events#SaveEvent(buffer) abort call setbufvar(a:buffer, 'ale_save_event_fired', 1) - let l:should_lint = ale#Var(a:buffer, 'enabled') && g:ale_lint_on_save + let l:should_lint = ale#Var(a:buffer, 'enabled') + \ && g:ale_lint_on_save + \ && !getbufvar(a:buffer, 'ale_quitting') if g:ale_fix_on_save let l:will_fix = ale#fix#Fix('save_file') @@ -24,6 +31,8 @@ function! s:LintOnEnter(buffer) abort endfunction function! ale#events#EnterEvent(buffer) abort + " When entering a buffer, we are no longer quitting it. + call setbufvar(a:buffer, 'ale_quitting', 0) let l:filetype = getbufvar(a:buffer, '&filetype') call setbufvar(a:buffer, 'ale_original_filetype', l:filetype) diff --git a/autoload/ale/fix.vim b/autoload/ale/fix.vim index e1210f17..2b5387de 100644 --- a/autoload/ale/fix.vim +++ b/autoload/ale/fix.vim @@ -56,7 +56,9 @@ function! ale#fix#ApplyQueuedFixes() abort " If ALE linting is enabled, check for problems with the file again after " fixing problems. - if g:ale_enabled && l:should_lint + if g:ale_enabled + \&& l:should_lint + \&& !getbufvar(l:buffer, 'ale_quitting') call ale#Queue(0, l:data.should_save ? 'lint_file' : '') endif endfunction diff --git a/plugin/ale.vim b/plugin/ale.vim index 9fac75ee..a0d9b271 100644 --- a/plugin/ale.vim +++ b/plugin/ale.vim @@ -383,6 +383,7 @@ augroup ALECleanupGroup autocmd! " Clean up buffers automatically when they are unloaded. autocmd BufUnload * call ale#engine#Cleanup(str2nr(expand(''))) + autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand(''))) augroup END " Backwards Compatibility diff --git a/test/test_autocmd_commands.vader b/test/test_autocmd_commands.vader index 2685f50b..17e3b16d 100644 --- a/test/test_autocmd_commands.vader +++ b/test/test_autocmd_commands.vader @@ -199,6 +199,12 @@ Execute (g:ale_echo_cursor = 1 should bind cursor events): \ 'InsertLeave * call ale#cursor#EchoCursorWarning()', \], CheckAutocmd('ALECursorGroup') +Execute (ALECleanupGroup should include the right commands): + AssertEqual [ + \ 'BufUnload * call ale#engine#Cleanup(str2nr(expand('''')))', + \ 'QuitPre * call ale#events#QuitEvent(str2nr(expand('''')))', + \], CheckAutocmd('ALECleanupGroup') + Execute(Enabling completion should set up autocmd events correctly): let g:ale_completion_enabled = 0 call ale#completion#Enable() diff --git a/test/test_no_linting_on_write_quit.vader b/test/test_no_linting_on_write_quit.vader new file mode 100644 index 00000000..dc78ef75 --- /dev/null +++ b/test/test_no_linting_on_write_quit.vader @@ -0,0 +1,71 @@ +Before: + Save g:ale_echo_cursor + Save g:ale_fix_on_save + Save g:ale_fixers + Save g:ale_lint_on_save + + let g:ale_echo_cursor = 0 + let g:ale_run_synchronously = 1 + + function! TestCallback(buffer, output) + return [{'lnum': 1, 'col': 1, 'text': 'xxx'}] + endfunction + + function AddLine(buffer, lines) abort + return a:lines + ['x'] + endfunction + + let g:ale_fixers = { + \ 'testft': ['AddLine'], + \} + + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': 'true', + \ 'command': 'true', + \}) + +Given testft (An empty file): + +After: + Restore + + unlet! g:ale_run_synchronously + unlet! b:ale_quitting + delfunction TestCallback + delfunction AddLine + + call ale#linter#Reset() + call setloclist(0, []) + +Execute(No linting should be done on :wq or :x): + let g:ale_lint_on_save = 1 + let g:ale_fix_on_save = 0 + + " First try just the SaveEvent, to be sure that we set errors in the test. + call ale#events#SaveEvent(bufnr('')) + + AssertEqual 1, len(getloclist(0)) + + " Now try doing it again, but where we run the quit event first. + call setloclist(0, []) + call ale#events#QuitEvent(bufnr('')) + call ale#events#SaveEvent(bufnr('')) + + AssertEqual [], getloclist(0) + +Execute(No linting should be done on :wq or :x after fixing files): + let g:ale_lint_on_save = 0 + let g:ale_fix_on_save = 1 + + call ale#events#SaveEvent(bufnr('')) + + AssertEqual 1, len(getloclist(0)) + + " Now try doing it again, but where we run the quit event first. + call setloclist(0, []) + call ale#events#QuitEvent(bufnr('')) + call ale#events#SaveEvent(bufnr('')) + + AssertEqual [], getloclist(0) diff --git a/test/test_quitting_variable.vader b/test/test_quitting_variable.vader new file mode 100644 index 00000000..80b0a8dd --- /dev/null +++ b/test/test_quitting_variable.vader @@ -0,0 +1,22 @@ +Before: + Save g:ale_enabled + + unlet! b:ale_quitting + let g:ale_enabled = 0 + +After: + Restore + + unlet! b:ale_quitting + +Execute(QuitEvent should set b:ale_quitting to 1): + call ale#events#QuitEvent(bufnr('')) + + AssertEqual 1, b:ale_quitting + +Execute(EnterEvent should set b:ale_quitting to 0): + let b:ale_quitting = 1 + + call ale#events#EnterEvent(bufnr('')) + + AssertEqual 0, b:ale_quitting