summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2017-08-20 15:59:18 +0100
committerw0rp <devw0rp@gmail.com>2017-08-20 15:59:27 +0100
commit456378cb53dbf38ff0077b8f41894bbdc7c9671e (patch)
tree9b4cd1a93f6bbce0bcceb40a47050f7edc3e513f
parent47e681529bbb98410d31bc0659b4b81c6fc7a97c (diff)
downloadale-456378cb53dbf38ff0077b8f41894bbdc7c9671e.zip
#653 - Jump to the position which Vim does not jump to for moving from quickfix/loclist items to other buffers
-rw-r--r--autoload/ale/events.vim30
-rw-r--r--ftplugin/qf.vim4
-rw-r--r--test/test_ale_init_au_groups.vader24
-rw-r--r--test/test_list_modification_error_cancelling.vader42
4 files changed, 98 insertions, 2 deletions
diff --git a/autoload/ale/events.vim b/autoload/ale/events.vim
index c84954c1..2ee7f86a 100644
--- a/autoload/ale/events.vim
+++ b/autoload/ale/events.vim
@@ -60,10 +60,40 @@ function! s:HitReturn(...) abort
if get(split(l:output, "\n"), -1, '') =~# '^E92[456]'
call ale#util#FeedKeys("\<CR>", 'n')
+
+ " If we hit one of the errors and cleared it, then Vim didn't
+ " move to the position we wanted. Change the position to the one
+ " the user selected.
+ if exists('g:ale_list_window_selection')
+ let l:pos = getcurpos()
+ let [l:pos[1], l:pos[2]] = g:ale_list_window_selection
+ call setpos('.', l:pos)
+ endif
endif
endif
+
+ " Always clear the last selection when trying to cancel the errors above
+ " here. This prevents us from remembering invalid positions.
+ unlet! g:ale_list_window_selection
endfunction
function! ale#events#BufWinLeave() abort
call timer_start(0, function('s:HitReturn'))
endfunction
+
+" Grab the position for a problem from the loclist or quickfix windows
+" when moving through selections. This selection will be remembered and
+" set as the position when jumping to an error in another file.
+function! ale#events#ParseLoclistWindowItemPosition() abort
+ " Parses lines like
+ " test.txt|72 col 5 error| ...
+ " test.txt|72| ...
+ let l:match = matchlist(getline('.'), '\v^[^|]+\|(\d+)( [^ ]+ )?(\d*)')
+
+ if !empty(l:match)
+ let g:ale_list_window_selection = [
+ \ l:match[1] + 0,
+ \ max([l:match[3] + 0, 1]),
+ \]
+ endif
+endfunction
diff --git a/ftplugin/qf.vim b/ftplugin/qf.vim
new file mode 100644
index 00000000..18e2c81a
--- /dev/null
+++ b/ftplugin/qf.vim
@@ -0,0 +1,4 @@
+augroup ALEQuickfixCursorMovedEvent
+ autocmd! * <buffer>
+ autocmd CursorMoved <buffer> call ale#events#ParseLoclistWindowItemPosition()
+augroup END
diff --git a/test/test_ale_init_au_groups.vader b/test/test_ale_init_au_groups.vader
index 109f84ae..3606402f 100644
--- a/test/test_ale_init_au_groups.vader
+++ b/test/test_ale_init_au_groups.vader
@@ -21,8 +21,14 @@ Before:
let l:header = split(l:line)[1]
let l:header = get(l:event_name_corrections, l:header, l:header)
elseif !empty(l:header)
- call add(l:matches, join(split(l:header . l:line)))
- let l:header = ''
+ " There's an extra line for buffer events, and we should only look
+ " for the one matching the current buffer.
+ if l:line =~# '<buffer=' . bufnr('') . '>'
+ let l:header .= ' <buffer>'
+ else
+ call add(l:matches, join(split(l:header . l:line)))
+ let l:header = ''
+ endif
endif
endfor
@@ -54,6 +60,11 @@ After:
call ALEInitAuGroups()
+ " Clean up the quickfix group.
+ augroup ALEQuickfixCursorMovedEvent
+ autocmd! * <buffer>
+ augroup END
+
Execute (g:ale_lint_on_text_changed = 0 should bind no events):
let g:ale_lint_on_text_changed = 0
@@ -211,3 +222,12 @@ Execute(Disabling completion should remove autocmd events correctly):
AssertEqual [], CheckAutocmd('ALECompletionGroup')
AssertEqual 0, g:ale_completion_enabled
+
+Execute(The cursor events should be set up for the quickfix list):
+ runtime! ftplugin/qf.vim
+
+ AssertEqual
+ \ [
+ \ 'CursorMoved <buffer> call ale#events#ParseLoclistWindowItemPosition()',
+ \ ],
+ \ CheckAutocmd('ALEQuickfixCursorMovedEvent')
diff --git a/test/test_list_modification_error_cancelling.vader b/test/test_list_modification_error_cancelling.vader
index 06449621..e4aa3afa 100644
--- a/test/test_list_modification_error_cancelling.vader
+++ b/test/test_list_modification_error_cancelling.vader
@@ -26,6 +26,7 @@ Before:
After:
unlet! b:fake_mode
unlet! b:feedkeys_calls
+ unlet! g:ale_list_window_selection
delfunction CheckError
@@ -52,3 +53,44 @@ Execute(The BufWinLeave event function should ignore other errors):
Execute(The BufWinLeave event function not send keys for other modes):
call CheckError('n', 'E924', [])
+
+Execute(The last window selection should always be cleared by the timer):
+ let g:ale_list_window_selection = [347, 2]
+
+ " The message and mode shouldn't matter, we should still clear the variable.
+ echom 'xyz'
+ let b:fake_mode = 'n'
+ call ale#events#BufWinLeave()
+ sleep 1ms
+
+ Assert !has_key(g:, 'ale_list_window_selection')
+
+Given qf(A quickfix list with some errors):
+ test.txt|23 col 9 warning| Some warning
+ test.txt|72 col 25 error| Some column error
+ test.txt|93 error| Some line error
+
+Execute(Line and column numbers should be parsed by the quickfix event function):
+ call setpos('.', [bufnr(''), 2, 1, 0])
+ call ale#events#ParseLoclistWindowItemPosition()
+ AssertEqual [72, 25], g:ale_list_window_selection
+
+Execute(Just Line numbers should be parsed by the quickfix event function):
+ call setpos('.', [bufnr(''), 3, 1, 0])
+ call ale#events#ParseLoclistWindowItemPosition()
+ AssertEqual [93, 1], g:ale_list_window_selection
+
+Given python(Some example Python file):
+ class FooBar:
+ def whatever(self):
+ self.do_something()
+
+Execute(We should jump to the window selection after cancelling the errors):
+ call setpos('.', [bufnr(''), 1, 1, 0])
+ let g:ale_list_window_selection = [3, 9]
+
+ echom 'E925'
+ call ale#events#BufWinLeave()
+ sleep 1ms
+
+ AssertEqual [3, 9], getcurpos()[1:2]