From 4c6c5bf84fa31ab18ff83122c12b7e8edb18bd1e Mon Sep 17 00:00:00 2001 From: w0rp Date: Thu, 13 Jul 2017 23:27:02 +0100 Subject: #697 - Remove highlights more thoroughly --- autoload/ale/engine.vim | 5 -- autoload/ale/highlight.vim | 131 +++++++++++++----------------------- test/test_highlight_clearing.vader | 4 -- test/test_highlight_placement.vader | 26 +++++++ 4 files changed, 71 insertions(+), 95 deletions(-) delete mode 100644 test/test_highlight_clearing.vader diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 616ee351..6cde4bf7 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -667,11 +667,6 @@ endfunction function! ale#engine#Cleanup(buffer) abort call ale#engine#RunLinters(a:buffer, [], 1) - if g:ale_set_highlights - call ale#highlight#UnqueueHighlights(a:buffer) - call ale#highlight#RemoveHighlights() - endif - call remove(g:ale_buffer_info, a:buffer) endfunction diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim index b24fd82b..a109a265 100644 --- a/autoload/ale/highlight.vim +++ b/autoload/ale/highlight.vim @@ -22,12 +22,6 @@ if !hlexists('ALEInfo') highlight link ALEInfo ALEWarning endif -" This map holds highlights to be set when buffers are opened. -" We can only set highlights for whatever the current buffer is, so we will -" wait until the buffer is entered again to show the highlights, unless -" the buffer is in focus when linting completes. -let s:buffer_highlights = {} -let s:buffer_restore_map = {} " The maximum number of items for the second argument of matchaddpos() let s:MAX_POS_VALUES = 8 let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) @@ -53,86 +47,56 @@ function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort \) endfunction -function! ale#highlight#UnqueueHighlights(buffer) abort - if has_key(s:buffer_highlights, a:buffer) - call remove(s:buffer_highlights, a:buffer) - endif - - if has_key(s:buffer_restore_map, a:buffer) - call remove(s:buffer_restore_map, a:buffer) - endif -endfunction - -function! s:GetALEMatches() abort - return filter(getmatches(), 'v:val.group =~# ''^ALE''') -endfunction - " Given a loclist for current items to highlight, remove all highlights " except these which have matching loclist item entries. function! ale#highlight#RemoveHighlights() abort - for l:match in s:GetALEMatches() - call matchdelete(l:match.id) + for l:match in getmatches() + if l:match.group =~# '^ALE' + call matchdelete(l:match.id) + endif endfor endfunction function! ale#highlight#UpdateHighlights() abort - let l:buffer = bufnr('%') - let l:has_new_items = has_key(s:buffer_highlights, l:buffer) - let l:loclist = l:has_new_items ? remove(s:buffer_highlights, l:buffer) : [] + let l:item_list = g:ale_enabled + \ ? get(b:, 'ale_highlight_items', []) + \ : [] - if l:has_new_items || !g:ale_enabled - call ale#highlight#RemoveHighlights() - endif + call ale#highlight#RemoveHighlights() - " Restore items from the map of hidden items, - " if we don't have some new items to set already. - if empty(l:loclist) && has_key(s:buffer_restore_map, l:buffer) - let l:loclist = s:buffer_restore_map[l:buffer] - endif - - if g:ale_enabled - for l:item in l:loclist - if l:item.type ==# 'W' - if get(l:item, 'sub_type', '') ==# 'style' - let l:group = 'ALEStyleWarning' - else - let l:group = 'ALEWarning' - endif - elseif l:item.type ==# 'I' - let l:group = 'ALEInfo' - elseif get(l:item, 'sub_type', '') ==# 'style' - let l:group = 'ALEStyleError' + for l:item in l:item_list + if l:item.type ==# 'W' + if get(l:item, 'sub_type', '') ==# 'style' + let l:group = 'ALEStyleWarning' else - let l:group = 'ALEError' + let l:group = 'ALEWarning' endif - - let l:line = l:item.lnum - let l:col = l:item.col - let l:end_line = get(l:item, 'end_lnum', l:line) - let l:end_col = get(l:item, 'end_col', l:col) - - " 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(l:line, l:col, l:end_line, l:end_col), - \ 'matchaddpos(l:group, v:val)' - \) - endfor - endif + elseif l:item.type ==# 'I' + let l:group = 'ALEInfo' + elseif get(l:item, 'sub_type', '') ==# 'style' + let l:group = 'ALEStyleError' + else + let l:group = 'ALEError' + endif + + let l:line = l:item.lnum + let l:col = l:item.col + let l:end_line = get(l:item, 'end_lnum', l:line) + let l:end_col = get(l:item, 'end_col', l:col) + + " 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(l:line, l:col, l:end_line, l:end_col), + \ 'matchaddpos(l:group, v:val)' + \) + endfor endfunction function! ale#highlight#BufferHidden(buffer) abort - let l:loclist = get(g:ale_buffer_info, a:buffer, {'loclist': []}).loclist - - " Remember loclist items, so they can be restored later. - if !empty(l:loclist) - let s:buffer_restore_map[a:buffer] = filter( - \ copy(l:loclist), - \ 'v:val.bufnr == a:buffer && v:val.col > 0' - \) - - call ale#highlight#RemoveHighlights() - endif + " Remove highlights right away when buffers are hidden. + " They will be restored later when buffers are entered. + call ale#highlight#RemoveHighlights() endfunction augroup ALEHighlightBufferGroup @@ -142,19 +106,14 @@ augroup ALEHighlightBufferGroup augroup END function! ale#highlight#SetHighlights(buffer, loclist) abort - " Only set set items for the buffer if ALE is enabled. - if g:ale_enabled - " Set a list of items to be set as highlights for a buffer when - " we next open it. - " - " We'll filter the loclist down to items we can set now. - let s:buffer_highlights[a:buffer] = filter( - \ copy(a:loclist), - \ 'v:val.bufnr == a:buffer && v:val.col > 0' - \) + let l:new_list = g:ale_enabled + \ ? filter(copy(a:loclist), 'v:val.bufnr == a:buffer && v:val.col > 0') + \ : [] - " Update highlights for the current buffer, which may or may not - " be the buffer we just set highlights for. - call ale#highlight#UpdateHighlights() - endif + " Set the list in the buffer variable. + call setbufvar(str2nr(a:buffer), 'ale_highlight_items', l:new_list) + + " Update highlights for the current buffer, which may or may not + " be the buffer we just set highlights for. + call ale#highlight#UpdateHighlights() endfunction diff --git a/test/test_highlight_clearing.vader b/test/test_highlight_clearing.vader deleted file mode 100644 index bf805924..00000000 --- a/test/test_highlight_clearing.vader +++ /dev/null @@ -1,4 +0,0 @@ -Execute(ALE should be able to queue highlights and clear them for some other buffer): - " We'll just make sure that this doesn't blow up. - call ale#highlight#SetHighlights(bufnr('%') + 1, []) - call ale#highlight#UnqueueHighlights(bufnr('%') + 1) diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader index 2e6a0ce3..02f570b9 100644 --- a/test/test_highlight_placement.vader +++ b/test/test_highlight_placement.vader @@ -204,3 +204,29 @@ Execute(Highlighting should support errors spanning many lines): \ }, \ ], \ GetMatchesWithoutIDs() + \ +Execute(Highlights should always be cleared when the buffer highlight list is empty): + " Add our highlights and something else. + call matchaddpos('ALEError', [[1, 1, 1]]) + call matchaddpos('SomeOtherGroup', [[1, 1, 1]]) + + AssertEqual + \ [ + \ {'group': 'ALEError', 'priority': 10, 'pos1': [1, 1, 1]}, + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}, + \ ], + \ GetMatchesWithoutIDs() + + " Set the List we use for holding highlights for buffers. + let b:ale_highlight_items = [] + + " Call the function for updating the highlights called when buffers + " are entered, or when problems are presented. + call ale#highlight#UpdateHighlights() + + " Check that we remove our highlights. + AssertEqual + \ [ + \ {'group': 'SomeOtherGroup', 'priority': 10, 'pos1': [1, 1, 1]}, + \ ], + \ GetMatchesWithoutIDs() -- cgit v1.2.3