diff --git a/autoload/ale/loclist_jumping.vim b/autoload/ale/loclist_jumping.vim index 94a83e6..58fb863 100644 --- a/autoload/ale/loclist_jumping.vim +++ b/autoload/ale/loclist_jumping.vim @@ -1,38 +1,6 @@ " Author: w0rp " Description: This file implements functions for jumping around in a file -" based on errors and warnings in the loclist or quickfix list. - -function! s:GetCurrentList() abort - let l:buffer = bufnr('%') - let l:list = [] - - if g:ale_set_quickfix - let l:list = getqflist() - elseif g:ale_set_loclist - let l:list = getloclist(winnr()) - endif - - return filter(l:list, 'get(v:val, ''bufnr'', -1) == ' . l:buffer) -endfunction - -function! ale#loclist_jumping#GetSortedList() abort - let l:loclist = [] - - for l:item in s:GetCurrentList() - if l:item.lnum < 1 - " Remove items we can't even jump to. - continue - endif - - call add(l:loclist, l:item) - endfor - - " We must sort the list again, as the loclist could contain items set - " by other plugins. - call sort(l:loclist, 'ale#util#LocItemCompare') - - return l:loclist -endfunction +" based on ALE's internal loclist. " Search for the nearest line either before or after the current position " in the loclist. The argument 'wrap' can be passed to enable wrapping @@ -42,18 +10,15 @@ endfunction " List will be returned, otherwise a pair of [line_number, column_number] will " be returned. function! ale#loclist_jumping#FindNearest(direction, wrap) abort - let l:loclist = ale#loclist_jumping#GetSortedList() - - if empty(l:loclist) - " We couldn't find anything, so stop here. - return [] - endif - - let l:search_item = {'lnum': getcurpos()[1], 'col': getcurpos()[2]} + let l:pos = getcurpos() + let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []}) + " This list will have already been sorted. + let l:loclist = l:info.loclist + let l:search_item = {'lnum': l:pos[1], 'col': l:pos[2]} " When searching backwards, so we can find the next smallest match. if a:direction ==# 'before' - call reverse(l:loclist) + let l:loclist = reverse(copy(l:loclist)) endif " Look for items before or after the current position. @@ -82,8 +47,8 @@ function! ale#loclist_jumping#FindNearest(direction, wrap) abort " If we found nothing, and the wrap option is set to 1, then we should " wrap around the list of warnings/errors - if a:wrap - let l:item = get(l:loclist, 0) + if a:wrap && !empty(l:loclist) + let l:item = l:loclist[0] return [l:item.lnum, l:item.col] endif diff --git a/doc/ale.txt b/doc/ale.txt index 2fe3ad8..bc5e927 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -1155,7 +1155,9 @@ ALENext *ALENext* ALENextWrap *ALENextWrap* *ale-navigation-commands* - Move between warnings or errors in a buffer. + Move between warnings or errors in a buffer. ALE will only navigate between + the errors or warnings it generated, even if both |g:ale_set_quickfix| + and |g:ale_set_loclist| are set to `0`. `ALEPrevious` and `ALENext` will stop at the top and bottom of a file, while `ALEPreviousWrap` and `ALENextWrap` will wrap around the file to find diff --git a/test/test_loclist_jumping_loading.vader b/test/test_loclist_jumping_loading.vader index fe43ef2..9da5bd5 100644 --- a/test/test_loclist_jumping_loading.vader +++ b/test/test_loclist_jumping_loading.vader @@ -1,86 +1,55 @@ Before: - let g:buffer = bufnr('%') + let g:ale_buffer_info = { + \ bufnr('%'): { + \ 'loclist': [ + \ {'lnum': 1, 'col': 2}, + \ {'lnum': 1, 'col': 3}, + \ {'lnum': 2, 'col': 1}, + \ {'lnum': 2, 'col': 2}, + \ {'lnum': 2, 'col': 3}, + \ {'lnum': 2, 'col': 6}, + \ {'lnum': 2, 'col': 700}, + \ ], + \ }, + \} - function! GetList() abort - return map( - \ ale#loclist_jumping#GetSortedList(), - \ '{''lnum'': v:val.lnum, ''col'': v:val.col, ''text'': v:val.text}' - \) + function! TestJump(direction, wrap, pos) + call cursor(a:pos) + call ale#loclist_jumping#Jump(a:direction, a:wrap) + + return getcurpos()[1:2] endfunction After: - unlet! g:buffer - unlet! g:new_buffer - let g:ale_set_loclist = 1 - let g:ale_set_quickfix = 0 - call setloclist(winnr(), []) - call setqflist([]) - delfunction GetList + let g:ale_buffer_info = {} + delfunction TestJump -Execute(The loclist should be filtered and sorted appropriately for jumping): - :new +Given foobar (Some imaginary filetype): + 12345678 + 12345678 - let g:new_buffer = bufnr('%') +Execute(loclist jumping should jump correctly when not wrapping): + AssertEqual [2, 1], TestJump('before', 0, [2, 2]) + AssertEqual [1, 3], TestJump('before', 0, [2, 1]) + AssertEqual [2, 3], TestJump('after', 0, [2, 2]) + AssertEqual [2, 1], TestJump('after', 0, [1, 3]) + AssertEqual [2, 6], TestJump('after', 0, [2, 4]) + AssertEqual [2, 8], TestJump('after', 0, [2, 6]) - AssertNotEqual g:new_buffer, g:buffer +Execute(loclist jumping should jump correctly when wrapping): + AssertEqual [2, 1], TestJump('before', 1, [2, 2]) + AssertEqual [1, 3], TestJump('before', 1, [2, 1]) + AssertEqual [2, 3], TestJump('after', 1, [2, 2]) + AssertEqual [2, 1], TestJump('after', 1, [1, 3]) + AssertEqual [2, 6], TestJump('after', 1, [2, 4]) - call setloclist(winnr(), [ - \ {'lnum': 1, 'col': 1, 'text': 'ignore this', 'bufnr': g:buffer}, - \ {'lnum': 20, 'col': 5, 'text': 'baz', 'bufnr': g:new_buffer}, - \ {'lnum': 10, 'col': 6, 'text': 'bar', 'bufnr': g:new_buffer}, - \ {'lnum': 10, 'col': 5, 'text': 'foo', 'bufnr': g:new_buffer}, - \]) + AssertEqual [1, 2], TestJump('after', 1, [2, 8]) + AssertEqual [2, 8], TestJump('before', 1, [1, 2]) - AssertEqual - \ [ - \ {'lnum': 10, 'col': 5, 'text': 'foo'}, - \ {'lnum': 10, 'col': 6, 'text': 'bar'}, - \ {'lnum': 20, 'col': 5, 'text': 'baz'}, - \ ], - \ GetList() +Execute(loclist jumping not jump when the loclist is empty): + let g:ale_buffer_info[bufnr('%')].loclist = [] -Execute(quickfix should be filtered and sorted appropriately for jumping): - let g:ale_set_loclist = 0 - let g:ale_set_quickfix = 1 - - :new - - let g:new_buffer = bufnr('%') - - AssertNotEqual g:new_buffer, g:buffer - - call setqflist([ - \ {'lnum': 1, 'col': 1, 'text': 'ignore this', 'bufnr': g:buffer}, - \ {'lnum': 20, 'col': 5, 'text': 'baz', 'bufnr': g:new_buffer}, - \ {'lnum': 10, 'col': 6, 'text': 'bar', 'bufnr': g:new_buffer}, - \ {'lnum': 10, 'col': 5, 'text': 'foo', 'bufnr': g:new_buffer}, - \]) - - AssertEqual - \ [ - \ {'lnum': 10, 'col': 5, 'text': 'foo'}, - \ {'lnum': 10, 'col': 6, 'text': 'bar'}, - \ {'lnum': 20, 'col': 5, 'text': 'baz'}, - \ ], - \ GetList() - -Execute(An empty List should be returned when both lists are turned off): - let g:ale_set_loclist = 0 - let g:ale_set_quickfix = 0 - - call setqflist([{'lnum': 1, 'col': 1, 'text': 'foo', 'bufnr': bufnr('%')}]) - call setloclist(winnr(), [{'lnum': 1, 'col': 1, 'text': 'foo', 'bufnr': bufnr('%')}]) - - AssertEqual [], GetList() - -Execute(quickfix should take precedence over loclist when on): - let g:ale_set_quickfix = 1 - - call setloclist(winnr(), [ - \ {'lnum': 1, 'col': 1, 'text': 'ignore this', 'bufnr': g:buffer} - \]) - call setqflist([ - \ {'lnum': 1, 'col': 1, 'text': 'foo', 'bufnr': g:buffer}, - \]) - - AssertEqual [{'lnum': 1, 'col': 1, 'text': 'foo'}], GetList() + AssertEqual [1, 6], TestJump('before', 0, [1, 6]) + AssertEqual [1, 6], TestJump('before', 1, [1, 6]) + AssertEqual [1, 6], TestJump('after', 0, [1, 6]) + AssertEqual [1, 6], TestJump('after', 1, [1, 6])