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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
|
" Config API.
let g:neomake#config#_defaults = {
\ 'maker_defaults': {
\ 'buffer_output': 1,
\ 'output_stream': 'both',
\ 'remove_invalid_entries': 0,
\ }}
lockvar g:neomake#config#_defaults
let g:neomake#config#undefined = {}
lockvar! g:neomake#config#undefined
" Resolve a:name (split on dots) and (optionally) init a:dict accordingly.
function! s:resolve_name(dict, name, init) abort
let parts = type(a:name) == type([]) ? a:name : split(a:name, '\.')
let c = a:dict
for p in parts[0:-2]
if !has_key(c, p)
if !a:init
return [g:neomake#config#undefined, '']
endif
let c[p] = {}
endif
if type(c[p]) != type({})
return [g:neomake#config#undefined, '']
endif
let c = c[p]
endfor
return [c, parts[-1]]
endfunction
" Get a:name (list of keys) from a:dict, using a:prefixes.
function! s:get(dict, parts, prefixes) abort
for prefix in a:prefixes
let [c, k] = s:resolve_name(a:dict, prefix + a:parts[0:-1], 0)
if has_key(c, k)
return [prefix, get(c, k)]
endif
endfor
return [[], g:neomake#config#undefined]
endfunction
" Get a:name (string (split on dots), or list of keys) from config.
" See neomake#config#get_with_source for args.
function! neomake#config#get(name, ...) abort
return call('neomake#config#get_with_source', [a:name] + a:000)[0]
endfunction
" Get a:name (string (split on dots), or list of keys) from config, with
" information about the setting's source ('buffer', 'tab', 'global', 'maker',
" 'default').
" Optional args:
" - a:1: default value
" - a:2: context: defaults to {'ft': &filetype}
" - maker: a maker dict (where maker.name is used from for prefixes, and
" as a lookup itself)
" - ft: filetype string (use an empty string to ignore it)
" - bufnr: buffer number (use an empty string to ignore it)
" - maker_only: should settings get looked up only in the maker context?
" (i.e. with maker.name prefix in general and in context.maker)
" - log_source: additional information to log.
function! neomake#config#get_with_source(name, ...) abort
let context = a:0 > 1 ? a:2 : {'ft': &filetype, 'bufnr': bufnr('%')}
let parts = type(a:name) == type([]) ? a:name : split(a:name, '\.')
let prefixes = [[]]
if has_key(context, 'ft') && !empty(context.ft)
for ft in neomake#utils#get_config_fts(context.ft, '.')
call insert(prefixes, ['ft', ft], 0)
endfor
endif
let maker_name = get(get(context, 'maker', {}), 'name', '')
let maker_only = get(context, 'maker_only', 0)
if parts[0][0:1] ==# 'b:'
if !has_key(context, 'bufnr')
let context.bufnr = bufnr('%')
endif
let parts[0] = parts[0][2:-1]
if context.bufnr is# ''
let lookups = []
else
let lookups = [['buffer', getbufvar(context.bufnr, 'neomake')]]
endif
call add(lookups, ['maker', get(context, 'maker', {})])
elseif empty(maker_name) && maker_only
let lookups = [['maker', get(context, 'maker', {})]]
else
let lookups = (has_key(context, 'bufnr') && context.bufnr isnot# ''
\ ? [['buffer', getbufvar(context.bufnr, 'neomake')]]
\ : []) + [
\ ['tab', get(t:, 'neomake', {})],
\ ['global', get(g:, 'neomake', {})],
\ ['maker', get(context, 'maker', {})]]
if !empty(maker_name)
if maker_only
if parts[0] !=# maker_name
call map(prefixes, 'add(v:val, maker_name)')
endif
else
for prefix in reverse(copy(prefixes))
call insert(prefixes, prefix + [maker_name], 0)
endfor
endif
endif
endif
for [source, lookup] in lookups
if !empty(lookup)
if source ==# 'maker'
let maker_prefixes = map(copy(prefixes), '!empty(v:val) && v:val[-1] ==# maker_name ? v:val[:-2] : v:val')
let maker_setting_parts = parts[0] == maker_name ? parts[1:] : parts
let [prefix, l:R] = s:get(lookup, maker_setting_parts, maker_prefixes)
else
let [prefix, l:R] = s:get(lookup, parts, prefixes)
endif
if R isnot# g:neomake#config#undefined
let log_name = join(map(copy(parts), "substitute(v:val, '\\.', '|', '')"), '.')
let log_source = get(context, 'log_source', '')
call neomake#log#debug(printf(
\ "Using setting %s=%s from '%s'%s%s.",
\ log_name, string(R), source,
\ empty(prefix) ? '' : ' (prefix: '.string(prefix).')',
\ empty(log_source) ? '' : ' ('.log_source.')'),
\ context)
return [R, source]
endif
unlet R " for Vim without patch-7.4.1546
endif
unlet lookup " for Vim without patch-7.4.1546
endfor
" Return default.
if a:0
return [a:1, 'default']
elseif has_key(g:neomake#config#_defaults, a:name)
return [copy(g:neomake#config#_defaults[a:name]), 'default']
endif
return [g:neomake#config#undefined, 'default']
endfunction
" Set a:name in a:dict to a:value, after resolving it (split on dots).
function! s:set(dict, name, value) abort
let [c, k] = s:resolve_name(a:dict, a:name, 1)
let c[k] = a:value
return c
endfunction
" Set a:name (resolved on dots) to a:value in the config.
function! neomake#config#set(name, value) abort
let parts = type(a:name) == type([]) ? a:name : split(a:name, '\.')
if parts[0] =~# '^b:'
let parts[0] = parts[0][2:-1]
return neomake#config#set_buffer(bufnr('%'), parts, a:value)
endif
if !has_key(g:, 'neomake')
let g:neomake = {}
endif
return s:set(g:neomake, parts, a:value)
endfunction
" Set a:name (resolved on dots) to a:value for buffer a:bufnr.
function! neomake#config#set_buffer(bufnr, name, value) abort
let bufnr = +a:bufnr
let bneomake = getbufvar(bufnr, 'neomake')
if bneomake is# ''
unlet bneomake " for Vim without patch-7.4.1546
let bneomake = {}
call setbufvar(bufnr, 'neomake', bneomake)
endif
return s:set(bneomake, a:name, a:value)
endfunction
" Set a:name (resolved on dots) to a:value in a:scope.
" This is meant for advanced usage, e.g.:
" set_scope(t:, 'neomake.disabled', 1)
function! neomake#config#set_dict(dict, name, value) abort
return s:set(a:dict, a:name, a:value)
endfunction
" Unset a:name (resolved on dots).
" This is meant for advanced usage, e.g.:
" unset_dict(t:, 'neomake.disabled', 1)
function! neomake#config#unset_dict(dict, name) abort
let [c, k] = s:resolve_name(a:dict, a:name, 0)
if has_key(c, k)
unlet c[k]
endif
endfunction
" vim: ts=4 sw=4 et
|