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
+
1
21
" @params {location} = {
2
22
" 'uri': 'file://....',
3
23
" 'range': {
@@ -12,16 +32,94 @@ function! lsp#utils#location#_open_lsp_location(location) abort
12
32
let [l: start_line , l: start_col ] = lsp#utils#position#_lsp_to_vim (l: bufnr , a: location [' range' ][' start' ])
13
33
let [l: end_line , l: end_col ] = lsp#utils#position#_lsp_to_vim (l: bufnr , a: location [' range' ][' end' ])
14
34
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 )
22
36
23
- let l: bufnr = bufnr (' %' )
24
37
normal ! V
25
38
call setpos (" '<" , [l: bufnr , l: start_line , l: start_col ])
26
39
call setpos (" '>" , [l: bufnr , l: end_line , l: end_col ])
27
40
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