summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Garber <spellcasterbryan@gmail.com>2024-05-01 07:58:06 -0300
committerGitHub <noreply@github.com>2024-05-01 11:58:06 +0100
commit70eeae54fbd5c2e254604d543674f02d42c0ccdd (patch)
tree3be622cad5c33da7bf10eb1880af7073a359ccea
parentd19b238aa2d7c426e71c5de083bd61328d5c4fd4 (diff)
downloadale-70eeae54fbd5c2e254604d543674f02d42c0ccdd.zip
Implement listing all returned results for LSP textDocument/implements (#4755)
* Fix list of definitions * Fix when LSP returns single response on definition/implementation * Update tag stack on ShowSelection
-rw-r--r--autoload/ale/definition.vim129
-rw-r--r--test/test_go_to_definition.vader10
2 files changed, 111 insertions, 28 deletions
diff --git a/autoload/ale/definition.vim b/autoload/ale/definition.vim
index 251bdcc5..210ee038 100644
--- a/autoload/ale/definition.vim
+++ b/autoload/ale/definition.vim
@@ -35,22 +35,94 @@ function! ale#definition#UpdateTagStack() abort
endif
endfunction
+function! ale#definition#FormatTSServerResponse(response_item, options) abort
+ if get(a:options, 'open_in') is# 'quickfix'
+ return {
+ \ 'filename': a:response_item.file,
+ \ 'lnum': a:response_item.start.line,
+ \ 'col': a:response_item.start.offset,
+ \}
+ else
+ return {
+ \ 'filename': a:response_item.file,
+ \ 'line': a:response_item.start.line,
+ \ 'column': a:response_item.start.offset,
+ \}
+ endif
+endfunction
+
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
if has_key(a:response, 'request_seq')
\&& has_key(s:go_to_definition_map, a:response.request_seq)
let l:options = remove(s:go_to_definition_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:true && !empty(a:response.body)
- let l:filename = a:response.body[0].file
- let l:line = a:response.body[0].start.line
- let l:column = a:response.body[0].start.offset
-
- call ale#definition#UpdateTagStack()
- call ale#util#Open(l:filename, l:line, l:column, l:options)
+ let l:item_list = []
+
+ for l:response_item in a:response.body
+ call add(
+ \ l:item_list,
+ \ ale#definition#FormatTSServerResponse(l:response_item, l:options)
+ \)
+ endfor
+
+ if empty(l:item_list)
+ call ale#util#Execute('echom ''No definitions found''')
+ elseif len(l:item_list) == 1
+ let l:filename = l:item_list[0].filename
+
+ if get(l:options, 'open_in') is# 'quickfix'
+ let l:line = l:item_list[0].lnum
+ let l:column = l:item_list[0].col
+ else
+ let l:line = l:item_list[0].line
+ let l:column = l:item_list[0].column
+ endif
+
+ call ale#definition#UpdateTagStack()
+ call ale#util#Open(l:filename, l:line, l:column, l:options)
+ else
+ if get(l:options, 'open_in') is# 'quickfix'
+ call setqflist([], 'r')
+ call setqflist(l:item_list, 'a')
+ call ale#util#Execute('cc 1')
+ else
+ call ale#definition#UpdateTagStack()
+ call ale#preview#ShowSelection(l:item_list, l:options)
+ endif
+ endif
endif
endif
endfunction
+function! ale#definition#FormatLSPResponse(response_item, options) abort
+ if has_key(a:response_item, 'targetUri')
+ " LocationLink items use targetUri
+ let l:uri = a:response_item.targetUri
+ let l:line = a:response_item.targetRange.start.line + 1
+ let l:column = a:response_item.targetRange.start.character + 1
+ else
+ " LocationLink items use uri
+ let l:uri = a:response_item.uri
+ let l:line = a:response_item.range.start.line + 1
+ let l:column = a:response_item.range.start.character + 1
+ endif
+
+ if get(a:options, 'open_in') is# 'quickfix'
+ return {
+ \ 'filename': ale#util#ToResource(l:uri),
+ \ 'lnum': l:line,
+ \ 'col': l:column,
+ \}
+ else
+ return {
+ \ 'filename': ale#util#ToResource(l:uri),
+ \ 'line': l:line,
+ \ 'column': l:column,
+ \}
+ endif
+endfunction
+
function! ale#definition#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:go_to_definition_map, a:response.id)
@@ -65,21 +137,29 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
let l:result = []
endif
- for l:item in l:result
- if has_key(l:item, 'targetUri')
- " LocationLink items use targetUri
- let l:uri = l:item.targetUri
- let l:line = l:item.targetRange.start.line + 1
- let l:column = l:item.targetRange.start.character + 1
- else
- " LocationLink items use uri
- let l:uri = l:item.uri
- let l:line = l:item.range.start.line + 1
- let l:column = l:item.range.start.character + 1
- endif
+ let l:item_list = []
+
+ for l:response_item in l:result
+ call add(l:item_list,
+ \ ale#definition#FormatLSPResponse(l:response_item, l:options)
+ \)
+ endfor
+ if empty(l:item_list)
+ call ale#util#Execute('echom ''No definitions found''')
+ elseif len(l:item_list) == 1
call ale#definition#UpdateTagStack()
+ let l:uri = ale#util#ToURI(l:item_list[0].filename)
+
+ if get(l:options, 'open_in') is# 'quickfix'
+ let l:line = l:item_list[0].lnum
+ let l:column = l:item_list[0].col
+ else
+ let l:line = l:item_list[0].line
+ let l:column = l:item_list[0].column
+ endif
+
let l:uri_handler = ale#uri#GetURIHandler(l:uri)
if l:uri_handler is# v:null
@@ -88,9 +168,16 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort
else
call l:uri_handler.OpenURILink(l:uri, l:line, l:column, l:options, a:conn_id)
endif
-
- break
- endfor
+ else
+ if get(l:options, 'open_in') is# 'quickfix'
+ call setqflist([], 'r')
+ call setqflist(l:item_list, 'a')
+ call ale#util#Execute('cc 1')
+ else
+ call ale#definition#UpdateTagStack()
+ call ale#preview#ShowSelection(l:item_list, l:options)
+ endif
+ endif
endif
endfunction
diff --git a/test/test_go_to_definition.vader b/test/test_go_to_definition.vader
index 726de551..2290054a 100644
--- a/test/test_go_to_definition.vader
+++ b/test/test_go_to_definition.vader
@@ -458,19 +458,15 @@ Execute(Definition responses with lists should be handled):
\ }
\)
- AssertEqual
- \ [
- \ 'edit +3 ' . fnameescape(ale#path#Simplify(g:dir . '/completion_dummy_file')),
- \ ],
- \ g:expr_list
- AssertEqual [3, 8], getpos('.')[1:2]
+ " Multiple results should either open the ALEPreview or go to quickfix
+ AssertEqual [1, 1], getpos('.')[1:2]
AssertEqual {}, ale#definition#GetMap()
Execute(Definition responses with null response should be handled):
call ale#definition#SetMap({3: {'open_in': 'current-buffer'}})
call ale#definition#HandleLSPResponse(1, {'id': 3, 'result': v:null})
- AssertEqual [], g:expr_list
+ AssertEqual ['echom ''No definitions found'''], g:expr_list
Execute(LSP definition requests should be sent):
runtime ale_linters/python/pylsp.vim