summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autoload/ale/list.vim37
1 files changed, 37 insertions, 0 deletions
diff --git a/autoload/ale/list.vim b/autoload/ale/list.vim
index e9f3f4ec..4bfe2a7b 100644
--- a/autoload/ale/list.vim
+++ b/autoload/ale/list.vim
@@ -103,6 +103,9 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endfor
endif
+ " Save the current view before opening/closing any window
+ call setbufvar(a:buffer, 'ale_winview', winsaveview())
+
" Open a window to show the problems if we need to.
"
" We'll check if the current buffer's List is not empty here, so the
@@ -141,6 +144,8 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
normal! "\<c-g>"
endif
endif
+
+ call s:RestoreViewIfNeeded(a:buffer)
endif
" If ALE isn't currently checking for more problems, close the window if
@@ -151,6 +156,30 @@ function! s:SetListsImpl(timer_id, buffer, loclist) abort
endif
endfunction
+" Try to restore the window view after closing any of the lists to avoid making
+" the it moving around, especially useful when on insert mode
+function! s:RestoreViewIfNeeded(buffer) abort
+ let l:saved_view = getbufvar(a:buffer, 'ale_winview', {})
+
+ " Saved view is empty, can't do anything
+ if empty(l:saved_view)
+ return
+ endif
+
+ " Check wether the cursor has moved since linting was actually requested. If
+ " the user has indeed moved lines, do nothing
+ let l:current_view = winsaveview()
+
+ if l:current_view['lnum'] != l:saved_view['lnum']
+ return
+ endif
+
+ " Anchor view by topline if the list is set to open horizontally
+ if ale#Var(a:buffer, 'list_vertical') == 0
+ call winrestview({'topline': l:saved_view['topline']})
+ endif
+endfunction
+
function! ale#list#SetLists(buffer, loclist) abort
if get(g:, 'ale_set_lists_synchronously') == 1
\|| getbufvar(a:buffer, 'ale_save_event_fired', 0)
@@ -174,12 +203,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
return
endif
+ let l:did_close_any_list = 0
+
try
" Only close windows if the quickfix list or loclist is completely empty,
" including errors set through other means.
if g:ale_set_quickfix
if empty(getqflist())
cclose
+ let l:did_close_any_list = 1
endif
else
let l:win_ids = s:WinFindBuf(a:buffer)
@@ -187,10 +219,15 @@ function! s:CloseWindowIfNeeded(buffer) abort
for l:win_id in l:win_ids
if g:ale_set_loclist && empty(getloclist(l:win_id))
lclose
+ let l:did_close_any_list = 1
endif
endfor
endif
" Ignore 'Cannot close last window' errors.
catch /E444/
endtry
+
+ if l:did_close_any_list
+ call s:RestoreViewIfNeeded(a:buffer)
+ endif
endfunction