From 5d734a74ec8b340548e4264633128798c1fe6df2 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 5 Dec 2023 07:02:56 -0800 Subject: [PATCH 1/3] sameids: fix trailing identifier highlighting Fix same id highlighting of identifiers that are at the very end of a line. Fixes #3605 --- autoload/go/lsp/lsp.vim | 12 ++++++------ autoload/go/lsp/lsp_test.vim | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/autoload/go/lsp/lsp.vim b/autoload/go/lsp/lsp.vim index c0cf3e082c..7138155623 100644 --- a/autoload/go/lsp/lsp.vim +++ b/autoload/go/lsp/lsp.vim @@ -28,17 +28,17 @@ function! s:character(line, col) abort endfunction " go#lsp#PositionOf returns len(content[0:units]) where units is utf-16 code -" units. This is mostly useful for converting LSP text position to vim -" position. +" units. This is mostly useful for converting zero-based LSP text position to +" vim one-based position. function! go#lsp#lsp#PositionOf(content, units, ...) abort - if a:units == 0 - return 1 + if len(a:content) is 0 + return 0 endif let l:remaining = a:units let l:str = '' for l:rune in split(a:content, '\zs') - if l:remaining < 0 + if l:remaining <= 0 break endif let l:remaining -= 1 @@ -48,7 +48,7 @@ function! go#lsp#lsp#PositionOf(content, units, ...) abort let l:str = l:str . l:rune endfor - return len(l:str) + return len(l:str) + 1 endfunction function! go#lsp#lsp#SeverityToErrorType(severity) abort diff --git a/autoload/go/lsp/lsp_test.vim b/autoload/go/lsp/lsp_test.vim index 24a2a7474e..49503f6a6a 100644 --- a/autoload/go/lsp/lsp_test.vim +++ b/autoload/go/lsp/lsp_test.vim @@ -9,6 +9,23 @@ function! Test_PositionOf_Simple() call assert_equal(4, l:actual) endfunc +function! Test_PositionOf_Start() + let l:str = 'abcd' + let l:actual = go#lsp#lsp#PositionOf(l:str, 0) + call assert_equal(l:actual, 1) + " subtract one, because PositionOf returns a one-based cursor position and + " while string indices are zero based. + call assert_equal(l:str[l:actual-1], 'a') +endfunc + +function! Test_PositionOf_End() + let l:str = 'abcd' + let l:actual = go#lsp#lsp#PositionOf(l:str, 3) + call assert_equal(l:actual, 4) + " subtract one, because PositionOf returns a one-based cursor position and + " while string indices are zero based. + call assert_equal(l:str[l:actual-1], 'd') +endfunc function! Test_PositionOf_MultiByte() " ⌘ is U+2318, which encodes to three bytes in utf-8 and 1 code unit in From 106ad64366025ff78ce0b17a6e8e3fe7611faf36 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 5 Dec 2023 14:54:28 -0800 Subject: [PATCH 2/3] def: fix jumping to definition Fix jumping to a definition so that it uses the actual definition line to calculate the position of the definition when the definition is not in the current buffer. --- autoload/go/config_test.vim | 4 ++-- autoload/go/lsp.vim | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/autoload/go/config_test.vim b/autoload/go/config_test.vim index b73ffc909c..51391922b6 100644 --- a/autoload/go/config_test.vim +++ b/autoload/go/config_test.vim @@ -21,7 +21,7 @@ func! Test_SetBuildTags() abort let l:expectedfilename = printf('%s/foo.go', l:dir) - let l:expected = [0, 5, 1, 0] + let l:expected = [0, 5, 6, 0] call assert_notequal(l:expected, l:jumpstart) call go#def#Jump('', 0) @@ -57,7 +57,7 @@ func! Test_SetBuildTags() abort call assert_equal(l:jumpstart, getpos('.')) let l:expectedfilename = printf('%s/constrainedfoo.go', l:dir) - let l:expected = [0, 6, 1, 0] + let l:expected = [0, 6, 6, 0] call assert_notequal(l:expected, l:jumpstart) call go#def#Jump('', 0) diff --git a/autoload/go/lsp.vim b/autoload/go/lsp.vim index c27d818540..4fab5a5574 100644 --- a/autoload/go/lsp.vim +++ b/autoload/go/lsp.vim @@ -615,7 +615,14 @@ function! s:definitionHandler(next, msg) abort dict " gopls returns a []Location; just take the first one. let l:msg = a:msg[0] - let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]] + + let l:line = s:lineinfile(go#path#FromURI(l:msg.uri), l:msg.range.start.line+1) + if l:line is -1 + call go#util#Warn('could not find definition') + return + endif + + let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(l:line, l:msg.range.start.character), 'lsp does not supply a description')]] call call(a:next, l:args) endfunction @@ -641,7 +648,14 @@ function! s:typeDefinitionHandler(next, msg) abort dict " gopls returns a []Location; just take the first one. let l:msg = a:msg[0] - let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(getline(l:msg.range.start.line+1), l:msg.range.start.character), 'lsp does not supply a description')]] + + let l:line = s:lineinfile(go#path#FromURI(l:msg.uri), l:msg.range.start.line+1) + if l:line is -1 + call go#util#Warn('could not find definition') + return + endif + + let l:args = [[printf('%s:%d:%d: %s', go#path#FromURI(l:msg.uri), l:msg.range.start.line+1, go#lsp#lsp#PositionOf(l:line, l:msg.range.start.character), 'lsp does not supply a description')]] call call(a:next, l:args) endfunction From c5b51a08301d25632674b2b12ab6d80b97a77951 Mon Sep 17 00:00:00 2001 From: Billie Cleek Date: Tue, 5 Dec 2023 14:55:28 -0800 Subject: [PATCH 3/3] lsp: use getbufoneline when possible use getbufoneline when it's available to get a line instead of getting all the lines of a buffer and selecting only the line of interest. --- autoload/go/lsp.vim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/autoload/go/lsp.vim b/autoload/go/lsp.vim index 4fab5a5574..55761391f5 100644 --- a/autoload/go/lsp.vim +++ b/autoload/go/lsp.vim @@ -2049,7 +2049,11 @@ function! s:lineinfile(fname, line) abort if l:bufnr == -1 || len(l:bufinfo) == 0 || l:bufinfo[0].loaded == 0 let l:filecontents = readfile(a:fname, '', a:line) else - let l:filecontents = getbufline(a:fname, a:line) + if exists('*getbufoneline') + let l:filecontents = [getbufoneline(a:fname, a:line)] + else + let l:filecontents = getbufline(a:fname, a:line) + endif endif if len(l:filecontents) == 0