mirror of
https://github.com/prabirshrestha/vim-lsp.git
synced 2025-12-14 20:35:59 +01:00
Add support for range diagnostics under cursor (#1586)
This commit is contained in:
@@ -29,20 +29,29 @@ function! lsp#internal#diagnostics#under_cursor#get_diagnostic(...) abort
|
|||||||
let l:line = line('.')
|
let l:line = line('.')
|
||||||
let l:col = col('.')
|
let l:col = col('.')
|
||||||
|
|
||||||
|
return lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, l:line, l:col)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Returns a diagnostic object, or empty dictionary if no diagnostics are
|
||||||
|
" available.
|
||||||
|
function! lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(diagnostics, line, col) abort
|
||||||
let l:closest_diagnostic = {}
|
let l:closest_diagnostic = {}
|
||||||
let l:closest_distance = -1
|
let l:closest_distance = -1
|
||||||
|
let l:closest_end_col = -1
|
||||||
|
|
||||||
for l:diagnostic in l:diagnostics
|
for l:diagnostic in a:diagnostics
|
||||||
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['start'])
|
let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['start'])
|
||||||
|
let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['end'])
|
||||||
|
|
||||||
if l:line == l:start_line
|
if (a:line > l:start_line || (a:line == l:start_line && a:col >= l:start_col)) &&
|
||||||
let l:distance = abs(l:start_col - l:col)
|
\ (a:line < l:end_line || (a:line == l:end_line && a:col < l:end_col))
|
||||||
|
let l:distance = abs(l:start_col - a:col)
|
||||||
if l:closest_distance < 0 || l:distance < l:closest_distance
|
if l:closest_distance < 0 || l:distance < l:closest_distance
|
||||||
|
let l:closest_end_col = l:end_col
|
||||||
let l:closest_diagnostic = l:diagnostic
|
let l:closest_diagnostic = l:diagnostic
|
||||||
let l:closest_distance = l:distance
|
let l:closest_distance = l:distance
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return l:closest_diagnostic
|
return l:closest_diagnostic
|
||||||
endfunction
|
endfunction
|
||||||
|
|||||||
88
test/lsp/internal/diagnostics/under_cursor.vimspec
Normal file
88
test/lsp/internal/diagnostics/under_cursor.vimspec
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
Describe lsp#internal#diagnostics#under_cursor
|
||||||
|
" refer to lsp#test#projectdir('go') . '/documentdiagnostics.go'
|
||||||
|
|
||||||
|
It should not trigger diagnostics when cursor is outside diagnostic range
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 1, 1), {})
|
||||||
|
End
|
||||||
|
|
||||||
|
It should trigger diagnostic when cursor is exactly at start position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 7, 13), l:expected)
|
||||||
|
End
|
||||||
|
|
||||||
|
It should not trigger diagnostic when cursor is at line before start position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 6, 13), {})
|
||||||
|
End
|
||||||
|
|
||||||
|
It should not trigger diagnostic when cursor is one character before start position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 7, 12), {})
|
||||||
|
End
|
||||||
|
|
||||||
|
It should trigger diagnostic when cursor is at start column on an intermediate line within range
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 8, 1), l:expected)
|
||||||
|
End
|
||||||
|
|
||||||
|
It should trigger diagnostic when cursor is at end column on an intermediate line within range
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 8, 15), l:expected)
|
||||||
|
End
|
||||||
|
|
||||||
|
It should trigger diagnostic when cursor is exactly at end position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 9, 5), l:expected)
|
||||||
|
End
|
||||||
|
|
||||||
|
It should not trigger diagnostic when cursor is at line after end position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 10, 5), {})
|
||||||
|
End
|
||||||
|
|
||||||
|
It should not return diagnostic when cursor is one character after end position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 9, 6), {})
|
||||||
|
End
|
||||||
|
|
||||||
|
It should return the closest diagnostic when multiple diagnostics exist across different ranges
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 10, 'line': 4}, 'end': {'character': 7, 'line': 10}} },
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 6}, 'end': {'character': 5, 'line': 8}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 10, 'line': 4}, 'end': {'character': 7, 'line': 10}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 7, 3), l:expected)
|
||||||
|
End
|
||||||
|
|
||||||
|
It should return the most specific diagnostic when multiple diagnostics overlap at cursor position
|
||||||
|
let l:diagnostics = [
|
||||||
|
\ { 'range': {'start': {'character': 10, 'line': 4}, 'end': {'character': 15, 'line': 4}} },
|
||||||
|
\ { 'range': {'start': {'character': 12, 'line': 4}, 'end': {'character': 14, 'line': 4}} }
|
||||||
|
\ ]
|
||||||
|
let l:expected = { 'range': {'start': {'character': 12, 'line': 4}, 'end': {'character': 14, 'line': 4}} }
|
||||||
|
Assert Equals(lsp#internal#diagnostics#under_cursor#_get_closest_diagnostic(l:diagnostics, 5, 13), l:expected)
|
||||||
|
End
|
||||||
|
End
|
||||||
11
test/testproject-go/documentdiagnositcs.go
Normal file
11
test/testproject-go/documentdiagnositcs.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func documentdiagnostics() {
|
||||||
|
msg := "msg"
|
||||||
|
fmt.Printf(msg +
|
||||||
|
msg +
|
||||||
|
msg,
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user