]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/utils/location.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge commit 'a39f715c13be3352193ffd9c5b7536b8786eff64' as '.vim/bundle/vim-lsp'
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / utils / location.vim
1 function! s:open_location(path, line, col, ...) abort
2     normal! m'
3     let l:mods = a:0 ? a:1 : ''
4     let l:buffer = bufnr(a:path)
5     if l:mods ==# '' && &modified && !&hidden && l:buffer != bufnr('%')
6         let l:mods = &splitbelow ? 'rightbelow' : 'leftabove'
7     endif
8     if l:mods ==# ''
9         if l:buffer == bufnr('%')
10             let l:cmd = ''
11         else
12             let l:cmd = (l:buffer !=# -1 ? 'b ' . l:buffer : 'edit ' . fnameescape(a:path)) . ' | '
13         endif
14     else
15         let l:cmd = l:mods . ' ' . (l:buffer !=# -1 ? 'sb ' . l:buffer : 'split ' . fnameescape(a:path)) . ' | '
16     endif
17     execute l:cmd . 'call cursor('.a:line.','.a:col.')'
18 endfunction
19
20 " @param location = {
21 "   'filename',
22 "   'lnum',
23 "   'col',
24 " }
25 function! lsp#utils#location#_open_vim_list_item(location, mods) abort
26     call s:open_location(a:location['filename'], a:location['lnum'], a:location['col'], a:mods)
27 endfunction
28
29 " @params {location} = {
30 "   'uri': 'file://....',
31 "   'range': {
32 "       'start': { 'line': 1, 'character': 1 },
33 "       'end': { 'line': 1, 'character': 1 },
34 "   }
35 " }
36 function! lsp#utils#location#_open_lsp_location(location) abort
37     let l:path = lsp#utils#uri_to_path(a:location['uri'])
38     let l:bufnr = bufnr(l:path)
39
40     let [l:start_line, l:start_col] = lsp#utils#position#lsp_to_vim(l:bufnr, a:location['range']['start'])
41     let [l:end_line, l:end_col] = lsp#utils#position#lsp_to_vim(l:bufnr, a:location['range']['end'])
42
43     call s:open_location(l:path, l:start_line, l:start_col)
44
45     normal! V
46     call setpos("'<", [l:bufnr, l:start_line, l:start_col])
47     call setpos("'>", [l:bufnr, l:end_line, l:end_col])
48 endfunction
49
50 " @param loc = Location | LocationLink
51 " @param cache = {} empty dict
52 " @returns {
53 "   'filename',
54 "   'lnum',
55 "   'col',
56 "   'text',
57 "   'viewstart?',
58 "   'viewend?',
59 " }
60 function! s:lsp_location_item_to_vim(loc, cache) abort
61     if has_key(a:loc, 'targetUri') " LocationLink
62         let l:uri = a:loc['targetUri']
63         let l:range = a:loc['targetSelectionRange']
64         let l:use_link = 1
65     else " Location
66         let l:uri = a:loc['uri']
67         let l:range = a:loc['range']
68         let l:use_link = 0
69     endif
70
71     if !lsp#utils#is_file_uri(l:uri)
72         return v:null
73     endif
74
75     let l:path = lsp#utils#uri_to_path(l:uri)
76     let [l:line, l:col] = lsp#utils#position#lsp_to_vim(l:path, l:range['start'])
77
78     let l:index = l:line - 1
79     if has_key(a:cache, l:path)
80         let l:text = a:cache[l:path][l:index]
81     else
82         let l:contents = getbufline(l:path, 1, '$')
83         if !empty(l:contents)
84             let l:text = get(l:contents, l:index, '')
85         else
86             let l:contents = readfile(l:path)
87             let a:cache[l:path] = l:contents
88             let l:text = get(l:contents, l:index, '')
89         endif
90     endif
91
92     if l:use_link
93         " viewstart/end decremented to account for incrementing in _lsp_to_vim
94         return {
95             \ 'filename': l:path,
96             \ 'lnum': l:line,
97             \ 'col': l:col,
98             \ 'text': l:text,
99             \ 'viewstart': lsp#utils#position#lsp_to_vim(l:path, a:loc['targetRange']['start'])[0] - 1,
100             \ 'viewend': lsp#utils#position#lsp_to_vim(l:path, a:loc['targetRange']['end'])[0] - 1,
101             \ }
102     else
103         return {
104             \ 'filename': l:path,
105             \ 'lnum': l:line,
106             \ 'col': l:col,
107             \ 'text': l:text,
108             \ }
109     endif
110 endfunction
111
112 " @summary Use this to convert loc to vim list that is compatible with
113 " quickfix and locllist items
114 " @param loc = v:null | Location | Location[] | LocationLink
115 " @returns []
116 function! lsp#utils#location#_lsp_to_vim_list(loc) abort
117     let l:result = []
118     let l:cache = {}
119     if empty(a:loc) " v:null
120         return l:result
121     elseif type(a:loc) == type([]) " Location[]
122         for l:location in a:loc
123             let l:vim_loc = s:lsp_location_item_to_vim(l:location, l:cache)
124             if !empty(l:vim_loc) " https:// uri will return empty
125                 call add(l:result, l:vim_loc)
126             endif
127         endfor
128     else " Location or LocationLink
129         let l:vim_loc = s:lsp_location_item_to_vim(a:loc, l:cache)
130         if !empty(l:vim_loc) " https:// uri will return empty
131             call add(l:result, l:vim_loc)
132         endif
133     endif
134     return l:result
135 endfunction