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
|
" Author: w0rp <devw0rp@gmail.com>
" Description: Contains miscellaneous functions
function! s:FindWrapperScript() abort
for l:parent in split(&runtimepath, ',')
" Expand the path to deal with ~ issues.
let l:path = expand(l:parent . '/' . 'stdin-wrapper')
if filereadable(l:path)
if has('win32')
return l:path . '.bat'
endif
return l:path
endif
endfor
endfunction
let g:ale#util#stdin_wrapper = s:FindWrapperScript()
" A null file for sending output to nothing.
let g:ale#util#nul_file = '/dev/null'
if has('win32')
let g:ale#util#nul_file = 'nul'
endif
" Return the number of lines for a given buffer.
function! ale#util#GetLineCount(buffer) abort
return len(getbufline(a:buffer, 1, '$'))
endfunction
" Given a buffer and a filename, find the nearest file by searching upwards
" through the paths relative to the given buffer.
function! ale#util#FindNearestFile(buffer, filename) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
let l:relative_path = findfile(a:filename, l:buffer_filename . ';')
if !empty(l:relative_path)
return fnamemodify(l:relative_path, ':p')
endif
return ''
endfunction
" Given a buffer and a directory name, find the nearest directory by searching upwards
" through the paths relative to the given buffer.
function! ale#util#FindNearestDirectory(buffer, directory_name) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p')
let l:relative_path = finddir(a:directory_name, l:buffer_filename . ';')
if !empty(l:relative_path)
return fnamemodify(l:relative_path, ':p')
endif
return ''
endfunction
" Given a buffer, a string to search for, an a global fallback for when
" the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead.
function! ale#util#ResolveLocalPath(buffer, search_string, global_fallback) abort
" Search for a locally installed file first.
let l:path = ale#util#FindNearestFile(a:buffer, a:search_string)
" If the serach fails, try the global executable instead.
if empty(l:path)
let l:path = a:global_fallback
endif
return l:path
endfunction
function! ale#util#GetFunction(string_or_ref) abort
if type(a:string_or_ref) == type('')
return function(a:string_or_ref)
endif
return a:string_or_ref
endfunction
function! ale#util#LocItemCompare(left, right) abort
if a:left['lnum'] < a:right['lnum']
return -1
endif
if a:left['lnum'] > a:right['lnum']
return 1
endif
if a:left['col'] < a:right['col']
return -1
endif
if a:left['col'] > a:right['col']
return 1
endif
return 0
endfunction
" This function will perform a binary search to find a message from the
" loclist to echo when the cursor moves.
function! ale#util#BinarySearch(loclist, line, column) abort
let l:min = 0
let l:max = len(a:loclist) - 1
let l:last_column_match = -1
while 1
if l:max < l:min
return l:last_column_match
endif
let l:mid = (l:min + l:max) / 2
let l:obj = a:loclist[l:mid]
" Binary search to get on the same line
if a:loclist[l:mid]['lnum'] < a:line
let l:min = l:mid + 1
elseif a:loclist[l:mid]['lnum'] > a:line
let l:max = l:mid - 1
else
let l:last_column_match = l:mid
" Binary search to get the same column, or near it
if a:loclist[l:mid]['col'] < a:column
let l:min = l:mid + 1
elseif a:loclist[l:mid]['col'] > a:column
let l:max = l:mid - 1
else
return l:mid
endif
endif
endwhile
endfunction
|