From ab50b3a88a741ac86315ae3e716815c6725b159b Mon Sep 17 00:00:00 2001 From: w0rp Date: Wed, 31 May 2017 13:14:39 +0100 Subject: [PATCH] Fix #604 - Support highlights spanning many lines --- autoload/ale/engine.vim | 6 +++- autoload/ale/highlight.vim | 21 ++++++----- test/test_highlight_placement.vader | 26 ++++++++++++++ test/test_highlight_position_chunking.vader | 34 +++++++++--------- test/test_loclist_corrections.vader | 40 ++++++++++++++++++++- 5 files changed, 100 insertions(+), 27 deletions(-) diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 36323354..a99eccca 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -291,11 +291,15 @@ function! ale#engine#FixLocList(buffer, linter, loclist) abort let l:item.detail = l:old_item.detail endif - " Pass on a col_length key if set, used for highlights. + " Pass on a end_col key if set, used for highlights. if has_key(l:old_item, 'end_col') let l:item.end_col = str2nr(l:old_item.end_col) endif + if has_key(l:old_item, 'end_lnum') + let l:item.end_lnum = str2nr(l:old_item.end_lnum) + endif + if has_key(l:old_item, 'sub_type') let l:item.sub_type = l:old_item.sub_type endif diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim index 7807c8da..d63e7166 100644 --- a/autoload/ale/highlight.vim +++ b/autoload/ale/highlight.vim @@ -30,7 +30,7 @@ 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 = 4294967296 +let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort if a:line >= a:end_line @@ -119,8 +119,6 @@ function! ale#highlight#UpdateHighlights() abort if g:ale_enabled for l:item in l:loclist - let l:col = l:item.col - if l:item.type ==# 'W' if get(l:item, 'sub_type', '') ==# 'style' let l:group = 'ALEStyleWarning' @@ -136,12 +134,19 @@ function! ale#highlight#UpdateHighlights() abort endif let l:line = l:item.lnum - let l:size = has_key(l:item, 'end_col') ? l:item.end_col - l:col + 1 : 1 + 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) - " Rememeber the match ID for the item. - " This ID will be used to preserve loclist items which are set - " many times. - let l:item.match_id_list = [matchaddpos(l:group, [[l:line, l:col, l:size]])] + " Set all of the positions, which are chunked into Lists which + " are as large as will be accepted by matchaddpos. + " + " We will remember the IDs we set, so we can preserve some + " highlights when linting buffers after linting files. + let l:item.match_id_list = map( + \ ale#highlight#CreatePositions(l:line, l:col, l:end_line, l:end_col), + \ 'matchaddpos(l:group, v:val)' + \) endfor endif endfunction diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader index a728fce0..6764dffe 100644 --- a/test/test_highlight_placement.vader +++ b/test/test_highlight_placement.vader @@ -31,6 +31,8 @@ Before: highlight link SomeOtherGroup SpellBad After: + unlet! g:items + delfunction GenerateResults call ale#linter#Reset() let g:ale_buffer_info = {} @@ -173,3 +175,27 @@ Execute(Higlight end columns should set an appropriate size): \ {'group': 'ALEInfo', 'id': 23, 'priority': 10, 'pos1': [7, 1, 1]}, \ ], \ getmatches() + +Execute(Highlighting should support errors spanning many lines): + let g:items = [ + \ {'bufnr': bufnr(''), 'type': 'E', 'lnum': 1, 'col': 1, 'end_lnum': 10, 'end_col': 3}, + \] + + call ale#highlight#SetHighlights(bufnr(''), g:items) + + " We should set 2 highlights for the item, as we can only add 8 at a time. + AssertEqual + \ [ + \ { + \ 'group': 'ALEError', 'id': 24, 'priority': 10, 'pos1': [1, 1, 1073741824], + \ 'pos2': [2], 'pos3': [3], 'pos4': [4], 'pos5': [5], 'pos6': [6], + \ 'pos7': [7], 'pos8': [8], + \ }, + \ { + \ 'group': 'ALEError', 'id': 25, 'priority': 10, + \ 'pos1': [9], 'pos2': [10, 1, 3] + \ }, + \ ], + \ getmatches() + + AssertEqual [[24, 25]], map(copy(g:items), 'v:val.match_id_list') diff --git a/test/test_highlight_position_chunking.vader b/test/test_highlight_position_chunking.vader index 120e294d..cd9161b5 100644 --- a/test/test_highlight_position_chunking.vader +++ b/test/test_highlight_position_chunking.vader @@ -9,68 +9,68 @@ Execute(CreatePositions() should support multiple character matches on a single AssertEqual [[[2, 5, 6]]], ale#highlight#CreatePositions(2, 5, 1, 10) Execute(CreatePositions() should support character matches two lines): - AssertEqual [[[1, 5, 4294967296], [2, 1, 10]]], ale#highlight#CreatePositions(1, 5, 2, 10) + AssertEqual [[[1, 5, 1073741824], [2, 1, 10]]], ale#highlight#CreatePositions(1, 5, 2, 10) Execute(CreatePositions() should support character matches across many lines): " Test chunks from 1,3 to 1,17 AssertEqual [ - \ [[1, 5, 4294967296], 2, [3, 1, 10]], + \ [[1, 5, 1073741824], 2, [3, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 3, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, [4, 1, 10]], + \ [[1, 5, 1073741824], 2, 3, [4, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 4, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, [5, 1, 10]], + \ [[1, 5, 1073741824], 2, 3, 4, [5, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 5, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, [6, 1, 10]], + \ [[1, 5, 1073741824], 2, 3, 4, 5, [6, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 6, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, [7, 1, 10]], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, [7, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 7, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, [8, 1, 10]], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, [8, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 8, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [[9, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 9, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, [10, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 10, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, [11, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 11, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, [12, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 12, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, 12, [13, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 13, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, 12, 13, [14, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 14, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, 12, 13, 14, [15, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 15, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, 12, 13, 14, 15, [16, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 16, 10) AssertEqual [ - \ [[1, 5, 4294967296], 2, 3, 4, 5, 6, 7, 8], + \ [[1, 5, 1073741824], 2, 3, 4, 5, 6, 7, 8], \ [9, 10, 11, 12, 13, 14, 15, 16], \ [[17, 1, 10]], \], ale#highlight#CreatePositions(1, 5, 17, 10) " Test another random sample at higher lines. AssertEqual [ - \ [[21, 8, 4294967296], 22, 23, 24, 25, 26, 27, 28], + \ [[21, 8, 1073741824], 22, 23, 24, 25, 26, 27, 28], \ [29, 30, 31, 32, 33, 34, 35, 36], \ [[37, 1, 2]], \], ale#highlight#CreatePositions(21, 8, 37, 2) diff --git a/test/test_loclist_corrections.vader b/test/test_loclist_corrections.vader index f424424d..4e3f543c 100644 --- a/test/test_loclist_corrections.vader +++ b/test/test_loclist_corrections.vader @@ -129,7 +129,7 @@ Execute(FixLocList should convert line and column numbers correctly): \ [{'text': 'a', 'lnum': '010', 'col': '010'}], \ ) -Execute(FixLocList should pass on col_length values): +Execute(FixLocList should pass on end_col values): " The numbers should be 10, not 8 as octals. AssertEqual \ [ @@ -165,6 +165,44 @@ Execute(FixLocList should pass on col_length values): \ ], \ ) +Execute(FixLocList should pass on end_lnum values): + AssertEqual + \ [ + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 10, + \ 'end_lnum': 13, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \ { + \ 'text': 'a', + \ 'lnum': 10, + \ 'col': 11, + \ 'end_lnum': 13, + \ 'end_col': 12, + \ 'bufnr': bufnr('%'), + \ 'vcol': 0, + \ 'type': 'E', + \ 'nr': -1, + \ 'linter_name': 'foobar', + \ }, + \], + \ ale#engine#FixLocList( + \ bufnr('%'), + \ {'name': 'foobar'}, + \ [ + \ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012', 'end_lnum': '013'}, + \ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12, 'end_lnum': 13}, + \ ], + \ ) + + Execute(FixLocList should allow subtypes to be set): AssertEqual \ [