Keep cursor position on screen when opening/closing lists (#2632)

* Trying to keep win view from bouncing
* Adjusting when views are saved and restored
* Also restore view when closing quickfix
* Don't restore view when opening list vertically
This commit is contained in:
Andre Souto 2019-08-17 19:14:22 +01:00 committed by w0rp
parent b62e306222
commit 219fb5873c
1 changed files with 37 additions and 0 deletions

View File

@ -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