Print the most severe problem with virtualtext

Fix the ordering of virtualtext so we print the most severe problem on a
line. If two problems are the most severe, we will print the left-most
problem.
This commit is contained in:
w0rp 2023-09-10 17:44:25 +01:00
parent 385dc4130c
commit 1bf445c6d5
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
3 changed files with 68 additions and 18 deletions

View File

@ -274,6 +274,32 @@ function! ale#virtualtext#ShowCursorWarningWithDelay() abort
endif
endfunction
function! ale#virtualtext#CompareSeverityPerLine(left, right) abort
" Compare lines
if a:left.lnum < a:right.lnum
return -1
endif
if a:left.lnum > a:right.lnum
return 1
endif
let l:left_priority = ale#util#GetItemPriority(a:left)
let l:right_priority = ale#util#GetItemPriority(a:right)
" Put highest priority items first.
if l:left_priority > l:right_priority
return -1
endif
if l:left_priority < l:right_priority
return 1
endif
" Put the first seen problem first.
return a:left.col - a:right.col
endfunction
function! ale#virtualtext#SetTexts(buffer, loclist) abort
if !has('nvim') && s:emulate_virt
return
@ -281,17 +307,19 @@ function! ale#virtualtext#SetTexts(buffer, loclist) abort
call ale#virtualtext#Clear(a:buffer)
let l:filter = ale#Var(a:buffer,'virtualtext_single')
let l:seen = {}
let l:buffer_list = filter(copy(a:loclist), 'v:val.bufnr == a:buffer')
for l:item in a:loclist
if l:item.bufnr == a:buffer
let l:line = max([1, l:item.lnum])
if ale#Var(a:buffer,'virtualtext_single')
" If we want a single problem per line, sort items on each line by
" highest severity and then lowest column position, then de-duplicate
" the items by line.
call uniq(
\ sort(l:buffer_list, function('ale#virtualtext#CompareSeverityPerLine')),
\ {a, b -> a.lnum - b.lnum}
\)
endif
if !has_key(l:seen,l:line) || l:filter == 0
call ale#virtualtext#ShowMessage(a:buffer, l:item)
let l:seen[l:line] = 1
endif
endif
for l:item in l:buffer_list
call ale#virtualtext#ShowMessage(a:buffer, l:item)
endfor
endfunction

View File

@ -2443,9 +2443,9 @@ g:ale_virtualtext_single *g:ale_virtualtext_single*
appended in turn.
With `single` set to a non-zero value, only the first problem on a line will
be printed with virtual text. The problem at the left-most position on a
line will be printed. If two problems exist at the same position, the most
severe problem will be printed.
be printed with virtual text. The most severe problem on a line will be
printed. If two problems exist on a line of equal severity, the problem at
the left-most position will be printed.
g:ale_virtualenv_dir_names *g:ale_virtualenv_dir_names*

View File

@ -37,6 +37,27 @@ Before:
\ 'col': 5,
\ 'text': 'Line 2 warning 2',
\ },
\ {
\ 'bufnr': bufnr(''),
\ 'type': 'W',
\ 'lnum': 3,
\ 'col': 3,
\ 'text': 'Line 3 warning 1',
\ },
\ {
\ 'bufnr': bufnr(''),
\ 'type': 'E',
\ 'lnum': 3,
\ 'col': 5,
\ 'text': 'Line 3 error 1',
\ },
\ {
\ 'bufnr': bufnr(''),
\ 'type': 'E',
\ 'lnum': 3,
\ 'col': 6,
\ 'text': 'Line 3 error 2',
\ },
\ ],
\ },
\}
@ -79,6 +100,7 @@ Execute(Comment text should be detected correctly for HTML files):
Given python(An example Python file):
# line 1
# line 2
# line 3
Execute(We should not show virtualtext when disabled):
if has('patch-9.0.0297') || has('nvim-0.8.0')
@ -157,11 +179,11 @@ Execute(We should be able to change the virtualtext prefix per-buffer):
AssertEqual 'B> Line 1 error', ale#virtualtext#GetLastMessageForTests()
endif
Execute(We should set errors across all lines):
Execute(We should be able to set messages across all lines):
if has('patch-9.0.0297') || has('nvim-0.8.0')
call ale#virtualtext#SetTexts(bufnr(''), g:ale_buffer_info[bufnr('')].loclist)
AssertEqual '# W: Line 2 warning 2', ale#virtualtext#GetLastMessageForTests()
AssertEqual '# E: Line 3 error 2', ale#virtualtext#GetLastMessageForTests()
if has('patch-9.0.0297')
AssertEqual ['ALEVirtualTextError'], map(prop_list(1), {_, v -> v.type})
@ -176,12 +198,12 @@ Execute(We should be able to limit virtual messages to the first one only):
if has('patch-9.0.0297') || has('nvim-0.8.0')
call ale#virtualtext#SetTexts(bufnr(''), g:ale_buffer_info[bufnr('')].loclist)
AssertEqual '# W: Line 2 warning 1', ale#virtualtext#GetLastMessageForTests()
AssertEqual '# E: Line 3 error 1', ale#virtualtext#GetLastMessageForTests()
if has('patch-9.0.0297')
AssertEqual ['ALEVirtualTextError'], map(prop_list(1), {_, v -> v.type})
AssertEqual ['ALEVirtualTextWarning'],
\ map(prop_list(2), {_, v -> v.type})
AssertEqual ['ALEVirtualTextWarning'], map(prop_list(2), {_, v -> v.type})
AssertEqual ['ALEVirtualTextError'], map(prop_list(3), {_, v -> v.type})
endif
endif