From 16cfedf04a46a3d498dfd4f7293c555562d0776e Mon Sep 17 00:00:00 2001 From: w0rp Date: Tue, 8 Aug 2017 00:46:42 +0100 Subject: [PATCH] Fix #271 - Add the ability to open the quickfix or loclist windows only after saving a file --- autoload/ale/cursor.vim | 7 ++++--- autoload/ale/engine.vim | 5 ++++- autoload/ale/events.vim | 1 + autoload/ale/list.vim | 18 +++++++++++++--- doc/ale.txt | 16 +++++++++------ test/test_lint_file_linters.vader | 16 +++++++++++++++ test/test_list_opening.vader | 34 +++++++++++++++++++++++++++++++ 7 files changed, 84 insertions(+), 13 deletions(-) diff --git a/autoload/ale/cursor.vim b/autoload/ale/cursor.vim index 0c6a863..85881c0 100644 --- a/autoload/ale/cursor.vim +++ b/autoload/ale/cursor.vim @@ -50,10 +50,11 @@ function! ale#cursor#TruncatedEcho(message) abort endfunction function! s:FindItemAtCursor() abort - let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []}) + let l:info = get(g:ale_buffer_info, bufnr(''), {}) + let l:loclist = get(l:info, 'loclist', []) let l:pos = getcurpos() - let l:index = ale#util#BinarySearch(l:info.loclist, l:pos[1], l:pos[2]) - let l:loc = l:index >= 0 ? l:info.loclist[l:index] : {} + let l:index = ale#util#BinarySearch(l:loclist, l:pos[1], l:pos[2]) + let l:loc = l:index >= 0 ? l:loclist[l:index] : {} return [l:info, l:loc] endfunction diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 9b90e95..75f3088 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -83,7 +83,7 @@ function! ale#engine#CreateDirectory(buffer) abort endfunction function! ale#engine#RemoveManagedFiles(buffer) abort - let l:info = get(g:ale_buffer_info, a:buffer) + let l:info = get(g:ale_buffer_info, a:buffer, {}) " We can't delete anything in a sandbox, so wait until we escape from " it to delete temporary files and directories. @@ -298,6 +298,9 @@ function! ale#engine#SetResults(buffer, loclist) abort endif if l:linting_is_done + " Reset the save event marker, used for opening windows, etc. + call setbufvar(a:buffer, 'ale_save_event_fired', 0) + " Automatically remove all managed temporary files and directories " now that all jobs have completed. call ale#engine#RemoveManagedFiles(a:buffer) diff --git a/autoload/ale/events.vim b/autoload/ale/events.vim index 4722afa..3cfe547 100644 --- a/autoload/ale/events.vim +++ b/autoload/ale/events.vim @@ -1,6 +1,7 @@ " Author: w0rp 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 if g:ale_fix_on_save diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim index 6186d86..f7c8ddd 100644 --- a/autoload/ale/list.vim +++ b/autoload/ale/list.vim @@ -11,6 +11,16 @@ function! ale#list#IsQuickfixOpen() abort return 0 endfunction +" Check if we should open the list, based on the save event being fired, and +" that setting being on, or the setting just being set to `1`. +function! s:ShouldOpen(buffer) abort + let l:val = ale#Var(a:buffer, 'open_list') + let l:saved = getbufvar(a:buffer, 'ale_save_event_fired', 0) + + return (type(l:val) == type(1) && l:val == 1) + \ || (l:val ==# 'on_save' && l:saved) +endfunction + function! ale#list#SetLists(buffer, loclist) abort let l:title = expand('#' . a:buffer . ':p') @@ -35,8 +45,10 @@ function! ale#list#SetLists(buffer, loclist) abort endif endif - " If we have errors in our list, open the list. Only if it isn't already open - if (g:ale_open_list && !empty(a:loclist)) || g:ale_keep_list_window_open + let l:keep_open = ale#Var(a:buffer, 'keep_list_window_open') + + " Open a window to show the problems if we need to. + if s:ShouldOpen(a:buffer) && (l:keep_open || !empty(a:loclist)) let l:winnr = winnr() let l:mode = mode() let l:reset_visual_selection = l:mode ==? 'v' || l:mode ==# "\" @@ -68,7 +80,7 @@ function! ale#list#SetLists(buffer, loclist) abort endfunction function! ale#list#CloseWindowIfNeeded(buffer) abort - if g:ale_keep_list_window_open || !g:ale_open_list + if ale#Var(a:buffer, 'keep_list_window_open') || !s:ShouldOpen(a:buffer) return endif diff --git a/doc/ale.txt b/doc/ale.txt index 51da946..1de7803 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -398,7 +398,7 @@ g:ale_history_log_output *g:ale_history_log_output* g:ale_keep_list_window_open *g:ale_keep_list_window_open* - + *b:ale_keep_list_window_open* Type: |Number| Default: `0` @@ -600,13 +600,17 @@ g:ale_maximum_file_size *g:ale_maximum_file_size* g:ale_open_list *g:ale_open_list* - - Type: |Number| + *b:ale_open_list* + Type: |Number| or |String| Default: `0` - When set to `1`, this will cause ALE to automatically open a window for - the loclist (|lopen|) or for the quickfix list instead if - |g:ale_set_quickfix| is `1`. (|copen|) + When set to `1`, this will cause ALE to automatically open a window for the + loclist (|lopen|) or for the quickfix list instead if |g:ale_set_quickfix| + is `1`. (|copen|) + + When set to `'on_save'`, ALE will only open the loclist after buffers have + been saved. The list will be opened some time after buffers are saved and + any linter for a buffer returns results. The window will be kept open until all warnings or errors are cleared, including those not set by ALE, unless |g:ale_keep_list_window_open| is set diff --git a/test/test_lint_file_linters.vader b/test/test_lint_file_linters.vader index 4110c05..2eb9b2e 100644 --- a/test/test_lint_file_linters.vader +++ b/test/test_lint_file_linters.vader @@ -81,6 +81,8 @@ Before: After: Restore + unlet! b:ale_save_event_fired + unlet! b:ale_enabled unlet g:buffer_result let g:ale_buffer_info = {} call ale#linter#Reset() @@ -251,3 +253,17 @@ Execute(The Save event should respect the buffer number): \ 'type': 'E', \ }, \], GetSimplerLoclist() + +Execute(The Save event should set b:ale_save_event_fired to 1): + let b:ale_enabled = 0 + call ale#events#SaveEvent(bufnr('')) + + " This flag needs to be set so windows can be opened, etc. + AssertEqual 1, b:ale_save_event_fired + +Execute(b:ale_save_event_fired should be set to 0 when results are set): + let b:ale_save_event_fired = 1 + + call ale#engine#SetResults(bufnr(''), []) + + AssertEqual 0, b:ale_save_event_fired diff --git a/test/test_list_opening.vader b/test/test_list_opening.vader index a46f28e..253efa4 100644 --- a/test/test_list_opening.vader +++ b/test/test_list_opening.vader @@ -34,6 +34,10 @@ After: unlet! g:loclist unlet! b:ale_list_window_size + unlet! b:ale_open_list + unlet! b:ale_keep_list_window_open + unlet! b:ale_save_event_fired + delfunction GetQuickfixHeight " Close quickfix window after every execute block @@ -163,3 +167,33 @@ Execute(The quickfix window height should be correct for the quickfix list with call ale#list#CloseWindowIfNeeded(bufnr('')) AssertEqual 8, GetQuickfixHeight() + +Execute(The buffer ale_open_list option should be respected): + let b:ale_open_list = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + Assert ale#list#IsQuickfixOpen() + +Execute(The buffer ale_keep_list_window_open option should be respected): + let b:ale_open_list = 1 + let b:ale_keep_list_window_open = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + call ale#list#CloseWindowIfNeeded(bufnr('')) + call ale#list#SetLists(bufnr('%'), []) + call ale#list#CloseWindowIfNeeded(bufnr('')) + + Assert ale#list#IsQuickfixOpen() + +Execute(The ale_open_list='on_save' option should work): + let b:ale_open_list = 'on_save' + + call ale#list#SetLists(bufnr('%'), g:loclist) + " The list shouldn't open yet, the event wasn't fired. + Assert !ale#list#IsQuickfixOpen() + + let b:ale_save_event_fired = 1 + + call ale#list#SetLists(bufnr('%'), g:loclist) + " Now the list should have opened. + Assert ale#list#IsQuickfixOpen()