diff options
-rw-r--r-- | autoload/ale/highlight.vim | 128 | ||||
-rw-r--r-- | test/test_nvim_api_highlight.vader | 160 |
2 files changed, 16 insertions, 272 deletions
diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim index f228aa44..3ce6bff4 100644 --- a/autoload/ale/highlight.vim +++ b/autoload/ale/highlight.vim @@ -26,41 +26,6 @@ endif let s:MAX_POS_VALUES = 8 let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) -" Check if we have neovim's buffer highlight API -" -" Below we define some functions' implementation conditionally if this API -" exists or not. -" -" The API itself is more ergonomic and neovim performs highlights positions -" rebases during edits so we see less stalled highlights. -let s:nvim_api = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace') - -function! ale#highlight#HasNeovimApi() abort - return s:nvim_api -endfunction - -function! ale#highlight#nvim_buf_clear_namespace(...) abort - return call('nvim_buf_clear_namespace', a:000) -endfunction - -function! ale#highlight#nvim_buf_add_highlight(...) abort - return call('nvim_buf_add_highlight', a:000) -endfunction - -function! s:ale_nvim_highlight_id(bufnr) abort - let l:id = getbufvar(a:bufnr, 'ale_nvim_highlight_id', -1) - - if l:id is -1 - " NOTE: This will highlight nothing but will allocate new id - let l:id = ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, 0, '', 0, 0, -1 - \) - call setbufvar(a:bufnr, 'ale_nvim_highlight_id', l:id) - endif - - return l:id -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. @@ -86,90 +51,29 @@ endfunction " except these which have matching loclist item entries. function! ale#highlight#RemoveHighlights() abort - if ale#highlight#HasNeovimApi() - if get(b:, 'ale_nvim_highlight_id', 0) - let l:bufnr = bufnr('%') - " NOTE: 0, -1 means from 0 line till the end of buffer - call ale#highlight#nvim_buf_clear_namespace( - \ l:bufnr, - \ b:ale_nvim_highlight_id, - \ 0, -1 - \) + for l:match in getmatches() + if l:match.group =~# '^ALE' + call matchdelete(l:match.id) endif - else - for l:match in getmatches() - if l:match.group =~# '^ALE' - call matchdelete(l:match.id) - endif - endfor - endif + endfor endfunction function! s:highlight_line(bufnr, lnum, group) abort - if ale#highlight#HasNeovimApi() - let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr) - call ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, l:highlight_id, a:group, - \ a:lnum - 1, 0, -1 - \) - else - call matchaddpos(a:group, [a:lnum]) - endif + call matchaddpos(a:group, [a:lnum]) endfunction function! s:highlight_range(bufnr, range, group) abort - if ale#highlight#HasNeovimApi() - let l:line_count = len(getbufline(a:bufnr, 1, '$')) - - let l:highlight_id = s:ale_nvim_highlight_id(a:bufnr) - " NOTE: lines and columns indicies are 0-based in nvim_buf_* API. - let l:lnum = a:range.lnum - 1 - let l:end_lnum = min([a:range.end_lnum, l:line_count]) - 1 - let l:col = a:range.col - 1 - let l:end_col = a:range.end_col - - if l:lnum is l:end_lnum - " For single lines, just return the one position. - call ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, l:highlight_id, a:group, - \ l:lnum, l:col, l:end_col - \) - elseif l:lnum < l:end_lnum - " highlight first line from start till the line end - call ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, l:highlight_id, a:group, - \ l:lnum, l:col, -1 - \) - - " highlight all lines between the first and last entirely - let l:cur = l:lnum + 1 - - while l:cur < l:end_lnum - call ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, l:highlight_id, a:group, - \ l:cur, 0, -1 - \ ) - let l:cur += 1 - endwhile - - call ale#highlight#nvim_buf_add_highlight( - \ a:bufnr, l:highlight_id, a:group, - \ l:end_lnum, 0, l:end_col - \) - endif - else - " Set all of the positions, which are chunked into Lists which - " are as large as will be accepted by matchaddpos. - call map( - \ ale#highlight#CreatePositions( - \ a:range.lnum, - \ a:range.col, - \ a:range.end_lnum, - \ a:range.end_col - \ ), - \ 'matchaddpos(a:group, v:val)' - \) - endif + " Set all of the positions, which are chunked into Lists which + " are as large as will be accepted by matchaddpos. + call map( + \ ale#highlight#CreatePositions( + \ a:range.lnum, + \ a:range.col, + \ a:range.end_lnum, + \ a:range.end_col + \ ), + \ 'matchaddpos(a:group, v:val)' + \) endfunction function! ale#highlight#UpdateHighlights() abort diff --git a/test/test_nvim_api_highlight.vader b/test/test_nvim_api_highlight.vader deleted file mode 100644 index 829c3ad7..00000000 --- a/test/test_nvim_api_highlight.vader +++ /dev/null @@ -1,160 +0,0 @@ -Before: - Save g:ale_enabled - Save g:ale_set_signs - - let g:nvim_buf_clear_namespace_calls = [] - let g:nvim_buf_add_highlight_calls = [] - - call ale#test#SetDirectory('/testplugin/test/highlight') - call ale#test#SetFilename('dummy.txt') - - runtime autoload/ale/highlight.vim - - let g:ale_set_signs = 1 - let g:ale_enabled = 1 - let b:ale_nvim_highlight_id = 42 - let b:ale_highlight_items = [] - - function! ale#highlight#nvim_buf_clear_namespace(...) abort - call add(g:nvim_buf_clear_namespace_calls, a:000) - endfunction - - function! ale#highlight#nvim_buf_add_highlight(...) abort - call add(g:nvim_buf_add_highlight_calls, a:000) - return 42 " returns namespace id - endfunction - -After: - Restore - - unlet! b:ale_enabled - unlet! b:ale_nvim_highlight_id - unlet! b:ale_highlight_items - - unlet! g:nvim_buf_clear_namespace_calls - unlet! g:nvim_buf_add_highlight_calls - - call ale#test#RestoreDirectory() - call ale#linter#Reset() - - runtime autoload/ale/highlight.vim - -Given foobar (Some imaginary filetype): - <contents> - -Execute(Check usage of nvim_buf_clear_namespace): - if ale#highlight#HasNeovimApi() - call ale#highlight#SetHighlights(bufnr(''), []) - - AssertEqual 1, len(g:nvim_buf_clear_namespace_calls) - AssertEqual - \ [[bufnr(''), 42, 0, -1]], - \ g:nvim_buf_clear_namespace_calls - endif - -Execute(Check usage of nvim_buf_add_highlight / single char): - if ale#highlight#HasNeovimApi() - call ale#highlight#SetHighlights(bufnr(''), [ - \ { - \ 'bufnr': bufnr(''), - \ 'type': 'E', - \ 'lnum': 2, - \ 'col': 4, - \ } - \]) - - " Highlights are cleared on update - AssertEqual 1, len(g:nvim_buf_clear_namespace_calls) - AssertEqual [[bufnr(''), 42, 0, -1]], g:nvim_buf_clear_namespace_calls - - " Should highlight a single char by lnum, col - AssertEqual 1, len(g:nvim_buf_add_highlight_calls) - AssertEqual - \ [[bufnr(''), 42, 'ALEError', 1, 3, 4]], - \ g:nvim_buf_add_highlight_calls - endif - -Execute(Check usage of nvim_buf_add_highlight / single line span): - if ale#highlight#HasNeovimApi() - call ale#highlight#SetHighlights(bufnr(''), [ - \ { - \ 'bufnr': bufnr(''), - \ 'type': 'E', - \ 'lnum': 2, - \ 'col': 4, - \ 'end_lnum': 2, - \ 'end_col': 10, - \ } - \]) - - " Highlights are cleared on update - AssertEqual 1, len(g:nvim_buf_clear_namespace_calls) - AssertEqual [[bufnr(''), 42, 0, -1]], g:nvim_buf_clear_namespace_calls - - " Should highlight a span between col and end_col on lnum - AssertEqual 1, len(g:nvim_buf_add_highlight_calls) - AssertEqual - \ [[bufnr(''), 42, 'ALEError', 1, 3, 10]], - \ g:nvim_buf_add_highlight_calls - endif - -Execute(Check usage of nvim_buf_add_highlight / multiple lines span): - if ale#highlight#HasNeovimApi() - call ale#highlight#SetHighlights(bufnr(''), [ - \ { - \ 'bufnr': bufnr(''), - \ 'type': 'E', - \ 'lnum': 2, - \ 'col': 4, - \ 'end_lnum': 5, - \ 'end_col': 10, - \ } - \]) - - " Highlights are cleared on update - AssertEqual 1, len(g:nvim_buf_clear_namespace_calls) - AssertEqual [[bufnr(''), 42, 0, -1]], g:nvim_buf_clear_namespace_calls - - " Should highlight all lines from lnum till end_lnum - AssertEqual 4, len(g:nvim_buf_add_highlight_calls) - AssertEqual - \ [ - \ [bufnr(''), 42, 'ALEError', 1, 3, -1], - \ [bufnr(''), 42, 'ALEError', 2, 0, -1], - \ [bufnr(''), 42, 'ALEError', 3, 0, -1], - \ [bufnr(''), 42, 'ALEError', 4, 0, 10] - \ ], - \ g:nvim_buf_add_highlight_calls - endif - -Execute(Check usage of nvim_buf_add_highlight / line highights): - let g:ale_set_signs = 0 - - if ale#highlight#HasNeovimApi() - call ale#highlight#SetHighlights(bufnr(''), [ - \ { - \ 'bufnr': bufnr(''), - \ 'type': 'E', - \ 'lnum': 2, - \ 'col': 4, - \ 'end_lnum': 5, - \ 'end_col': 10, - \ } - \]) - - " Highlights are cleared on update - AssertEqual 1, len(g:nvim_buf_clear_namespace_calls) - AssertEqual [[bufnr(''), 42, 0, -1]], g:nvim_buf_clear_namespace_calls - - " Now the last highlight should be put on the entire line - AssertEqual 5, len(g:nvim_buf_add_highlight_calls) - AssertEqual - \ [ - \ [bufnr(''), 42, 'ALEError', 1, 3, -1], - \ [bufnr(''), 42, 'ALEError', 2, 0, -1], - \ [bufnr(''), 42, 'ALEError', 3, 0, -1], - \ [bufnr(''), 42, 'ALEError', 4, 0, 10], - \ [bufnr(''), 42, 'ALEErrorLine', 1, 0, -1] - \ ], - \ g:nvim_buf_add_highlight_calls - endif |