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.
1 " Author: w0rp <devw0rp@gmail.com>
2 " Description: This file implements functions for jumping around in a file
3 " based on ALE's internal loclist.
5 " Search for the nearest line either before or after the current position
6 " in the loclist. The argument 'wrap' can be passed to enable wrapping
7 " around the end of the list.
9 " If there are no items or we have hit the end with wrapping off, an empty
10 " List will be returned, otherwise a pair of [line_number, column_number] will
12 function! ale#loclist_jumping#FindNearest(direction, wrap, ...) abort
13 let l:buffer = bufnr('')
14 let l:pos = getpos('.')
15 let l:info = get(g:ale_buffer_info, bufnr('%'), {'loclist': []})
16 " Copy the list and filter to only the items in this buffer.
17 let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer')
18 let l:search_item = {'bufnr': l:buffer, 'lnum': l:pos[1], 'col': l:pos[2]}
27 let l:subtype_filter = a:2
29 let l:subtype_filter = 'any'
32 " When searching backwards, so we can find the next smallest match.
33 if a:direction is# 'before'
34 call reverse(l:loclist)
37 " Look for items before or after the current position.
38 for l:item in l:loclist
39 " Compare the cursor with a item where the column number is bounded,
40 " such that it's possible for the cursor to actually be on the given
41 " column number, without modifying the cursor number we return. This
42 " will allow us to move through matches, but still let us move the
43 " cursor to a line without changing the column, in some cases.
44 let l:cmp_value = ale#util#LocItemCompare(
47 \ 'lnum': l:item.lnum,
49 \ max([l:item.col, 1]),
50 \ max([len(getline(l:item.lnum)), 1]),
56 if (l:filter is# 'any' || l:filter is# l:item.type)
58 \ l:subtype_filter is# 'any'
59 \ || l:subtype_filter is# get(l:item, 'sub_type', '')
62 if a:direction is# 'before' && l:cmp_value < 0
63 return [l:item.lnum, l:item.col]
66 if a:direction is# 'after' && l:cmp_value > 0
67 return [l:item.lnum, l:item.col]
72 " If we found nothing, and the wrap option is set to 1, then we should
73 " wrap around the list of warnings/errors
75 for l:item in l:loclist
76 if (l:filter is# 'any' || l:filter is# l:item.type)
78 \ l:subtype_filter is# 'any'
79 \ || l:subtype_filter is# get(l:item, 'sub_type', '')
81 return [l:item.lnum, l:item.col]
89 " As before, find the nearest match, but position the cursor at it.
90 function! ale#loclist_jumping#Jump(direction, ...) abort
104 let l:subtype_filter = a:3
106 let l:subtype_filter = 'any'
109 let l:nearest = ale#loclist_jumping#FindNearest(a:direction,
110 \ l:wrap, l:filter, l:subtype_filter)
114 call cursor([l:nearest[0], max([l:nearest[1], 1])])
118 function! ale#loclist_jumping#WrapJump(direction, sargs) abort
119 let [l:args, l:rest] = ale#args#Parse(['error', 'warning', 'info', 'wrap',
120 \ 'style', 'nostyle'], a:sargs)
123 let l:type_filter = 'any'
124 let l:subtype_filter = 'any'
126 if get(l:args, 'wrap', 'nil') is# ''
130 if get(l:args, 'error', 'nil') is# ''
131 let l:type_filter = 'E'
132 elseif get(l:args, 'warning', 'nil') is# ''
133 let l:type_filter = 'W'
134 elseif get(l:args, 'info', 'nil') is# ''
135 let l:type_filter = 'I'
138 if get(l:args, 'nostyle', 'nil') is# ''
139 let l:subtype_filter = 'style'
140 elseif get(l:args, 'style', 'nil') is# ''
141 let l:subtype_filter = ''
144 call ale#loclist_jumping#Jump(a:direction, l:wrap, l:type_filter,
148 function! ale#loclist_jumping#JumpToIndex(index) abort
149 let l:buffer = bufnr('')
150 let l:info = get(g:ale_buffer_info, l:buffer, {'loclist': []})
151 let l:loclist = filter(copy(l:info.loclist), 'v:val.bufnr == l:buffer')
157 let l:item = l:loclist[a:index]
161 call cursor([l:item.lnum, l:item.col])