aboutsummaryrefslogtreecommitdiff
path: root/.vim/autoload/neomake/config.vim
blob: 5f03cd137ad59b61f05162211b1ac428df34f41f (plain)
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