#653 - Update the loclist binary search to work with buffer numbers, to filter out items for other buffers

This commit is contained in:
w0rp
2017-08-12 14:27:47 +01:00
parent 7614560a6e
commit c52a4910bf
5 changed files with 83 additions and 41 deletions

View File

@@ -3,7 +3,7 @@
function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
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 : ''
endfunction

View File

@@ -62,10 +62,11 @@ function! ale#cursor#TruncatedEcho(message) abort
endfunction
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: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] : {}
return [l:info, l:loc]

View File

@@ -41,37 +41,52 @@ function! ale#util#LocItemCompare(left, right) abort
return 0
endfunction
" This function will perform a binary search to find a message from the
" loclist to echo when the cursor moves.
function! ale#util#BinarySearch(loclist, line, column) abort
" This function will perform a binary search and a small sequential search
" on the list to find the last problem in the buffer and line which is
" 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:max = len(a:loclist) - 1
let l:last_column_match = -1
while 1
if l:max < l:min
return l:last_column_match
return -1
endif
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
if a:loclist[l:mid]['lnum'] < a:line
" Binary search for equal buffers, equal lines, then near columns.
if l:item.bufnr < a:buffer
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
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
if a:loclist[l:mid]['col'] < a:column
let l:min = l:mid + 1
elseif a:loclist[l:mid]['col'] > a:column
let l:max = l:mid - 1
else
return l:mid
endif
" Search backwards to find the first problem on the line.
while l:index > 0
\&& a:loclist[l:index - 1].bufnr == a:buffer
\&& a:loclist[l:index - 1].lnum == a:line
let l:index -= 1
endwhile
" 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
endwhile
endfunction