Merge pull request #2638 from frangio/nvim-highlight

Use Neovim API for highlights when available
This commit is contained in:
w0rp 2019-09-01 10:47:28 +01:00 committed by GitHub
commit 7d7ddf22d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 12 deletions

View File

@ -26,6 +26,21 @@ endif
let s:MAX_POS_VALUES = 8
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
if s:has_nvim_highlight
let s:ns_id = nvim_create_namespace('ale_highlight')
endif
" Wrappers are necessary to test this functionality by faking the calls in tests.
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
endfunction
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
endfunction
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
if a:line >= a:end_line
" For single lines, just return the one position.
@ -51,15 +66,53 @@ endfunction
" except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort
for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
if s:has_nvim_highlight
call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
else
for l:match in getmatches()
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
endif
endfunction
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
" available. This involves iterating over the position list, switching from
" 1-based indexing to 0-based indexing, and translating the multiple ways
" that position can be specified for matchaddpos into line + col_start +
" col_end.
function! s:matchaddpos(group, pos_list) abort
if s:has_nvim_highlight
for l:pos in a:pos_list
let l:line = type(l:pos) == v:t_number
\ ? l:pos - 1
\ : l:pos[0] - 1
if type(l:pos) == v:t_number || len(l:pos) == 1
let l:col_start = 0
let l:col_end = s:MAX_COL_SIZE
else
let l:col_start = l:pos[1] - 1
let l:col_end = l:col_start + get(l:pos, 2, 1)
endif
call ale#highlight#nvim_buf_add_highlight(
\ bufnr(''),
\ s:ns_id,
\ a:group,
\ l:line,
\ l:col_start,
\ l:col_end,
\)
endfor
else
call matchaddpos(a:group, a:pos_list)
endif
endfunction
function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum])
call s:matchaddpos(a:group, [a:lnum])
endfunction
function! s:highlight_range(bufnr, range, group) abort
@ -72,7 +125,7 @@ function! s:highlight_range(bufnr, range, group) abort
\ a:range.end_lnum,
\ a:range.end_col
\ ),
\ 'matchaddpos(a:group, v:val)'
\ 's:matchaddpos(a:group, v:val)'
\)
endfunction

View File

@ -8,6 +8,8 @@ Before:
Save g:ale_set_quickfix
Save g:ale_set_signs
runtime autoload/ale/highlight.vim
let g:ale_run_synchronously = 1
unlet! g:ale_run_synchronously_callbacks
let g:ale_set_highlights = 1
@ -42,16 +44,54 @@ Before:
\]
endfunction
let g:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
let g:nvim_highlight_matches = {}
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
if a:line_end != -1
throw 'nvim api behavior not supported'
endif
let l:matches = get(g:nvim_highlight_matches, a:buffer, [])
call filter(
\ l:matches,
\ {_, val -> val.pos1[0] < (a:line_start + 1) },
\)
endfunction
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
if a:col_end == -1
throw 'nvim api behavior not supported'
endif
let l:matches = get(g:nvim_highlight_matches, a:buffer, [])
let g:nvim_highlight_matches[a:buffer] = l:matches
let l:new_match = {
\ 'group': a:hl_group,
\ 'priority': 10,
\ 'pos1': [a:line + 1, a:col_start + 1, a:col_end - a:col_start],
\}
call add(l:matches, l:new_match)
" sort by line number to emulate getmatches faithfully
call sort(l:matches, {m1, m2 -> m1.pos1[0] - m2.pos1[0]})
endfunction
" We don't care what the IDs are, just that we have some matches.
" The IDs are generated.
function! GetMatchesWithoutIDs() abort
let l:list = getmatches()
if g:has_nvim_highlight
return get(g:nvim_highlight_matches, bufnr(''), [])
else
let l:list = getmatches()
for l:item in l:list
call remove(l:item, 'id')
endfor
for l:item in l:list
call remove(l:item, 'id')
endfor
return l:list
return l:list
endif
endfunction
call ale#linter#Define('testft', {
@ -68,6 +108,8 @@ After:
unlet! g:ale_run_synchronously_callbacks
unlet! g:items
unlet! b:ale_enabled
unlet! g:has_nvim_highlight
unlet! g:nvim_highlight_matches
delfunction GenerateResults
call ale#linter#Reset()
@ -75,6 +117,8 @@ After:
sign unplace *
highlight clear SomeOtherGroup
runtime autoload/ale/highlight.vim
Given testft(A Javscript file with warnings/errors):
foo
bar