1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
" Author: w0rp <devw0rp@gmail.com>
" Description: This file implements functions for jumping around in a file
" based on ALE's internal loclist.
" Search for the nearest line either before or after the current position
" in the loclist. The argument 'wrap' can be passed to enable wrapping
" around the end of the list.
"
" If there are no items or we have hit the end with wrapping off, an empty
" List will be returned, otherwise a pair of [line_number, column_number] will
" be returned.
function! ale#loclist_jumping#FindNearest(direction, wrap, ...) abort
let l:buffer = bufnr('')
let l:pos = getpos('.')
let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []})
" Copy the list and filter to only the items in this buffer.
let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer')
let l:search_item = {'bufnr': l:buffer, 'lnum': l:pos[1], 'col': l:pos[2]}
if a:0 > 0
let l:filter = a:1
else
let l:filter = 'any'
endif
if a:0 > 1
let l:subtype_filter = a:2
else
let l:subtype_filter = 'any'
endif
" When searching backwards, so we can find the next smallest match.
if a:direction is# 'before'
call reverse(l:loclist)
endif
" Look for items before or after the current position.
for l:item in l:loclist
" Compare the cursor with a item where the column number is bounded,
" such that it's possible for the cursor to actually be on the given
" column number, without modifying the cursor number we return. This
" will allow us to move through matches, but still let us move the
" cursor to a line without changing the column, in some cases.
let l:cmp_value = ale#util#LocItemCompare(
\ {
\ 'bufnr': l:buffer,
\ 'lnum': l:item.lnum,
\ 'col': min([
\ max([l:item.col, 1]),
\ max([len(getline(l:item.lnum)), 1]),
\ ]),
\ },
\ l:search_item
\)
if (l:filter is# 'any' || l:filter is# l:item.type)
\&& (
\ l:subtype_filter is# 'any'
\ || l:subtype_filter is# get(l:item, 'sub_type', '')
\)
if a:direction is# 'before' && l:cmp_value < 0
return [l:item.lnum, l:item.col]
endif
if a:direction is# 'after' && l:cmp_value > 0
return [l:item.lnum, l:item.col]
endif
endif
endfor
" If we found nothing, and the wrap option is set to 1, then we should
" wrap around the list of warnings/errors
if a:wrap
for l:item in l:loclist
if (l:filter is# 'any' || l:filter is# l:item.type)
\&& (
\ l:subtype_filter is# 'any'
\ || l:subtype_filter is# get(l:item, 'sub_type', '')
\)
return [l:item.lnum, l:item.col]
endif
endfor
endif
return []
endfunction
" As before, find the nearest match, but position the cursor at it.
function! ale#loclist_jumping#Jump(direction, ...) abort
if a:0 > 0
let l:wrap = a:1
else
let l:wrap = 0
endif
if a:0 > 1
let l:filter = a:2
else
let l:filter = 'any'
endif
if a:0 > 2
let l:subtype_filter = a:3
else
let l:subtype_filter = 'any'
endif
let l:nearest = ale#loclist_jumping#FindNearest(a:direction,
\ l:wrap, l:filter, l:subtype_filter)
if !empty(l:nearest)
normal! m`
call cursor([l:nearest[0], max([l:nearest[1], 1])])
endif
endfunction
function! ale#loclist_jumping#WrapJump(direction, sargs) abort
let [l:args, l:rest] = ale#args#Parse(['error', 'warning', 'info', 'wrap',
\ 'style', 'nostyle'], a:sargs)
let l:wrap = 0
let l:type_filter = 'any'
let l:subtype_filter = 'any'
if get(l:args, 'wrap', 'nil') is# ''
let l:wrap = 1
endif
if get(l:args, 'error', 'nil') is# ''
let l:type_filter = 'E'
elseif get(l:args, 'warning', 'nil') is# ''
let l:type_filter = 'W'
elseif get(l:args, 'info', 'nil') is# ''
let l:type_filter = 'I'
endif
if get(l:args, 'nostyle', 'nil') is# ''
let l:subtype_filter = 'style'
elseif get(l:args, 'style', 'nil') is# ''
let l:subtype_filter = ''
endif
call ale#loclist_jumping#Jump(a:direction, l:wrap, l:type_filter,
\ l:subtype_filter)
endfunction
function! ale#loclist_jumping#JumpToIndex(index) abort
let l:buffer = bufnr('')
let l:info = get(g:ale_buffer_info, l:buffer, {'loclist': []})
let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer')
if empty(l:loclist)
return
endif
let l:item = l:loclist[a:index]
if !empty(l:item)
normal! m`
call cursor([l:item.lnum, l:item.col])
endif
endfunction
|