]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/movement.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:

Do not set EDITOR/VISUAL for shell
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / internal / diagnostics / movement.vim
1 function! s:severity_of(diagnostic) abort
2     return get(a:diagnostic, 'severity', 1)
3 endfunction
4
5 function! lsp#internal#diagnostics#movement#_next_error(...) abort
6     let l:diagnostics = filter(s:get_all_buffer_diagnostics(),
7         \ {_, diagnostic -> s:severity_of(diagnostic) ==# 1 })
8     let l:options = lsp#utils#parse_command_options(a:000)
9     call s:next_diagnostic(l:diagnostics, l:options)
10 endfunction
11
12 function! lsp#internal#diagnostics#movement#_next_warning(...) abort
13     let l:diagnostics = filter(s:get_all_buffer_diagnostics(),
14         \ {_, diagnostic -> s:severity_of(diagnostic) ==# 2 })
15     let l:options = lsp#utils#parse_command_options(a:000)
16     call s:next_diagnostic(l:diagnostics, l:options)
17 endfunction
18
19 function! lsp#internal#diagnostics#movement#_next_diagnostics(...) abort
20     let l:options = lsp#utils#parse_command_options(a:000)
21     call s:next_diagnostic(s:get_all_buffer_diagnostics(), l:options)
22 endfunction
23
24 function! s:next_diagnostic(diagnostics, options) abort
25     if !len(a:diagnostics)
26         return
27     endif
28     call sort(a:diagnostics, 's:compare_diagnostics')
29
30     let l:wrap = 1
31     if has_key(a:options, 'wrap')
32         let l:wrap = a:options['wrap']
33     endif
34
35     let l:view = winsaveview()
36     let l:next_line = 0
37     let l:next_col = 0
38     for l:diagnostic in a:diagnostics
39         let [l:line, l:col] = lsp#utils#position#lsp_to_vim('%', l:diagnostic['range']['start'])
40         if l:line > l:view['lnum']
41             \ || (l:line == l:view['lnum'] && l:col > l:view['col'] + 1)
42             let l:next_line = l:line
43             let l:next_col = l:col - 1
44             break
45         endif
46     endfor
47
48     if l:next_line == 0
49         if !l:wrap
50             return
51         endif
52         " Wrap to start
53         let [l:next_line, l:next_col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[0]['range']['start'])
54         let l:next_col -= 1
55     endif
56
57     let l:view['lnum'] = l:next_line
58     let l:view['col'] = l:next_col
59     let l:view['topline'] = 1
60     let l:height = winheight(0)
61     let l:totalnum = line('$')
62     if l:totalnum > l:height
63         let l:half = l:height / 2
64         if l:totalnum - l:half < l:view['lnum']
65             let l:view['topline'] = l:totalnum - l:height + 1
66         else
67             let l:view['topline'] = l:view['lnum'] - l:half
68         endif
69     endif
70     call winrestview(l:view)
71 endfunction
72
73 function! lsp#internal#diagnostics#movement#_previous_error(...) abort
74     let l:diagnostics = filter(s:get_all_buffer_diagnostics(),
75         \ {_, diagnostic -> s:severity_of(diagnostic) ==# 1 })
76     let l:options = lsp#utils#parse_command_options(a:000)
77     call s:previous_diagnostic(l:diagnostics, l:options)
78 endfunction
79
80 function! lsp#internal#diagnostics#movement#_previous_warning(...) abort
81     let l:options = lsp#utils#parse_command_options(a:000)
82     let l:diagnostics = filter(s:get_all_buffer_diagnostics(),
83         \ {_, diagnostic -> s:severity_of(diagnostic) ==# 2 })
84     call s:previous_diagnostic(l:diagnostics, l:options)
85 endfunction
86
87 function! lsp#internal#diagnostics#movement#_previous_diagnostics(...) abort
88     let l:options = lsp#utils#parse_command_options(a:000)
89     call s:previous_diagnostic(s:get_all_buffer_diagnostics(), l:options)
90 endfunction
91
92 function! s:previous_diagnostic(diagnostics, options) abort
93     if !len(a:diagnostics)
94         return
95     endif
96     call sort(a:diagnostics, 's:compare_diagnostics')
97
98     let l:wrap = 1
99     if has_key(a:options, 'wrap')
100         let l:wrap = a:options['wrap']
101     endif
102
103     let l:view = winsaveview()
104     let l:next_line = 0
105     let l:next_col = 0
106     let l:index = len(a:diagnostics) - 1
107     while l:index >= 0
108         let [l:line, l:col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[l:index]['range']['start'])
109         if l:line < l:view['lnum']
110             \ || (l:line == l:view['lnum'] && l:col < l:view['col'])
111             let l:next_line = l:line
112             let l:next_col = l:col - 1
113             break
114         endif
115         let l:index = l:index - 1
116     endwhile
117
118     if l:next_line == 0
119         if !l:wrap
120             return
121         endif
122         " Wrap to end
123         let [l:next_line, l:next_col] = lsp#utils#position#lsp_to_vim('%', a:diagnostics[-1]['range']['start'])
124         let l:next_col -= 1
125     endif
126
127     let l:view['lnum'] = l:next_line
128     let l:view['col'] = l:next_col
129     let l:view['topline'] = 1
130     let l:height = winheight(0)
131     let l:totalnum = line('$')
132     if l:totalnum > l:height
133         let l:half = l:height / 2
134         if l:totalnum - l:half < l:view['lnum']
135             let l:view['topline'] = l:totalnum - l:height + 1
136         else
137             let l:view['topline'] = l:view['lnum'] - l:half
138         endif
139     endif
140     call winrestview(l:view)
141 endfunction
142
143 function! s:get_diagnostics(uri) abort
144     if has_key(s:diagnostics, a:uri)
145         return [1, s:diagnostics[a:uri]]
146     else
147         if s:is_win
148             " vim in windows always uses upper case for drive letter, so use lowercase in case lang server uses lowercase
149             " https://github.com/theia-ide/typescript-language-server/issues/23
150             let l:uri = substitute(a:uri, '^' . a:uri[:8], tolower(a:uri[:8]), '')
151             if has_key(s:diagnostics, l:uri)
152                 return [1, s:diagnostics[l:uri]]
153             endif
154         endif
155     endif
156     return [0, {}]
157 endfunction
158
159 " Get diagnostics for the current buffer URI from all servers
160 function! s:get_all_buffer_diagnostics(...) abort
161     let l:server = get(a:000, 0, '')
162
163     let l:bufnr = bufnr('%')
164     let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
165
166     if !lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr)
167         return []
168     endif
169
170     let l:diagnostics_by_server = lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri)
171     let l:diagnostics = []
172     if empty(l:server)
173         for l:item in values(l:diagnostics_by_server)
174             let l:diagnostics += lsp#utils#iteratable(l:item['params']['diagnostics'])
175         endfor
176     else
177         if has_key(l:diagnostics_by_server, l:server)
178             let l:diagnostics = lsp#utils#iteratable(l:diagnostics_by_server[l:server]['params']['diagnostics'])
179         endif
180     endif
181
182     return l:diagnostics
183 endfunction
184
185 function! s:compare_diagnostics(d1, d2) abort
186     let l:range1 = a:d1['range']
187     let l:line1 = l:range1['start']['line'] + 1
188     let l:col1 = l:range1['start']['character'] + 1
189     let l:range2 = a:d2['range']
190     let l:line2 = l:range2['start']['line'] + 1
191     let l:col2 = l:range2['start']['character'] + 1
192
193     if l:line1 == l:line2
194         return l:col1 == l:col2 ? 0 : l:col1 > l:col2 ? 1 : -1
195     else
196         return l:line1 > l:line2 ? 1 : -1
197     endif
198 endfunction
199 " vim sw=4 ts=4 et