From d6bf13502ad7a018a739b82bc068d299aacc5d26 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Thu, 7 Dec 2017 15:26:20 +0000 Subject: [PATCH 1/2] Add ALEStartLint autocmd This grew out of my work in #1193; to ensure the statusline was being updated I had to add: fun! s:redraw(timer) redrawstatus endfun augroup ALEProgress autocmd! autocmd BufWritePost * call timer_start(100, function('s:redraw')) autocmd User ALELint redrawstatus augroup end Which kind of works, but is ugly. With this, I can replace the `BufWritePost` with: autocmd User ALEStartLint redrawstatus Which is much better, IMHO. Actually, this patch actually replaces adding a function, since you can do: augroup ALEProgress autocmd! autocmd User ALEStartLint hi Statusline ctermfg=darkgrey autocmd User ALELint hi Statusline ctermfg=NONE augroup end or: let s:ale_running = 0 let l:stl .= '%{s:ale_running ? "[linting]" : ""}' augroup ALEProgress autocmd! autocmd User ALEStartLint let s:ale_running = 1 | redrawstatus autocmd User ALELint let s:ale_running = 0 | redrawstatus augroup end Both seem to work very well in my testing. No need to `ale#Statusline#IsRunning()` anymore, I think? --- README.md | 10 ++++++---- autoload/ale/engine.vim | 2 ++ doc/ale.txt | 6 ++++++ test/test_alelint_autocmd.vader | 25 ++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 89bcc25..0292d52 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ formatting tools, and some Language Server Protocol and `tsserver` features. 5. [How can I show errors or warnings in my statusline?](#faq-statusline) 6. [How can I show errors or warnings in my lightline?](#faq-lightline) 7. [How can I change the format for echo messages?](#faq-echo-format) - 8. [How can I execute some code when ALE stops linting?](#faq-autocmd) + 8. [How can I execute some code when ALE starts or stops linting?](#faq-autocmd) 9. [How can I navigate between errors quickly?](#faq-navigation) 10. [How can I run linters only when I save files?](#faq-lint-on-save) 11. [How can I use the quickfix list instead of the loclist?](#faq-quickfix) @@ -493,15 +493,17 @@ Will give you: -### 5.viii. How can I execute some code when ALE stops linting? +### 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) -event whenever has a linter has been successfully executed and processed. This -autocmd event can be used to call arbitrary functions after ALE stops linting. +events whenever has a linter is started and has been successfully executed and +processed. This autocmd event can be used to call arbitrary functions before and +after ALE stops linting. ```vim augroup YourGroup autocmd! + autocmd User ALEStartLint call YourFunction() autocmd User ALELint call YourFunction() augroup END ``` diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 150b53c..895544f 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -556,6 +556,8 @@ function! s:RunJob(options) abort \ 'output': [], \ 'next_chain_index': l:next_chain_index, \} + + silent doautocmd User ALEStartLint endif if g:ale_history_enabled diff --git a/doc/ale.txt b/doc/ale.txt index 8e8f5f4..e45cfa9 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2196,6 +2196,12 @@ ALELint *ALELint-autocmd* The autocmd commands are run with |:silent|, so |:unsilent| is required for echoing messges. + +ALEStartLint *ALEStartLint-autocmd* + + This |User| autocommand is triggered by ALE right after it started a new + linting job. + =============================================================================== 10. Special Thanks *ale-special-thanks* diff --git a/test/test_alelint_autocmd.vader b/test/test_alelint_autocmd.vader index 4503005..bf96abf 100644 --- a/test/test_alelint_autocmd.vader +++ b/test/test_alelint_autocmd.vader @@ -1,18 +1,41 @@ Before: + let g:start = 0 let g:success = 0 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': has('win32') ? 'cmd' : 'true', + \ 'command': has('win32') ? 'echo' : 'true', + \}) + "let g:ale_linters = {'foobar': ['lint_file_linter']} + After: let g:ale_run_synchronously = 0 let g:ale_buffer_info = {} + let g:ale_linters = {} + call ale#linter#Reset() + delfunction TestCallback augroup! VaderTest Execute (Run a lint cycle, and check that a variable is set in the autocmd): + set filetype=foobar augroup VaderTest autocmd! - autocmd User ALELint let g:success = 1 + autocmd User ALEStartLint let g:start = 1 + autocmd User ALELint let g:success = 1 augroup end call ale#Lint() + AssertEqual g:start, 1 AssertEqual g:success, 1 From 4825cce1cc9ec729ea59ae90eb819f67239d335b Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sun, 10 Dec 2017 13:03:03 +0000 Subject: [PATCH 2/2] Run before lint cycle, rename autocmds --- README.md | 8 +++---- autoload/ale/engine.vim | 6 +++-- doc/ale.txt | 40 +++++++++++++++++++-------------- test/test_alelint_autocmd.vader | 32 +++++--------------------- 4 files changed, 37 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 0292d52..fd919c0 100644 --- a/README.md +++ b/README.md @@ -497,14 +497,14 @@ Will give you: ALE runs its own [autocmd](http://vimdoc.sourceforge.net/htmldoc/autocmd.html) events whenever has a linter is started and has been successfully executed and -processed. This autocmd event can be used to call arbitrary functions before and -after ALE stops linting. +processed. These events can be used to call arbitrary functions before and after +ALE stops linting. ```vim augroup YourGroup autocmd! - autocmd User ALEStartLint call YourFunction() - autocmd User ALELint call YourFunction() + autocmd User ALELintPre call YourFunction() + autocmd User ALELintPost call YourFunction() augroup END ``` diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 895544f..65e663a 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -321,6 +321,8 @@ function! ale#engine#SetResults(buffer, loclist) abort call ale#engine#RemoveManagedFiles(a:buffer) " Call user autocommands. This allows users to hook into ALE's lint cycle. + silent doautocmd User ALELintPost + " Old DEPRECATED name; call it for backwards compatibility. silent doautocmd User ALELint endif endfunction @@ -556,8 +558,6 @@ function! s:RunJob(options) abort \ 'output': [], \ 'next_chain_index': l:next_chain_index, \} - - silent doautocmd User ALEStartLint endif if g:ale_history_enabled @@ -787,6 +787,8 @@ function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort " We can only clear the results if we aren't checking the buffer. let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer) + silent doautocmd User ALELintPre + for l:linter in a:linters " Only run lint_file linters if we should. if !l:linter.lint_file || a:should_lint_file diff --git a/doc/ale.txt b/doc/ale.txt index e45cfa9..79101c6 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2048,7 +2048,7 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()* the file on disk, including |g:ale_lint_on_enter| and |g:ale_lint_on_save|. Linters with this option set to `1` will also be run when linters are run - manually, per |ALELint-autocmd|. + manually, per |ALELintPost-autocmd|. When this option is set to `1`, `read_buffer` will be set automatically to `0`. The two options cannot @@ -2182,26 +2182,32 @@ ale#statusline#Count(buffer) *ale#statusline#Count()* `total` -> The total number of problems. -ALELint *ALELint-autocmd* +ALELintPre ALELintPost *ALELintPre-autocmd* *ALELintPost-autocmd* - This |User| autocommand is triggered by ALE every time it completes a lint - cycle. It can be used to update statuslines, send notifications, or - complete any other operation that needs to be done after linting has been - performed. - - For example, you can echo a message when linting is complete like so: - > - autocmd User ALELint unsilent echom 'ALE run!' -< + These |User| autocommands are triggered before and after every lint cycle. + It can be used to update statuslines, send notifications, etc. The autocmd commands are run with |:silent|, so |:unsilent| is required for echoing messges. - -ALEStartLint *ALEStartLint-autocmd* - - This |User| autocommand is triggered by ALE right after it started a new - linting job. - + For example to change the color of the statusline while the linter is + running: +> + augroup ALEProgress + autocmd! + autocmd User ALELintPre hi Statusline ctermfg=darkgrey + autocmd User ALELintPOST hi Statusline ctermfg=NONE + augroup end +< + Or to display the progress in the statusline: +> + let s:ale_running = 0 + let l:stl .= '%{s:ale_running ? "[linting]" : ""}' + augroup ALEProgress + autocmd! + autocmd User ALELintPre let s:ale_running = 1 | redrawstatus + autocmd User ALELintPost let s:ale_running = 0 | redrawstatus + augroup end +< =============================================================================== 10. Special Thanks *ale-special-thanks* diff --git a/test/test_alelint_autocmd.vader b/test/test_alelint_autocmd.vader index bf96abf..b19e6b4 100644 --- a/test/test_alelint_autocmd.vader +++ b/test/test_alelint_autocmd.vader @@ -1,41 +1,21 @@ Before: - let g:start = 0 - let g:success = 0 + let g:pre_success = 0 + let g:post_success = 0 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': has('win32') ? 'cmd' : 'true', - \ 'command': has('win32') ? 'echo' : 'true', - \}) - "let g:ale_linters = {'foobar': ['lint_file_linter']} - After: let g:ale_run_synchronously = 0 let g:ale_buffer_info = {} - let g:ale_linters = {} - call ale#linter#Reset() - delfunction TestCallback augroup! VaderTest Execute (Run a lint cycle, and check that a variable is set in the autocmd): - set filetype=foobar augroup VaderTest autocmd! - autocmd User ALEStartLint let g:start = 1 - autocmd User ALELint let g:success = 1 + autocmd User ALELintPre let g:pre_success = 1 + autocmd User ALELintPost let g:post_success = 1 augroup end call ale#Lint() - AssertEqual g:start, 1 - AssertEqual g:success, 1 + AssertEqual g:pre_success, 1 + AssertEqual g:post_success, 1