Skip to content

Commit b02345d

Browse files
added lsp#utils#location#_lsp_to_vim_list (#647)
* added lsp#utils#location#_lsp_to_vim_list * check of response.result * remove lsp#ui#vim#utils#locations_to_loc_list * refactor to use s:open_location * use lsp#utils#is_file_uri
1 parent 3aba91c commit b02345d

File tree

4 files changed

+116
-92
lines changed

4 files changed

+116
-92
lines changed

autoload/lsp/ui/vim.vim

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,10 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
481481

482482
let a:ctx['counter'] = a:ctx['counter'] - 1
483483

484-
if lsp#client#is_error(a:data['response'])
484+
if lsp#client#is_error(a:data['response']) || !has_key(a:data['response'], 'result')
485485
call lsp#utils#error('Failed to retrieve '. a:type . ' for ' . a:server . ': ' . lsp#client#error_message(a:data['response']))
486486
else
487-
let a:ctx['list'] = a:ctx['list'] + lsp#ui#vim#utils#locations_to_loc_list(a:data)
487+
let a:ctx['list'] = a:ctx['list'] + lsp#utils#location#_lsp_to_vim_list(a:data['response']['result'])
488488
endif
489489

490490
if a:ctx['counter'] == 0
@@ -496,14 +496,7 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
496496
let l:loc = a:ctx['list'][0]
497497

498498
if len(a:ctx['list']) == 1 && a:ctx['jump_if_one'] && !a:ctx['in_preview']
499-
normal! m'
500-
let l:buffer = bufnr(l:loc['filename'])
501-
if &modified && !&hidden
502-
let l:cmd = l:buffer !=# -1 ? 'sb ' . l:buffer : 'split ' . fnameescape(l:loc['filename'])
503-
else
504-
let l:cmd = l:buffer !=# -1 ? 'b ' . l:buffer : 'edit ' . fnameescape(l:loc['filename'])
505-
endif
506-
execute l:cmd . ' | call cursor('.l:loc['lnum'].','.l:loc['col'].')'
499+
call lsp#utils#location#_open_vim_list_item(l:loc)
507500
echo 'Retrieved ' . a:type
508501
redraw
509502
elseif !a:ctx['in_preview']

autoload/lsp/ui/vim/utils.vim

Lines changed: 3 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,3 @@
1-
function! lsp#ui#vim#utils#locations_to_loc_list(result) abort
2-
if !has_key(a:result['response'], 'result')
3-
return []
4-
endif
5-
6-
let l:list = []
7-
8-
let l:locations = type(a:result['response']['result']) == type({}) ? [a:result['response']['result']] : a:result['response']['result']
9-
10-
if empty(l:locations) " some servers also return null so check to make sure it isn't empty
11-
return []
12-
endif
13-
14-
if has_key(l:locations[0],'targetUri') " server returns locationLinks
15-
let l:use_link = 1
16-
let l:uri = 'targetUri'
17-
let l:range = 'targetSelectionRange'
18-
else
19-
let l:use_link = 0
20-
let l:uri = 'uri'
21-
let l:range = 'range'
22-
endif
23-
24-
let l:cache={}
25-
for l:location in l:locations
26-
if s:is_file_uri(l:location[l:uri])
27-
let l:path = lsp#utils#uri_to_path(l:location[l:uri])
28-
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:location[l:range]['start'])
29-
30-
let l:index = l:line - 1
31-
if has_key(l:cache, l:path)
32-
let l:text = l:cache[l:path][l:index]
33-
else
34-
let l:contents = getbufline(l:path, 1, '$')
35-
if !empty(l:contents)
36-
let l:text = l:contents[l:index]
37-
else
38-
let l:contents = readfile(l:path)
39-
let l:cache[l:path] = l:contents
40-
let l:text = l:contents[l:index]
41-
endif
42-
endif
43-
if l:use_link
44-
let l:viewstart = l:location['targetRange']['start']['line']
45-
let l:viewend = l:location['targetRange']['end']['line']
46-
call add(l:list, {
47-
\ 'filename': l:path,
48-
\ 'lnum': l:line,
49-
\ 'col': l:col,
50-
\ 'text': l:text,
51-
\ 'viewstart': l:viewstart,
52-
\ 'viewend': l:viewend
53-
\ })
54-
else
55-
call add(l:list, {
56-
\ 'filename': l:path,
57-
\ 'lnum': l:line,
58-
\ 'col': l:col,
59-
\ 'text': l:text,
60-
\ })
61-
endif
62-
endif
63-
endfor
64-
65-
return l:list
66-
endfunction
67-
681
let s:default_symbol_kinds = {
692
\ '1': 'file',
703
\ '2': 'module',
@@ -132,7 +65,7 @@ function! lsp#ui#vim#utils#symbols_to_loc_list(server, result) abort
13265
for l:symbol in a:result['response']['result']
13366
if has_key(l:symbol, 'location')
13467
let l:location = l:symbol['location']
135-
if s:is_file_uri(l:location['uri'])
68+
if lsp#utils#is_file_uri(l:location['uri'])
13669
let l:path = lsp#utils#uri_to_path(l:location['uri'])
13770
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:location['range']['start'])
13871
call add(l:list, {
@@ -144,7 +77,7 @@ function! lsp#ui#vim#utils#symbols_to_loc_list(server, result) abort
14477
endif
14578
else
14679
let l:location = a:result['request']['params']['textDocument']['uri']
147-
if s:is_file_uri(l:location)
80+
if lsp#utils#is_file_uri(l:location)
14881
let l:path = lsp#utils#uri_to_path(l:location)
14982
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:symbol['range']['start'])
15083
call add(l:list, {
@@ -174,7 +107,7 @@ function! lsp#ui#vim#utils#diagnostics_to_loc_list(result) abort
174107

175108
let l:list = []
176109

177-
if !empty(l:diagnostics) && s:is_file_uri(l:uri)
110+
if !empty(l:diagnostics) && lsp#utils#is_file_uri(l:uri)
178111
let l:path = lsp#utils#uri_to_path(l:uri)
179112
for l:item in l:diagnostics
180113
let l:text = ''
@@ -201,10 +134,6 @@ function! lsp#ui#vim#utils#diagnostics_to_loc_list(result) abort
201134
return l:list
202135
endfunction
203136

204-
function! s:is_file_uri(uri) abort
205-
return stridx(a:uri, 'file:///') == 0
206-
endfunction
207-
208137
function! s:get_symbol_text_from_kind(server, kind) abort
209138
if !has_key(s:symbol_kinds, a:server)
210139
let l:server_info = lsp#get_server_info(a:server)

autoload/lsp/utils.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
function! lsp#utils#is_file_uri(uri) abort
2+
return stridx(a:uri, 'file:///') == 0
3+
endfunction
4+
15
function! lsp#utils#is_remote_uri(uri) abort
26
return a:uri =~# '^\w\+::' || a:uri =~# '^\w\+://'
37
endfunction

autoload/lsp/utils/location.vim

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
function! s:open_location(path, line, col) abort
2+
normal! m'
3+
let l:buffer = bufnr(a:path)
4+
if &modified && !&hidden
5+
let l:cmd = l:buffer !=# -1 ? 'sb ' . l:buffer : 'split ' . fnameescape(a:path)
6+
else
7+
let l:cmd = l:buffer !=# -1 ? 'b ' . l:buffer : 'edit ' . fnameescape(a:path)
8+
endif
9+
execute l:cmd . ' | call cursor('.a:line.','.a:col.')'
10+
endfunction
11+
12+
" @param location = {
13+
" 'filename',
14+
" 'lnum',
15+
" 'col',
16+
" }
17+
function! lsp#utils#location#_open_vim_list_item(location) abort
18+
call s:open_location(a:location['filename'], a:location['lnum'], a:location['col'])
19+
endfunction
20+
121
" @params {location} = {
222
" 'uri': 'file://....',
323
" 'range': {
@@ -12,16 +32,94 @@ function! lsp#utils#location#_open_lsp_location(location) abort
1232
let [l:start_line, l:start_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, a:location['range']['start'])
1333
let [l:end_line, l:end_col] = lsp#utils#position#_lsp_to_vim(l:bufnr, a:location['range']['end'])
1434

15-
normal! m'
16-
if &modified && !&hidden
17-
let l:cmd = l:bufnr !=# -1 ? 'sb ' . l:bufnr : 'split ' . fnameescape(l:path)
18-
else
19-
let l:cmd = l:bufnr !=# -1 ? 'b ' . l:bufnr : 'edit ' . fnameescape(l:path)
20-
endif
21-
execute l:cmd . ' | call cursor('.l:start_line.','.l:start_col.')'
35+
call s:open_location(l:path, l:start_line, l:start_col)
2236

23-
let l:bufnr = bufnr('%')
2437
normal! V
2538
call setpos("'<", [l:bufnr, l:start_line, l:start_col])
2639
call setpos("'>", [l:bufnr, l:end_line, l:end_col])
2740
endfunction
41+
42+
" @param loc = Location | LocationLink
43+
" @param cache = {} empty dict
44+
" @returns {
45+
" 'filename',
46+
" 'lnum',
47+
" 'col',
48+
" 'viewstart?',
49+
" 'viewend?',
50+
" }
51+
function! s:lsp_location_item_to_vim(loc, cache) abort
52+
if has_key(a:loc, 'targetUri') " LocationLink
53+
let l:uri = a:loc['targetUri']
54+
let l:range = a:loc['targetSelectionRange']
55+
let l:use_link = 1
56+
else " Location
57+
let l:uri = a:loc['uri']
58+
let l:range = a:loc['range']
59+
let l:use_link = 0
60+
endif
61+
62+
if !lsp#utils#is_file_uri(l:uri)
63+
return v:null
64+
endif
65+
66+
let l:path = lsp#utils#uri_to_path(l:uri)
67+
let [l:line, l:col] = lsp#utils#position#_lsp_to_vim(l:path, l:range['start'])
68+
69+
let l:index = l:line - 1
70+
if has_key(a:cache, l:path)
71+
let l:text = a:cache[l:path][l:index]
72+
else
73+
let l:contents = getbufline(l:path, 1, '$')
74+
if !empty(l:contents)
75+
let l:text = l:contents[l:index]
76+
else
77+
let l:contents = readfile(l:path)
78+
let a:cache[l:path] = l:contents
79+
let l:text = l:contents[l:index]
80+
endif
81+
endif
82+
83+
if l:use_link
84+
return {
85+
\ 'filename': l:path,
86+
\ 'lnum': l:line,
87+
\ 'col': l:col,
88+
\ 'text': l:text,
89+
\ 'viewstart': lsp#utils#position#_lsp_to_vim(l:path, a:loc['targetRange']['start'])[0],
90+
\ 'viewend': lsp#utils#position#_lsp_to_vim(l:path, a:loc['targetRange']['end'])[0],
91+
\ }
92+
else
93+
return {
94+
\ 'filename': l:path,
95+
\ 'lnum': l:line,
96+
\ 'col': l:col,
97+
\ 'text': l:text,
98+
\ }
99+
endif
100+
endfunction
101+
102+
" @summary Use this to convert loc to vim list that is compatible with
103+
" quickfix and locllist items
104+
" @param loc = v:null | Location | Location[] | LocationLink
105+
" @returns []
106+
function! lsp#utils#location#_lsp_to_vim_list(loc) abort
107+
let l:result = []
108+
let l:cache = {}
109+
if empty(a:loc) " v:null
110+
return l:result
111+
elseif type(a:loc) == type([]) " Location[]
112+
for l:location in a:loc
113+
let l:vim_loc = s:lsp_location_item_to_vim(l:location, l:cache)
114+
if !empty(l:vim_loc) " https:// uri will return empty
115+
call add(l:result, l:vim_loc)
116+
endif
117+
endfor
118+
else " Location or LocationLink
119+
let l:vim_loc = s:lsp_location_item_to_vim(l:location, l:cache)
120+
if !empty(l:vim_loc) " https:// uri will return empty
121+
call add(l:result, l:vim_loc)
122+
endif
123+
endif
124+
return l:result
125+
endfunction

0 commit comments

Comments
 (0)