From b7996803c99a0a5f5dba1cef330a2bfb77f08c42 Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Fri, 27 Apr 2018 15:40:02 -0700 Subject: [PATCH 1/5] Add ALEJobStarted User autocommand event The ALELintPre and ALELintPost autocommand events are currently being used by lightline-ale to refresh the status line and check the linter status for a current buffer. One of the plugin's checks looks to see if linters are currently running, via ale#engine#IsCheckingBuffer(). This currently only works partially in certain situations. In my particular case, working with Go files, this only seems to function properly when a file is initially opened. Saving a file does not correctly update the status. This seems to be due to the fact that ALELintPre actually runs before any jobs are carried out, making it plausible that hooking into ALELintPre for the purpose of checking to see if there are any currently running linters for a buffer is unreliable as it would be prone to pretty obvious race conditions. This adds a new User autocommand, ALEJobStarted, that gets fired at the start of every new job that is successfully run. This allows a better point to hook into checking the linter status of a buffer using ale#engine#IsCheckingBuffer() by ensuring that at least one job has started by the time IsCheckingBuffer is run. --- autoload/ale/engine.vim | 2 ++ doc/ale.txt | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 0704fd5..e1c4155 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -586,6 +586,8 @@ function! s:RunJob(options) abort \ 'output': [], \ 'next_chain_index': l:next_chain_index, \} + + silent doautocmd User ALEJobStarted endif if g:ale_history_enabled diff --git a/doc/ale.txt b/doc/ale.txt index de6507e..d52e8fe 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2452,7 +2452,14 @@ ALEFixPost *ALEFixPost-autocmd* autocmd User ALELintPre let s:ale_running = 1 | redrawstatus autocmd User ALELintPost let s:ale_running = 0 | redrawstatus augroup end + < +ALEJobStarted *ALEJobStarted-autocmd* + + This |User| autocommand is triggered immediately after a job is successfully + run. This provides better accuracy for checking linter status with + |ale#engine#IsCheckingBuffer()| over |ALELintPre|, which is actually + triggered before any linters are executed. =============================================================================== 10. Special Thanks *ale-special-thanks* From 9da015f74fd95658e6714ac4a5e8f979bc7a638f Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Fri, 27 Apr 2018 22:00:50 -0700 Subject: [PATCH 2/5] Add test for ALEJobStarted --- test/test_alejobstarted_autocmd.vader | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test/test_alejobstarted_autocmd.vader diff --git a/test/test_alejobstarted_autocmd.vader b/test/test_alejobstarted_autocmd.vader new file mode 100644 index 0000000..51a5788 --- /dev/null +++ b/test/test_alejobstarted_autocmd.vader @@ -0,0 +1,42 @@ +Given testft (An empty file): + +Before: + let g:job_started_success = 0 + let g:ale_run_synchronously = 1 + + unlet! b:ale_linted + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \}) + +After: + let g:ale_run_synchronously = 0 + let g:ale_buffer_info = {} + + try + augroup! VaderTest + catch + endtry + + unlet! g:job_started_success + + delfunction TestCallback + call ale#linter#Reset() + +Execute(Run a lint cycle with an actual job to check for ALEJobStarted): + augroup VaderTest + autocmd! + autocmd User ALEJobStarted let g:job_started_success = 1 + augroup end + + call ale#Lint() + + AssertEqual g:job_started_success, 1 From 129eb9656135265b67f93463da424446a6f332fa Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Fri, 27 Apr 2018 22:32:21 -0700 Subject: [PATCH 3/5] Fix tests by setting proper link tag in doc for ALEJobStarted --- doc/ale.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ale.txt b/doc/ale.txt index d52e8fe..3252fc6 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2458,7 +2458,7 @@ ALEJobStarted *ALEJobStarted-autocmd* This |User| autocommand is triggered immediately after a job is successfully run. This provides better accuracy for checking linter status with - |ale#engine#IsCheckingBuffer()| over |ALELintPre|, which is actually + |ale#engine#IsCheckingBuffer()| over |ALELintPre-autocmd|, which is actually triggered before any linters are executed. =============================================================================== From 11780e1d3d0da101eb7a313d1c4974ae2d5e323a Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Sat, 28 Apr 2018 14:50:20 -0700 Subject: [PATCH 4/5] Add some tests for IsCheckingBuffer Adding a couple of tests to demonstrate how IsCheckingBuffer behaves during specific autocommand hooks: * At ALELintPre, no linters have actually executed yet, hence IsCheckingBuffer should be returning false. * ALEJobStarted, fires as early as reasonably possible after a job has successfully started, and hence hooking into IsCheckingBuffer here should return true. This distinction is important when using these two events during things like statusline refreshes, namely for "linter running" indicators. --- test/test_checkingbuffer_autocmd.vader | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 test/test_checkingbuffer_autocmd.vader diff --git a/test/test_checkingbuffer_autocmd.vader b/test/test_checkingbuffer_autocmd.vader new file mode 100644 index 0000000..1cbfa34 --- /dev/null +++ b/test/test_checkingbuffer_autocmd.vader @@ -0,0 +1,57 @@ +Given testft (An empty file): + +Before: + Save g:ale_run_synchronously + Save g:ale_buffer_info + + let g:ale_run_synchronously = 1 + let g:ale_buffer_info = {} + + let g:checking_buffer = 0 + + unlet! b:ale_linted + + function! TestCallback(buffer, output) + return [] + endfunction + + call ale#linter#Define('testft', { + \ 'name': 'testlinter', + \ 'callback': 'TestCallback', + \ 'executable': has('win32') ? 'cmd' : 'true', + \ 'command': 'true', + \}) + +After: + Restore + + unlet! g:checking_buffer + + delfunction TestCallback + call ale#linter#Reset() + + augroup VaderTest + autocmd! + augroup end + + augroup! VaderTest + +Execute(ALELintPre should not return success on ale#engine#IsCheckingBuffer): + augroup VaderTest + autocmd! + autocmd User ALELintPre let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0 + augroup end + + call ale#Lint() + + AssertEqual g:checking_buffer, 0 + +Execute(ALEJobStarted should return success on ale#engine#IsCheckingBuffer): + augroup VaderTest + autocmd! + autocmd User ALEJobStarted let g:checking_buffer = ale#engine#IsCheckingBuffer(bufnr('')) ? 1 : 0 + augroup end + + call ale#Lint() + + AssertEqual g:checking_buffer, 1 From b81bc8d481c9967938118a0fffeb299b470cfd59 Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Sat, 28 Apr 2018 15:10:59 -0700 Subject: [PATCH 5/5] A couple of more doc fixes * Update section 5.viii in the README with ALEJobStarted and re-format the example. * Add an extra line after documentation update to ensure consistency with the rest of the doc. --- README.md | 16 ++++++++++------ doc/ale.txt | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dc397d0..53b6379 100644 --- a/README.md +++ b/README.md @@ -524,17 +524,21 @@ Will give you: ### 5.viii. How can I execute some code when ALE starts or stops linting? ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) -events when a lint or fix cycle are started and stopped. These events can be -used to call arbitrary functions before and after ALE stops linting. +events when a lint or fix cycle are started and stopped. There is also an event +that runs when a linter job has been successfully started. These events can be +used to call arbitrary functions during these respective parts of the ALE's +operation. ```vim augroup YourGroup autocmd! - autocmd User ALELintPre call YourFunction() - autocmd User ALELintPost call YourFunction() + autocmd User ALELintPre call YourFunction() + autocmd User ALELintPost call YourFunction() - autocmd User ALEFixPre call YourFunction() - autocmd User ALEFixPost call YourFunction() + autocmd User ALEJobStarted call YourFunction() + + autocmd User ALEFixPre call YourFunction() + autocmd User ALEFixPost call YourFunction() augroup END ``` diff --git a/doc/ale.txt b/doc/ale.txt index 3252fc6..41a177a 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2461,6 +2461,7 @@ ALEJobStarted *ALEJobStarted-autocmd* |ale#engine#IsCheckingBuffer()| over |ALELintPre-autocmd|, which is actually triggered before any linters are executed. + =============================================================================== 10. Special Thanks *ale-special-thanks*