#653 - Update the loclist binary search to work with buffer numbers, to filter out items for other buffers
This commit is contained in:
parent
7614560a6e
commit
c52a4910bf
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
|
function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
|
||||||
let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
|
let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
|
||||||
let l:index = ale#util#BinarySearch(l:loclist, a:lnum, a:col)
|
let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col)
|
||||||
|
|
||||||
return l:index >= 0 ? l:loclist[l:index].text : ''
|
return l:index >= 0 ? l:loclist[l:index].text : ''
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -62,10 +62,11 @@ function! ale#cursor#TruncatedEcho(message) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:FindItemAtCursor() abort
|
function! s:FindItemAtCursor() abort
|
||||||
let l:info = get(g:ale_buffer_info, bufnr(''), {})
|
let l:buf = bufnr('')
|
||||||
|
let l:info = get(g:ale_buffer_info, l:buf, {})
|
||||||
let l:loclist = get(l:info, 'loclist', [])
|
let l:loclist = get(l:info, 'loclist', [])
|
||||||
let l:pos = getcurpos()
|
let l:pos = getcurpos()
|
||||||
let l:index = ale#util#BinarySearch(l:loclist, l:pos[1], l:pos[2])
|
let l:index = ale#util#BinarySearch(l:loclist, l:buf, l:pos[1], l:pos[2])
|
||||||
let l:loc = l:index >= 0 ? l:loclist[l:index] : {}
|
let l:loc = l:index >= 0 ? l:loclist[l:index] : {}
|
||||||
|
|
||||||
return [l:info, l:loc]
|
return [l:info, l:loc]
|
||||||
|
@ -41,37 +41,52 @@ function! ale#util#LocItemCompare(left, right) abort
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" This function will perform a binary search to find a message from the
|
" This function will perform a binary search and a small sequential search
|
||||||
" loclist to echo when the cursor moves.
|
" on the list to find the last problem in the buffer and line which is
|
||||||
function! ale#util#BinarySearch(loclist, line, column) abort
|
" on or before the column. The index of the problem will be returned.
|
||||||
|
"
|
||||||
|
" -1 will be returned if nothing can be found.
|
||||||
|
function! ale#util#BinarySearch(loclist, buffer, line, column) abort
|
||||||
let l:min = 0
|
let l:min = 0
|
||||||
let l:max = len(a:loclist) - 1
|
let l:max = len(a:loclist) - 1
|
||||||
let l:last_column_match = -1
|
|
||||||
|
|
||||||
while 1
|
while 1
|
||||||
if l:max < l:min
|
if l:max < l:min
|
||||||
return l:last_column_match
|
return -1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:mid = (l:min + l:max) / 2
|
let l:mid = (l:min + l:max) / 2
|
||||||
let l:obj = a:loclist[l:mid]
|
let l:item = a:loclist[l:mid]
|
||||||
|
|
||||||
" Binary search to get on the same line
|
" Binary search for equal buffers, equal lines, then near columns.
|
||||||
if a:loclist[l:mid]['lnum'] < a:line
|
if l:item.bufnr < a:buffer
|
||||||
let l:min = l:mid + 1
|
let l:min = l:mid + 1
|
||||||
elseif a:loclist[l:mid]['lnum'] > a:line
|
elseif l:item.bufnr > a:buffer
|
||||||
|
let l:max = l:mid - 1
|
||||||
|
elseif l:item.lnum < a:line
|
||||||
|
let l:min = l:mid + 1
|
||||||
|
elseif l:item.lnum > a:line
|
||||||
let l:max = l:mid - 1
|
let l:max = l:mid - 1
|
||||||
else
|
else
|
||||||
let l:last_column_match = l:mid
|
" This part is a small sequential search.
|
||||||
|
let l:index = l:mid
|
||||||
|
|
||||||
" Binary search to get the same column, or near it
|
" Search backwards to find the first problem on the line.
|
||||||
if a:loclist[l:mid]['col'] < a:column
|
while l:index > 0
|
||||||
let l:min = l:mid + 1
|
\&& a:loclist[l:index - 1].bufnr == a:buffer
|
||||||
elseif a:loclist[l:mid]['col'] > a:column
|
\&& a:loclist[l:index - 1].lnum == a:line
|
||||||
let l:max = l:mid - 1
|
let l:index -= 1
|
||||||
else
|
endwhile
|
||||||
return l:mid
|
|
||||||
endif
|
" Find the last problem on or before this column.
|
||||||
|
while l:index < l:max
|
||||||
|
\&& a:loclist[l:index + 1].bufnr == a:buffer
|
||||||
|
\&& a:loclist[l:index + 1].lnum == a:line
|
||||||
|
\&& a:loclist[l:index + 1].col <= a:column
|
||||||
|
let l:index += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return l:index
|
||||||
endif
|
endif
|
||||||
endwhile
|
endwhile
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -3,16 +3,19 @@ Before:
|
|||||||
|
|
||||||
let g:ale_buffer_info[347] = {'loclist': [
|
let g:ale_buffer_info[347] = {'loclist': [
|
||||||
\ {
|
\ {
|
||||||
|
\ 'bufnr': 347,
|
||||||
\ 'lnum': 1,
|
\ 'lnum': 1,
|
||||||
\ 'col': 10,
|
\ 'col': 10,
|
||||||
\ 'text': 'Missing semicolon. (semi)',
|
\ 'text': 'Missing semicolon. (semi)',
|
||||||
\ },
|
\ },
|
||||||
\ {
|
\ {
|
||||||
|
\ 'bufnr': 347,
|
||||||
\ 'lnum': 2,
|
\ 'lnum': 2,
|
||||||
\ 'col': 10,
|
\ 'col': 10,
|
||||||
\ 'text': 'Infix operators must be spaced. (space-infix-ops)'
|
\ 'text': 'Infix operators must be spaced. (space-infix-ops)'
|
||||||
\ },
|
\ },
|
||||||
\ {
|
\ {
|
||||||
|
\ 'bufnr': 347,
|
||||||
\ 'lnum': 2,
|
\ 'lnum': 2,
|
||||||
\ 'col': 15,
|
\ 'col': 15,
|
||||||
\ 'text': 'Missing radix parameter (radix)'
|
\ 'text': 'Missing radix parameter (radix)'
|
||||||
|
@ -1,26 +1,49 @@
|
|||||||
Before:
|
Before:
|
||||||
let g:loclist = [
|
let g:loclist = [
|
||||||
\ {'lnum': 2, 'col': 10},
|
\ {'bufnr': 1, 'lnum': 2, 'col': 10},
|
||||||
\ {'lnum': 3, 'col': 2},
|
\ {'bufnr': 1, 'lnum': 3, 'col': 2},
|
||||||
\ {'lnum': 3, 'col': 10},
|
\ {'bufnr': 1, 'lnum': 3, 'col': 10},
|
||||||
\ {'lnum': 3, 'col': 12},
|
\ {'bufnr': 1, 'lnum': 3, 'col': 12},
|
||||||
\ {'lnum': 3, 'col': 25},
|
\ {'bufnr': 1, 'lnum': 3, 'col': 25},
|
||||||
\ {'lnum': 5, 'col': 4},
|
\ {'bufnr': 1, 'lnum': 5, 'col': 4},
|
||||||
\ {'lnum': 5, 'col': 5},
|
\ {'bufnr': 1, 'lnum': 5, 'col': 5},
|
||||||
|
\ {'bufnr': 1, 'lnum': 9, 'col': 5},
|
||||||
|
\ {'bufnr': 1, 'lnum': 10, 'col': 1},
|
||||||
|
\ {'bufnr': 2, 'lnum': 7, 'col': 10},
|
||||||
|
\ {'bufnr': 2, 'lnum': 9, 'col': 2},
|
||||||
|
\ {'bufnr': 2, 'lnum': 10, 'col': 2},
|
||||||
|
\ {'bufnr': 2, 'lnum': 11, 'col': 2},
|
||||||
\]
|
\]
|
||||||
|
|
||||||
Execute (Exact column matches should be correct):
|
|
||||||
AssertEqual 1, ale#util#BinarySearch(g:loclist, 3, 2)
|
|
||||||
|
|
||||||
Execute (Off lines, there should be no match):
|
|
||||||
AssertEqual -1, ale#util#BinarySearch(g:loclist, 4, 2)
|
|
||||||
|
|
||||||
Execute (Near column matches should be taken):
|
|
||||||
AssertEqual 2, ale#util#BinarySearch(g:loclist, 3, 11)
|
|
||||||
AssertEqual 4, ale#util#BinarySearch(g:loclist, 3, 13)
|
|
||||||
|
|
||||||
Execute (Columns before should be taken when the cursor is far ahead):
|
|
||||||
AssertEqual 4, ale#util#BinarySearch(g:loclist, 3, 300)
|
|
||||||
|
|
||||||
After:
|
After:
|
||||||
unlet g:loclist
|
unlet g:loclist
|
||||||
|
|
||||||
|
Execute(Exact column matches should be correct):
|
||||||
|
AssertEqual 1, ale#util#BinarySearch(g:loclist, 1, 3, 2)
|
||||||
|
|
||||||
|
Execute(Off lines, there should be no match):
|
||||||
|
AssertEqual -1, ale#util#BinarySearch(g:loclist, 1, 4, 2)
|
||||||
|
|
||||||
|
Execute(Near column matches should be taken):
|
||||||
|
AssertEqual 2, ale#util#BinarySearch(g:loclist, 1, 3, 11)
|
||||||
|
AssertEqual 3, ale#util#BinarySearch(g:loclist, 1, 3, 13)
|
||||||
|
|
||||||
|
Execute(Columns before should be taken when the cursor is far ahead):
|
||||||
|
AssertEqual 4, ale#util#BinarySearch(g:loclist, 1, 3, 300)
|
||||||
|
|
||||||
|
Execute(The only problems on lines in later columns should be matched):
|
||||||
|
AssertEqual 7, ale#util#BinarySearch(g:loclist, 1, 9, 1)
|
||||||
|
|
||||||
|
Execute(The only problems on lines in earlier columns should be matched):
|
||||||
|
AssertEqual 8, ale#util#BinarySearch(g:loclist, 1, 10, 30)
|
||||||
|
|
||||||
|
Execute(Lines for other buffers should not be matched):
|
||||||
|
AssertEqual -1, ale#util#BinarySearch(g:loclist, 1, 7, 10)
|
||||||
|
|
||||||
|
Execute(Searches for buffers later in the list should work):
|
||||||
|
AssertEqual 10, ale#util#BinarySearch(g:loclist, 2, 9, 10)
|
||||||
|
|
||||||
|
Execute(Searches should work with just one item):
|
||||||
|
let g:loclist = [{'bufnr': 1, 'lnum': 3, 'col': 10}]
|
||||||
|
|
||||||
|
AssertEqual 0, ale#util#BinarySearch(g:loclist, 1, 3, 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user