diff options
Diffstat (limited to 'dotfiles/.local/share')
249 files changed, 31833 insertions, 1 deletions
diff --git a/dotfiles/.local/share/nvim/site b/dotfiles/.local/share/nvim/site deleted file mode 120000 index 26d6278..0000000 --- a/dotfiles/.local/share/nvim/site +++ /dev/null @@ -1 +0,0 @@ -/home/yaroslav/.vim
\ No newline at end of file diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/c.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/c.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/c.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/cpp.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/cpp.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/cpp.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/html.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/html.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/html.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/javascript.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/javascript.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/javascript.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/json.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/json.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/json.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/python.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/python.vim new file mode 100644 index 0000000..289b7cd --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/python.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=4 +setlocal tabstop=4 diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/toml.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/toml.vim new file mode 100644 index 0000000..9075e88 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/toml.vim @@ -0,0 +1,21 @@ +" File: ftplugin/toml.vim +" Author: Kevin Ballard <kevin@sb.org> +" Description: FileType Plugin for Toml +" Last Change: Feb 12, 2019 + +if exists('b:did_ftplugin') + finish +endif +let b:did_ftplugin = 1 + +let s:save_cpo = &cpo +set cpo&vim +let b:undo_ftplugin = 'setlocal commentstring< comments<' + +setlocal commentstring=#\ %s +setlocal comments=:# + +let &cpo = s:save_cpo +unlet s:save_cpo + +" vim: set et sw=4 ts=4: diff --git a/dotfiles/.local/share/nvim/site/after/ftplugin/yaml.vim b/dotfiles/.local/share/nvim/site/after/ftplugin/yaml.vim new file mode 100644 index 0000000..810fd8f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/after/ftplugin/yaml.vim @@ -0,0 +1,2 @@ +setlocal shiftwidth=2 +setlocal tabstop=2 diff --git a/dotfiles/.local/share/nvim/site/autoload/airline.vim b/dotfiles/.local/share/nvim/site/autoload/airline.vim new file mode 100644 index 0000000..eacdc7c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline.vim @@ -0,0 +1,267 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let g:airline_statusline_funcrefs = get(g:, 'airline_statusline_funcrefs', []) + +let s:sections = ['a','b','c','gutter','x','y','z', 'error', 'warning'] +let s:inactive_funcrefs = [] +let s:contexts = {} +let s:core_funcrefs = [ + \ function('airline#extensions#apply'), + \ function('airline#extensions#default#apply') ] + + +function! airline#add_statusline_func(name) + call airline#add_statusline_funcref(function(a:name)) +endfunction + +function! airline#add_statusline_funcref(function) + if index(g:airline_statusline_funcrefs, a:function) >= 0 + call airline#util#warning(printf('The airline statusline funcref "%s" has already been added.', string(a:function))) + return + endif + call add(g:airline_statusline_funcrefs, a:function) +endfunction + +function! airline#remove_statusline_func(name) + let i = index(g:airline_statusline_funcrefs, function(a:name)) + if i > -1 + call remove(g:airline_statusline_funcrefs, i) + endif +endfunction + +function! airline#add_inactive_statusline_func(name) + call add(s:inactive_funcrefs, function(a:name)) +endfunction + +function! airline#load_theme() + let g:airline_theme = get(g:, 'airline_theme', 'dark') + if exists('*airline#themes#{g:airline_theme}#refresh') + call airline#themes#{g:airline_theme}#refresh() + endif + + let palette = g:airline#themes#{g:airline_theme}#palette + call airline#themes#patch(palette) + + if exists('g:airline_theme_patch_func') + let Fn = function(g:airline_theme_patch_func) + call Fn(palette) + endif + + call airline#highlighter#load_theme() + call airline#extensions#load_theme() + call airline#update_statusline() +endfunction + +" Load an airline theme +function! airline#switch_theme(name, ...) + let silent = get(a:000, '0', 0) + " get all available themes + let themes = airline#util#themes('') + let err = 0 + try + if index(themes, a:name) == -1 + " Theme not available + if !silent + call airline#util#warning(printf('The specified theme "%s" cannot be found.', a:name)) + endif + throw "not-found" + let err = 1 + else + exe "ru autoload/airline/themes/". a:name. ".vim" + let g:airline_theme = a:name + endif + catch /^Vim/ + " catch only Vim errors, not "not-found" + call airline#util#warning(printf('There is an error in theme "%s".', a:name)) + if &vbs + call airline#util#warning(v:exception) + endif + let err = 1 + endtry + + if err + if exists('g:airline_theme') + return + else + let g:airline_theme = 'dark' + endif + endif + + unlet! w:airline_lastmode + call airline#load_theme() + + call airline#util#doautocmd('AirlineAfterTheme') + + " this is required to prevent clobbering the startup info message, i don't know why... + call airline#check_mode(winnr()) +endfunction + +" Try to load the right theme for the current colorscheme +function! airline#switch_matching_theme() + if exists('g:colors_name') + let existing = g:airline_theme + let theme = tr(tolower(g:colors_name), '-', '_') + try + call airline#switch_theme(theme, 1) + return 1 + catch + for map in items(g:airline_theme_map) + if match(g:colors_name, map[0]) > -1 + try + call airline#switch_theme(map[1], 1) + catch + call airline#switch_theme(existing) + endtry + return 1 + endif + endfor + endtry + endif + return 0 +endfunction + +" Update the statusline +function! airline#update_statusline() + if airline#util#getwinvar(winnr(), 'airline_disabled', 0) + return + endif + let range = filter(range(1, winnr('$')), 'v:val != winnr()') + " create inactive statusline + call airline#update_statusline_inactive(range) + + unlet! w:airline_render_left w:airline_render_right + exe 'unlet! ' 'w:airline_section_'. join(s:sections, ' w:airline_section_') + + " Now create the active statusline + let w:airline_active = 1 + let context = { 'winnr': winnr(), 'active': 1, 'bufnr': winbufnr(winnr()) } + call s:invoke_funcrefs(context, g:airline_statusline_funcrefs) +endfunction + +" Function to be called to make all statuslines inactive +" Triggered on FocusLost autocommand +function! airline#update_statusline_focuslost() + if get(g:, 'airline_focuslost_inactive', 0) + let bufnr=bufnr('%') + call airline#highlighter#highlight_modified_inactive(bufnr) + call airline#highlighter#highlight(['inactive'], bufnr) + call airline#update_statusline_inactive(range(1, winnr('$'))) + endif +endfunction + +" Function to draw inactive statuslines for inactive windows +function! airline#update_statusline_inactive(range) + if airline#util#getwinvar(winnr(), 'airline_disabled', 0) + return + endif + for nr in a:range + if airline#util#getwinvar(nr, 'airline_disabled', 0) + continue + endif + call setwinvar(nr, 'airline_active', 0) + let context = { 'winnr': nr, 'active': 0, 'bufnr': winbufnr(nr) } + if get(g:, 'airline_inactive_alt_sep', 0) + call extend(context, { + \ 'left_sep': g:airline_left_alt_sep, + \ 'right_sep': g:airline_right_alt_sep }, 'keep') + endif + call s:invoke_funcrefs(context, s:inactive_funcrefs) + endfor +endfunction + +" Gather output from all funcrefs which will later be returned by the +" airline#statusline() function +function! s:invoke_funcrefs(context, funcrefs) + let builder = airline#builder#new(a:context) + let err = airline#util#exec_funcrefs(a:funcrefs + s:core_funcrefs, builder, a:context) + if err == 1 + let a:context.line = builder.build() + let s:contexts[a:context.winnr] = a:context + call setwinvar(a:context.winnr, '&statusline', '%!airline#statusline('.a:context.winnr.')') + endif +endfunction + +" Main statusline function per window +" will be set to the statusline option +function! airline#statusline(winnr) + if has_key(s:contexts, a:winnr) + return '%{airline#check_mode('.a:winnr.')}'.s:contexts[a:winnr].line + endif + + " in rare circumstances this happens...see #276 + return '' +endfunction + +" Check if mode as changed +function! airline#check_mode(winnr) + if !has_key(s:contexts, a:winnr) + return '' + endif + let context = s:contexts[a:winnr] + + if get(w:, 'airline_active', 1) + let l:m = mode(1) + if l:m ==# "i" + let l:mode = ['insert'] + elseif l:m[0] ==# "i" + let l:mode = ['insert'] + elseif l:m ==# "Rv" + let l:mode =['replace'] + elseif l:m[0] ==# "R" + let l:mode = ['replace'] + elseif l:m[0] =~# '\v(v|V||s|S|)' + let l:mode = ['visual'] + elseif l:m ==# "t" + let l:mode = ['terminal'] + elseif l:m[0] ==# "c" + let l:mode = ['commandline'] + elseif l:m ==# "no" " does not work, most likely, Vim does not refresh the statusline in OP mode + let l:mode = ['normal'] + elseif l:m[0:1] ==# 'ni' + let l:mode = ['normal'] + let l:m = 'ni' + else + let l:mode = ['normal'] + endif + if index(['Rv', 'no', 'ni', 'ix', 'ic'], l:m) == -1 + let l:m = l:m[0] + endif + let w:airline_current_mode = get(g:airline_mode_map, l:m, l:m) + else + let l:mode = ['inactive'] + let w:airline_current_mode = get(g:airline_mode_map, '__') + endif + + if g:airline_detect_modified && &modified + call add(l:mode, 'modified') + endif + + if g:airline_detect_paste && &paste + call add(l:mode, 'paste') + endif + + if g:airline_detect_crypt && exists("+key") && !empty(&key) + call add(l:mode, 'crypt') + endif + + if g:airline_detect_spell && &spell + call add(l:mode, 'spell') + endif + + if &readonly || ! &modifiable + call add(l:mode, 'readonly') + endif + + let mode_string = join(l:mode) + if get(w:, 'airline_lastmode', '') != mode_string + call airline#highlighter#highlight_modified_inactive(context.bufnr) + call airline#highlighter#highlight(l:mode, context.bufnr) + call airline#util#doautocmd('AirlineModeChanged') + let w:airline_lastmode = mode_string + endif + + return '' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/async.vim b/dotfiles/.local/share/nvim/site/autoload/airline/async.vim new file mode 100644 index 0000000..93bbfe7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/async.vim @@ -0,0 +1,259 @@ +" MIT License. Copyright (c) 2013-2018 C.Brabandt et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:untracked_jobs = {} +let s:mq_jobs = {} +let s:po_jobs = {} + +" Generic functions handling on exit event of the various async functions +function! s:untracked_output(dict, buf) + if a:buf =~? ('^'. a:dict.cfg['untracked_mark']) + let a:dict.cfg.untracked[a:dict.file] = get(g:, 'airline#extensions#branch#notexists', g:airline_symbols.notexists) + else + let a:dict.cfg.untracked[a:dict.file] = '' + endif +endfunction + +" also called from branch extension (for non-async vims) +function! airline#async#mq_output(buf, file) + let buf=a:buf + if !empty(a:buf) + if a:buf =~# 'no patches applied' || + \ a:buf =~# "unknown command 'qtop'" || + \ a:buf =~# "abort" + let buf = '' + elseif exists("b:mq") && b:mq isnot# buf + " make sure, statusline is updated + unlet! b:airline_head + endif + let b:mq = buf + endif + if has_key(s:mq_jobs, a:file) + call remove(s:mq_jobs, a:file) + endif +endfunction + +function! s:po_output(buf, file) + if !empty(a:buf) + let b:airline_po_stats = printf("%s", a:buf) + else + let b:airline_po_stats = '' + endif + if has_key(s:po_jobs, a:file) + call remove(s:po_jobs, a:file) + endif +endfunction + +function! s:valid_dir(dir) + if empty(a:dir) || !isdirectory(a:dir) + return getcwd() + endif + return a:dir +endfunction + +if v:version >= 800 && has("job") + " Vim 8.0 with Job feature + " TODO: Check if we need the cwd option for the job_start() functions + " (only works starting with Vim 8.0.0902) + + function! s:on_stdout(channel, msg) dict abort + let self.buf .= a:msg + endfunction + + function! s:on_exit_mq(channel) dict abort + call airline#async#mq_output(self.buf, self.file) + endfunction + + function! s:on_exit_untracked(channel) dict abort + call s:untracked_output(self, self.buf) + if has_key(s:untracked_jobs, self.file) + call remove(s:untracked_jobs, self.file) + endif + endfunction + + function! s:on_exit_po(channel) dict abort + call s:po_output(self.buf, self.file) + call airline#extensions#po#shorten() + endfunction + + function! airline#async#get_mq_async(cmd, file) + if g:airline#init#is_windows && &shell =~ 'cmd' + let cmd = a:cmd + else + let cmd = ['sh', '-c', a:cmd] + endif + + let options = {'cmd': a:cmd, 'buf': '', 'file': a:file} + if has_key(s:mq_jobs, a:file) + if job_status(get(s:mq_jobs, a:file)) == 'run' + return + elseif has_key(s:mq_jobs, a:file) + call remove(s:mq_jobs, a:file) + endif + endif + let id = job_start(cmd, { + \ 'err_io': 'out', + \ 'out_cb': function('s:on_stdout', options), + \ 'close_cb': function('s:on_exit_mq', options)}) + let s:mq_jobs[a:file] = id + endfunction + + function! airline#async#get_msgfmt_stat(cmd, file) + if g:airline#init#is_windows || !executable('msgfmt') + " no msgfmt on windows? + return + else + let cmd = ['sh', '-c', a:cmd. shellescape(a:file)] + endif + + let options = {'buf': '', 'file': a:file} + if has_key(s:po_jobs, a:file) + if job_status(get(s:po_jobs, a:file)) == 'run' + return + elseif has_key(s:po_jobs, a:file) + call remove(s:po_jobs, a:file) + endif + endif + let id = job_start(cmd, { + \ 'err_io': 'out', + \ 'out_cb': function('s:on_stdout', options), + \ 'close_cb': function('s:on_exit_po', options)}) + let s:po_jobs[a:file] = id + endfunction + + function! airline#async#vim_vcs_untracked(config, file) + if g:airline#init#is_windows && &shell =~ 'cmd' + let cmd = a:config['cmd'] . shellescape(a:file) + else + let cmd = ['sh', '-c', a:config['cmd'] . shellescape(a:file)] + endif + + let options = {'cfg': a:config, 'buf': '', 'file': a:file} + if has_key(s:untracked_jobs, a:file) + if job_status(get(s:untracked_jobs, a:file)) == 'run' + return + elseif has_key(s:untracked_jobs, a:file) + call remove(s:untracked_jobs, a:file) + endif + endif + let id = job_start(cmd, { + \ 'err_io': 'out', + \ 'out_cb': function('s:on_stdout', options), + \ 'close_cb': function('s:on_exit_untracked', options)}) + let s:untracked_jobs[a:file] = id + endfunction + +elseif has("nvim") + " NVim specific functions + + function! s:nvim_output_handler(job_id, data, event) dict + if a:event == 'stdout' || a:event == 'stderr' + let self.buf .= join(a:data) + endif + endfunction + + function! s:nvim_untracked_job_handler(job_id, data, event) dict + if a:event == 'exit' + call s:untracked_output(self, self.buf) + if has_key(s:untracked_jobs, self.file) + call remove(s:untracked_jobs, self.file) + endif + endif + endfunction + + function! s:nvim_mq_job_handler(job_id, data, event) dict + if a:event == 'exit' + call airline#async#mq_output(self.buf, self.file) + endif + endfunction + + function! s:nvim_po_job_handler(job_id, data, event) dict + if a:event == 'exit' + call s:po_output(self.buf, self.file) + call airline#extensions#po#shorten() + endif + endfunction + + function! airline#async#nvim_get_mq_async(cmd, file) + let config = { + \ 'buf': '', + \ 'file': a:file, + \ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')), + \ 'on_stdout': function('s:nvim_output_handler'), + \ 'on_stderr': function('s:nvim_output_handler'), + \ 'on_exit': function('s:nvim_mq_job_handler') + \ } + if g:airline#init#is_windows && &shell =~ 'cmd' + let cmd = a:cmd + else + let cmd = ['sh', '-c', a:cmd] + endif + + if has_key(s:mq_jobs, a:file) + call remove(s:mq_jobs, a:file) + endif + let id = jobstart(cmd, config) + let s:mq_jobs[a:file] = id + endfunction + + function! airline#async#nvim_get_msgfmt_stat(cmd, file) + let config = { + \ 'buf': '', + \ 'file': a:file, + \ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')), + \ 'on_stdout': function('s:nvim_output_handler'), + \ 'on_stderr': function('s:nvim_output_handler'), + \ 'on_exit': function('s:nvim_po_job_handler') + \ } + if g:airline#init#is_windows && &shell =~ 'cmd' + " no msgfmt on windows? + return + else + let cmd = ['sh', '-c', a:cmd. shellescape(a:file)] + endif + + if has_key(s:po_jobs, a:file) + call remove(s:po_jobs, a:file) + endif + let id = jobstart(cmd, config) + let s:po_jobs[a:file] = id + endfunction + +endif + +" Should work in either Vim pre 8 or Nvim +function! airline#async#nvim_vcs_untracked(cfg, file, vcs) + let cmd = a:cfg.cmd . shellescape(a:file) + let id = -1 + let config = { + \ 'buf': '', + \ 'vcs': a:vcs, + \ 'cfg': a:cfg, + \ 'file': a:file, + \ 'cwd': s:valid_dir(fnamemodify(a:file, ':p:h')) + \ } + if has("nvim") + call extend(config, { + \ 'on_stdout': function('s:nvim_output_handler'), + \ 'on_exit': function('s:nvim_untracked_job_handler')}) + if has_key(s:untracked_jobs, config.file) + " still running + return + endif + try + let id = jobstart(cmd, config) + catch + " catch-all, jobstart() failed, fall back to system() + let id=-1 + endtry + let s:untracked_jobs[a:file] = id + endif + " vim without job feature or nvim jobstart failed + if id < 1 + let output=system(cmd) + call s:untracked_output(config, output) + call airline#extensions#branch#update_untracked_config(a:file, a:vcs) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/builder.vim b/dotfiles/.local/share/nvim/site/autoload/airline/builder.vim new file mode 100644 index 0000000..b0352e3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/builder.vim @@ -0,0 +1,244 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:prototype = {} + +function! s:prototype.split(...) dict + call add(self._sections, ['|', a:0 ? a:1 : '%=']) +endfunction + +function! s:prototype.add_section_spaced(group, contents) dict + let spc = empty(a:contents) ? '' : g:airline_symbols.space + call self.add_section(a:group, spc.a:contents.spc) +endfunction + +function! s:prototype.add_section(group, contents) dict + call add(self._sections, [a:group, a:contents]) +endfunction + +function! s:prototype.add_raw(text) dict + call add(self._sections, ['', a:text]) +endfunction + +function! s:prototype.insert_section(group, contents, position) dict + call insert(self._sections, [a:group, a:contents], a:position) +endfunction + +function! s:prototype.insert_raw(text, position) dict + call insert(self._sections, ['', a:text], a:position) +endfunction + +function! s:prototype.get_position() dict + return len(self._sections) +endfunction + +function! airline#builder#get_prev_group(sections, i) + let x = a:i - 1 + while x >= 0 + let group = a:sections[x][0] + if group != '' && group != '|' + return group + endif + let x = x - 1 + endwhile + return '' +endfunction + +function! airline#builder#get_next_group(sections, i) + let x = a:i + 1 + let l = len(a:sections) + while x < l + let group = a:sections[x][0] + if group != '' && group != '|' + return group + endif + let x = x + 1 + endwhile + return '' +endfunction + +function! s:prototype.build() dict + let side = 1 + let line = '' + let i = 0 + let length = len(self._sections) + let split = 0 + let is_empty = 0 + let prev_group = '' + + while i < length + let section = self._sections[i] + let group = section[0] + let contents = section[1] + let pgroup = prev_group + let prev_group = airline#builder#get_prev_group(self._sections, i) + if group ==# 'airline_c' && &buftype ==# 'terminal' && self._context.active + let group = 'airline_term' + elseif group ==# 'airline_c' && !self._context.active && has_key(self._context, 'bufnr') + let group = 'airline_c'. self._context.bufnr + elseif prev_group ==# 'airline_c' && !self._context.active && has_key(self._context, 'bufnr') + let prev_group = 'airline_c'. self._context.bufnr + endif + if is_empty + let prev_group = pgroup + endif + let is_empty = s:section_is_empty(self, contents) + + if is_empty + " need to fix highlighting groups, since we + " have skipped a section, we actually need + " the previous previous group and so the + " seperator goes from the previous previous group + " to the current group + let pgroup = group + endif + + if group == '' + let line .= contents + elseif group == '|' + let side = 0 + let line .= contents + let split = 1 + else + if prev_group == '' + let line .= '%#'.group.'#' + elseif split + if !is_empty + let line .= s:get_transitioned_seperator(self, prev_group, group, side) + endif + let split = 0 + else + if !is_empty + let line .= s:get_seperator(self, prev_group, group, side) + endif + endif + let line .= is_empty ? '' : s:get_accented_line(self, group, contents) + endif + + let i = i + 1 + endwhile + + if !self._context.active + "let line = substitute(line, '%#airline_c#', '%#airline_c'.self._context.bufnr.'#', '') + let line = substitute(line, '%#.\{-}\ze#', '\0_inactive', 'g') + endif + return line +endfunction + +function! airline#builder#should_change_group(group1, group2) + if a:group1 == a:group2 + return 0 + endif + let color1 = airline#highlighter#get_highlight(a:group1) + let color2 = airline#highlighter#get_highlight(a:group2) + if g:airline_gui_mode ==# 'gui' + return color1[1] != color2[1] || color1[0] != color2[0] + else + return color1[3] != color2[3] || color1[2] != color2[2] + endif +endfunction + +function! s:get_transitioned_seperator(self, prev_group, group, side) + let line = '' + if get(a:self._context, 'tabline', 0) && get(g:, 'airline#extensions#tabline#alt_sep', 0) && a:group ==# 'airline_tabsel' && a:side + call airline#highlighter#add_separator(a:prev_group, a:group, 0) + let line .= '%#'.a:prev_group.'_to_'.a:group.'#' + let line .= a:self._context.right_sep.'%#'.a:group.'#' + else + call airline#highlighter#add_separator(a:prev_group, a:group, a:side) + let line .= '%#'.a:prev_group.'_to_'.a:group.'#' + let line .= a:side ? a:self._context.left_sep : a:self._context.right_sep + let line .= '%#'.a:group.'#' + endif + return line +endfunction + +function! s:get_seperator(self, prev_group, group, side) + if airline#builder#should_change_group(a:prev_group, a:group) + return s:get_transitioned_seperator(a:self, a:prev_group, a:group, a:side) + else + return a:side ? a:self._context.left_alt_sep : a:self._context.right_alt_sep + endif +endfunction + +function! s:get_accented_line(self, group, contents) + if a:self._context.active + " active window + let contents = [] + let content_parts = split(a:contents, '__accent') + for cpart in content_parts + let accent = matchstr(cpart, '_\zs[^#]*\ze') + call add(contents, cpart) + endfor + let line = join(contents, a:group) + let line = substitute(line, '__restore__', a:group, 'g') + else + " inactive window + let line = substitute(a:contents, '%#__accent[^#]*#', '', 'g') + let line = substitute(line, '%#__restore__#', '', 'g') + endif + return line +endfunction + +function! s:section_is_empty(self, content) + let start=1 + + " do not check for inactive windows or the tabline + if a:self._context.active == 0 + return 0 + elseif get(a:self._context, 'tabline', 0) + return 0 + endif + + " only check, if airline#skip_empty_sections == 1 + if get(g:, 'airline_skip_empty_sections', 0) == 0 + return 0 + endif + + " only check, if airline#skip_empty_sections == 1 + if get(w:, 'airline_skip_empty_sections', -1) == 0 + return 0 + endif + " assume accents sections to be never empty + " (avoides, that on startup the mode message becomes empty) + if match(a:content, '%#__accent_[^#]*#.*__restore__#') > -1 + return 0 + endif + if empty(a:content) + return 1 + endif + let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start) + if empty(list) + return 0 " no function in statusline text + endif + while len(list) > 0 + let expr = list[0] + try + " catch all exceptions, just in case + if !empty(eval(expr)) + return 0 + endif + catch + return 0 + endtry + let start += 1 + let list=matchlist(a:content, '%{\zs.\{-}\ze}', 1, start) + endw + return 1 +endfunction + +function! airline#builder#new(context) + let builder = copy(s:prototype) + let builder._context = a:context + let builder._sections = [] + + call extend(builder._context, { + \ 'left_sep': g:airline_left_sep, + \ 'left_alt_sep': g:airline_left_alt_sep, + \ 'right_sep': g:airline_right_sep, + \ 'right_alt_sep': g:airline_right_alt_sep, + \ }, 'keep') + return builder +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/debug.vim b/dotfiles/.local/share/nvim/site/autoload/airline/debug.vim new file mode 100644 index 0000000..afa42af --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/debug.vim @@ -0,0 +1,51 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#debug#profile1() + profile start airline-profile-switch.log + profile func * + profile file * + split + for i in range(1, 1000) + wincmd w + redrawstatus + endfor + profile pause + noautocmd qall! +endfunction + +function! airline#debug#profile2() + profile start airline-profile-cursor.log + profile func * + profile file * + edit blank + call setline(1, 'all your base are belong to us') + call setline(2, 'all your base are belong to us') + let positions = [[1,2], [2,2], [1,2], [1,1]] + for i in range(1, 1000) + for pos in positions + call cursor(pos[0], pos[1]) + redrawstatus + endfor + endfor + profile pause + noautocmd qall! +endfunction + +function! airline#debug#profile3() + profile start airline-profile-mode.log + profile func * + profile file * + + for i in range(1000) + startinsert + redrawstatus + stopinsert + redrawstatus + endfor + + profile pause + noautocmd qall! +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions.vim new file mode 100644 index 0000000..726e983 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions.vim @@ -0,0 +1,389 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:loaded_ext = [] +let s:ext = {} +let s:ext._theme_funcrefs = [] + +function! s:ext.add_statusline_func(name) dict + call airline#add_statusline_func(a:name) +endfunction +function! s:ext.add_statusline_funcref(function) dict + call airline#add_statusline_funcref(a:function) +endfunction +function! s:ext.add_inactive_statusline_func(name) dict + call airline#add_inactive_statusline_func(a:name) +endfunction +function! s:ext.add_theme_func(name) dict + call add(self._theme_funcrefs, function(a:name)) +endfunction + +let s:script_path = tolower(resolve(expand('<sfile>:p:h'))) + +let s:filetype_overrides = { + \ 'nerdtree': [ get(g:, 'NERDTreeStatusline', 'NERD'), '' ], + \ 'gundo': [ 'Gundo', '' ], + \ 'vimfiler': [ 'vimfiler', '%{vimfiler#get_status_string()}' ], + \ 'minibufexpl': [ 'MiniBufExplorer', '' ], + \ 'startify': [ 'startify', '' ], + \ 'vim-plug': [ 'Plugins', '' ], + \ } + +let s:filetype_regex_overrides = {} + +function! s:check_defined_section(name) + if !exists('w:airline_section_{a:name}') + let w:airline_section_{a:name} = g:airline_section_{a:name} + endif +endfunction + +function! airline#extensions#append_to_section(name, value) + call <sid>check_defined_section(a:name) + let w:airline_section_{a:name} .= a:value +endfunction + +function! airline#extensions#prepend_to_section(name, value) + call <sid>check_defined_section(a:name) + let w:airline_section_{a:name} = a:value . w:airline_section_{a:name} +endfunction + +function! airline#extensions#apply_left_override(section1, section2) + let w:airline_section_a = a:section1 + let w:airline_section_b = a:section2 + let w:airline_section_c = airline#section#create(['readonly']) + let w:airline_render_left = 1 + let w:airline_render_right = 0 +endfunction + +function! airline#extensions#apply(...) + + if s:is_excluded_window() + return -1 + endif + + if &buftype == 'help' + call airline#extensions#apply_left_override('Help', '%f') + let w:airline_section_x = '' + let w:airline_section_y = '' + let w:airline_render_right = 1 + endif + + if &buftype == 'terminal' + let w:airline_section_x = '' + let w:airline_section_y = '' + endif + + if &previewwindow + let w:airline_section_a = 'Preview' + let w:airline_section_b = '' + let w:airline_section_c = bufname(winbufnr(winnr())) + endif + + if has_key(s:filetype_overrides, &ft) + let args = s:filetype_overrides[&ft] + call airline#extensions#apply_left_override(args[0], args[1]) + endif + + for item in items(s:filetype_regex_overrides) + if match(&ft, item[0]) >= 0 + call airline#extensions#apply_left_override(item[1][0], item[1][1]) + endif + endfor +endfunction + +function! s:is_excluded_window() + for matchft in g:airline_exclude_filetypes + if matchft ==# &ft + return 1 + endif + endfor + + for matchw in g:airline_exclude_filenames + if matchstr(expand('%'), matchw) ==# matchw + return 1 + endif + endfor + + if g:airline_exclude_preview && &previewwindow + return 1 + endif + + return 0 +endfunction + +function! airline#extensions#load_theme() + call airline#util#exec_funcrefs(s:ext._theme_funcrefs, g:airline#themes#{g:airline_theme}#palette) +endfunction + +function! airline#extensions#load() + let s:loaded_ext = [] + + if exists('g:airline_extensions') + for ext in g:airline_extensions + try + call airline#extensions#{ext}#init(s:ext) + catch /^Vim\%((\a\+)\)\=:E117/ " E117, function does not exist + call airline#util#warning("Extension '".ext."' not installed, ignoring!") + endtry + endfor + return + endif + + call airline#extensions#quickfix#init(s:ext) + call add(s:loaded_ext, 'quickfix') + + if get(g:, 'loaded_unite', 0) + call airline#extensions#unite#init(s:ext) + call add(s:loaded_ext, 'unite') + endif + + if get(g:, 'loaded_denite', 0) + call airline#extensions#denite#init(s:ext) + call add(s:loaded_ext, 'denite') + endif + + if exists(':NetrwSettings') + call airline#extensions#netrw#init(s:ext) + call add(s:loaded_ext, 'netrw') + endif + + if has("terminal") || has('nvim') + call airline#extensions#term#init(s:ext) + call add(s:loaded_ext, 'term') + endif + + if get(g:, 'airline#extensions#ycm#enabled', 0) + call airline#extensions#ycm#init(s:ext) + call add(s:loaded_ext, 'ycm') + endif + + if get(g:, 'loaded_vimfiler', 0) + let g:vimfiler_force_overwrite_statusline = 0 + endif + + if get(g:, 'loaded_ctrlp', 0) + call airline#extensions#ctrlp#init(s:ext) + call add(s:loaded_ext, 'ctrlp') + endif + + if get(g:, 'loaded_localsearch', 0) + call airline#extensions#localsearch#init(s:ext) + call add(s:loaded_ext, 'localsearch') + endif + + if get(g:, 'CtrlSpaceLoaded', 0) + call airline#extensions#ctrlspace#init(s:ext) + call add(s:loaded_ext, 'ctrlspace') + endif + + if get(g:, 'command_t_loaded', 0) + call airline#extensions#commandt#init(s:ext) + call add(s:loaded_ext, 'commandt') + endif + + if exists(':UndotreeToggle') + call airline#extensions#undotree#init(s:ext) + call add(s:loaded_ext, 'undotree') + endif + + if get(g:, 'airline#extensions#hunks#enabled', 1) + \ && (exists('g:loaded_signify') || exists('g:loaded_gitgutter') || exists('g:loaded_changes') || exists('g:loaded_quickfixsigns')) + call airline#extensions#hunks#init(s:ext) + call add(s:loaded_ext, 'hunks') + endif + + if get(g:, 'airline#extensions#vimagit#enabled', 1) + \ && (exists('g:loaded_magit')) + call airline#extensions#vimagit#init(s:ext) + call add(s:loaded_ext, 'vimagit') + endif + + if get(g:, 'airline#extensions#tagbar#enabled', 1) + \ && exists(':TagbarToggle') + call airline#extensions#tagbar#init(s:ext) + call add(s:loaded_ext, 'tagbar') + endif + + if get(g:, 'airline#extensions#csv#enabled', 1) + \ && (get(g:, 'loaded_csv', 0) || exists(':Table')) + call airline#extensions#csv#init(s:ext) + call add(s:loaded_ext, 'csv') + endif + + if exists(':VimShell') + let s:filetype_overrides['vimshell'] = ['vimshell','%{vimshell#get_status_string()}'] + let s:filetype_regex_overrides['^int-'] = ['vimshell','%{substitute(&ft, "int-", "", "")}'] + endif + + if exists(':Defx') + let s:filetype_overrides['defx'] = ['defx', '%{b:defx.paths[0]}'] + endif + + if get(g:, 'airline#extensions#branch#enabled', 1) && ( + \ airline#util#has_fugitive() || + \ airline#util#has_lawrencium() || + \ airline#util#has_vcscommand() || + \ airline#util#has_custom_scm()) + call airline#extensions#branch#init(s:ext) + call add(s:loaded_ext, 'branch') + endif + + if get(g:, 'airline#extensions#bufferline#enabled', 1) + \ && exists('*bufferline#get_status_string') + call airline#extensions#bufferline#init(s:ext) + call add(s:loaded_ext, 'bufferline') + endif + + if get(g:, 'airline#extensions#fugitiveline#enabled', 1) + \ && airline#util#has_fugitive() + \ && index(s:loaded_ext, 'bufferline') == -1 + call airline#extensions#fugitiveline#init(s:ext) + call add(s:loaded_ext, 'fugitiveline') + endif + + if (get(g:, 'airline#extensions#virtualenv#enabled', 1) && (exists(':VirtualEnvList') || isdirectory($VIRTUAL_ENV))) + call airline#extensions#virtualenv#init(s:ext) + call add(s:loaded_ext, 'virtualenv') + endif + + if (get(g:, 'airline#extensions#eclim#enabled', 1) && exists(':ProjectCreate')) + call airline#extensions#eclim#init(s:ext) + call add(s:loaded_ext, 'eclim') + endif + + if get(g:, 'airline#extensions#syntastic#enabled', 1) + \ && exists(':SyntasticCheck') + call airline#extensions#syntastic#init(s:ext) + call add(s:loaded_ext, 'syntastic') + endif + + if (get(g:, 'airline#extensions#ale#enabled', 1) && exists(':ALELint')) + call airline#extensions#ale#init(s:ext) + call add(s:loaded_ext, 'ale') + endif + + if (get(g:, 'airline#extensions#languageclient#enabled', 1) && exists(':LanguageClientStart')) + call airline#extensions#languageclient#init(s:ext) + call add(s:loaded_ext, 'languageclient') + endif + + if get(g:, 'airline#extensions#whitespace#enabled', 1) + call airline#extensions#whitespace#init(s:ext) + call add(s:loaded_ext, 'whitespace') + endif + + if (get(g:, 'airline#extensions#neomake#enabled', 1) && exists(':Neomake')) + call airline#extensions#neomake#init(s:ext) + call add(s:loaded_ext, 'neomake') + endif + + if get(g:, 'airline#extensions#po#enabled', 1) && executable('msgfmt') + call airline#extensions#po#init(s:ext) + call add(s:loaded_ext, 'po') + endif + + if get(g:, 'airline#extensions#wordcount#enabled', 1) + call airline#extensions#wordcount#init(s:ext) + call add(s:loaded_ext, 'wordcount') + endif + + if get(g:, 'airline#extensions#tabline#enabled', 0) + call airline#extensions#tabline#init(s:ext) + call add(s:loaded_ext, 'tabline') + endif + + if get(g:, 'airline#extensions#tmuxline#enabled', 1) && exists(':Tmuxline') + call airline#extensions#tmuxline#init(s:ext) + call add(s:loaded_ext, 'tmuxline') + endif + + if get(g:, 'airline#extensions#promptline#enabled', 1) && exists(':PromptlineSnapshot') && len(get(g:, 'airline#extensions#promptline#snapshot_file', '')) + call airline#extensions#promptline#init(s:ext) + call add(s:loaded_ext, 'promptline') + endif + + if get(g:, 'airline#extensions#nrrwrgn#enabled', 1) && exists(':NR') == 2 + call airline#extensions#nrrwrgn#init(s:ext) + call add(s:loaded_ext, 'nrrwrgn') + endif + + if get(g:, 'airline#extensions#unicode#enabled', 1) && exists(':UnicodeTable') == 2 + call airline#extensions#unicode#init(s:ext) + call add(s:loaded_ext, 'unicode') + endif + + if (get(g:, 'airline#extensions#capslock#enabled', 1) && exists('*CapsLockStatusline')) + call airline#extensions#capslock#init(s:ext) + call add(s:loaded_ext, 'capslock') + endif + + if (get(g:, 'airline#extensions#gutentags#enabled', 1) && get(g:, 'loaded_gutentags', 0)) + call airline#extensions#gutentags#init(s:ext) + call add(s:loaded_ext, 'gutentags') + endif + + if (get(g:, 'airline#extensions#grepper#enabled', 1) && get(g:, 'loaded_grepper', 0)) + call airline#extensions#grepper#init(s:ext) + call add(s:loaded_ext, 'grepper') + endif + + if (get(g:, 'airline#extensions#xkblayout#enabled', 1) && exists('g:XkbSwitchLib')) + call airline#extensions#xkblayout#init(s:ext) + call add(s:loaded_ext, 'xkblayout') + endif + + if (get(g:, 'airline#extensions#keymap#enabled', 1) && has('keymap')) + call airline#extensions#keymap#init(s:ext) + call add(s:loaded_ext, 'keymap') + endif + + if (get(g:, 'airline#extensions#windowswap#enabled', 1) && get(g:, 'loaded_windowswap', 0)) + call airline#extensions#windowswap#init(s:ext) + call add(s:loaded_ext, 'windowswap') + endif + + if (get(g:, 'airline#extensions#obsession#enabled', 1) && exists('*ObsessionStatus')) + call airline#extensions#obsession#init(s:ext) + call add(s:loaded_ext, 'obsession') + endif + + if get(g:, 'airline#extensions#vimtex#enabled', 1) + runtime autoload/vimtex.vim + if exists('*vimtex#init') + call airline#extensions#vimtex#init(s:ext) + call add(s:loaded_ext, 'vimtex') + endif + endif + + if (get(g:, 'airline#extensions#cursormode#enabled', 0)) + call airline#extensions#cursormode#init(s:ext) + call add(s:loaded_ext, 'cursormode') + endif + + if !get(g:, 'airline#extensions#disable_rtp_load', 0) + " load all other extensions, which are not part of the default distribution. + " (autoload/airline/extensions/*.vim outside of our s:script_path). + for file in split(globpath(&rtp, "autoload/airline/extensions/*.vim"), "\n") + " we have to check both resolved and unresolved paths, since it's possible + " that they might not get resolved properly (see #187) + if stridx(tolower(resolve(fnamemodify(file, ':p'))), s:script_path) < 0 + \ && stridx(tolower(fnamemodify(file, ':p')), s:script_path) < 0 + let name = fnamemodify(file, ':t:r') + if !get(g:, 'airline#extensions#'.name.'#enabled', 1) || + \ index(s:loaded_ext, name) > -1 + continue + endif + try + call airline#extensions#{name}#init(s:ext) + catch + endtry + endif + endfor + endif +endfunction + +function! airline#extensions#get_loaded_extensions() + return s:loaded_ext +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ale.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ale.vim new file mode 100644 index 0000000..71f6317 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ale.vim @@ -0,0 +1,88 @@ +" MIT License. Copyright (c) 2013-2018 Bjorn Neergaard, w0rp et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! s:airline_ale_count(cnt, symbol) + return a:cnt ? a:symbol. a:cnt : '' +endfunction + +function! s:airline_ale_get_line_number(cnt, type) abort + if a:cnt == 0 + return '' + endif + + let buffer = bufnr('') + let problem_type = (a:type ==# 'error') ? 'E' : 'W' + let problems = copy(ale#engine#GetLoclist(buffer)) + + call filter(problems, 'v:val.bufnr is buffer && v:val.type is# problem_type') + + if empty(problems) + return '' + endif + + let open_lnum_symbol = get(g:, 'airline#extensions#ale#open_lnum_symbol', '(L') + let close_lnum_symbol = get(g:, 'airline#extensions#ale#close_lnum_symbol', ')') + + return open_lnum_symbol . problems[0].lnum . close_lnum_symbol +endfunction + +function! airline#extensions#ale#get(type) + if !exists(':ALELint') + return '' + endif + + let error_symbol = get(g:, 'airline#extensions#ale#error_symbol', 'E:') + let warning_symbol = get(g:, 'airline#extensions#ale#warning_symbol', 'W:') + let checking_symbol = get(g:, 'airline#extensions#ale#checking_symbol', '...') + let show_line_numbers = get(g:, 'airline#extensions#ale#show_line_numbers', 1) + + let is_err = a:type ==# 'error' + + if ale#engine#IsCheckingBuffer(bufnr('')) == 1 + return is_err ? '' : checking_symbol + endif + + let symbol = is_err ? error_symbol : warning_symbol + + let counts = ale#statusline#Count(bufnr('')) + if type(counts) == type({}) && has_key(counts, 'error') + " Use the current Dictionary format. + let errors = counts.error + counts.style_error + let num = is_err ? errors : counts.total - errors + else + " Use the old List format. + let num = is_err ? counts[0] : counts[1] + endif + + if show_line_numbers == 1 + return s:airline_ale_count(num, symbol) . <sid>airline_ale_get_line_number(num, a:type) + else + return s:airline_ale_count(num, symbol) + endif +endfunction + +function! airline#extensions#ale#get_warning() + return airline#extensions#ale#get('warning') +endfunction + +function! airline#extensions#ale#get_error() + return airline#extensions#ale#get('error') +endfunction + +function! airline#extensions#ale#init(ext) + call airline#parts#define_function('ale_error_count', 'airline#extensions#ale#get_error') + call airline#parts#define_function('ale_warning_count', 'airline#extensions#ale#get_warning') + augroup airline_ale + autocmd! + autocmd CursorHold,BufWritePost * call <sid>ale_refresh() + autocmd User ALEJobStarted,ALELintPost call <sid>ale_refresh() + augroup END +endfunction + +function! s:ale_refresh() + if get(g:, 'airline_skip_empty_sections', 0) + exe ':AirlineRefresh' + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/branch.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/branch.vim new file mode 100644 index 0000000..fcf4d3a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/branch.vim @@ -0,0 +1,312 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +" s:vcs_config contains static configuration of VCSes and their status relative +" to the active file. +" 'branch' - The name of currently active branch. This field is empty iff it +" has not been initialized yet or the current file is not in +" an active branch. +" 'untracked' - Cache of untracked files represented as a dictionary with files +" as keys. A file has a not exists symbol set as its value if it +" is untracked. A file is present in this dictionary iff its +" status is considered up to date. +" 'untracked_mark' - used as regexp to test against the output of 'cmd' +let s:vcs_config = { +\ 'git': { +\ 'exe': 'git', +\ 'cmd': 'git status --porcelain -- ', +\ 'untracked_mark': '??', +\ 'exclude': '\.git', +\ 'update_branch': 's:update_git_branch', +\ 'display_branch': 's:display_git_branch', +\ 'branch': '', +\ 'untracked': {}, +\ }, +\ 'mercurial': { +\ 'exe': 'hg', +\ 'cmd': 'hg status -u -- ', +\ 'untracked_mark': '?', +\ 'exclude': '\.hg', +\ 'update_branch': 's:update_hg_branch', +\ 'display_branch': 's:display_hg_branch', +\ 'branch': '', +\ 'untracked': {}, +\ }, +\} + +" Initializes b:buffer_vcs_config. b:buffer_vcs_config caches the branch and +" untracked status of the file in the buffer. Caching those fields is necessary, +" because s:vcs_config may be updated asynchronously and s:vcs_config fields may +" be invalid during those updates. b:buffer_vcs_config fields are updated +" whenever corresponding fields in s:vcs_config are updated or an inconsistency +" is detected during update_* operation. +" +" b:airline_head caches the head string it is empty iff it needs to be +" recalculated. b:airline_head is recalculated based on b:buffer_vcs_config. +function! s:init_buffer() + let b:buffer_vcs_config = {} + for vcs in keys(s:vcs_config) + let b:buffer_vcs_config[vcs] = { + \ 'branch': '', + \ 'untracked': '', + \ } + endfor + unlet! b:airline_head +endfunction + +let s:head_format = get(g:, 'airline#extensions#branch#format', 0) +if s:head_format == 1 + function! s:format_name(name) + return fnamemodify(a:name, ':t') + endfunction +elseif s:head_format == 2 + function! s:format_name(name) + return pathshorten(a:name) + endfunction +elseif type(s:head_format) == type('') + function! s:format_name(name) + return call(s:head_format, [a:name]) + endfunction +else + function! s:format_name(name) + return a:name + endfunction +endif + + +" Fugitive special revisions. call '0' "staging" ? +let s:names = {'0': 'index', '1': 'orig', '2':'fetch', '3':'merge'} +let s:sha1size = get(g:, 'airline#extensions#branch#sha1_len', 7) + +function! s:update_git_branch() + if !airline#util#has_fugitive() + let s:vcs_config['git'].branch = '' + return + endif + + let s:vcs_config['git'].branch = exists("*FugitiveHead") ? + \ FugitiveHead(s:sha1size) : fugitive#head(s:sha1size) + if s:vcs_config['git'].branch is# 'master' && winwidth(0) < 81 + " Shorten default a bit + let s:vcs_config['git'].branch='mas' + endif +endfunction + +function! s:display_git_branch() + let name = b:buffer_vcs_config['git'].branch + try + let commit = fugitive#buffer().commit() + + if has_key(s:names, commit) + let name = get(s:names, commit)."(".name.")" + elseif !empty(commit) + let ref = fugitive#repo().git_chomp('describe', '--all', '--exact-match', commit) + if ref !~ "^fatal: no tag exactly matches" + let name = s:format_name(substitute(ref, '\v\C^%(heads/|remotes/|tags/)=','',''))."(".name.")" + else + let name = matchstr(commit, '.\{'.s:sha1size.'}')."(".name.")" + endif + endif + catch + endtry + + return name +endfunction + +function! s:update_hg_branch() + if airline#util#has_lawrencium() + let cmd='LC_ALL=C hg qtop' + let stl=lawrencium#statusline() + let file=expand('%:p') + if !empty(stl) && get(b:, 'airline_do_mq_check', 1) + if g:airline#init#vim_async + noa call airline#async#get_mq_async(cmd, file) + elseif has("nvim") + noa call airline#async#nvim_get_mq_async(cmd, file) + else + " remove \n at the end of the command + let output=system(cmd)[0:-2] + noa call airline#async#mq_output(output, file) + endif + endif + " do not do mq check anymore + let b:airline_do_mq_check = 0 + if exists("b:mq") && !empty(b:mq) + if stl is# 'default' + " Shorten default a bit + let stl='def' + endif + let stl.=' ['.b:mq.']' + endif + let s:vcs_config['mercurial'].branch = stl + else + let s:vcs_config['mercurial'].branch = '' + endif +endfunction + +function! s:display_hg_branch() + return b:buffer_vcs_config['mercurial'].branch +endfunction + +function! s:update_branch() + for vcs in keys(s:vcs_config) + call {s:vcs_config[vcs].update_branch}() + if b:buffer_vcs_config[vcs].branch != s:vcs_config[vcs].branch + let b:buffer_vcs_config[vcs].branch = s:vcs_config[vcs].branch + unlet! b:airline_head + endif + endfor +endfunction + +function! airline#extensions#branch#update_untracked_config(file, vcs) + if !has_key(s:vcs_config[a:vcs].untracked, a:file) + return + elseif s:vcs_config[a:vcs].untracked[a:file] != b:buffer_vcs_config[a:vcs].untracked + let b:buffer_vcs_config[a:vcs].untracked = s:vcs_config[a:vcs].untracked[a:file] + unlet! b:airline_head + endif +endfunction + +function! s:update_untracked() + let file = expand("%:p") + if empty(file) || isdirectory(file) + return + endif + + let needs_update = 1 + for vcs in keys(s:vcs_config) + if file =~ s:vcs_config[vcs].exclude + " Skip check for files that live in the exclude directory + let needs_update = 0 + endif + if has_key(s:vcs_config[vcs].untracked, file) + let needs_update = 0 + call airline#extensions#branch#update_untracked_config(file, vcs) + endif + endfor + + if !needs_update + return + endif + + for vcs in keys(s:vcs_config) + let config = s:vcs_config[vcs] + if g:airline#init#vim_async + " Note that asynchronous update updates s:vcs_config only, and only + " s:update_untracked updates b:buffer_vcs_config. If s:vcs_config is + " invalidated again before s:update_untracked is called, then we lose the + " result of the previous call, i.e. the head string is not updated. It + " doesn't happen often in practice, so we let it be. + noa call airline#async#vim_vcs_untracked(config, file) + else + " nvim async or vim without job-feature + noa call airline#async#nvim_vcs_untracked(config, file, vcs) + endif + endfor +endfunction + +function! airline#extensions#branch#head() + if !exists('b:buffer_vcs_config') + call s:init_buffer() + endif + + call s:update_branch() + call s:update_untracked() + + if exists('b:airline_head') && !empty(b:airline_head) + return b:airline_head + endif + + let b:airline_head = '' + let vcs_priority = get(g:, "airline#extensions#branch#vcs_priority", ["git", "mercurial"]) + + let heads = [] + for vcs in vcs_priority + if !empty(b:buffer_vcs_config[vcs].branch) + let heads += [vcs] + endif + endfor + + for vcs in heads + if !empty(b:airline_head) + let b:airline_head .= ' | ' + endif + if len(heads) > 1 + let b:airline_head .= s:vcs_config[vcs].exe .':' + endif + let b:airline_head .= s:format_name({s:vcs_config[vcs].display_branch}()) + let b:airline_head .= b:buffer_vcs_config[vcs].untracked + endfor + + if empty(heads) + if airline#util#has_vcscommand() + noa call VCSCommandEnableBufferSetup() + if exists('b:VCSCommandBufferInfo') + let b:airline_head = s:format_name(get(b:VCSCommandBufferInfo, 0, '')) + endif + endif + endif + + if empty(heads) + if airline#util#has_custom_scm() + try + let Fn = function(g:airline#extensions#branch#custom_head) + let b:airline_head = Fn() + endtry + endif + endif + + if exists("g:airline#extensions#branch#displayed_head_limit") + let w:displayed_head_limit = g:airline#extensions#branch#displayed_head_limit + if len(b:airline_head) > w:displayed_head_limit - 1 + let b:airline_head = b:airline_head[0:(w:displayed_head_limit - 1)].(&encoding ==? 'utf-8' ? '…' : '.') + endif + endif + + let minwidth = empty(get(b:, 'airline_hunks', '')) ? 14 : 7 + let b:airline_head = airline#util#shorten(b:airline_head, 120, minwidth) + return b:airline_head +endfunction + +function! airline#extensions#branch#get_head() + let head = airline#extensions#branch#head() + let empty_message = get(g:, 'airline#extensions#branch#empty_message', '') + let symbol = get(g:, 'airline#extensions#branch#symbol', g:airline_symbols.branch) + return empty(head) + \ ? empty_message + \ : printf('%s%s', empty(symbol) ? '' : symbol.(g:airline_symbols.space), head) +endfunction + +function! s:reset_untracked_cache(shellcmdpost) + " shellcmdpost - whether function was called as a result of ShellCmdPost hook + if !g:airline#init#vim_async && !has('nvim') + if a:shellcmdpost + " Clear cache only if there was no error or the script uses an + " asynchronous interface. Otherwise, cache clearing would overwrite + " v:shell_error with a system() call inside get_*_untracked. + if v:shell_error + return + endif + endif + endif + + let file = expand("%:p") + for vcs in keys(s:vcs_config) + " Dump the value of the cache for the current file. Partially mitigates the + " issue of cache invalidation happening before a call to + " s:update_untracked() + call airline#extensions#branch#update_untracked_config(file, vcs) + let s:vcs_config[vcs].untracked = {} + endfor +endfunction + +function! airline#extensions#branch#init(ext) + call airline#parts#define_function('branch', 'airline#extensions#branch#get_head') + + autocmd ShellCmdPost,CmdwinLeave * unlet! b:airline_head b:airline_do_mq_check + autocmd User AirlineBeforeRefresh unlet! b:airline_head b:airline_do_mq_check + autocmd BufWritePost * call s:reset_untracked_cache(0) + autocmd ShellCmdPost * call s:reset_untracked_cache(1) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/bufferline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/bufferline.vim new file mode 100644 index 0000000..b7ccc09 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/bufferline.vim @@ -0,0 +1,29 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('*bufferline#get_status_string') + finish +endif + +let s:overwrite = get(g:, 'airline#extensions#bufferline#overwrite_variables', 1) + +function! airline#extensions#bufferline#init(ext) + if s:overwrite + highlight bufferline_selected gui=bold cterm=bold term=bold + highlight link bufferline_selected_inactive airline_c_inactive + let g:bufferline_inactive_highlight = 'airline_c' + let g:bufferline_active_highlight = 'bufferline_selected' + let g:bufferline_active_buffer_left = '' + let g:bufferline_active_buffer_right = '' + let g:bufferline_separator = g:airline_symbols.space + endif + + if exists("+autochdir") && &autochdir == 1 + " if 'acd' is set, vim-airline uses the path section, so we need ot redefine this here as well + call airline#parts#define_raw('path', '%{bufferline#refresh_status()}'.bufferline#get_status_string()) + else + call airline#parts#define_raw('file', '%{bufferline#refresh_status()}'.bufferline#get_status_string()) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/capslock.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/capslock.vim new file mode 100644 index 0000000..55b28da --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/capslock.vim @@ -0,0 +1,16 @@ +" MIT License. Copyright (c) 2014-2018 Mathias Andersson et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('*CapsLockStatusline') + finish +endif + +function! airline#extensions#capslock#status() + return tolower(CapsLockStatusline()) == '[caps]' ? 'CAPS' : '' +endfunction + +function! airline#extensions#capslock#init(ext) + call airline#parts#define_function('capslock', 'airline#extensions#capslock#status') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/commandt.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/commandt.vim new file mode 100644 index 0000000..1e05a58 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/commandt.vim @@ -0,0 +1,18 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'command_t_loaded', 0) + finish +endif + +function! airline#extensions#commandt#apply(...) + if bufname('%') ==# 'GoToFile' + call airline#extensions#apply_left_override('CommandT', '') + endif +endfunction + +function! airline#extensions#commandt#init(ext) + call a:ext.add_statusline_func('airline#extensions#commandt#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/csv.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/csv.vim new file mode 100644 index 0000000..d0eb64b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/csv.vim @@ -0,0 +1,32 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_csv', 0) && !exists(':Table') + finish +endif + +let s:column_display = get(g:, 'airline#extensions#csv#column_display', 'Number') + +function! airline#extensions#csv#get_column() + if exists('*CSV_WCol') + if s:column_display ==# 'Name' + return '['.CSV_WCol('Name').CSV_WCol().']' + else + return '['.CSV_WCol().']' + endif + endif + return '' +endfunction + +function! airline#extensions#csv#apply(...) + if &ft ==# "csv" + call airline#extensions#prepend_to_section('gutter', + \ g:airline_left_alt_sep.' %{airline#extensions#csv#get_column()}') + endif +endfunction + +function! airline#extensions#csv#init(ext) + call a:ext.add_statusline_func('airline#extensions#csv#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlp.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlp.vim new file mode 100644 index 0000000..c477a6a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlp.vim @@ -0,0 +1,81 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_ctrlp', 0) + finish +endif + +let s:color_template = get(g:, 'airline#extensions#ctrlp#color_template', 'insert') + +function! airline#extensions#ctrlp#generate_color_map(dark, light, white) + return { + \ 'CtrlPdark' : a:dark, + \ 'CtrlPlight' : a:light, + \ 'CtrlPwhite' : a:white, + \ 'CtrlParrow1' : [ a:light[1] , a:white[1] , a:light[3] , a:white[3] , '' ] , + \ 'CtrlParrow2' : [ a:white[1] , a:light[1] , a:white[3] , a:light[3] , '' ] , + \ 'CtrlParrow3' : [ a:light[1] , a:dark[1] , a:light[3] , a:dark[3] , '' ] , + \ } +endfunction + +function! airline#extensions#ctrlp#load_theme(palette) + if exists('a:palette.ctrlp') + let theme = a:palette.ctrlp + else + let s:color_template = has_key(a:palette, s:color_template) ? s:color_template : 'insert' + let theme = airline#extensions#ctrlp#generate_color_map( + \ a:palette[s:color_template]['airline_c'], + \ a:palette[s:color_template]['airline_b'], + \ a:palette[s:color_template]['airline_a']) + endif + for key in keys(theme) + call airline#highlighter#exec(key, theme[key]) + endfor +endfunction + +" Arguments: focus, byfname, regexp, prv, item, nxt, marked +function! airline#extensions#ctrlp#ctrlp_airline(...) + let b = airline#builder#new({'active': 1}) + if a:2 == 'file' + call b.add_section_spaced('CtrlPlight', 'by fname') + endif + if a:3 + call b.add_section_spaced('CtrlPlight', 'regex') + endif + if get(g:, 'airline#extensions#ctrlp#show_adjacent_modes', 1) + call b.add_section_spaced('CtrlPlight', a:4) + call b.add_section_spaced('CtrlPwhite', a:5) + call b.add_section_spaced('CtrlPlight', a:6) + else + call b.add_section_spaced('CtrlPwhite', a:5) + endif + call b.add_section_spaced('CtrlPdark', a:7) + call b.split() + call b.add_section_spaced('CtrlPdark', a:1) + call b.add_section_spaced('CtrlPdark', a:2) + call b.add_section_spaced('CtrlPlight', '%{getcwd()}') + return b.build() +endfunction + +" Argument: len +function! airline#extensions#ctrlp#ctrlp_airline_status(...) + let len = '%#CtrlPdark# '.a:1 + let dir = '%=%<%#CtrlParrow3#'.g:airline_right_sep.'%#CtrlPlight# '.getcwd().' %*' + return len.dir +endfunction + +function! airline#extensions#ctrlp#apply(...) + " disable statusline overwrite if ctrlp already did it + return match(&statusline, 'CtrlPwhite') >= 0 ? -1 : 0 +endfunction + +function! airline#extensions#ctrlp#init(ext) + let g:ctrlp_status_func = { + \ 'main': 'airline#extensions#ctrlp#ctrlp_airline', + \ 'prog': 'airline#extensions#ctrlp#ctrlp_airline_status', + \ } + call a:ext.add_statusline_func('airline#extensions#ctrlp#apply') + call a:ext.add_theme_func('airline#extensions#ctrlp#load_theme') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlspace.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlspace.vim new file mode 100644 index 0000000..66f29a5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ctrlspace.vim @@ -0,0 +1,20 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space +let s:padding = s:spc . s:spc . s:spc +let s:cs = ctrlspace#context#Configuration().Symbols.CS + +function! airline#extensions#ctrlspace#statusline(...) + let b = airline#builder#new({ 'active': 1 }) + call b.add_section('airline_b', s:cs . s:padding . ctrlspace#api#StatuslineModeSegment(s:padding)) + call b.split() + call b.add_section('airline_x', s:spc . ctrlspace#api#StatuslineTabSegment() . s:spc) + return b.build() +endfunction + +function! airline#extensions#ctrlspace#init(ext) + let g:CtrlSpaceStatuslineFunction = "airline#extensions#ctrlspace#statusline()" +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/cursormode.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/cursormode.vim new file mode 100644 index 0000000..097ddd8 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/cursormode.vim @@ -0,0 +1,132 @@ +" Copyright (C) 2014 Andrea Cedraro <a.cedraro@gmail.com> +" Copyright (C) 2017 Eduardo Suarez-Santana <e.suarezsantana@gmail.com> +" +" Permission is hereby granted, free of charge, to any person obtaining +" a copy of this software and associated documentation files (the "Software"), +" to deal in the Software without restriction, including without limitation +" the rights to use, copy, modify, merge, publish, distribute, sublicense, +" and/or sell copies of the Software, and to permit persons to whom the +" Software is furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included +" in all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +" OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +scriptencoding utf-8 + +let s:is_win = has('win32') || has('win64') +let s:is_iTerm = exists('$TERM_PROGRAM') && $TERM_PROGRAM =~# 'iTerm.app' +let s:is_AppleTerminal = exists('$TERM_PROGRAM') && $TERM_PROGRAM =~# 'Apple_Terminal' + +let s:is_good = !has('gui_running') && !s:is_win && !s:is_AppleTerminal + +let s:last_mode = '' + +if !exists('g:cursormode_exit_mode') + let g:cursormode_exit_mode='n' +endif + +function! airline#extensions#cursormode#tmux_escape(escape) + return '\033Ptmux;'.substitute(a:escape, '\\033', '\\033\\033', 'g').'\033\\' +endfunction + +let s:iTerm_escape_template = '\033]Pl%s\033\\' +let s:xterm_escape_template = '\033]12;%s\007' + +function! s:get_mode() + return call(get(g:, 'cursormode_mode_func', 'mode'), []) +endfunction + +function! airline#extensions#cursormode#set(...) + let mode = s:get_mode() + if mode !=# s:last_mode + let s:last_mode = mode + call s:set_cursor_color_for(mode) + endif + return '' +endfunction + +function! s:set_cursor_color_for(mode) + let mode = a:mode + for mode in [a:mode, a:mode.&background] + if has_key(s:color_map, mode) + try + let save_eventignore = &eventignore + set eventignore=all + let save_shelltemp = &shelltemp + set noshelltemp + + silent call system(s:build_command(s:color_map[mode])) + return + finally + let &shelltemp = save_shelltemp + let &eventignore = save_eventignore + endtry + endif + endfor +endfunction + +function! s:build_command(color) + if s:is_iTerm + let color = substitute(a:color, '^#', '', '') + let escape_template = s:iTerm_escape_template + else + let color = a:color + let escape_template = s:xterm_escape_template + endif + + let escape = printf(escape_template, color) + if exists('$TMUX') + let escape = airline#extensions#cursormode#tmux_escape(escape) + endif + return "printf '".escape."' > /dev/tty" +endfunction + +function! s:get_color_map() + if exists('g:cursormode_color_map') + return g:cursormode_color_map + endif + + try + let map = g:cursormode#{g:colors_name}#color_map + return map + catch + return { + \ "nlight": "#000000", + \ "ndark": "#BBBBBB", + \ "i": "#0000BB", + \ "v": "#FF5555", + \ "V": "#BBBB00", + \ "\<C-V>": "#BB00BB", + \ } + endtry +endfunction + +augroup airline#extensions#cursormode + autocmd! + autocmd VimLeave * nested call s:set_cursor_color_for(g:cursormode_exit_mode) + " autocmd VimEnter * call airline#extensions#cursormode#activate() + autocmd Colorscheme * call airline#extensions#cursormode#activate() +augroup END + +function! airline#extensions#cursormode#activate() + let s:color_map = s:get_color_map() + call airline#extensions#cursormode#set() +endfunction + +function! airline#extensions#cursormode#apply(...) + let w:airline_section_a = get(w:, 'airline_section_a', g:airline_section_a) + let w:airline_section_a .= '%{airline#extensions#cursormode#set()}' +endfunction + +function! airline#extensions#cursormode#init(ext) + let s:color_map = s:get_color_map() + call a:ext.add_statusline_func('airline#extensions#cursormode#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/default.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/default.vim new file mode 100644 index 0000000..f9ca3d4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/default.vim @@ -0,0 +1,100 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:section_use_groups = get(g:, 'airline#extensions#default#section_use_groupitems', 1) +let s:section_truncate_width = get(g:, 'airline#extensions#default#section_truncate_width', { + \ 'b': 79, + \ 'x': 60, + \ 'y': 88, + \ 'z': 45, + \ 'warning': 80, + \ 'error': 80, + \ }) +let s:layout = get(g:, 'airline#extensions#default#layout', [ + \ [ 'a', 'b', 'c' ], + \ [ 'x', 'y', 'z', 'warning', 'error' ] + \ ]) + +function! s:get_section(winnr, key, ...) + if has_key(s:section_truncate_width, a:key) + if winwidth(a:winnr) < s:section_truncate_width[a:key] + return '' + endif + endif + let spc = g:airline_symbols.space + if !exists('g:airline_section_{a:key}') + return '' + endif + let text = airline#util#getwinvar(a:winnr, 'airline_section_'.a:key, g:airline_section_{a:key}) + let [prefix, suffix] = [get(a:000, 0, '%('.spc), get(a:000, 1, spc.'%)')] + return empty(text) ? '' : prefix.text.suffix +endfunction + +function! s:build_sections(builder, context, keys) + for key in a:keys + if (key == 'warning' || key == 'error') && !a:context.active + continue + endif + call s:add_section(a:builder, a:context, key) + endfor +endfunction + +" There still is a highlighting bug when using groups %(%) in the statusline, +" deactivate it, unless it is fixed (7.4.1511) +if s:section_use_groups && (v:version >= 704 || (v:version >= 703 && has('patch81'))) + function! s:add_section(builder, context, key) + let condition = (a:key is# "warning" || a:key is# "error") && + \ (v:version == 704 && !has("patch1511")) + " i have no idea why the warning section needs special treatment, but it's + " needed to prevent separators from showing up + if ((a:key == 'error' || a:key == 'warning') && empty(s:get_section(a:context.winnr, a:key))) + return + endif + if condition + call a:builder.add_raw('%(') + endif + call a:builder.add_section('airline_'.a:key, s:get_section(a:context.winnr, a:key)) + if condition + call a:builder.add_raw('%)') + endif + endfunction +else + " older version don't like the use of %(%) + function! s:add_section(builder, context, key) + if ((a:key == 'error' || a:key == 'warning') && empty(s:get_section(a:context.winnr, a:key))) + return + endif + if a:key == 'warning' + call a:builder.add_raw('%#airline_warning#'.s:get_section(a:context.winnr, a:key)) + elseif a:key == 'error' + call a:builder.add_raw('%#airline_error#'.s:get_section(a:context.winnr, a:key)) + else + call a:builder.add_section('airline_'.a:key, s:get_section(a:context.winnr, a:key)) + endif + endfunction +endif + +function! airline#extensions#default#apply(builder, context) + let winnr = a:context.winnr + let active = a:context.active + + if airline#util#getwinvar(winnr, 'airline_render_left', active || (!active && !g:airline_inactive_collapse)) + call s:build_sections(a:builder, a:context, s:layout[0]) + else + let text = s:get_section(winnr, 'c') + if empty(text) + let text = ' %f%m ' + endif + call a:builder.add_section('airline_c'.(a:context.bufnr), text) + endif + + call a:builder.split(s:get_section(winnr, 'gutter', '', '')) + + if airline#util#getwinvar(winnr, 'airline_render_right', 1) + call s:build_sections(a:builder, a:context, s:layout[1]) + endif + + return 1 +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/denite.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/denite.vim new file mode 100644 index 0000000..e3c1f3b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/denite.vim @@ -0,0 +1,41 @@ +" MIT License. Copyright (c) 2017-2018 Thomas Dy et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_denite', 0) + finish +endif + +" Denite does not use vim's built-in modal editing but has a custom prompt +" that implements its own insert/normal mode so we have to handle changing the +" highlight +function! airline#extensions#denite#check_denite_mode(bufnr) + if &filetype != 'denite' + return '' + endif + let mode = split(denite#get_status_mode(), ' ') + let mode = tolower(mode[1]) + if !exists('b:denite_mode_cache') || mode != b:denite_mode_cache + call airline#highlighter#highlight([mode], a:bufnr) + let b:denite_mode_cache = mode + endif + return '' +endfunction + +function! airline#extensions#denite#apply(...) + if &ft == 'denite' + let w:airline_skip_empty_sections = 0 + call a:1.add_section('airline_a', ' Denite %{airline#extensions#denite#check_denite_mode('.a:2['bufnr'].')}') + call a:1.add_section('airline_c', ' %{denite#get_status_sources()}') + call a:1.split() + call a:1.add_section('airline_y', ' %{denite#get_status_path()} ') + call a:1.add_section('airline_z', ' %{denite#get_status_linenr()} ') + return 1 + endif +endfunction + +function! airline#extensions#denite#init(ext) + call denite#custom#option('_', 'statusline', 0) + call a:ext.add_statusline_func('airline#extensions#denite#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/eclim.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/eclim.vim new file mode 100644 index 0000000..3c48d75 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/eclim.vim @@ -0,0 +1,61 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':ProjectCreate') + finish +endif + +function! airline#extensions#eclim#creat_line(...) + if &filetype == "tree" + let builder = a:1 + call builder.add_section('airline_a', ' Project ') + call builder.add_section('airline_b', ' %f ') + call builder.add_section('airline_c', '') + return 1 + endif +endfunction + +function! airline#extensions#eclim#get_warnings() + " Cache vavlues, so that it isn't called too often + if exists("s:eclim_errors") && + \ get(b:, 'airline_changenr', 0) == changenr() + return s:eclim_errors + endif + let eclimList = eclim#display#signs#GetExisting() + let s:eclim_errors = '' + + if !empty(eclimList) + " Remove any non-eclim signs (see eclim#display#signs#Update) + " First check for just errors since they are more important. + " If there are no errors, then check for warnings. + let errorList = filter(copy(eclimList), 'v:val.name =~ "^\\(qf_\\)\\?\\(error\\)$"') + + if (empty(errorList)) + " use the warnings + call filter(eclimList, 'v:val.name =~ "^\\(qf_\\)\\?\\(warning\\)$"') + let type = 'W' + else + " Use the errors + let eclimList = errorList + let type = 'E' + endif + + if !empty(eclimList) + let errorsLine = eclimList[0]['line'] + let errorsNumber = len(eclimList) + let errors = "[Eclim:" . type . " line:".string(errorsLine)." (".string(errorsNumber).")]" + if !exists(':SyntasticCheck') || SyntasticStatuslineFlag() == '' + let s:eclim_errors = errors.(g:airline_symbols.space) + endif + endif + endif + let b:airline_changenr = changenr() + return s:eclim_errors +endfunction + +function! airline#extensions#eclim#init(ext) + call airline#parts#define_function('eclim', 'airline#extensions#eclim#get_warnings') + call a:ext.add_statusline_func('airline#extensions#eclim#creat_line') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/example.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/example.vim new file mode 100644 index 0000000..50a327d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/example.vim @@ -0,0 +1,55 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +" we don't actually want this loaded :P +finish + +" Due to some potential rendering issues, the use of the `space` variable is +" recommended. +let s:spc = g:airline_symbols.space + +" Extension specific variables can be defined the usual fashion. +if !exists('g:airline#extensions#example#number_of_cats') + let g:airline#extensions#example#number_of_cats = 42 +endif + +" First we define an init function that will be invoked from extensions.vim +function! airline#extensions#example#init(ext) + + " Here we define a new part for the plugin. This allows users to place this + " extension in arbitrary locations. + call airline#parts#define_raw('cats', '%{airline#extensions#example#get_cats()}') + + " Next up we add a funcref so that we can run some code prior to the + " statusline getting modifed. + call a:ext.add_statusline_func('airline#extensions#example#apply') + + " You can also add a funcref for inactive statuslines. + " call a:ext.add_inactive_statusline_func('airline#extensions#example#unapply') +endfunction + +" This function will be invoked just prior to the statusline getting modified. +function! airline#extensions#example#apply(...) + " First we check for the filetype. + if &filetype == "nyancat" + + " Let's say we want to append to section_c, first we check if there's + " already a window-local override, and if not, create it off of the global + " section_c. + let w:airline_section_c = get(w:, 'airline_section_c', g:airline_section_c) + + " Then we just append this extenion to it, optionally using separators. + let w:airline_section_c .= s:spc.g:airline_left_alt_sep.s:spc.'%{airline#extensions#example#get_cats()}' + endif +endfunction + +" Finally, this function will be invoked from the statusline. +function! airline#extensions#example#get_cats() + let cats = '' + for i in range(1, g:airline#extensions#example#number_of_cats) + let cats .= ' (,,,)=(^.^)=(,,,) ' + endfor + return cats +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/fugitiveline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/fugitiveline.vim new file mode 100644 index 0000000..5dab995 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/fugitiveline.vim @@ -0,0 +1,49 @@ +" MIT License. Copyright (c) 2017-2018 Cimbali et al +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !airline#util#has_fugitive() + finish +endif + + +if exists("+autochdir") && &autochdir == 1 + let s:fmod = ':p' +else + let s:fmod = ':.' +endif + +function! airline#extensions#fugitiveline#bufname() + if !exists('b:fugitive_name') + let b:fugitive_name = '' + try + if bufname('%') =~? '^fugitive:' && exists('*FugitiveReal') + let b:fugitive_name = FugitiveReal(bufname('%')) + elseif exists('b:git_dir') + let buffer = fugitive#buffer() + if buffer.type('blob') + let b:fugitive_name = buffer.repo().translate(buffer.path('/')) + endif + endif + catch + endtry + endif + + if empty(b:fugitive_name) + return fnamemodify(bufname('%'), s:fmod) + else + return fnamemodify(b:fugitive_name, s:fmod) + endif +endfunction + +function! airline#extensions#fugitiveline#init(ext) + if exists("+autochdir") && &autochdir == 1 + " if 'acd' is set, vim-airline uses the path section, so we need to redefine this here as well + call airline#parts#define_raw('path', '%<%{airline#extensions#fugitiveline#bufname()}%m') + else + call airline#parts#define_raw('file', '%<%{airline#extensions#fugitiveline#bufname()}%m') + endif + autocmd ShellCmdPost,CmdwinLeave * unlet! b:fugitive_name + autocmd User AirlineBeforeRefresh unlet! b:fugitive_name +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/grepper.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/grepper.vim new file mode 100644 index 0000000..3e5debf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/grepper.vim @@ -0,0 +1,19 @@ +" MIT License. Copyright (c) 2014-2018 Mathias Andersson et al. +" vim: et ts=2 sts=2 sw=2 + +" Heavily derived from the Gutentags extension + +scriptencoding utf-8 + +if !get(g:, 'loaded_grepper', 0) + finish +endif + +function! airline#extensions#grepper#status() + let msg = grepper#statusline() + return empty(msg) ? '' : 'grepper' +endfunction + +function! airline#extensions#grepper#init(ext) + call airline#parts#define_function('grepper', 'airline#extensions#grepper#status') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/gutentags.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/gutentags.vim new file mode 100644 index 0000000..4af2d78 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/gutentags.vim @@ -0,0 +1,17 @@ +" MIT License. Copyright (c) 2014-2018 Mathias Andersson et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_gutentags', 0) + finish +endif + +function! airline#extensions#gutentags#status() + let msg = gutentags#statusline() + return empty(msg) ? '' : 'Gen. ' . msg +endfunction + +function! airline#extensions#gutentags#init(ext) + call airline#parts#define_function('gutentags', 'airline#extensions#gutentags#status') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/hunks.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/hunks.vim new file mode 100644 index 0000000..aba84cc --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/hunks.vim @@ -0,0 +1,93 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_signify', 0) && !get(g:, 'loaded_gitgutter', 0) && !get(g:, 'loaded_changes', 0) && !get(g:, 'loaded_quickfixsigns', 0) + finish +endif + +let s:non_zero_only = get(g:, 'airline#extensions#hunks#non_zero_only', 0) +let s:hunk_symbols = get(g:, 'airline#extensions#hunks#hunk_symbols', ['+', '~', '-']) + +function! s:get_hunks_signify() + let hunks = sy#repo#get_stats() + if hunks[0] >= 0 + return hunks + endif + return [] +endfunction + +function! s:is_branch_empty() + return exists('*airline#extensions#branch#head') && + \ empty(get(b:, 'airline_head', '')) +endfunction + +function! s:get_hunks_gitgutter() + if !get(g:, 'gitgutter_enabled', 0) || s:is_branch_empty() + return '' + endif + return GitGutterGetHunkSummary() +endfunction + +function! s:get_hunks_changes() + if !get(b:, 'changes_view_enabled', 0) || s:is_branch_empty() + return [] + endif + let hunks = changes#GetStats() + return hunks == [0, 0, 0] ? [] : hunks +endfunction + +function! s:get_hunks_empty() + return '' +endfunction + +function! s:get_hunks() + if !exists('b:source_func') || get(b:, 'source_func', '') is# 's:get_hunks_empty' + if get(g:, 'loaded_signify') && sy#buffer_is_active() + let b:source_func = 's:get_hunks_signify' + elseif exists('*GitGutterGetHunkSummary') + let b:source_func = 's:get_hunks_gitgutter' + elseif exists('*changes#GetStats') + let b:source_func = 's:get_hunks_changes' + elseif exists('*quickfixsigns#vcsdiff#GetHunkSummary') + let b:source_func = 'quickfixsigns#vcsdiff#GetHunkSummary' + else + let b:source_func = 's:get_hunks_empty' + endif + endif + return {b:source_func}() +endfunction + +function! airline#extensions#hunks#get_hunks() + if !get(w:, 'airline_active', 0) + return '' + endif + " Cache values, so that it isn't called too often + if exists("b:airline_hunks") && + \ get(b:, 'airline_changenr', 0) == b:changedtick && + \ winwidth(0) == get(s:, 'airline_winwidth', 0) && + \ get(b:, 'source_func', '') isnot# 's:get_hunks_signify' && + \ get(b:, 'source_func', '') isnot# 's:get_hunks_gitgutter' && + \ get(b:, 'source_func', '') isnot# 's:get_hunks_empty' && + \ get(b:, 'source_func', '') isnot# 's:get_hunks_changes' + return b:airline_hunks + endif + let hunks = s:get_hunks() + let string = '' + if !empty(hunks) + for i in [0, 1, 2] + if (s:non_zero_only == 0 && winwidth(0) > 100) || hunks[i] > 0 + let string .= printf('%s%s ', s:hunk_symbols[i], hunks[i]) + endif + endfor + endif + let b:airline_hunks = string + let b:airline_changenr = b:changedtick + let s:airline_winwidth = winwidth(0) + return string +endfunction + +function! airline#extensions#hunks#init(ext) + call airline#parts#define_function('hunks', 'airline#extensions#hunks#get_hunks') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/keymap.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/keymap.vim new file mode 100644 index 0000000..c09c68b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/keymap.vim @@ -0,0 +1,20 @@ +" MIT License. Copyright (c) 2013-2018 Doron Behar, C.Brabandt et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !has('keymap') + finish +endif + +function! airline#extensions#keymap#status() + if (get(g:, 'airline#extensions#keymap#enabled', 1) && has('keymap')) + return printf('%s', (!empty(&keymap) ? (g:airline_symbols.keymap . ' '. &keymap) : '')) + else + return '' + endif +endfunction + +function! airline#extensions#keymap#init(ext) + call airline#parts#define_function('keymap', 'airline#extensions#keymap#status') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/languageclient.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/languageclient.vim new file mode 100644 index 0000000..82fed28 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/languageclient.vim @@ -0,0 +1,101 @@ +" MIT License. Copyright (c) 2013-2018 Bjorn Neergaard, w0rp, hallettj et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:error_symbol = get(g:, 'airline#extensions#languageclient#error_symbol', 'E:') +let s:warning_symbol = get(g:, 'airline#extensions#languageclient#warning_symbol', 'W:') +let s:show_line_numbers = get(g:, 'airline#extensions#languageclient#show_line_numbers', 1) + +" Severity codes from the LSP spec +let s:severity_error = 1 +let s:severity_warning = 2 +let s:severity_info = 3 +let s:severity_hint = 4 + +" After each LanguageClient state change `s:diagnostics` will be populated with +" a map from file names to lists of errors, warnings, informational messages, +" and hints. +let s:diagnostics = {} + +function! s:languageclient_refresh() + if get(g:, 'airline_skip_empty_sections', 0) + exe ':AirlineRefresh' + endif +endfunction + +function! s:record_diagnostics(state) + let result = json_decode(a:state.result) + let s:diagnostics = result.diagnostics + call s:languageclient_refresh() +endfunction + +function! s:get_diagnostics() + call LanguageClient#getState(function("s:record_diagnostics")) +endfunction + +function! s:diagnostics_for_buffer() + return get(s:diagnostics, expand('%:p'), []) +endfunction + +function! s:airline_languageclient_count(cnt, symbol) + return a:cnt ? a:symbol. a:cnt : '' +endfunction + +function! s:airline_languageclient_get_line_number(type) abort + let linenumber_of_first_problem = 0 + for d in s:diagnostics_for_buffer() + if has_key(d, 'severity') && d.severity == a:type + let linenumber_of_first_problem = d.range.start.line + break + endif + endfor + + if linenumber_of_first_problem == 0 + return '' + endif + + let open_lnum_symbol = get(g:, 'airline#extensions#languageclient#open_lnum_symbol', '(L') + let close_lnum_symbol = get(g:, 'airline#extensions#languageclient#close_lnum_symbol', ')') + + return open_lnum_symbol . linenumber_of_first_problem . close_lnum_symbol +endfunction + +function! airline#extensions#languageclient#get(type) + let is_err = a:type == s:severity_error + let symbol = is_err ? s:error_symbol : s:warning_symbol + + let cnt = 0 + for d in s:diagnostics_for_buffer() + if has_key(d, 'severity') && d.severity == a:type + let cnt += 1 + endif + endfor + + if cnt == 0 + return '' + endif + + if s:show_line_numbers == 1 + return s:airline_languageclient_count(cnt, symbol) . <sid>airline_languageclient_get_line_number(a:type) + else + return s:airline_languageclient_count(cnt, symbol) + endif +endfunction + +function! airline#extensions#languageclient#get_warning() + return airline#extensions#languageclient#get(s:severity_warning) +endfunction + +function! airline#extensions#languageclient#get_error() + return airline#extensions#languageclient#get(s:severity_error) +endfunction + +function! airline#extensions#languageclient#init(ext) + call airline#parts#define_function('languageclient_error_count', 'airline#extensions#languageclient#get_error') + call airline#parts#define_function('languageclient_warning_count', 'airline#extensions#languageclient#get_warning') + augroup airline_languageclient + autocmd! + autocmd User LanguageClientDiagnosticsChanged call <sid>get_diagnostics() + augroup END +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/localsearch.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/localsearch.vim new file mode 100644 index 0000000..685be47 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/localsearch.vim @@ -0,0 +1,35 @@ +" MIT License. Copyright (c) 2018 mox et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:enabled = get(g:, 'airline#extensions#localsearch#enabled', 1) +if !get(g:, 'loaded_localsearch', 0) || !s:enabled || get(g:, 'airline#extensions#localsearch#loaded', 0) + finish +endif +let g:airline#extensions#localsearch#loaded = 001 + +let s:spc = g:airline_symbols.space + +function! airline#extensions#localsearch#load_theme(palette) + call airline#highlighter#exec('localsearch_dark', [ '#ffffff' , '#000000' , 15 , 1 , '']) +endfunction + + +function! airline#extensions#localsearch#init(ext) + call a:ext.add_theme_func('airline#extensions#localsearch#load_theme') + call a:ext.add_statusline_func('airline#extensions#localsearch#apply') +endfunction + + +function! airline#extensions#localsearch#apply(...) + " first variable is the statusline builder + let builder = a:1 + + """"" WARNING: the API for the builder is not finalized and may change + if exists('#localsearch#WinEnter') " If localsearch mode is enabled + call builder.add_section('localsearch_dark', s:spc.airline#section#create('LS').s:spc) + endif + return 0 +endfunction + diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/neomake.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/neomake.vim new file mode 100644 index 0000000..b82d6c3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/neomake.vim @@ -0,0 +1,36 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +if !exists(':Neomake') + finish +endif + +let s:error_symbol = get(g:, 'airline#extensions#neomake#error_symbol', 'E:') +let s:warning_symbol = get(g:, 'airline#extensions#neomake#warning_symbol', 'W:') + +function! s:get_counts() + let l:counts = neomake#statusline#LoclistCounts() + + if empty(l:counts) + return neomake#statusline#QflistCounts() + else + return l:counts + endif +endfunction + +function! airline#extensions#neomake#get_warnings() + let counts = s:get_counts() + let warnings = get(counts, 'W', 0) + return warnings ? s:warning_symbol.warnings : '' +endfunction + +function! airline#extensions#neomake#get_errors() + let counts = s:get_counts() + let errors = get(counts, 'E', 0) + return errors ? s:error_symbol.errors : '' +endfunction + +function! airline#extensions#neomake#init(ext) + call airline#parts#define_function('neomake_warning_count', 'airline#extensions#neomake#get_warnings') + call airline#parts#define_function('neomake_error_count', 'airline#extensions#neomake#get_errors') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/netrw.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/netrw.vim new file mode 100644 index 0000000..10f024a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/netrw.vim @@ -0,0 +1,34 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':NetrwSettings') + finish +endif + +function! airline#extensions#netrw#apply(...) + if &ft == 'netrw' + let spc = g:airline_symbols.space + + call a:1.add_section('airline_a', spc.'netrw'.spc) + if exists('*airline#extensions#branch#get_head') + call a:1.add_section('airline_b', spc.'%{airline#extensions#branch#get_head()}'.spc) + endif + call a:1.add_section('airline_c', spc.'%f'.spc) + call a:1.split() + call a:1.add_section('airline_y', spc.'%{airline#extensions#netrw#sortstring()}'.spc) + return 1 + endif +endfunction + +function! airline#extensions#netrw#init(ext) + let g:netrw_force_overwrite_statusline = 0 + call a:ext.add_statusline_func('airline#extensions#netrw#apply') +endfunction + + +function! airline#extensions#netrw#sortstring() + let order = (get(g:, 'netrw_sort_direction', 'n') =~ 'n') ? '+' : '-' + return g:netrw_sort_by . (g:airline_symbols.space) . '[' . order . ']' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/nrrwrgn.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/nrrwrgn.vim new file mode 100644 index 0000000..e97c8a5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/nrrwrgn.vim @@ -0,0 +1,57 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_nrrw_rgn', 0) + finish +endif + +function! airline#extensions#nrrwrgn#apply(...) + if exists(":WidenRegion") == 2 + let spc = g:airline_symbols.space + if !exists("*nrrwrgn#NrrwRgnStatus()") || empty(nrrwrgn#NrrwRgnStatus()) + call a:1.add_section('airline_a', printf('%s[Narrowed%s#%d]', spc, spc, b:nrrw_instn)) + let bufname=(get(b:, 'orig_buf', 0) ? bufname(b:orig_buf) : substitute(bufname('%'), '^Nrrwrgn_\zs.*\ze_\d\+$', submatch(0), '')) + call a:1.add_section('airline_c', spc.bufname.spc) + call a:1.split() + else + let dict=nrrwrgn#NrrwRgnStatus() + let vmode = { 'v': 'Char ', 'V': 'Line ', '': 'Block '} + let mode = dict.visual ? vmode[dict.visual] : vmode['V'] + let winwidth = winwidth(0) + if winwidth < 80 + let mode = mode[0] + endif + let title = (winwidth < 80 ? "Nrrw" : "Narrowed ") + let multi = (winwidth < 80 ? 'M' : 'Multi') + call a:1.add_section('airline_a', printf('[%s%s%s#%d]%s', (dict.multi ? multi : ""), + \ title, mode, b:nrrw_instn, spc)) + let name = dict.fullname + if name !=# '[No Name]' + if winwidth > 100 + " need some space + let name = fnamemodify(dict.fullname, ':~') + if strlen(name) > 8 + " shorten name + let name = substitute(name, '\(.\)[^/\\]*\([/\\]\)', '\1\2', 'g') + endif + else + let name = fnamemodify(dict.fullname, ':t') + endif + endif + let range=(dict.multi ? '' : printf("[%d-%d]", dict.start[1], dict.end[1])) + call a:1.add_section('airline_c', printf("%s %s %s", name, range, + \ dict.enabled ? (&encoding ==? 'utf-8' ? "\u2713" : '') : '!')) + call a:1.split() + call a:1.add_section('airline_x', get(g:, 'airline_section_x').spc) + call a:1.add_section('airline_y', spc.get(g:, 'airline_section_y').spc) + call a:1.add_section('airline_z', spc.get(g:, 'airline_section_z')) + endif + return 1 + endif +endfunction + +function! airline#extensions#nrrwrgn#init(ext) + call a:ext.add_statusline_func('airline#extensions#nrrwrgn#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/obsession.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/obsession.vim new file mode 100644 index 0000000..04105d0 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/obsession.vim @@ -0,0 +1,22 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('*ObsessionStatus') + finish +endif + +let s:spc = g:airline_symbols.space + +if !exists('g:airline#extensions#obsession#indicator_text') + let g:airline#extensions#obsession#indicator_text = '$' +endif + +function! airline#extensions#obsession#init(ext) + call airline#parts#define_function('obsession', 'airline#extensions#obsession#get_status') +endfunction + +function! airline#extensions#obsession#get_status() + return ObsessionStatus((g:airline#extensions#obsession#indicator_text . s:spc), '') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/po.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/po.vim new file mode 100644 index 0000000..3ec2942 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/po.vim @@ -0,0 +1,81 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#po#shorten() + " Format and shorte the output of msgfmt + let b:airline_po_stats = substitute(get(b:, 'airline_po_stats', ''), ' \(message\|translation\)s*\.*', '', 'g') + let b:airline_po_stats = substitute(b:airline_po_stats, ', ', '/', 'g') + if exists("g:airline#extensions#po#displayed_limit") + let w:displayed_po_limit = g:airline#extensions#po#displayed_limit + if len(b:airline_po_stats) > w:displayed_po_limit - 1 + let b:airline_po_stats = b:airline_po_stats[0:(w:displayed_po_limit - 2)].(&encoding==?'utf-8' ? '…' : '.'). ']' + endif + endif + if strlen(get(b:, 'airline_po_stats', '')) >= 30 && winwidth(0) < 150 + let fuzzy = '' + let untranslated = '' + let messages = '' + " Shorten [120 translated, 50 fuzzy, 4 untranslated] to [120T/50F/4U] + if b:airline_po_stats =~ 'fuzzy' + let fuzzy = substitute(b:airline_po_stats, '.*\(\d\+\) fuzzy.*', '\1F', '') + endif + if b:airline_po_stats =~ 'untranslated' + let untranslated = substitute(b:airline_po_stats, '.*\(\d\+\) untranslated.*', '\1U', '') + endif + let messages = substitute(b:airline_po_stats, '\(\d\+\) translated.*', '\1T', '') + let b:airline_po_stats = printf('%s%s%s', fuzzy, (empty(fuzzy) || empty(untranslated) ? '' : '/'), untranslated) + if strlen(b:airline_po_stats) < 8 + let b:airline_po_stats = messages. (!empty(b:airline_po_stats) ? '/':''). b:airline_po_stats + endif + endif + let b:airline_po_stats = '['.b:airline_po_stats. ']' +endfunction + +function! airline#extensions#po#on_winenter() + " only reset cache, if the window size changed + if get(b:, 'airline_winwidth', 0) != winwidth(0) + let b:airline_winwidth = winwidth(0) + " needs re-formatting + unlet! b:airline_po_stats + endif +endfunction + +function! airline#extensions#po#apply(...) + if &ft ==# 'po' + call airline#extensions#prepend_to_section('z', '%{airline#extensions#po#stats()}') + " Also reset the cache variable, if a window has been split, e.g. the winwidth changed + autocmd airline BufWritePost * unlet! b:airline_po_stats + autocmd airline WinEnter * call airline#extensions#po#on_winenter() + endif +endfunction + +function! airline#extensions#po#stats() + if exists('b:airline_po_stats') && !empty(b:airline_po_stats) + return b:airline_po_stats + endif + + let cmd = 'msgfmt --statistics -o /dev/null -- ' + if g:airline#init#vim_async + call airline#async#get_msgfmt_stat(cmd, expand('%:p')) + elseif has("nvim") + call airline#async#nvim_get_msgfmt_stat(cmd, expand('%:p')) + else + let airline_po_stats = system(cmd. shellescape(expand('%:p'))) + if v:shell_error + return '' + endif + try + let b:airline_po_stats = split(airline_po_stats, '\n')[0] + catch + let b:airline_po_stats = '' + endtry + call airline#extensions#po#shorten() + endif + return get(b:, 'airline_po_stats', '') +endfunction + +function! airline#extensions#po#init(ext) + call a:ext.add_statusline_func('airline#extensions#po#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/promptline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/promptline.vim new file mode 100644 index 0000000..7c90b7c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/promptline.vim @@ -0,0 +1,35 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':PromptlineSnapshot') + finish +endif + +if !exists('airline#extensions#promptline#snapshot_file') || !len('airline#extensions#promptline#snapshot_file') + finish +endif + +let s:prompt_snapshot_file = get(g:, 'airline#extensions#promptline#snapshot_file', '') +let s:color_template = get(g:, 'airline#extensions#promptline#color_template', 'normal') + +function! airline#extensions#promptline#init(ext) + call a:ext.add_theme_func('airline#extensions#promptline#set_prompt_colors') +endfunction + +function! airline#extensions#promptline#set_prompt_colors(palette) + let color_template = has_key(a:palette, s:color_template) ? s:color_template : 'normal' + let mode_palette = a:palette[color_template] + + if !has_key(g:, 'promptline_symbols') + let g:promptline_symbols = { + \ 'left' : g:airline_left_sep, + \ 'right' : g:airline_right_sep, + \ 'left_alt' : g:airline_left_alt_sep, + \ 'right_alt' : g:airline_right_alt_sep} + endif + + let promptline_theme = promptline#api#create_theme_from_airline(mode_palette) + call promptline#api#create_snapshot_with_theme(s:prompt_snapshot_file, promptline_theme) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/quickfix.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/quickfix.vim new file mode 100644 index 0000000..2680371 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/quickfix.vim @@ -0,0 +1,58 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('g:airline#extensions#quickfix#quickfix_text') + let g:airline#extensions#quickfix#quickfix_text = 'Quickfix' +endif + +if !exists('g:airline#extensions#quickfix#location_text') + let g:airline#extensions#quickfix#location_text = 'Location' +endif + +function! airline#extensions#quickfix#apply(...) + if &buftype == 'quickfix' + let w:airline_section_a = airline#extensions#quickfix#get_type() + let w:airline_section_b = '%{get(w:, "quickfix_title", "")}' + let w:airline_section_c = '' + let w:airline_section_x = '' + endif +endfunction + +function! airline#extensions#quickfix#init(ext) + call a:ext.add_statusline_func('airline#extensions#quickfix#apply') + call a:ext.add_inactive_statusline_func('airline#extensions#quickfix#inactive_qf_window') +endfunction + +function! airline#extensions#quickfix#inactive_qf_window(...) + if getbufvar(a:2.bufnr, '&filetype') is# 'qf' && !empty(airline#util#getwinvar(a:2.winnr, 'quickfix_title', '')) + call setwinvar(a:2.winnr, 'airline_section_c', '[%{get(w:, "quickfix_title", "")}] %f %m') + endif +endfunction + +function! airline#extensions#quickfix#get_type() + if exists("*win_getid") && exists("*getwininfo") + let dict = getwininfo(win_getid()) + if len(dict) > 0 && get(dict[0], 'quickfix', 0) && !get(dict[0], 'loclist', 0) + return g:airline#extensions#quickfix#quickfix_text + elseif len(dict) > 0 && get(dict[0], 'quickfix', 0) && get(dict[0], 'loclist', 0) + return g:airline#extensions#quickfix#location_text + endif + endif + redir => buffers + silent ls + redir END + + let nr = bufnr('%') + for buf in split(buffers, '\n') + if match(buf, '\v^\s*'.nr) > -1 + if match(buf, '\cQuickfix') > -1 + return g:airline#extensions#quickfix#quickfix_text + else + return g:airline#extensions#quickfix#location_text + endif + endif + endfor + return '' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/syntastic.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/syntastic.vim new file mode 100644 index 0000000..be21fb4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/syntastic.vim @@ -0,0 +1,43 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':SyntasticCheck') + finish +endif + +let s:error_symbol = get(g:, 'airline#extensions#syntastic#error_symbol', 'E:') +let s:warning_symbol = get(g:, 'airline#extensions#syntastic#warning_symbol', 'W:') + +function! airline#extensions#syntastic#get_warning() + return airline#extensions#syntastic#get('warning') +endfunction + +function! airline#extensions#syntastic#get_error() + return airline#extensions#syntastic#get('error') +endfunction + +function! airline#extensions#syntastic#get(type) + let _backup = get(g:, 'syntastic_stl_format', '') + let is_err = (a:type is# 'error') + if is_err + let g:syntastic_stl_format = get(g:, 'airline#extensions#syntastic#stl_format_err', '%E{[%e(#%fe)]}') + else + let g:syntastic_stl_format = get(g:, 'airline#extensions#syntastic#stl_format_warn', '%W{[%w(#%fw)]}') + endif + let cnt = SyntasticStatuslineFlag() + if !empty(_backup) + let g:syntastic_stl_format = _backup + endif + if empty(cnt) + return '' + else + return (is_err ? s:error_symbol : s:warning_symbol).cnt + endif +endfunction + +function! airline#extensions#syntastic#init(ext) + call airline#parts#define_function('syntastic-warn', 'airline#extensions#syntastic#get_warning') + call airline#parts#define_function('syntastic-err', 'airline#extensions#syntastic#get_error') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline.vim new file mode 100644 index 0000000..10e235e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline.vim @@ -0,0 +1,213 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + + +let s:taboo = get(g:, 'airline#extensions#taboo#enabled', 1) && get(g:, 'loaded_taboo', 0) +if s:taboo + let g:taboo_tabline = 0 +endif + +let s:ctrlspace = get(g:, 'CtrlSpaceLoaded', 0) + +function! airline#extensions#tabline#init(ext) + if has('gui_running') + set guioptions-=e + endif + + autocmd User AirlineToggledOn call s:toggle_on() + autocmd User AirlineToggledOff call s:toggle_off() + + call s:toggle_on() + call a:ext.add_theme_func('airline#extensions#tabline#load_theme') +endfunction + +function! s:toggle_off() + call airline#extensions#tabline#autoshow#off() + call airline#extensions#tabline#tabs#off() + call airline#extensions#tabline#buffers#off() + if s:ctrlspace + call airline#extensions#tabline#ctrlspace#off() + endif +endfunction + +function! s:toggle_on() + call airline#extensions#tabline#autoshow#on() + call airline#extensions#tabline#tabs#on() + call airline#extensions#tabline#buffers#on() + if s:ctrlspace + call airline#extensions#tabline#ctrlspace#on() + endif + + set tabline=%!airline#extensions#tabline#get() +endfunction + +function! s:update_tabline() + if get(g:, 'airline#extensions#tabline#disable_refresh', 0) + return + endif + let match = expand('<afile>') + if pumvisible() + return + elseif !get(g:, 'airline#extensions#tabline#enabled', 0) + return + " return, if buffer matches ignore pattern or is directory (netrw) + elseif empty(match) || airline#util#ignore_buf(match) + \ || isdirectory(expand("<afile>")) + return + endif + call airline#util#doautocmd('BufMRUChange') + " sometimes, the tabline is not correctly updated see #1580 + " so force redraw here + if exists(":redrawtabline") == 2 + redrawtabline + else + let &tabline = &tabline + endif +endfunction + +function! airline#extensions#tabline#load_theme(palette) + if pumvisible() + return + endif + let colors = get(a:palette, 'tabline', {}) + let tablabel = get(colors, 'airline_tablabel', a:palette.normal.airline_b) + " Theme for tabs on the left + let tab = get(colors, 'airline_tab', a:palette.normal.airline_b) + let tabsel = get(colors, 'airline_tabsel', a:palette.normal.airline_a) + let tabtype = get(colors, 'airline_tabtype', a:palette.visual.airline_a) + let tabfill = get(colors, 'airline_tabfill', a:palette.normal.airline_c) + let tabmod = get(colors, 'airline_tabmod', a:palette.insert.airline_a) + let tabhid = get(colors, 'airline_tabhid', a:palette.normal.airline_c) + if has_key(a:palette, 'normal_modified') && has_key(a:palette.normal_modified, 'airline_c') + let tabmodu = get(colors, 'airline_tabmod_unsel', a:palette.normal_modified.airline_c) + else + "Fall back to normal airline_c if modified airline_c isn't present + let tabmodu = get(colors, 'airline_tabmod_unsel', a:palette.normal.airline_c) + endif + call airline#highlighter#exec('airline_tablabel', tablabel) + call airline#highlighter#exec('airline_tab', tab) + call airline#highlighter#exec('airline_tabsel', tabsel) + call airline#highlighter#exec('airline_tabtype', tabtype) + call airline#highlighter#exec('airline_tabfill', tabfill) + call airline#highlighter#exec('airline_tabmod', tabmod) + call airline#highlighter#exec('airline_tabmod_unsel', tabmodu) + call airline#highlighter#exec('airline_tabhid', tabhid) + + " Theme for tabs on the right + let tabsel_right = get(colors, 'airline_tabsel_right', a:palette.normal.airline_a) + let tab_right = get(colors, 'airline_tab_right', a:palette.inactive.airline_c) + let tabmod_right = get(colors, 'airline_tabmod_right', a:palette.insert.airline_a) + let tabhid_right = get(colors, 'airline_tabhid_right', a:palette.normal.airline_c) + if has_key(a:palette, 'normal_modified') && has_key(a:palette.normal_modified, 'airline_c') + let tabmodu_right = get(colors, 'airline_tabmod_unsel_right', a:palette.normal_modified.airline_c) + else + "Fall back to normal airline_c if modified airline_c isn't present + let tabmodu_right = get(colors, 'airline_tabmod_unsel_right', a:palette.normal.airline_c) + endif + call airline#highlighter#exec('airline_tab_right', tab_right) + call airline#highlighter#exec('airline_tabsel_right', tabsel_right) + call airline#highlighter#exec('airline_tabmod_right', tabmod_right) + call airline#highlighter#exec('airline_tabhid_right', tabhid_right) + call airline#highlighter#exec('airline_tabmod_unsel_right', tabmodu_right) +endfunction + +let s:current_tabcnt = -1 + +function! airline#extensions#tabline#get() + let show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1) + let show_tabs = get(g:, 'airline#extensions#tabline#show_tabs', 1) + + let curtabcnt = tabpagenr('$') + if curtabcnt != s:current_tabcnt + let s:current_tabcnt = curtabcnt + call airline#extensions#tabline#tabs#invalidate() + call airline#extensions#tabline#buffers#invalidate() + call airline#extensions#tabline#ctrlspace#invalidate() + endif + + if !exists('#airline#BufAdd#*') + autocmd airline BufAdd * call <sid>update_tabline() + endif + if s:ctrlspace + return airline#extensions#tabline#ctrlspace#get() + elseif show_buffers && curtabcnt == 1 || !show_tabs + return airline#extensions#tabline#buffers#get() + else + return airline#extensions#tabline#tabs#get() + endif +endfunction + +function! airline#extensions#tabline#title(n) + let title = '' + if s:taboo + let title = TabooTabTitle(a:n) + endif + + if empty(title) && exists('*gettabvar') + let title = gettabvar(a:n, 'title') + endif + + if empty(title) + let buflist = tabpagebuflist(a:n) + let winnr = tabpagewinnr(a:n) + let all_buffers = airline#extensions#tabline#buflist#list() + return airline#extensions#tabline#get_buffer_name( + \ buflist[winnr - 1], + \ filter(buflist, 'index(all_buffers, v:val) != -1')) + endif + + return title +endfunction + +function! airline#extensions#tabline#get_buffer_name(nr, ...) + let buffers = a:0 ? a:1 : airline#extensions#tabline#buflist#list() + let formatter = get(g:, 'airline#extensions#tabline#formatter', 'default') + return airline#extensions#tabline#formatters#{formatter}#format(a:nr, buffers) +endfunction + +function! airline#extensions#tabline#new_builder() + let builder_context = { + \ 'active' : 1, + \ 'tabline' : 1, + \ 'right_sep' : get(g:, 'airline#extensions#tabline#right_sep' , g:airline_right_sep), + \ 'right_alt_sep' : get(g:, 'airline#extensions#tabline#right_alt_sep', g:airline_right_alt_sep), + \ } + if get(g:, 'airline_powerline_fonts', 0) + let builder_context.left_sep = get(g:, 'airline#extensions#tabline#left_sep' , g:airline_left_sep) + let builder_context.left_alt_sep = get(g:, 'airline#extensions#tabline#left_alt_sep' , g:airline_left_alt_sep) + else + let builder_context.left_sep = get(g:, 'airline#extensions#tabline#left_sep' , ' ') + let builder_context.left_alt_sep = get(g:, 'airline#extensions#tabline#left_alt_sep' , '|') + endif + + return airline#extensions#tabline#builder#new(builder_context) +endfunction + +function! airline#extensions#tabline#group_of_bufnr(tab_bufs, bufnr) + let cur = bufnr('%') + if cur == a:bufnr + if g:airline_detect_modified && getbufvar(a:bufnr, '&modified') + let group = 'airline_tabmod' + else + let group = 'airline_tabsel' + endif + else + if g:airline_detect_modified && getbufvar(a:bufnr, '&modified') + let group = 'airline_tabmod_unsel' + elseif index(a:tab_bufs, a:bufnr) > -1 + let group = 'airline_tab' + else + let group = 'airline_tabhid' + endif + endif + return group +endfunction + +function! airline#extensions#tabline#add_label(dict, type) + if get(g:, 'airline#extensions#tabline#show_tab_type', 1) + call a:dict.add_section_spaced('airline_tablabel', + \ get(g:, 'airline#extensions#tabline#'.a:type.'_label', a:type)) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/autoshow.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/autoshow.vim new file mode 100644 index 0000000..ac1413f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/autoshow.vim @@ -0,0 +1,55 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1) +let s:buf_min_count = get(g:, 'airline#extensions#tabline#buffer_min_count', 0) +let s:tab_min_count = get(g:, 'airline#extensions#tabline#tab_min_count', 0) + +function! airline#extensions#tabline#autoshow#off() + if exists('s:original_tabline') + let &tabline = s:original_tabline + let &showtabline = s:original_showtabline + endif + + augroup airline_tabline_autoshow + autocmd! + augroup END +endfunction + +function! airline#extensions#tabline#autoshow#on() + let [ s:original_tabline, s:original_showtabline ] = [ &tabline, &showtabline ] + + augroup airline_tabline_autoshow + autocmd! + if s:buf_min_count <= 0 && s:tab_min_count <= 1 + if &lines > 3 + set showtabline=2 + endif + else + if s:show_buffers == 1 + autocmd BufEnter * call <sid>show_tabline(s:buf_min_count, len(airline#extensions#tabline#buflist#list())) + autocmd BufUnload * call <sid>show_tabline(s:buf_min_count, len(airline#extensions#tabline#buflist#list()) - 1) + else + autocmd TabEnter * call <sid>show_tabline(s:tab_min_count, tabpagenr('$')) + endif + endif + + " Invalidate cache. This has to come after the BufUnload for + " s:show_buffers, to invalidate the cache for BufEnter. + autocmd BufLeave,BufAdd,BufUnload * call airline#extensions#tabline#buflist#invalidate() + augroup END +endfunction + +function! s:show_tabline(min_count, total_count) + if a:total_count >= a:min_count + if &showtabline != 2 && &lines > 3 + set showtabline=2 + endif + else + if &showtabline != 0 + set showtabline=0 + endif + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buffers.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buffers.vim new file mode 100644 index 0000000..88ebe5c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buffers.vim @@ -0,0 +1,246 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space + +let s:current_bufnr = -1 +let s:current_modified = 0 +let s:current_tabline = '' +let s:current_visible_buffers = [] + +let s:number_map = { + \ '0': '⁰', + \ '1': '¹', + \ '2': '²', + \ '3': '³', + \ '4': '⁴', + \ '5': '⁵', + \ '6': '⁶', + \ '7': '⁷', + \ '8': '⁸', + \ '9': '⁹' + \ } +let s:number_map = &encoding == 'utf-8' + \ ? get(g:, 'airline#extensions#tabline#buffer_idx_format', s:number_map) + \ : {} + +function! airline#extensions#tabline#buffers#off() + augroup airline_tabline_buffers + autocmd! + augroup END +endfunction + +function! airline#extensions#tabline#buffers#on() + augroup airline_tabline_buffers + autocmd! + autocmd BufDelete * call airline#extensions#tabline#buflist#clean() + autocmd User BufMRUChange call airline#extensions#tabline#buflist#clean() + augroup END +endfunction + +function! airline#extensions#tabline#buffers#invalidate() + let s:current_bufnr = -1 +endfunction + +function! airline#extensions#tabline#buffers#get() + try + call <sid>map_keys() + catch + " no-op + endtry + let cur = bufnr('%') + if cur == s:current_bufnr && &columns == s:column_width + if !g:airline_detect_modified || getbufvar(cur, '&modified') == s:current_modified + return s:current_tabline + endif + endif + + let b = airline#extensions#tabline#new_builder() + let tab_bufs = tabpagebuflist(tabpagenr()) + let show_buf_label_first = 0 + + if get(g:, 'airline#extensions#tabline#buf_label_first', 0) + let show_buf_label_first = 1 + endif + if show_buf_label_first + call airline#extensions#tabline#add_label(b, 'buffers') + endif + + let b.tab_bufs = tabpagebuflist(tabpagenr()) + + let b.overflow_group = 'airline_tabhid' + let b.buffers = airline#extensions#tabline#buflist#list() + if get(g:, 'airline#extensions#tabline#current_first', 0) + if index(b.buffers, cur) > -1 + call remove(b.buffers, index(b.buffers, cur)) + endif + let b.buffers = [cur] + b.buffers + endif + + function! b.get_group(i) dict + let bufnum = get(self.buffers, a:i, -1) + if bufnum == -1 + return '' + endif + let group = airline#extensions#tabline#group_of_bufnr(self.tab_bufs, bufnum) + if bufnum == bufnr('%') + let s:current_modified = (group == 'airline_tabmod') ? 1 : 0 + endif + return group + endfunction + + if has("tablineat") + function! b.get_pretitle(i) dict + let bufnum = get(self.buffers, a:i, -1) + return '%'.bufnum.'@airline#extensions#tabline#buffers#clickbuf@' + endfunction + + function! b.get_posttitle(i) dict + return '%X' + endfunction + endif + + function! b.get_title(i) dict + let bufnum = get(self.buffers, a:i, -1) + let group = self.get_group(a:i) + let pgroup = self.get_group(a:i - 1) + " always add a space when powerline_fonts are used + " or for the very first item + if get(g:, 'airline_powerline_fonts', 0) || a:i == 0 + let space = s:spc + else + let space= (pgroup == group ? s:spc : '') + endif + + if get(g:, 'airline#extensions#tabline#buffer_idx_mode', 0) + if len(s:number_map) > 0 + return space. get(s:number_map, a:i+1, '') . '%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)' . s:spc + else + return '['.(a:i+1).s:spc.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.']' + endif + else + return space.'%(%{airline#extensions#tabline#get_buffer_name('.bufnum.')}%)'.s:spc + endif + endfunction + + let current_buffer = max([index(b.buffers, cur), 0]) + let last_buffer = len(b.buffers) - 1 + call b.insert_titles(current_buffer, 0, last_buffer) + + call b.add_section('airline_tabfill', '') + call b.split() + call b.add_section('airline_tabfill', '') + if !show_buf_label_first + call airline#extensions#tabline#add_label(b, 'buffers') + endif + + if tabpagenr('$') > 1 + call b.add_section_spaced('airline_tabmod', printf('%s %d/%d', "tab", tabpagenr(), tabpagenr('$'))) + endif + + let s:current_bufnr = cur + let s:column_width = &columns + let s:current_tabline = b.build() + let s:current_visible_buffers = copy(b.buffers) + if b._right_title <= last_buffer + call remove(s:current_visible_buffers, b._right_title, last_buffer) + endif + if b._left_title > 0 + call remove(s:current_visible_buffers, 0, b._left_title) + endif + return s:current_tabline +endfunction + +function! s:select_tab(buf_index) + " no-op when called in 'keymap_ignored_filetypes' + if count(get(g:, 'airline#extensions#tabline#keymap_ignored_filetypes', + \ ['vimfiler', 'nerdtree']), &ft) + return + endif + + let idx = a:buf_index + if s:current_visible_buffers[0] == -1 + let idx = idx + 1 + endif + + let buf = get(s:current_visible_buffers, idx, 0) + if buf != 0 + exec 'b!' . buf + endif +endfunction + +function! s:jump_to_tab(offset) + let l = airline#extensions#tabline#buflist#list() + let i = index(l, bufnr('%')) + if i > -1 + exec 'b!' . l[(i + a:offset) % len(l)] + endif +endfunction + +function! s:map_keys() + if get(g:, 'airline#extensions#tabline#buffer_idx_mode', 1) + noremap <silent> <Plug>AirlineSelectTab1 :call <SID>select_tab(0)<CR> + noremap <silent> <Plug>AirlineSelectTab2 :call <SID>select_tab(1)<CR> + noremap <silent> <Plug>AirlineSelectTab3 :call <SID>select_tab(2)<CR> + noremap <silent> <Plug>AirlineSelectTab4 :call <SID>select_tab(3)<CR> + noremap <silent> <Plug>AirlineSelectTab5 :call <SID>select_tab(4)<CR> + noremap <silent> <Plug>AirlineSelectTab6 :call <SID>select_tab(5)<CR> + noremap <silent> <Plug>AirlineSelectTab7 :call <SID>select_tab(6)<CR> + noremap <silent> <Plug>AirlineSelectTab8 :call <SID>select_tab(7)<CR> + noremap <silent> <Plug>AirlineSelectTab9 :call <SID>select_tab(8)<CR> + noremap <silent> <Plug>AirlineSelectPrevTab :<C-u>call <SID>jump_to_tab(-v:count1)<CR> + noremap <silent> <Plug>AirlineSelectNextTab :<C-u>call <SID>jump_to_tab(v:count1)<CR> + endif +endfunction + +function! airline#extensions#tabline#buffers#clickbuf(minwid, clicks, button, modifiers) abort + " Clickable buffers + " works only in recent NeoVim with has('tablineat') + + " single mouse button click without modifiers pressed + if a:clicks == 1 && a:modifiers !~# '[^ ]' + if a:button is# 'l' + " left button - switch to buffer + silent execute 'buffer' a:minwid + elseif a:button is# 'm' + " middle button - delete buffer + + if get(g:, 'airline#extensions#tabline#middle_click_preserves_windows', 0) == 0 || winnr('$') == 1 + " just simply delete the clicked buffer. This will cause windows + " associated with the clicked buffer to be closed. + silent execute 'bdelete' a:minwid + else + " find windows displaying the clicked buffer and open an new + " buffer in them. + let current_window = bufwinnr("%") + let window_number = bufwinnr(a:minwid) + let last_window_visited = -1 + + " Set to 1 if the clicked buffer was open in any windows. + let buffer_in_window = 0 + + " Find the next window with the clicked buffer open. If bufwinnr() + " returns the same window number, this is because we clicked a new + " buffer, and then tried editing a new buffer. Vim won't create a + " new empty buffer for the same window, so we get the same window + " number from bufwinnr(). In this case we just give up and don't + " delete the buffer. + " This could be made cleaner if we could check if the clicked buffer + " is a new buffer, but I don't know if there is a way to do that. + while window_number != -1 && window_number != last_window_visited + let buffer_in_window = 1 + silent execute window_number . 'wincmd w' + silent execute 'enew' + let last_window_visited = window_number + let window_number = bufwinnr(a:minwid) + endwhile + silent execute current_window . 'wincmd w' + if window_number != last_window_visited || buffer_in_window == 0 + silent execute 'bdelete' a:minwid + endif + endif + endif + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buflist.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buflist.vim new file mode 100644 index 0000000..a944cb9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/buflist.vim @@ -0,0 +1,77 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#buflist#invalidate() + unlet! s:current_buffer_list +endfunction + +function! airline#extensions#tabline#buflist#clean() + call airline#extensions#tabline#buflist#invalidate() + call airline#extensions#tabline#buffers#invalidate() +endfunction + +" paths in excludes list +function! s:ExcludePaths(nr, exclude_paths) + let bpath = fnamemodify(bufname(a:nr), ":p") + for f in a:exclude_paths + if bpath =~# f | return 1 | endif + endfor +endfunction + +" other types to exclude +function! s:ExcludeOther(nr, exclude_preview) + if (getbufvar(a:nr, 'current_syntax') == 'qf') || + \ (a:exclude_preview && getbufvar(a:nr, '&bufhidden') == 'wipe' + \ && getbufvar(a:nr, '&buftype') == 'nofile') + return 1 | endif +endfunction + +function! airline#extensions#tabline#buflist#list() + if exists('s:current_buffer_list') + return s:current_buffer_list + endif + + let exclude_buffers = get(g:, 'airline#extensions#tabline#exclude_buffers', []) + let exclude_paths = get(g:, 'airline#extensions#tabline#excludes', []) + let exclude_preview = get(g:, 'airline#extensions#tabline#exclude_preview', 1) + + let list = (exists('g:did_bufmru') && g:did_bufmru) ? BufMRUList() : range(1, bufnr("$")) + + let buffers = [] + " If this is too slow, we can switch to a different algorithm. + " Basically branch 535 already does it, but since it relies on + " BufAdd autocommand, I'd like to avoid this if possible. + for nr in list + if buflisted(nr) + " Do not add to the bufferlist, if either + " 1) bufnr is exclude_buffers list + " 2) buffername matches one of exclude_paths patterns + " 3) buffer is a quickfix buffer + " 4) when excluding preview windows: + " 'bufhidden' == wipe + " 'buftype' == nofile + " 5) ignore buffers matching airline#extensions#tabline#ignore_bufadd_pat + + " check buffer numbers first + if index(exclude_buffers, nr) >= 0 + continue + " check paths second + elseif !empty(exclude_paths) && s:ExcludePaths(nr, exclude_paths) + continue + " ignore buffers matching airline#extensions#tabline#ignore_bufadd_pat + elseif airline#util#ignore_buf(bufname(nr)) + continue + " check other types last + elseif s:ExcludeOther(nr, exclude_preview) + continue + endif + + call add(buffers, nr) + endif + endfor + + let s:current_buffer_list = buffers + return buffers +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/builder.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/builder.vim new file mode 100644 index 0000000..20964b1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/builder.vim @@ -0,0 +1,232 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:prototype = {} + +" Set the point in the tabline where the builder should insert the titles. +" +" Subsequent calls will overwrite the previous ones, so only the last call +" determines to location to insert titles. +" +" NOTE: The titles are not inserted until |build| is called, so that the +" remaining contents of the tabline can be taken into account. +" +" Callers should define at least |get_title| and |get_group| on the host +" object before calling |build|. +function! s:prototype.insert_titles(current, first, last) dict + let self._first_title = a:first " lowest index + let self._last_title = a:last " highest index + let self._left_title = a:current " next index to add on the left + let self._right_title = a:current + 1 " next index to add on the right + let self._left_position = self.get_position() " left end of titles + let self._right_position = self._left_position " right end of the titles +endfunction + +" Insert a title for entry number |index|, of group |group| at position |pos|, +" if there is space for it. Returns 1 if it is inserted, 0 otherwise +" +" |force| inserts the title even if there isn't enough space left for it. +" |sep_size| adjusts the size change that the title is considered to take up, +" to account for changes to the separators +" +" The title is defined by |get_title| on the hosting object, called with +" |index| as its only argument. +" |get_pretitle| and |get_posttitle| may be defined on the host object to +" insert some formatting before or after the title. These should be 0-width. +" +" This method updates |_right_position| and |_remaining_space| on the host +" object, if the title is inserted. +function! s:prototype.try_insert_title(index, group, pos, sep_size, force) dict + let title = self.get_title(a:index) + let title_size = s:tabline_evaluated_length(title) + a:sep_size + if a:force || self._remaining_space >= title_size + let pos = a:pos + if has_key(self, "get_pretitle") + call self.insert_raw(self.get_pretitle(a:index), pos) + let self._right_position += 1 + let pos += 1 + endif + + call self.insert_section(a:group, title, pos) + let self._right_position += 1 + let pos += 1 + + if has_key(self, "get_posttitle") + call self.insert_raw(self.get_posttitle(a:index), pos) + let self._right_position += 1 + let pos += 1 + endif + + let self._remaining_space -= title_size + return 1 + endif + return 0 +endfunction + +function! s:get_separator_change(new_group, old_group, end_group, sep_size, alt_sep_size) + return s:get_separator_change_with_end(a:new_group, a:old_group, a:end_group, a:end_group, a:sep_size, a:alt_sep_size) +endfunction + +" Compute the change in size of the tabline caused by separators +" +" This should be kept up-to-date with |s:get_transitioned_seperator| and +" |s:get_separator| in autoload/airline/builder.vim +function! s:get_separator_change_with_end(new_group, old_group, new_end_group, old_end_group, sep_size, alt_sep_size) + let sep_change = 0 + if !empty(a:new_end_group) " Separator between title and the end + let sep_change += airline#builder#should_change_group(a:new_group, a:new_end_group) ? a:sep_size : a:alt_sep_size + endif + if !empty(a:old_group) " Separator between the title and the one adjacent + let sep_change += airline#builder#should_change_group(a:new_group, a:old_group) ? a:sep_size : a:alt_sep_size + if !empty(a:old_end_group) " Remove mis-predicted separator + let sep_change -= airline#builder#should_change_group(a:old_group, a:old_end_group) ? a:sep_size : a:alt_sep_size + endif + endif + return sep_change +endfunction + +" This replaces the build function of the |airline#builder#new| object, to +" insert titles as specified by the last call to |insert_titles| before +" passing to the original build function. +" +" Callers should define at least |get_title| and |get_group| on the host +" object if |insert_titles| has been called on it. +function! s:prototype.build() dict + if has_key(self, '_left_position') && self._first_title <= self._last_title + let self._remaining_space = &columns - s:tabline_evaluated_length(self._build()) + + let center_active = get(g:, 'airline#extensions#tabline#center_active', 0) + + let sep_size = s:tabline_evaluated_length(self._context.left_sep) + let alt_sep_size = s:tabline_evaluated_length(self._context.left_alt_sep) + + let outer_left_group = airline#builder#get_prev_group(self._sections, self._left_position) + let outer_right_group = airline#builder#get_next_group(self._sections, self._right_position) + + let overflow_marker = get(g:, 'airline#extensions#tabline#overflow_marker', g:airline_symbols.ellipsis) + let overflow_marker_size = s:tabline_evaluated_length(overflow_marker) + " Allow space for the markers before we begin filling in titles. + if self._left_title > self._first_title + let self._remaining_space -= overflow_marker_size + + \ s:get_separator_change(self.overflow_group, "", outer_left_group, sep_size, alt_sep_size) + endif + if self._left_title < self._last_title + let self._remaining_space -= overflow_marker_size + + \ s:get_separator_change(self.overflow_group, "", outer_right_group, sep_size, alt_sep_size) + endif + + " Add the current title + let group = self.get_group(self._left_title) + if self._left_title == self._first_title + let sep_change = s:get_separator_change(group, "", outer_left_group, sep_size, alt_sep_size) + else + let sep_change = s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) + endif + if self._left_title == self._last_title + let sep_change += s:get_separator_change(group, "", outer_right_group, sep_size, alt_sep_size) + else + let sep_change += s:get_separator_change(group, "", self.overflow_group, sep_size, alt_sep_size) + endif + let left_group = group + let right_group = group + let self._left_title -= + \ self.try_insert_title(self._left_title, group, self._left_position, sep_change, 1) + + if get(g:, 'airline#extensions#tabline#current_first', 0) + " always have current title first + let self._left_position += 1 + endif + + if !center_active && self._right_title <= self._last_title + " Add the title to the right + let group = self.get_group(self._right_title) + if self._right_title == self._last_title + let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) + endif + let right_group = group + let self._right_title += + \ self.try_insert_title(self._right_title, group, self._right_position, sep_change, 1) + endif + + while self._remaining_space > 0 + let done = 0 + if self._left_title >= self._first_title + " Insert next title to the left + let group = self.get_group(self._left_title) + if self._left_title == self._first_title + let sep_change = s:get_separator_change_with_end(group, left_group, outer_left_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, left_group, self.overflow_group, sep_size, alt_sep_size) + endif + let left_group = group + let done = self.try_insert_title(self._left_title, group, self._left_position, sep_change, 0) + let self._left_title -= done + endif + " If center_active is set, this |if| operates as an independent |if|, + " otherwise as an |elif|. + if self._right_title <= self._last_title && (center_active || !done) + " Insert next title to the right + let group = self.get_group(self._right_title) + if self._right_title == self._last_title + let sep_change = s:get_separator_change_with_end(group, right_group, outer_right_group, self.overflow_group, sep_size, alt_sep_size) - overflow_marker_size + else + let sep_change = s:get_separator_change(group, right_group, self.overflow_group, sep_size, alt_sep_size) + endif + let right_group = group + let done = self.try_insert_title(self._right_title, group, self._right_position, sep_change, 0) + let self._right_title += done + endif + if !done + break + endif + endwhile + + if self._left_title >= self._first_title + if get(g:, 'airline#extensions#tabline#current_first', 0) + let self._left_position -= 1 + endif + call self.insert_section(self.overflow_group, overflow_marker, self._left_position) + let self._right_position += 1 + endif + + if self._right_title <= self._last_title + call self.insert_section(self.overflow_group, overflow_marker, self._right_position) + endif + endif + + return self._build() +endfunction + +let s:prototype.overflow_group = 'airline_tab' + +" Extract the text content a tabline will render. (Incomplete). +" +" See :help 'statusline' for the list of fields. +function! s:evaluate_tabline(tabline) + let tabline = a:tabline + let tabline = substitute(tabline, '%{\([^}]\+\)}', '\=eval(submatch(1))', 'g') + let tabline = substitute(tabline, '%#[^#]\+#', '', 'g') + let tabline = substitute(tabline, '%(\([^)]\+\)%)', '\1', 'g') + let tabline = substitute(tabline, '%\d\+[TX]', '', 'g') + let tabline = substitute(tabline, '%=', '', 'g') + let tabline = substitute(tabline, '%\d*\*', '', 'g') + if has('tablineat') + let tabline = substitute(tabline, '%@[^@]\+@', '', 'g') + endif + return tabline +endfunction + +function! s:tabline_evaluated_length(tabline) + return airline#util#strchars(s:evaluate_tabline(a:tabline)) +endfunction + +function! airline#extensions#tabline#builder#new(context) + let builder = airline#builder#new(a:context) + let builder._build = builder.build + call extend(builder, s:prototype, 'force') + return builder +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/ctrlspace.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/ctrlspace.vim new file mode 100644 index 0000000..bb2d518 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/ctrlspace.vim @@ -0,0 +1,157 @@ +" MIT License. Copyright (c) 2016-2018 Kevin Sapper et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:current_bufnr = -1 +let s:current_modified = 0 +let s:current_tabnr = -1 +let s:current_tabline = '' +let s:highlight_groups = ['hid', 0, '', 'sel', 'mod_unsel', 0, 'mod_unsel', 'mod'] + +function! airline#extensions#tabline#ctrlspace#off() + augroup airline_tabline_ctrlspace + autocmd! + augroup END +endfunction + +function! airline#extensions#tabline#ctrlspace#on() + augroup airline_tabline_ctrlspace + autocmd! + autocmd BufDelete * call airline#extensions#tabline#ctrlspace#invalidate() + augroup END +endfunction + +function! airline#extensions#tabline#ctrlspace#invalidate() + let s:current_bufnr = -1 + let s:current_tabnr = -1 +endfunction + +function! airline#extensions#tabline#ctrlspace#add_buffer_section(builder, cur_tab, cur_buf, pull_right) + let pos_extension = (a:pull_right ? '_right' : '') + let buffer_list = ctrlspace#api#BufferList(a:cur_tab) + + " add by tenfy(tenfyzhong@qq.com) + " if the current buffer no in the buffer list + " return false and no redraw tabline. + " Fixes #1515. if there a BufEnter autocmd execute redraw. The tabline may no update. + let bufnr_list = map(copy(buffer_list), 'v:val["index"]') + if index(bufnr_list, a:cur_buf) == -1 && a:cur_tab == s:current_tabnr + return 0 + endif + + let s:current_modified = getbufvar(a:cur_buf, '&modified') + + for buffer in buffer_list + let group = 'airline_tab' + \ .s:highlight_groups[(4 * buffer.modified) + (2 * buffer.visible) + (a:cur_buf == buffer.index)] + \ .pos_extension + + let buf_name = '%(%{airline#extensions#tabline#get_buffer_name('.buffer.index.')}%)' + + if has("tablineat") + let buf_name = '%'.buffer.index.'@airline#extensions#tabline#buffers#clickbuf@'.buf_name.'%X' + endif + + call a:builder.add_section_spaced(group, buf_name) + endfor + + " add by tenfy(tenfyzhong@qq.com) + " if the selected buffer was updated + " return true + return 1 +endfunction + +function! airline#extensions#tabline#ctrlspace#add_tab_section(builder, pull_right) + let pos_extension = (a:pull_right ? '_right' : '') + let tab_list = ctrlspace#api#TabList() + + for tab in tab_list + let group = 'airline_tab' + \ .s:highlight_groups[(4 * tab.modified) + (3 * tab.current)] + \ .pos_extension + + if get(g:, 'airline#extensions#tabline#ctrlspace_show_tab_nr', 0) == 0 + call a:builder.add_section_spaced(group, '%'.tab.index.'T'.tab.title.ctrlspace#api#TabBuffersNumber(tab.index).'%T') + else + call a:builder.add_section_spaced(group, '%'.(tab.index).'T'.(tab.index).(g:airline_symbols.space).(tab.title).ctrlspace#api#TabBuffersNumber(tab.index).'%T') + endif + endfor +endfunction + +function! airline#extensions#tabline#ctrlspace#get() + let cur_buf = bufnr('%') + let buffer_label = get(g:, 'airline#extensions#tabline#buffers_label', 'buffers') + let tab_label = get(g:, 'airline#extensions#tabline#tabs_label', 'tabs') + let switch_buffers_and_tabs = get(g:, 'airline#extensions#tabline#switch_buffers_and_tabs', 0) + + try + call airline#extensions#tabline#tabs#map_keys() + endtry + + let cur_tab = tabpagenr() + + if cur_buf == s:current_bufnr && cur_tab == s:current_tabnr + if !g:airline_detect_modified || getbufvar(cur_buf, '&modified') == s:current_modified + return s:current_tabline + endif + endif + + let builder = airline#extensions#tabline#new_builder() + + let show_buffers = get(g:, 'airline#extensions#tabline#show_buffers', 1) + let show_tabs = get(g:, 'airline#extensions#tabline#show_tabs', 1) + + let AppendBuffers = function('airline#extensions#tabline#ctrlspace#add_buffer_section', [builder, cur_tab, cur_buf]) + let AppendTabs = function('airline#extensions#tabline#ctrlspace#add_tab_section', [builder]) + let AppendLabel = function(builder.add_section_spaced, ['airline_tabtype'], builder) + + " <= 1: |{Tabs} <tab| + " == 2: |{Buffers} <buffers| + " == 3: |buffers> {Buffers} {Tabs} <tabs| + let showing_mode = (2 * show_buffers) + (show_tabs) + let ignore_update = 0 + + " Add left tabline content + if showing_mode <= 1 " Tabs only mode + call AppendTabs(0) + elseif showing_mode == 2 " Buffers only mode + let ignore_update = !AppendBuffers(0) + else + if !switch_buffers_and_tabs + call AppendLabel(buffer_label) + let ignore_update = !AppendBuffers(0) + else + call AppendLabel(tab_label) + call AppendTabs(0) + endif + endif + + if ignore_update | return s:current_tabline | endif + + call builder.add_section('airline_tabfill', '') + call builder.split() + call builder.add_section('airline_tabfill', '') + + " Add right tabline content + if showing_mode <= 1 " Tabs only mode + call AppendLabel(tab_label) + elseif showing_mode == 2 " Buffers only mode + call AppendLabel(buffer_label) + else + if !switch_buffers_and_tabs + call AppendTabs(1) + call AppendLabel(tab_label) + else + let ignore_update = AppendBuffers(1) + call AppendLabel(buffer_label) + endif + endif + + if ignore_update | return s:current_tabline | endif + + let s:current_bufnr = cur_buf + let s:current_tabnr = cur_tab + let s:current_tabline = builder.build() + return s:current_tabline +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/default.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/default.vim new file mode 100644 index 0000000..c98d7ef --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/default.vim @@ -0,0 +1,43 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:fnamecollapse = get(g:, 'airline#extensions#tabline#fnamecollapse', 1) +let s:fnametruncate = get(g:, 'airline#extensions#tabline#fnametruncate', 0) +let s:buf_nr_format = get(g:, 'airline#extensions#tabline#buffer_nr_format', '%s: ') +let s:buf_nr_show = get(g:, 'airline#extensions#tabline#buffer_nr_show', 0) +let s:buf_modified_symbol = g:airline_symbols.modified + +function! airline#extensions#tabline#formatters#default#format(bufnr, buffers) + let fmod = get(g:, 'airline#extensions#tabline#fnamemod', ':~:.') + let _ = '' + + let name = bufname(a:bufnr) + if empty(name) + let _ .= '[No Name]' + else + if s:fnamecollapse + " Does not handle non-ascii characters like Cyrillic: 'D/Учёба/t.c' + "let _ .= substitute(fnamemodify(name, fmod), '\v\w\zs.{-}\ze(\\|/)', '', 'g') + let _ .= pathshorten(fnamemodify(name, fmod)) + else + let _ .= fnamemodify(name, fmod) + endif + if a:bufnr != bufnr('%') && s:fnametruncate && strlen(_) > s:fnametruncate + let _ = strpart(_, 0, s:fnametruncate) + endif + endif + + return airline#extensions#tabline#formatters#default#wrap_name(a:bufnr, _) +endfunction + +function! airline#extensions#tabline#formatters#default#wrap_name(bufnr, buffer_name) + let _ = s:buf_nr_show ? printf(s:buf_nr_format, a:bufnr) : '' + let _ .= substitute(a:buffer_name, '\\', '/', 'g') + + if getbufvar(a:bufnr, '&modified') == 1 + let _ .= s:buf_modified_symbol + endif + return _ +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/jsformatter.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/jsformatter.vim new file mode 100644 index 0000000..b16d06f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/jsformatter.vim @@ -0,0 +1,15 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#jsformatter#format(bufnr, buffers) + let buf = bufname(a:bufnr) + let filename = fnamemodify(buf, ':t') + + if filename == 'index.js' || filename == 'index.jsx' || filename == 'index.ts' || filename == 'index.tsx' + return fnamemodify(buf, ':p:h:t') . '/i' + else + return airline#extensions#tabline#formatters#unique_tail_improved#format(a:bufnr, a:buffers) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/tabnr.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/tabnr.vim new file mode 100644 index 0000000..fa71014 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/tabnr.vim @@ -0,0 +1,14 @@ +" MIT License. Copyright (c) 2017-2018 C.Brabandt et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#tabnr#format(tab_nr_type, nr) + if a:tab_nr_type == 0 " nr of splits + return (g:airline_symbols.space).'%{len(tabpagebuflist('.a:nr.'))}' + elseif a:tab_nr_type == 1 " tab number + return (g:airline_symbols.space).a:nr + else "== 2 splits and tab number + return (g:airline_symbols.space).a:nr.'.%{len(tabpagebuflist('.a:nr.'))}' + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail.vim new file mode 100644 index 0000000..3e61b60 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail.vim @@ -0,0 +1,41 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#tabline#formatters#unique_tail#format(bufnr, buffers) + let duplicates = {} + let tails = {} + let map = {} + for nr in a:buffers + let name = bufname(nr) + if empty(name) + let map[nr] = '[No Name]' + else + let tail = fnamemodify(name, ':s?/\+$??:t') + if has_key(tails, tail) + let duplicates[nr] = nr + endif + let tails[tail] = 1 + let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, tail) + endif + endfor + + let fmod = get(g:, 'airline#extensions#tabline#fnamemod', ':p:.') + for nr in values(duplicates) + let name = bufname(nr) + let fnamecollapse = get(g:, 'airline#extensions#tabline#fnamecollapse', 1) + if fnamecollapse + let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, substitute(fnamemodify(name, fmod), '\v\w\zs.{-}\ze(\\|/)', '', 'g')) + else + let map[nr] = airline#extensions#tabline#formatters#default#wrap_name(nr, fnamemodify(name, fmod)) + endif + endfor + + if has_key(map, a:bufnr) + return map[a:bufnr] + endif + + " if we get here, the buffer list isn't in sync with the selected buffer yet, fall back to the default + return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim new file mode 100644 index 0000000..c48174b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/formatters/unique_tail_improved.vim @@ -0,0 +1,91 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:skip_symbol = '…' + +function! airline#extensions#tabline#formatters#unique_tail_improved#format(bufnr, buffers) + if len(a:buffers) <= 1 " don't need to compare bufnames if has less than one buffer opened + return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) + endif + + let curbuf_tail = fnamemodify(bufname(a:bufnr), ':t') + let do_deduplicate = 0 + let path_tokens = {} + + for nr in a:buffers + let name = bufname(nr) + if !empty(name) && nr != a:bufnr && fnamemodify(name, ':t') == curbuf_tail " only perform actions if curbuf_tail isn't unique + let do_deduplicate = 1 + let tokens = reverse(split(substitute(fnamemodify(name, ':p:h'), '\\', '/', 'g'), '/')) + let token_index = 0 + for token in tokens + if token == '' | continue | endif + if token == '.' | break | endif + if !has_key(path_tokens, token_index) + let path_tokens[token_index] = {} + endif + let path_tokens[token_index][token] = 1 + let token_index += 1 + endfor + endif + endfor + + if do_deduplicate == 1 + let path = [] + let token_index = 0 + for token in reverse(split(substitute(fnamemodify(bufname(a:bufnr), ':p:h'), '\\', '/', 'g'), '/')) + if token == '.' | break | endif + let duplicated = 0 + let uniq = 1 + let single = 1 + if has_key(path_tokens, token_index) + let duplicated = 1 + if len(keys(path_tokens[token_index])) > 1 | let single = 0 | endif + if has_key(path_tokens[token_index], token) | let uniq = 0 | endif + endif + call insert(path, {'token': token, 'duplicated': duplicated, 'uniq': uniq, 'single': single}) + let token_index += 1 + endfor + + let buf_name = [curbuf_tail] + let has_uniq = 0 + let has_skipped = 0 + for token1 in reverse(path) + if !token1['duplicated'] && len(buf_name) > 1 + call insert(buf_name, s:skip_symbol) + let has_skipped = 0 + break + endif + + if has_uniq == 1 + call insert(buf_name, s:skip_symbol) + let has_skipped = 0 + break + endif + + if token1['uniq'] == 0 && token1['single'] == 1 + let has_skipped = 1 + else + if has_skipped == 1 + call insert(buf_name, s:skip_symbol) + let has_skipped = 0 + endif + call insert(buf_name, token1['token']) + endif + + if token1['uniq'] == 1 + let has_uniq = 1 + endif + endfor + + if has_skipped == 1 + call insert(buf_name, s:skip_symbol) + endif + + return airline#extensions#tabline#formatters#default#wrap_name(a:bufnr, join(buf_name, '/')) + else + return airline#extensions#tabline#formatters#default#format(a:bufnr, a:buffers) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/tabs.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/tabs.vim new file mode 100644 index 0000000..a74ab5b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/tabs.vim @@ -0,0 +1,124 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space +let s:current_bufnr = -1 +let s:current_tabnr = -1 +let s:current_modified = 0 + +function! airline#extensions#tabline#tabs#off() + augroup airline_tabline_tabs + autocmd! + augroup END +endfunction + +function! airline#extensions#tabline#tabs#on() + augroup airline_tabline_tabs + autocmd! + autocmd BufDelete * call airline#extensions#tabline#tabs#invalidate() + augroup END +endfunction + +function! airline#extensions#tabline#tabs#invalidate() + let s:current_bufnr = -1 +endfunction + +function! airline#extensions#tabline#tabs#get() + let curbuf = bufnr('%') + let curtab = tabpagenr() + try + call airline#extensions#tabline#tabs#map_keys() + catch + " no-op + endtry + if curbuf == s:current_bufnr && curtab == s:current_tabnr && &columns == s:column_width + if !g:airline_detect_modified || getbufvar(curbuf, '&modified') == s:current_modified + return s:current_tabline + endif + endif + + let b = airline#extensions#tabline#new_builder() + + call airline#extensions#tabline#add_label(b, 'tabs') + + function! b.get_group(i) dict + let curtab = tabpagenr() + let group = 'airline_tab' + if a:i == curtab + let group = 'airline_tabsel' + if g:airline_detect_modified + for bi in tabpagebuflist(curtab) + if getbufvar(bi, '&modified') + let group = 'airline_tabmod' + endif + endfor + endif + let s:current_modified = (group == 'airline_tabmod') ? 1 : 0 + endif + return group + endfunction + + function! b.get_title(i) dict + let val = '%(' + + if get(g:, 'airline#extensions#tabline#show_tab_nr', 1) + let tab_nr_type = get(g:, 'airline#extensions#tabline#tab_nr_type', 0) + let val .= airline#extensions#tabline#tabs#tabnr_formatter(tab_nr_type, a:i) + endif + + return val.'%'.a:i.'T %{airline#extensions#tabline#title('.a:i.')} %)' + endfunction + + call b.insert_titles(curtab, 1, tabpagenr('$')) + + call b.add_section('airline_tabfill', '') + call b.split() + call b.add_section('airline_tabfill', '') + + if get(g:, 'airline#extensions#tabline#show_close_button', 1) + call b.add_section('airline_tab_right', ' %999X'. + \ get(g:, 'airline#extensions#tabline#close_symbol', 'X').' ') + endif + + if get(g:, 'airline#extensions#tabline#show_splits', 1) == 1 + let buffers = tabpagebuflist(curtab) + for nr in buffers + let group = airline#extensions#tabline#group_of_bufnr(buffers, nr) . "_right" + call b.add_section_spaced(group, '%(%{airline#extensions#tabline#get_buffer_name('.nr.')}%)') + endfor + if get(g:, 'airline#extensions#tabline#show_buffers', 1) + call airline#extensions#tabline#add_label(b, 'buffers') + endif + endif + + let s:current_bufnr = curbuf + let s:current_tabnr = curtab + let s:column_width = &columns + let s:current_tabline = b.build() + return s:current_tabline +endfunction + +function! airline#extensions#tabline#tabs#map_keys() + if maparg('<Plug>AirlineSelectTab1', 'n') is# ':1tabn<CR>' + return + endif + noremap <silent> <Plug>AirlineSelectTab1 :1tabn<CR> + noremap <silent> <Plug>AirlineSelectTab2 :2tabn<CR> + noremap <silent> <Plug>AirlineSelectTab3 :3tabn<CR> + noremap <silent> <Plug>AirlineSelectTab4 :4tabn<CR> + noremap <silent> <Plug>AirlineSelectTab5 :5tabn<CR> + noremap <silent> <Plug>AirlineSelectTab6 :6tabn<CR> + noremap <silent> <Plug>AirlineSelectTab7 :7tabn<CR> + noremap <silent> <Plug>AirlineSelectTab8 :8tabn<CR> + noremap <silent> <Plug>AirlineSelectTab9 :9tabn<CR> + noremap <silent> <Plug>AirlineSelectPrevTab gT + " tabn {count} goes to count tab does not go {count} tab pages forward! + noremap <silent> <Plug>AirlineSelectNextTab :<C-U>exe repeat(':tabn\|', v:count1)<cr> +endfunction + +function! airline#extensions#tabline#tabs#tabnr_formatter(nr, i) + let formatter = get(g:, 'airline#extensions#tabline#tabnr_formatter', 'tabnr') + return airline#extensions#tabline#formatters#{formatter}#format(a:nr, a:i) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/xtabline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/xtabline.vim new file mode 100644 index 0000000..4d1cdec --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tabline/xtabline.vim @@ -0,0 +1,397 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" xTabline - Reduced version for vim-airline +" Copyright (C) 2018 Gianmaria Bajo <mg1979.git@gmail.com> +" License: MIT License +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + +function! airline#extensions#tabline#xtabline#init() + + let s:state = 0 + + " initialize mappings + call airline#extensions#tabline#xtabline#maps() + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + " Variables + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + let g:loaded_xtabline = 1 + let s:most_recent = -1 + let s:xtabline_filtering = 1 + + let t:xtl_excluded = get(g:, 'airline#extensions#tabline#exclude_buffers', []) + let t:xtl_accepted = [] + + let g:xtabline_include_previews = get(g:, 'xtabline_include_previews', 1) + + let g:xtabline_alt_action = get(g:, 'xtabline_alt_action', "buffer #") + + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + " Autocommands + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + augroup plugin-xtabline + autocmd! + + autocmd TabNew * call s:Do('new') + autocmd TabEnter * call s:Do('enter') + autocmd TabLeave * call s:Do('leave') + autocmd TabClosed * call s:Do('close') + + autocmd BufEnter * let g:xtabline_changing_buffer = 0 + autocmd BufAdd,BufDelete,BufWrite * call airline#extensions#tabline#xtabline#filter_buffers() + augroup END + + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + " Commands + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + com! XTabReopen call airline#extensions#tabline#xtabline#reopen_last_tab() + +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Mappings +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#maps() + + if !exists('g:xtabline_disable_keybindings') + + fun! s:mapkeys(keys, plug) + if empty(mapcheck(a:keys)) && !hasmapto(a:plug) + silent! execute 'nmap <unique> '.a:keys.' '.a:plug + endif + endfun + + call s:mapkeys('<F5>','<Plug>XTablineToggleTabs') + call s:mapkeys('<leader><F5>','<Plug>XTablineToggleFiltering') + call s:mapkeys('<BS>','<Plug>XTablineSelectBuffer') + call s:mapkeys(']l','<Plug>XTablineNextBuffer') + call s:mapkeys('[l','<Plug>XTablinePrevBuffer') + call s:mapkeys('<leader>tr','<Plug>XTablineReopen') + endif + + nnoremap <unique> <script> <Plug>XTablineToggleTabs <SID>ToggleTabs + nnoremap <silent> <SID>ToggleTabs :call airline#extensions#tabline#xtabline#toggle_tabs()<cr> + + nnoremap <unique> <script> <Plug>XTablineToggleFiltering <SID>ToggleFiltering + nnoremap <silent> <SID>ToggleFiltering :call airline#extensions#tabline#xtabline#toggle_buffers()<cr> + + nnoremap <unique> <script> <Plug>XTablineSelectBuffer <SID>SelectBuffer + nnoremap <silent> <expr> <SID>SelectBuffer g:xtabline_changing_buffer ? "\<C-c>" : ":<C-u>call airline#extensions#tabline#xtabline#select_buffer(v:count)\<cr>" + + nnoremap <unique> <script> <Plug>XTablineNextBuffer <SID>NextBuffer + nnoremap <silent> <expr> <SID>NextBuffer airline#extensions#tabline#xtabline#next_buffer(v:count1) + + nnoremap <unique> <script> <Plug>XTablinePrevBuffer <SID>PrevBuffer + nnoremap <silent> <expr> <SID>PrevBuffer airline#extensions#tabline#xtabline#prev_buffer(v:count1) + + nnoremap <unique> <script> <Plug>XTablineReopen <SID>ReopenLastTab + nnoremap <silent> <SID>ReopenLastTab :XTabReopen<cr> + + if get(g:, 'xtabline_cd_commands', 0) + map <unique> <leader>cdc <Plug>XTablineCdCurrent + map <unique> <leader>cdd <Plug>XTablineCdDown1 + map <unique> <leader>cd2 <Plug>XTablineCdDown2 + map <unique> <leader>cd3 <Plug>XTablineCdDown3 + map <unique> <leader>cdh <Plug>XTablineCdHome + nnoremap <unique> <script> <Plug>XTablineCdCurrent :cd %:p:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> + nnoremap <unique> <script> <Plug>XTablineCdDown1 :cd %:p:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> + nnoremap <unique> <script> <Plug>XTablineCdDown2 :cd %:p:h:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> + nnoremap <unique> <script> <Plug>XTablineCdDown3 :cd %:p:h:h:h:h<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> + nnoremap <unique> <script> <Plug>XTablineCdHome :cd ~<cr>:call airline#util#doautocmd('BufAdd')<cr>:pwd<cr> + endif +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Commands functions +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#toggle_tabs() + """Toggle between tabs/buffers tabline.""" + + if tabpagenr("$") == 1 | call airline#util#warning("There is only one tab.") | return | endif + + if g:airline#extensions#tabline#show_tabs + let g:airline#extensions#tabline#show_tabs = 0 + call airline#util#warning("Showing buffers") + else + let g:airline#extensions#tabline#show_tabs = 1 + call airline#util#warning("Showing tabs") + endif + + doautocmd BufAdd +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#toggle_buffers() + """Toggle buffer filtering in the tabline.""" + + if s:xtabline_filtering + let s:xtabline_filtering = 0 + let g:airline#extensions#tabline#exclude_buffers = [] + call airline#util#warning("Buffer filtering turned off") + doautocmd BufAdd + else + let s:xtabline_filtering = 1 + call airline#extensions#tabline#xtabline#filter_buffers() + call airline#util#warning("Buffer filtering turned on") + doautocmd BufAdd + endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#reopen_last_tab() + """Reopen the last closed tab.""" + + if !exists('s:most_recently_closed_tab') + call airline#util#warning("No recent tabs.") + return + endif + + let tab = s:most_recently_closed_tab + tabnew + let empty = bufnr("%") + let t:cwd = tab['cwd'] + cd `=t:cwd` + let t:name = tab['name'] + for buf in tab['buffers'] | execute "badd ".buf | endfor + execute "edit ".tab['buffers'][0] + execute "bdelete ".empty +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#filter_buffers() + """Filter buffers so that only the ones within the tab's cwd will show up. + + " 'accepted' is a list of buffer numbers, for quick access. + " 'excluded' is a list of buffer numbers, it will be used by Airline to hide buffers. + + if !s:xtabline_filtering | return | endif + + let g:airline#extensions#tabline#exclude_buffers = [] + let t:xtl_excluded = g:airline#extensions#tabline#exclude_buffers + let t:xtl_accepted = [] | let accepted = t:xtl_accepted + let previews = g:xtabline_include_previews + + " bufnr(0) is the alternate buffer + for buf in range(1, bufnr("$")) + + if !buflisted(buf) | continue | endif + + " get the path + let path = expand("#".buf.":p") + + " confront with the cwd + if !previews && path =~ "^".getcwd() + call add(accepted, buf) + elseif previews && path =~ getcwd() + call add(accepted, buf) + else + call add(t:xtl_excluded, buf) + endif + endfor + + call s:RefreshTabline() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#next_buffer(nr) + """Switch to next visible buffer.""" + + if ( s:NotEnoughBuffers() || !s:xtabline_filtering ) | return | endif + let accepted = t:xtl_accepted + + let ix = index(accepted, bufnr("%")) + let target = ix + a:nr + let total = len(accepted) + + if ix == -1 + " not in index, go back to most recent or back to first + if s:most_recent == -1 || s:most_recent >= total + let s:most_recent = 0 + endif + + elseif target >= total + " over last buffer + while target >= total | let target -= total | endwhile + let s:most_recent = target + + else + let s:most_recent = target + endif + + return ":buffer " . accepted[s:most_recent] . "\<cr>" +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#prev_buffer(nr) + """Switch to previous visible buffer.""" + + if ( s:NotEnoughBuffers() || !s:xtabline_filtering ) | return | endif + let accepted = t:xtl_accepted + + let ix = index(accepted, bufnr("%")) + let target = ix - a:nr + let total = len(accepted) + + if ix == -1 + " not in index, go back to most recent or back to first + if s:most_recent == -1 || s:most_recent >= total + let s:most_recent = 0 + endif + + elseif target < 0 + " before first buffer + while target < 0 | let target += total | endwhile + let s:most_recent = target + + else + let s:most_recent = target + endif + + return ":buffer " . accepted[s:most_recent] . "\<cr>" +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#select_buffer(nr) + """Switch to visible buffer in the tabline with [count].""" + + if ( a:nr == 0 || !s:xtabline_filtering ) | execute g:xtabline_alt_action | return | endif + let accepted = t:xtl_accepted + + if (a:nr > len(accepted)) || s:NotEnoughBuffers() || accepted[a:nr - 1] == bufnr("%") + return + else + let g:xtabline_changing_buffer = 1 + execute "buffer ".accepted[a:nr - 1] + endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:TabBuffers() + """Return a list of buffers names for this tab.""" + + return map(copy(t:xtl_accepted), 'bufname(v:val)') +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Helper functions +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:NotEnoughBuffers() + """Just return if there aren't enough buffers.""" + + if len(t:xtl_accepted) < 2 + if index(t:xtl_accepted, bufnr("%")) == -1 + return + elseif !len(t:xtl_accepted) + call airline#util#warning("No available buffers for this tab.") + else + call airline#util#warning("No other available buffers for this tab.") + endif + return 1 + endif +endfunction + +function! s:RefreshTabline() + call airline#extensions#tabline#buflist#invalidate() +endfunction + + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" TabPageCd +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" tabpagecd - Turn :cd into :tabpagecd, to use one tab page per project +" expanded version by mg979 +" Copyright (C) 2012-2013 Kana Natsuno <http://whileimautomaton.net/> +" Copyright (C) 2018 Gianmaria Bajo <mg1979.git@gmail.com> +" License: MIT License + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:InitCwds() + if !exists('g:xtab_cwds') | let g:xtab_cwds = [] | endif + + while len(g:xtab_cwds) < tabpagenr("$") + call add(g:xtab_cwds, getcwd()) + endwhile + let s:state = 1 + let t:cwd = getcwd() + let s:last_tab = 0 + call airline#extensions#tabline#xtabline#filter_buffers() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! airline#extensions#tabline#xtabline#update_obsession() + let string = 'let g:xtab_cwds = '.string(g:xtab_cwds).' | call airline#extensions#tabline#xtabline#update_obsession()' + if !exists('g:obsession_append') + let g:obsession_append = [string] + else + call filter(g:obsession_append, 'v:val !~# "^let g:xtab_cwds"') + call add(g:obsession_append, string) + endif +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:Do(action) + let arg = a:action + if !s:state | call s:InitCwds() | return | endif + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + if arg == 'new' + + call insert(g:xtab_cwds, getcwd(), tabpagenr()-1) + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + elseif arg == 'enter' + + let t:cwd =g:xtab_cwds[tabpagenr()-1] + + cd `=t:cwd` + call airline#extensions#tabline#xtabline#filter_buffers() + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + elseif arg == 'leave' + + let t:cwd = getcwd() + let g:xtab_cwds[tabpagenr()-1] = t:cwd + let s:last_tab = tabpagenr() - 1 + + if !exists('t:name') | let t:name = t:cwd | endif + let s:most_recent_tab = {'cwd': t:cwd, 'name': t:name, 'buffers': s:TabBuffers()} + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + elseif arg == 'close' + + let s:most_recently_closed_tab = copy(s:most_recent_tab) + call remove(g:xtab_cwds, s:last_tab) + endif + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + call airline#extensions#tabline#xtabline#update_obsession() +endfunction + +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tagbar.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tagbar.vim new file mode 100644 index 0000000..5db53ee --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tagbar.vim @@ -0,0 +1,58 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':TagbarToggle') + finish +endif + +let s:flags = get(g:, 'airline#extensions#tagbar#flags', '') +let s:spc = g:airline_symbols.space +let s:init=0 + +" Arguments: current, sort, fname +function! airline#extensions#tagbar#get_status(...) + let builder = airline#builder#new({ 'active': a:1 }) + call builder.add_section('airline_a', s:spc.'Tagbar'.s:spc) + call builder.add_section('airline_b', s:spc.a:2.s:spc) + call builder.add_section('airline_c', s:spc.a:3.s:spc) + return builder.build() +endfunction + +function! airline#extensions#tagbar#inactive_apply(...) + if getwinvar(a:2.winnr, '&filetype') == 'tagbar' + return -1 + endif +endfunction + +let s:airline_tagbar_last_lookup_time = 0 +let s:airline_tagbar_last_lookup_val = '' +function! airline#extensions#tagbar#currenttag() + if get(w:, 'airline_active', 0) + if !s:init + try + " try to load the plugin, if filetypes are disabled, + " this will cause an error, so try only once + let a=tagbar#currenttag('%', '', '') + catch + endtry + unlet! a + let s:init=1 + endif + " function tagbar#currenttag does not exist, if filetype is not enabled + if s:airline_tagbar_last_lookup_time != localtime() && exists("*tagbar#currenttag") + let s:airline_tagbar_last_lookup_val = tagbar#currenttag('%s', '', s:flags) + let s:airline_tagbar_last_lookup_time = localtime() + endif + return s:airline_tagbar_last_lookup_val + endif + return '' +endfunction + +function! airline#extensions#tagbar#init(ext) + call a:ext.add_inactive_statusline_func('airline#extensions#tagbar#inactive_apply') + let g:tagbar_status_func = 'airline#extensions#tagbar#get_status' + + call airline#parts#define_function('tagbar', 'airline#extensions#tagbar#currenttag') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/term.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/term.vim new file mode 100644 index 0000000..c5b578e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/term.vim @@ -0,0 +1,43 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#term#apply(...) + if &buftype == 'terminal' + let spc = g:airline_symbols.space + + let name=get(g:airline_mode_map, 't', 't') + call a:1.add_section('airline_a', spc.name.spc) + call a:1.add_section('airline_b', '') + call a:1.add_section('airline_term', spc.s:termname()) + call a:1.split() + call a:1.add_section('airline_y', '') + call a:1.add_section('airline_z', spc.airline#section#create_right(['linenr', 'maxlinenr'])) + return 1 + endif +endfunction + +function! airline#extensions#term#inactive_apply(...) + if getbufvar(a:2.bufnr, '&buftype') == 'terminal' + let spc = g:airline_symbols.space + call a:1.add_section('airline_a', spc.'TERMINAL'.spc) + call a:1.add_section('airline_b', spc.'%f') + return 1 + endif +endfunction + +function! s:termname() + let bufname = bufname('%') + if has('nvim') + return matchstr(bufname, 'term.*:\zs.*') + else + " get rid of leading '!' + return bufname[1:] + endif +endfunction + +function! airline#extensions#term#init(ext) + call a:ext.add_statusline_func('airline#extensions#term#apply') + call a:ext.add_inactive_statusline_func('airline#extensions#term#inactive_apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tmuxline.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tmuxline.vim new file mode 100644 index 0000000..44c7ec2 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/tmuxline.vim @@ -0,0 +1,27 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':Tmuxline') + finish +endif + +let s:tmuxline_snapshot_file = get(g:, 'airline#extensions#tmuxline#snapshot_file', '') +let s:color_template = get(g:, 'airline#extensions#tmuxline#color_template', 'normal') + +function! airline#extensions#tmuxline#init(ext) + call a:ext.add_theme_func('airline#extensions#tmuxline#set_tmux_colors') +endfunction + +function! airline#extensions#tmuxline#set_tmux_colors(palette) + let color_template = has_key(a:palette, s:color_template) ? s:color_template : 'normal' + let mode_palette = a:palette[color_template] + + let tmuxline_theme = tmuxline#api#create_theme_from_airline(mode_palette) + call tmuxline#api#set_theme(tmuxline_theme) + + if strlen(s:tmuxline_snapshot_file) + call tmuxline#api#snapshot(s:tmuxline_snapshot_file) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/undotree.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/undotree.vim new file mode 100644 index 0000000..9e43dfb --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/undotree.vim @@ -0,0 +1,28 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists(':UndotreeToggle') + finish +endif + +function! airline#extensions#undotree#apply(...) + if exists('t:undotree') + if &ft == 'undotree' + if exists('*t:undotree.GetStatusLine') + call airline#extensions#apply_left_override('undo', '%{t:undotree.GetStatusLine()}') + else + call airline#extensions#apply_left_override('undotree', '%f') + endif + endif + + if &ft == 'diff' && exists('*t:diffpanel.GetStatusLine') + call airline#extensions#apply_left_override('diff', '%{t:diffpanel.GetStatusLine()}') + endif + endif +endfunction + +function! airline#extensions#undotree#init(ext) + call a:ext.add_statusline_func('airline#extensions#undotree#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unicode.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unicode.vim new file mode 100644 index 0000000..4afe129 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unicode.vim @@ -0,0 +1,24 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_unicodePlugin', 0) + finish +endif + +function! airline#extensions#unicode#apply(...) + if exists(":UnicodeTable") == 2 && bufname('') ==# 'UnicodeTable' + call airline#parts#define('unicode', { + \ 'text': '[UnicodeTable]', + \ 'accent': 'bold' }) + let w:airline_section_a = airline#section#create(['unicode']) + let w:airline_section_b = '' + let w:airline_section_c = ' ' + let w:airline_section_y = '' + endif +endfunction + +function! airline#extensions#unicode#init(ext) + call a:ext.add_statusline_func('airline#extensions#unicode#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unite.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unite.vim new file mode 100644 index 0000000..c6a09f0 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/unite.vim @@ -0,0 +1,24 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !get(g:, 'loaded_unite', 0) + finish +endif + +function! airline#extensions#unite#apply(...) + if &ft == 'unite' + call a:1.add_section('airline_a', ' Unite ') + call a:1.add_section('airline_b', ' %{get(unite#get_context(), "buffer_name", "")} ') + call a:1.add_section('airline_c', ' %{unite#get_status_string()} ') + call a:1.split() + call a:1.add_section('airline_y', ' %{get(unite#get_context(), "real_buffer_name", "")} ') + return 1 + endif +endfunction + +function! airline#extensions#unite#init(ext) + let g:unite_force_overwrite_statusline = 0 + call a:ext.add_statusline_func('airline#extensions#unite#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimagit.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimagit.vim new file mode 100644 index 0000000..8c98ec9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimagit.vim @@ -0,0 +1,34 @@ +" MIT License. Copyright (c) 2016-2018 Jerome Reybert et al. +" vim: et ts=2 sts=2 sw=2 + +" This plugin replace the whole section_a when in vimagit buffer +scriptencoding utf-8 + +if !get(g:, 'loaded_magit', 0) + finish +endif + +function! airline#extensions#vimagit#init(ext) + call a:ext.add_statusline_func('airline#extensions#vimagit#apply') +endfunction + +function! airline#extensions#vimagit#get_mode() + if ( exists("*magit#get_current_mode") ) + return magit#get_current_mode() + else + if ( b:magit_current_commit_mode == '' ) + return "STAGING" + elseif ( b:magit_current_commit_mode == 'CC' ) + return "COMMIT" + elseif ( b:magit_current_commit_mode == 'CA' ) + return "AMEND" + else + return "???" + endif +endfunction + +function! airline#extensions#vimagit#apply(...) + if ( &filetype == 'magit' ) + let w:airline_section_a = '%{airline#extensions#vimagit#get_mode()}' + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimtex.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimtex.vim new file mode 100644 index 0000000..9eda8d5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/vimtex.vim @@ -0,0 +1,84 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +" This plugin replace the whole section_a when in vimagit buffer +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space + +function! s:SetDefault(var, val) + if !exists(a:var) + execute 'let ' . a:var . '=' . string(a:val) + endif +endfunction + +" Left and right delimiters (added only when status string is not empty) +call s:SetDefault( 'g:airline#extensions#vimtex#left', "{") +call s:SetDefault( 'g:airline#extensions#vimtex#right', "}") + +" The current tex file is the main project file +call s:SetDefault( 'g:airline#extensions#vimtex#main', "" ) +" +" The current tex file is a subfile of the project +" and the compilation is set for the main file +call s:SetDefault( 'g:airline#extensions#vimtex#sub_main', "m") +" +" The current tex file is a subfile of the project +" and the compilation is set for this subfile +call s:SetDefault( 'g:airline#extensions#vimtex#sub_local', "l") +" +" Compilation is running and continuous compilation is off +call s:SetDefault( 'g:airline#extensions#vimtex#compiled', "c₁") + +" Compilation is running and continuous compilation is on +call s:SetDefault( 'g:airline#extensions#vimtex#continuous', "c") + +" Viewer is opened +call s:SetDefault( 'g:airline#extensions#vimtex#viewer', "v") + +function! airline#extensions#vimtex#init(ext) + call airline#parts#define_raw('vimtex', '%{airline#extensions#vimtex#get_scope()}') + call a:ext.add_statusline_func('airline#extensions#vimtex#apply') +endfunction + +function! airline#extensions#vimtex#apply(...) + if exists("b:vimtex") + let w:airline_section_x = get(w:, 'airline_section_x', g:airline_section_x) + let w:airline_section_x.=s:spc.g:airline_left_alt_sep.s:spc.'%{airline#extensions#vimtex#get_scope()}' + endif +endfunction + +function! airline#extensions#vimtex#get_scope() + let l:status = '' + + let vt_local = get(b:, 'vimtex_local', {}) + if empty(vt_local) + let l:status .= g:airline#extensions#vimtex#main + else + if get(vt_local, 'active') + let l:status .= g:airline#extensions#vimtex#sub_local + else + let l:status .= g:airline#extensions#vimtex#sub_main + endif + endif + + if get(get(get(b:, 'vimtex', {}), 'viewer', {}), 'xwin_id') + let l:status .= g:airline#extensions#vimtex#viewer + endif + + let l:compiler = get(get(b:, 'vimtex', {}), 'compiler', {}) + if !empty(l:compiler) + if has_key(l:compiler, 'is_running') && b:vimtex.compiler.is_running() + if get(l:compiler, 'continuous') + let l:status .= g:airline#extensions#vimtex#continuous + else + let l:status .= g:airline#extensions#vimtex#compiled + endif + endif + endif + + if !empty(l:status) + let l:status = g:airline#extensions#vimtex#left . l:status . g:airline#extensions#vimtex#right + endif + return l:status +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/virtualenv.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/virtualenv.vim new file mode 100644 index 0000000..b494d85 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/virtualenv.vim @@ -0,0 +1,31 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space + +function! airline#extensions#virtualenv#init(ext) + call a:ext.add_statusline_func('airline#extensions#virtualenv#apply') +endfunction + +function! airline#extensions#virtualenv#apply(...) + if &filetype =~# "python" + if get(g:, 'virtualenv_loaded', 0) + let statusline = virtualenv#statusline() + else + let statusline = fnamemodify($VIRTUAL_ENV, ':t') + endif + if !empty(statusline) + call airline#extensions#append_to_section('x', + \ s:spc.g:airline_right_alt_sep.s:spc.statusline) + endif + endif +endfunction + +function! airline#extensions#virtualenv#update() + if &filetype =~# "python" + call airline#extensions#virtualenv#apply() + call airline#update_statusline() + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/whitespace.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/whitespace.vim new file mode 100644 index 0000000..c9b5a2a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/whitespace.vim @@ -0,0 +1,171 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +" http://got-ravings.blogspot.com/2008/10/vim-pr0n-statusline-whitespace-flags.html + +scriptencoding utf-8 + +let s:show_message = get(g:, 'airline#extensions#whitespace#show_message', 1) +let s:symbol = get(g:, 'airline#extensions#whitespace#symbol', g:airline_symbols.whitespace) +let s:default_checks = ['indent', 'trailing', 'mixed-indent-file'] + +let s:enabled = get(g:, 'airline#extensions#whitespace#enabled', 1) +let s:skip_check_ft = {'make': ['indent', 'mixed-indent-file']} + +function! s:check_mixed_indent() + let indent_algo = get(g:, 'airline#extensions#whitespace#mixed_indent_algo', 0) + if indent_algo == 1 + " [<tab>]<space><tab> + " spaces before or between tabs are not allowed + let t_s_t = '(^\t* +\t\s*\S)' + " <tab>(<space> x count) + " count of spaces at the end of tabs should be less than tabstop value + let t_l_s = '(^\t+ {' . &ts . ',}' . '\S)' + return search('\v' . t_s_t . '|' . t_l_s, 'nw') + elseif indent_algo == 2 + return search('\v(^\t* +\t\s*\S)', 'nw') + else + return search('\v(^\t+ +)|(^ +\t+)', 'nw') + endif +endfunction + +function! s:check_mixed_indent_file() + let c_like_langs = get(g:, 'airline#extensions#c_like_langs', + \ [ 'arduino', 'c', 'cpp', 'cuda', 'go', 'javascript', 'ld', 'php' ]) + if index(c_like_langs, &ft) > -1 + " for C-like languages: allow /** */ comment style with one space before the '*' + let head_spc = '\v(^ +\*@!)' + else + let head_spc = '\v(^ +)' + endif + let indent_tabs = search('\v(^\t+)', 'nw') + let indent_spc = search(head_spc, 'nw') + if indent_tabs > 0 && indent_spc > 0 + return printf("%d:%d", indent_tabs, indent_spc) + else + return '' + endif +endfunction + +function! airline#extensions#whitespace#check() + let max_lines = get(g:, 'airline#extensions#whitespace#max_lines', 20000) + if &readonly || !&modifiable || !s:enabled || line('$') > max_lines + \ || get(b:, 'airline_whitespace_disabled', 0) + return '' + endif + let skip_check_ft = extend(s:skip_check_ft, + \ get(g:, 'airline#extensions#whitespace#skip_indent_check_ft', {}), 'force') + + if !exists('b:airline_whitespace_check') + let b:airline_whitespace_check = '' + let checks = get(b:, 'airline_whitespace_checks', get(g:, 'airline#extensions#whitespace#checks', s:default_checks)) + + let trailing = 0 + let check = 'trailing' + if index(checks, check) > -1 && index(get(skip_check_ft, &ft, []), check) < 0 + try + let regexp = get(g:, 'airline#extensions#whitespace#trailing_regexp', '\s$') + let trailing = search(regexp, 'nw') + catch + call airline#util#warning(printf('Whitespace: error occurred evaluating "%s"', regexp)) + echomsg v:exception + return '' + endtry + endif + + let mixed = 0 + let check = 'indent' + if index(checks, check) > -1 && index(get(skip_check_ft, &ft, []), check) < 0 + let mixed = s:check_mixed_indent() + endif + + let mixed_file = '' + let check = 'mixed-indent-file' + if index(checks, check) > -1 && index(get(skip_check_ft, &ft, []), check) < 0 + let mixed_file = s:check_mixed_indent_file() + endif + + let long = 0 + if index(checks, 'long') > -1 && &tw > 0 + let long = search('\%>'.&tw.'v.\+', 'nw') + endif + + if trailing != 0 || mixed != 0 || long != 0 || !empty(mixed_file) + let b:airline_whitespace_check = s:symbol + if strlen(s:symbol) > 0 + let space = (g:airline_symbols.space) + else + let space = '' + endif + + if s:show_message + if trailing != 0 + let trailing_fmt = get(g:, 'airline#extensions#whitespace#trailing_format', '[%s]trailing') + let b:airline_whitespace_check .= space.printf(trailing_fmt, trailing) + endif + if mixed != 0 + let mixed_indent_fmt = get(g:, 'airline#extensions#whitespace#mixed_indent_format', '[%s]mixed-indent') + let b:airline_whitespace_check .= space.printf(mixed_indent_fmt, mixed) + endif + if long != 0 + let long_fmt = get(g:, 'airline#extensions#whitespace#long_format', '[%s]long') + let b:airline_whitespace_check .= space.printf(long_fmt, long) + endif + if !empty(mixed_file) + let mixed_indent_file_fmt = get(g:, 'airline#extensions#whitespace#mixed_indent_file_format', '[%s]mix-indent-file') + let b:airline_whitespace_check .= space.printf(mixed_indent_file_fmt, mixed_file) + endif + endif + endif + endif + return airline#util#shorten(b:airline_whitespace_check, 120, 9) +endfunction + +function! airline#extensions#whitespace#toggle() + if s:enabled + augroup airline_whitespace + autocmd! + augroup END + augroup! airline_whitespace + let s:enabled = 0 + else + call airline#extensions#whitespace#init() + let s:enabled = 1 + endif + + if exists("g:airline#extensions#whitespace#enabled") + let g:airline#extensions#whitespace#enabled = s:enabled + if s:enabled && match(g:airline_section_warning, '#whitespace#check') < 0 + let g:airline_section_warning .= airline#section#create(['whitespace']) + call airline#update_statusline() + endif + endif + call airline#util#warning(printf('Whitespace checking: %s',(s:enabled ? 'Enabled' : 'Disabled'))) +endfunction + +function! airline#extensions#whitespace#disable() + if s:enabled + call airline#extensions#whitespace#toggle() + endif +endfunction + +function! airline#extensions#whitespace#init(...) + call airline#parts#define_function('whitespace', 'airline#extensions#whitespace#check') + + unlet! b:airline_whitespace_check + augroup airline_whitespace + autocmd! + autocmd CursorHold,BufWritePost * call <sid>ws_refresh() + augroup END +endfunction + +function! s:ws_refresh() + if get(b:, 'airline_ws_changedtick', 0) == b:changedtick + return + endif + unlet! b:airline_whitespace_check + if get(g:, 'airline_skip_empty_sections', 0) + exe ':AirlineRefresh' + endif + let b:airline_ws_changedtick = b:changedtick +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/windowswap.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/windowswap.vim new file mode 100644 index 0000000..5ef531e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/windowswap.vim @@ -0,0 +1,29 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('g:loaded_windowswap') + finish +endif + +let s:spc = g:airline_symbols.space + +if !exists('g:airline#extensions#windowswap#indicator_text') + let g:airline#extensions#windowswap#indicator_text = 'WS' +endif + +function! airline#extensions#windowswap#init(ext) + call airline#parts#define_function('windowswap', 'airline#extensions#windowswap#get_status') +endfunction + +function! airline#extensions#windowswap#get_status() + " use new tab-aware api if WS is up to date + let s:mark = exists('*WindowSwap#IsCurrentWindowMarked') ? + \WindowSwap#IsCurrentWindowMarked() : + \(WindowSwap#HasMarkedWindow() && WindowSwap#GetMarkedWindowNum() == winnr()) + if s:mark + return g:airline#extensions#windowswap#indicator_text.s:spc + endif + return '' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount.vim new file mode 100644 index 0000000..a9b9aac --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount.vim @@ -0,0 +1,117 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 fdm=marker + +scriptencoding utf-8 + +" get wordcount {{{1 +if exists('*wordcount') + function! s:get_wordcount(visual_mode_active) + let query = a:visual_mode_active ? 'visual_words' : 'words' + return get(wordcount(), query, 0) + endfunction +else " Pull wordcount from the g_ctrl-g stats + function! s:get_wordcount(visual_mode_active) + let pattern = a:visual_mode_active + \ ? '^.\D*\d\+\D\+\d\+\D\+\zs\d\+' + \ : '^.\D*\%(\d\+\D\+\)\{5}\zs\d\+' + + let save_status = v:statusmsg + if !a:visual_mode_active && col('.') == col('$') + let save_pos = getpos('.') + execute "silent normal! g\<c-g>" + call setpos('.', save_pos) + else + execute "silent normal! g\<c-g>" + endif + let stats = v:statusmsg + let v:statusmsg = save_status + + return str2nr(matchstr(stats, pattern)) + endfunction +endif + +" format {{{1 +let s:formatter = get(g:, 'airline#extensions#wordcount#formatter', 'default') + +" wrapper function for compatibility; redefined below for old-style formatters +function! s:format_wordcount(wordcount) + return airline#extensions#wordcount#formatters#{s:formatter}#to_string(a:wordcount) +endfunction + +" check user-defined formatter exists with appropriate functions, otherwise +" fall back to default +if s:formatter !=# 'default' + execute 'runtime! autoload/airline/extensions/wordcount/formatters/'.s:formatter + if !exists('*airline#extensions#wordcount#formatters#{s:formatter}#to_string') + if !exists('*airline#extensions#wordcount#formatters#{s:formatter}#format') + let s:formatter = 'default' + else + " redefine for backwords compatibility + function! s:format_wordcount(_) + if mode() ==? 'v' + return b:airline_wordcount + else + return airline#extensions#wordcount#formatters#{s:formatter}#format() + endif + endfunction + endif + endif +endif + +" update {{{1 +let s:wordcount_cache = 0 " cache wordcount for performance when force_update=0 +function! s:update_wordcount(force_update) + let wordcount = s:get_wordcount(0) + if wordcount != s:wordcount_cache || a:force_update + let s:wordcount_cache = wordcount + let b:airline_wordcount = s:format_wordcount(wordcount) + endif +endfunction + +let s:visual_active = 0 " Boolean: for when to get visual wordcount +function airline#extensions#wordcount#get() + if s:visual_active + return s:format_wordcount(s:get_wordcount(1)) + else + if get(b:, 'airline_changedtick', 0) != b:changedtick + call s:update_wordcount(0) + let b:airline_changedtick = b:changedtick + endif + return get(b:, 'airline_wordcount', '') + endif +endfunction + +" airline functions {{{1 +" default filetypes: +let s:filetypes = ['help', 'markdown', 'rst', 'org', 'text', 'asciidoc', 'tex', 'mail'] +function! airline#extensions#wordcount#apply(...) + let filetypes = get(g:, 'airline#extensions#wordcount#filetypes', s:filetypes) + + " Check if filetype needs testing + if did_filetype() || filetypes isnot s:filetypes + let s:filetypes = filetypes + + " Select test based on type of "filetypes": new=list, old=string + if type(filetypes) == get(v:, 't_list', type([])) + \ ? index(filetypes, &filetype) > -1 || index(filetypes, 'all') > -1 + \ : match(&filetype, filetypes) > -1 + let b:airline_changedtick = -1 + call s:update_wordcount(1) " force update: ensures initial worcount exists + elseif exists('b:airline_wordcount') " cleanup when filetype is removed + unlet b:airline_wordcount + endif + endif + + if exists('b:airline_wordcount') + call airline#extensions#prepend_to_section( + \ 'z', '%{airline#extensions#wordcount#get()}') + endif +endfunction + +function! airline#extensions#wordcount#init(ext) + augroup airline_wordcount + autocmd! User AirlineModeChanged nested + \ let s:visual_active = (mode() ==? 'v' || mode() ==? 's') + augroup END + call a:ext.add_statusline_func('airline#extensions#wordcount#apply') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount/formatters/default.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount/formatters/default.vim new file mode 100644 index 0000000..5682921 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/wordcount/formatters/default.vim @@ -0,0 +1,39 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! airline#extensions#wordcount#formatters#default#update_fmt(...) + let s:fmt = get(g:, 'airline#extensions#wordcount#formatter#default#fmt', '%s words') + let s:fmt_short = get(g:, 'airline#extensions#wordcount#formatter#default#fmt_short', s:fmt == '%s words' ? '%sW' : s:fmt) +endfunction + +" Reload format when statusline is rebuilt +call airline#extensions#wordcount#formatters#default#update_fmt() +if index(g:airline_statusline_funcrefs, function('airline#extensions#wordcount#formatters#default#update_fmt')) == -1 + " only add it, if not already done + call airline#add_statusline_funcref(function('airline#extensions#wordcount#formatters#default#update_fmt')) +endif + +if match(get(v:, 'lang', ''), '\v\cC|en') > -1 + let s:decimal_group = ',' +elseif match(get(v:, 'lang', ''), '\v\cde|dk|fr|pt') > -1 + let s:decimal_group = '.' +else + let s:decimal_group = '' +endif + +function! airline#extensions#wordcount#formatters#default#to_string(wordcount) + if winwidth(0) >= 80 + if a:wordcount > 999 + " Format number according to locale, e.g. German: 1.245 or English: 1,245 + let wordcount = substitute(a:wordcount, '\d\@<=\(\(\d\{3\}\)\+\)$', s:decimal_group.'&', 'g') + else + let wordcount = a:wordcount + endif + let str = printf(s:fmt, wordcount) + else + let str = printf(s:fmt_short, a:wordcount) + endif + return str . g:airline_symbols.space . g:airline_right_alt_sep . g:airline_symbols.space +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/xkblayout.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/xkblayout.vim new file mode 100644 index 0000000..b9d56a1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/xkblayout.vim @@ -0,0 +1,24 @@ +" MIT License. Copyright (c) 2017-2018 YoungHoon Rhiu et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if !exists('g:XkbSwitchLib') + finish +endif + +function! airline#extensions#xkblayout#status() + let keyboard_layout = libcall(g:XkbSwitchLib, 'Xkb_Switch_getXkbLayout', '') + let keyboard_layout = split(keyboard_layout, '\.')[-1] + let short_codes = get(g:, 'airline#extensions#xkblayout#short_codes', {'2SetKorean': 'KR', 'Chinese': 'CN', 'Japanese': 'JP'}) + + if has_key(short_codes, keyboard_layout) + let keyboard_layout = short_codes[keyboard_layout] + endif + + return keyboard_layout +endfunction + +function! airline#extensions#xkblayout#init(ext) + call airline#parts#define_function('xkblayout', 'airline#extensions#xkblayout#status') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ycm.vim b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ycm.vim new file mode 100644 index 0000000..677ba03 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/extensions/ycm.vim @@ -0,0 +1,37 @@ +" MIT License. Copyright (c) 2015-2018 Evgeny Firsov et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:spc = g:airline_symbols.space +let s:error_symbol = get(g:, 'airline#extensions#ycm#error_symbol', 'E:') +let s:warning_symbol = get(g:, 'airline#extensions#ycm#warning_symbol', 'W:') + +function! airline#extensions#ycm#init(ext) + call airline#parts#define_function('ycm_error_count', 'airline#extensions#ycm#get_error_count') + call airline#parts#define_function('ycm_warning_count', 'airline#extensions#ycm#get_warning_count') +endfunction + +function! airline#extensions#ycm#get_error_count() + if exists(':YcmDiag') && exists("*youcompleteme#GetErrorCount") + let cnt = youcompleteme#GetErrorCount() + + if cnt != 0 + return s:error_symbol.cnt + endif + endif + + return '' +endfunction + +function! airline#extensions#ycm#get_warning_count() + if exists(':YcmDiag') && exists("*youcompleteme#GetWarningCount") + let cnt = youcompleteme#GetWarningCount() + + if cnt != 0 + return s:warning_symbol.cnt.s:spc + endif + endif + + return '' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/highlighter.vim b/dotfiles/.local/share/nvim/site/autoload/airline/highlighter.vim new file mode 100644 index 0000000..5d4a7d7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/highlighter.vim @@ -0,0 +1,319 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:is_win32term = (has('win32') || has('win64')) && + \ !has('gui_running') && + \ (empty($CONEMUBUILD) || &term !=? 'xterm') && + \ !(exists("+termguicolors") && &termguicolors) + +let s:separators = {} +let s:accents = {} +let s:hl_groups = {} + +function! s:gui2cui(rgb, fallback) + if a:rgb == '' + return a:fallback + elseif match(a:rgb, '^\%(NONE\|[fb]g\)$') > -1 + return a:rgb + endif + let rgb = map(split(a:rgb[1:], '..\zs'), '0 + ("0x".v:val)') + return airline#msdos#round_msdos_colors(rgb) +endfunction + +function! s:group_not_done(list, name) + if index(a:list, a:name) == -1 + call add(a:list, a:name) + return 1 + else + if &vbs + echomsg printf("airline: group: %s already done, skipping", a:name) + endif + return 0 + endif +endfu + +function! s:get_syn(group, what) + if !exists("g:airline_gui_mode") + let g:airline_gui_mode = airline#init#gui_mode() + endif + let color = '' + if hlexists(a:group) + let color = synIDattr(synIDtrans(hlID(a:group)), a:what, g:airline_gui_mode) + endif + if empty(color) || color == -1 + " should always exists + let color = synIDattr(synIDtrans(hlID('Normal')), a:what, g:airline_gui_mode) + " however, just in case + if empty(color) || color == -1 + let color = 'NONE' + endif + endif + return color +endfunction + +function! s:get_array(fg, bg, opts) + let opts=empty(a:opts) ? '' : join(a:opts, ',') + return g:airline_gui_mode ==# 'gui' + \ ? [ a:fg, a:bg, '', '', opts ] + \ : [ '', '', a:fg, a:bg, opts ] +endfunction + +function! airline#highlighter#reset_hlcache() + let s:hl_groups = {} +endfunction + +function! airline#highlighter#get_highlight(group, ...) + let reverse = get(g:, 'airline_gui_mode', '') ==# 'gui' + \ ? synIDattr(synIDtrans(hlID(a:group)), 'reverse', 'gui') + \ : synIDattr(synIDtrans(hlID(a:group)), 'reverse', 'cterm') + \|| synIDattr(synIDtrans(hlID(a:group)), 'reverse', 'term') + if get(g:, 'airline_highlighting_cache', 0) && has_key(s:hl_groups, a:group) + let res = s:hl_groups[a:group] + return reverse ? [ res[1], res[0], res[3], res[2], res[4] ] : res + else + let fg = s:get_syn(a:group, 'fg') + let bg = s:get_syn(a:group, 'bg') + let bold = synIDattr(synIDtrans(hlID(a:group)), 'bold') + if reverse + let res = s:get_array(bg, fg, bold ? ['bold'] : a:000) + else + let res = s:get_array(fg, bg, bold ? ['bold'] : a:000) + endif + endif + let s:hl_groups[a:group] = res + return res +endfunction + +function! airline#highlighter#get_highlight2(fg, bg, ...) + let fg = s:get_syn(a:fg[0], a:fg[1]) + let bg = s:get_syn(a:bg[0], a:bg[1]) + return s:get_array(fg, bg, a:000) +endfunction + +function! s:hl_group_exists(group) + if !hlexists(a:group) + return 0 + elseif empty(synIDattr(hlID(a:group), 'fg')) + return 0 + endif + return 1 +endfunction + +function! airline#highlighter#exec(group, colors) + if pumvisible() + return + endif + let colors = a:colors + if s:is_win32term + let colors[2] = s:gui2cui(get(colors, 0, ''), get(colors, 2, '')) + let colors[3] = s:gui2cui(get(colors, 1, ''), get(colors, 3, '')) + endif + let old_hi = airline#highlighter#get_highlight(a:group) + if len(colors) == 4 + call add(colors, '') + endif + if g:airline_gui_mode ==# 'gui' + let new_hi = [colors[0], colors[1], '', '', colors[4]] + else + let new_hi = ['', '', printf("%s", colors[2]), printf("%s", colors[3]), colors[4]] + endif + let colors = s:CheckDefined(colors) + if old_hi != new_hi || !s:hl_group_exists(a:group) + let cmd = printf('hi %s%s', a:group, s:GetHiCmd(colors)) + exe cmd + if has_key(s:hl_groups, a:group) + let s:hl_groups[a:group] = colors + endif + endif +endfunction + +function! s:CheckDefined(colors) + " Checks, whether the definition of the colors is valid and is not empty or NONE + " e.g. if the colors would expand to this: + " hi airline_c ctermfg=NONE ctermbg=NONE + " that means to clear that highlighting group, therefore, fallback to Normal + " highlighting group for the cterm values + + " This only works, if the Normal highlighting group is actually defined, so + " return early, if it has been cleared + if !exists("g:airline#highlighter#normal_fg_hi") + let g:airline#highlighter#normal_fg_hi = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'cterm') + endif + if empty(g:airline#highlighter#normal_fg_hi) || g:airline#highlighter#normal_fg_hi < 0 + return a:colors + endif + + for val in a:colors + if !empty(val) && val !=# 'NONE' + return a:colors + endif + endfor + " this adds the bold attribute to the term argument of the :hi command, + " but at least this makes sure, the group will be defined + let fg = g:airline#highlighter#normal_fg_hi + let bg = synIDattr(synIDtrans(hlID('Normal')), 'bg', 'cterm') + if bg < 0 + " in case there is no background color defined for Normal + let bg = a:colors[3] + endif + return a:colors[0:1] + [fg, bg] + [a:colors[4]] +endfunction + +function! s:GetHiCmd(list) + " a:list needs to have 5 items! + let res = '' + let i = -1 + while i < 4 + let i += 1 + let item = get(a:list, i, '') + if item is '' + continue + endif + if i == 0 + let res .= ' guifg='.item + elseif i == 1 + let res .= ' guibg='.item + elseif i == 2 + let res .= ' ctermfg='.item + elseif i == 3 + let res .= ' ctermbg='.item + elseif i == 4 + let res .= printf(' gui=%s cterm=%s term=%s', item, item, item) + endif + endwhile + return res +endfunction + +function! s:exec_separator(dict, from, to, inverse, suffix) + if pumvisible() + return + endif + let group = a:from.'_to_'.a:to.a:suffix + let l:from = airline#themes#get_highlight(a:from.a:suffix) + let l:to = airline#themes#get_highlight(a:to.a:suffix) + if a:inverse + let colors = [ l:from[1], l:to[1], l:from[3], l:to[3] ] + else + let colors = [ l:to[1], l:from[1], l:to[3], l:from[3] ] + endif + let a:dict[group] = colors + call airline#highlighter#exec(group, colors) +endfunction + +function! airline#highlighter#load_theme() + if pumvisible() + return + endif + for winnr in filter(range(1, winnr('$')), 'v:val != winnr()') + call airline#highlighter#highlight_modified_inactive(winbufnr(winnr)) + endfor + call airline#highlighter#highlight(['inactive']) + if getbufvar( bufnr('%'), '&modified' ) + call airline#highlighter#highlight(['normal', 'modified']) + else + call airline#highlighter#highlight(['normal']) + endif +endfunction + +function! airline#highlighter#add_separator(from, to, inverse) + let s:separators[a:from.a:to] = [a:from, a:to, a:inverse] + call <sid>exec_separator({}, a:from, a:to, a:inverse, '') +endfunction + +function! airline#highlighter#add_accent(accent) + let s:accents[a:accent] = 1 +endfunction + +function! airline#highlighter#highlight_modified_inactive(bufnr) + if getbufvar(a:bufnr, '&modified') + let colors = exists('g:airline#themes#{g:airline_theme}#palette.inactive_modified.airline_c') + \ ? g:airline#themes#{g:airline_theme}#palette.inactive_modified.airline_c : [] + else + let colors = exists('g:airline#themes#{g:airline_theme}#palette.inactive.airline_c') + \ ? g:airline#themes#{g:airline_theme}#palette.inactive.airline_c : [] + endif + + if !empty(colors) + call airline#highlighter#exec('airline_c'.(a:bufnr).'_inactive', colors) + endif +endfunction + +function! airline#highlighter#highlight(modes, ...) + let bufnr = a:0 ? a:1 : '' + let p = g:airline#themes#{g:airline_theme}#palette + + " draw the base mode, followed by any overrides + let mapped = map(a:modes, 'v:val == a:modes[0] ? v:val : a:modes[0]."_".v:val') + let suffix = a:modes[0] == 'inactive' ? '_inactive' : '' + let airline_grouplist = [] + let buffers_in_tabpage = sort(tabpagebuflist()) + if exists("*uniq") + let buffers_in_tabpage = uniq(buffers_in_tabpage) + endif + " mapped might be something like ['normal', 'normal_modified'] + " if a group is in both modes available, only define the second + " that is how this was done previously overwrite the previous definition + for mode in reverse(mapped) + if exists('g:airline#themes#{g:airline_theme}#palette[mode]') + let dict = g:airline#themes#{g:airline_theme}#palette[mode] + for kvp in items(dict) + let mode_colors = kvp[1] + let name = kvp[0] + if name is# 'airline_c' && !empty(bufnr) && suffix is# '_inactive' + let name = 'airline_c'.bufnr + endif + " do not re-create highlighting for buffers that are no longer visible + " in the current tabpage + if name =~# 'airline_c\d\+' + let bnr = matchstr(name, 'airline_c\zs\d\+') + 0 + if bnr > 0 && index(buffers_in_tabpage, bnr) == -1 + continue + endif + elseif (name =~# '_to_') || (name[0:10] is# 'airline_tab' && !empty(suffix)) + " group will be redefined below at exec_separator + " or is not needed for tabline with '_inactive' suffix + " since active flag is 1 for builder) + continue + endif + if s:group_not_done(airline_grouplist, name.suffix) + call airline#highlighter#exec(name.suffix, mode_colors) + endif + + for accent in keys(s:accents) + if !has_key(p.accents, accent) + continue + endif + let colors = copy(mode_colors) + if p.accents[accent][0] != '' + let colors[0] = p.accents[accent][0] + endif + if p.accents[accent][2] != '' + let colors[2] = p.accents[accent][2] + endif + if len(colors) >= 5 + let colors[4] = get(p.accents[accent], 4, '') + else + call add(colors, get(p.accents[accent], 4, '')) + endif + if s:group_not_done(airline_grouplist, name.suffix.'_'.accent) + call airline#highlighter#exec(name.suffix.'_'.accent, colors) + endif + endfor + endfor + + if empty(s:separators) + " nothing to be done + continue + endif + " TODO: optimize this + for sep in items(s:separators) + " we cannot check, that the group already exists, else the separators + " might not be correctly defined. But perhaps we can skip above groups + " that match the '_to_' name, because they would be redefined here... + call <sid>exec_separator(dict, sep[1][0], sep[1][1], sep[1][2], suffix) + endfor + endif + endfor +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/init.vim b/dotfiles/.local/share/nvim/site/autoload/airline/init.vim new file mode 100644 index 0000000..18a59da --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/init.vim @@ -0,0 +1,209 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +function! s:check_defined(variable, default) + if !exists(a:variable) + let {a:variable} = a:default + endif +endfunction + +let s:loaded = 0 +function! airline#init#bootstrap() + if s:loaded + return + endif + let s:loaded = 1 + + let g:airline#init#bootstrapping = 1 + + let g:airline#init#vim_async = (v:version >= 800 && has('job')) + let g:airline#init#is_windows = has('win32') || has('win64') + + call s:check_defined('g:airline_detect_modified', 1) + call s:check_defined('g:airline_detect_paste', 1) + call s:check_defined('g:airline_detect_crypt', 1) + call s:check_defined('g:airline_detect_spell', 1) + call s:check_defined('g:airline_detect_spelllang', 1) + call s:check_defined('g:airline_detect_iminsert', 0) + call s:check_defined('g:airline_inactive_collapse', 1) + call s:check_defined('g:airline_exclude_filenames', ['DebuggerWatch','DebuggerStack','DebuggerStatus']) + call s:check_defined('g:airline_exclude_filetypes', []) + call s:check_defined('g:airline_exclude_preview', 0) + call s:check_defined('g:airline_gui_mode', airline#init#gui_mode()) + + call s:check_defined('g:airline_mode_map', {}) + call extend(g:airline_mode_map, { + \ '__' : '------', + \ 'c' : 'COMMAND', + \ 'i' : 'INSERT', + \ 'ic' : 'INSERT COMPL', + \ 'ix' : 'INSERT COMPL', + \ 'n' : 'NORMAL', + \ 'ni' : '(INSERT)', + \ 'no' : 'OP PENDING', + \ 'R' : 'REPLACE', + \ 'Rv' : 'V REPLACE', + \ 's' : 'SELECT', + \ 'S' : 'S-LINE', + \ '' : 'S-BLOCK', + \ 't' : 'TERMINAL', + \ 'v' : 'VISUAL', + \ 'V' : 'V-LINE', + \ '' : 'V-BLOCK', + \ }, 'keep') + + call s:check_defined('g:airline_theme_map', {}) + call extend(g:airline_theme_map, { + \ 'default': 'dark', + \ '\CTomorrow': 'tomorrow', + \ 'base16': 'base16', + \ 'mo[l|n]okai': 'molokai', + \ 'wombat': 'wombat', + \ 'zenburn': 'zenburn', + \ 'solarized': 'solarized', + \ 'flattened': 'solarized', + \ '\CNeoSolarized': 'solarized', + \ }, 'keep') + + call s:check_defined('g:airline_symbols', {}) + " First define the symbols, + " that are common in Powerline/Unicode/ASCII mode, + " then add specific symbols for either mode + call extend(g:airline_symbols, { + \ 'paste': 'PASTE', + \ 'spell': 'SPELL', + \ 'modified': '+', + \ 'space': ' ', + \ 'keymap': 'Keymap:', + \ 'ellipsis': '...' + \ }, 'keep') + + if get(g:, 'airline_powerline_fonts', 0) + " Symbols for Powerline terminals + call s:check_defined('g:airline_left_sep', "\ue0b0") " + call s:check_defined('g:airline_left_alt_sep', "\ue0b1") " + call s:check_defined('g:airline_right_sep', "\ue0b2") " + call s:check_defined('g:airline_right_alt_sep', "\ue0b3") " + " ro=, ws=☲, lnr=☰, mlnr=, br=, nx=Ɇ, crypt=🔒 + call extend(g:airline_symbols, { + \ 'readonly': "\ue0a2", + \ 'whitespace': "\u2632", + \ 'linenr': "\u2630 ", + \ 'maxlinenr': " \ue0a1", + \ 'branch': "\ue0a0", + \ 'notexists': "\u0246", + \ 'crypt': nr2char(0x1F512), + \ }, 'keep') + elseif &encoding==?'utf-8' && !get(g:, "airline_symbols_ascii", 0) + " Symbols for Unicode terminals + call s:check_defined('g:airline_left_sep', "") + call s:check_defined('g:airline_left_alt_sep', "") + call s:check_defined('g:airline_right_sep', "") + call s:check_defined('g:airline_right_alt_sep', "") + " ro=⊝, ws=☲, lnr=☰, mlnr=㏑, br=ᚠ, nx=Ɇ, crypt=🔒 + call extend(g:airline_symbols, { + \ 'readonly': "\u229D", + \ 'whitespace': "\u2632", + \ 'linenr': "\u2630 ", + \ 'maxlinenr': " \u33D1", + \ 'branch': "\u16A0", + \ 'notexists': "\u0246", + \ 'crypt': nr2char(0x1F512), + \ }, 'keep') + else + " Symbols for ASCII terminals + call s:check_defined('g:airline_left_sep', "") + call s:check_defined('g:airline_left_alt_sep', "") + call s:check_defined('g:airline_right_sep', "") + call s:check_defined('g:airline_right_alt_sep', "") + call extend(g:airline_symbols, { + \ 'readonly': 'RO', + \ 'whitespace': '!', + \ 'linenr': 'ln ', + \ 'maxlinenr': ' :', + \ 'branch': '', + \ 'notexists': '?', + \ 'crypt': 'cr', + \ }, 'keep') + endif + + call airline#parts#define('mode', { + \ 'function': 'airline#parts#mode', + \ 'accent': 'bold', + \ }) + call airline#parts#define_function('iminsert', 'airline#parts#iminsert') + call airline#parts#define_function('paste', 'airline#parts#paste') + call airline#parts#define_function('crypt', 'airline#parts#crypt') + call airline#parts#define_function('spell', 'airline#parts#spell') + call airline#parts#define_function('filetype', 'airline#parts#filetype') + call airline#parts#define('readonly', { + \ 'function': 'airline#parts#readonly', + \ 'accent': 'red', + \ }) + call airline#parts#define_raw('file', '%f%m') + call airline#parts#define_raw('path', '%F%m') + call airline#parts#define('linenr', { + \ 'raw': '%{g:airline_symbols.linenr}%4l', + \ 'accent': 'bold'}) + call airline#parts#define('maxlinenr', { + \ 'raw': '/%L%{g:airline_symbols.maxlinenr}', + \ 'accent': 'bold'}) + call airline#parts#define_function('ffenc', 'airline#parts#ffenc') + call airline#parts#define_empty(['hunks', 'branch', 'obsession', 'tagbar', + \ 'syntastic-warn', 'syntastic-err', 'eclim', 'whitespace','windowswap', + \ 'ycm_error_count', 'ycm_warning_count', 'neomake_error_count', + \ 'neomake_warning_count', 'ale_error_count', 'ale_warning_count', + \ 'languageclient_error_count', 'languageclient_warning_count']) + call airline#parts#define_text('capslock', '') + call airline#parts#define_text('gutentags', '') + call airline#parts#define_text('grepper', '') + call airline#parts#define_text('xkblayout', '') + call airline#parts#define_text('keymap', '') + + unlet g:airline#init#bootstrapping +endfunction + +function! airline#init#gui_mode() + return has('gui_running') || (has("termguicolors") && &termguicolors == 1) ? 'gui' : 'cterm' +endfunction + +function! airline#init#sections() + let spc = g:airline_symbols.space + if !exists('g:airline_section_a') + let g:airline_section_a = airline#section#create_left(['mode', 'crypt', 'paste', 'keymap', 'spell', 'capslock', 'xkblayout', 'iminsert']) + endif + if !exists('g:airline_section_b') + let g:airline_section_b = airline#section#create(['hunks', 'branch']) + endif + if !exists('g:airline_section_c') + if exists("+autochdir") && &autochdir == 1 + let g:airline_section_c = airline#section#create(['%<', 'path', spc, 'readonly']) + else + let g:airline_section_c = airline#section#create(['%<', 'file', spc, 'readonly']) + endif + endif + if !exists('g:airline_section_gutter') + let g:airline_section_gutter = airline#section#create(['%=']) + endif + if !exists('g:airline_section_x') + let g:airline_section_x = airline#section#create_right(['tagbar', 'gutentags', 'grepper', 'filetype']) + endif + if !exists('g:airline_section_y') + let g:airline_section_y = airline#section#create_right(['ffenc']) + endif + if !exists('g:airline_section_z') + if winwidth(0) > 80 + let g:airline_section_z = airline#section#create(['windowswap', 'obsession', '%3p%%'.spc, 'linenr', 'maxlinenr', spc.':%3v']) + else + let g:airline_section_z = airline#section#create(['%3p%%'.spc, 'linenr', ':%3v']) + endif + endif + if !exists('g:airline_section_error') + let g:airline_section_error = airline#section#create(['ycm_error_count', 'syntastic-err', 'eclim', 'neomake_error_count', 'ale_error_count', 'languageclient_error_count']) + endif + if !exists('g:airline_section_warning') + let g:airline_section_warning = airline#section#create(['ycm_warning_count', 'syntastic-warn', 'neomake_warning_count', 'ale_warning_count', 'languageclient_warning_count', 'whitespace']) + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/msdos.vim b/dotfiles/.local/share/nvim/site/autoload/airline/msdos.vim new file mode 100644 index 0000000..2d2d4e8 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/msdos.vim @@ -0,0 +1,59 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +" basic 16 msdos from MSDOS +" see output of color, should be +" 0 Black +" 1 DarkBlue +" 2 DarkGreen +" 3 DarkCyan +" 4 DarkRed +" 5 DarkMagenta +" 6 Brown +" 7 LightGray +" 8 DarkGray +" 9 Blue +" 10 Green +" 11 Cyan +" 12 Red +" 13 Magenta +" 14 Yellow +" 15 White + +let s:basic16 = [ + \ [ 0x00, 0x00, 0x00 ], + \ [ 0x00, 0x00, 0x80 ], + \ [ 0x00, 0x80, 0x00 ], + \ [ 0x00, 0x80, 0x80 ], + \ [ 0x80, 0x00, 0x00 ], + \ [ 0x80, 0x00, 0x80 ], + \ [ 0x80, 0x80, 0x00 ], + \ [ 0xC0, 0xC0, 0xC0 ], + \ [ 0x80, 0x80, 0x80 ], + \ [ 0x00, 0x00, 0xFF ], + \ [ 0x00, 0xFF, 0x00 ], + \ [ 0x00, 0xFF, 0xFF ], + \ [ 0xFF, 0x00, 0x00 ], + \ [ 0xFF, 0x00, 0xFF ], + \ [ 0xFF, 0xFF, 0x00 ], + \ [ 0xFF, 0xFF, 0xFF ] + \ ] + +function! airline#msdos#round_msdos_colors(rgblist) + " Check for values from MSDOS 16 color terminal + let best = [] + let min = 100000 + let list = s:basic16 + for value in list + let t = abs(value[0] - a:rgblist[0]) + + \ abs(value[1] - a:rgblist[1]) + + \ abs(value[2] - a:rgblist[2]) + if min > t + let min = t + let best = value + endif + endfor + return index(s:basic16, best) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/parts.vim b/dotfiles/.local/share/nvim/site/autoload/airline/parts.vim new file mode 100644 index 0000000..b6625c6 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/parts.vim @@ -0,0 +1,114 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +let s:parts = {} + +" PUBLIC API {{{ + +function! airline#parts#define(key, config) + let s:parts[a:key] = get(s:parts, a:key, {}) + if exists('g:airline#init#bootstrapping') + call extend(s:parts[a:key], a:config, 'keep') + else + call extend(s:parts[a:key], a:config, 'force') + endif +endfunction + +function! airline#parts#define_function(key, name) + call airline#parts#define(a:key, { 'function': a:name }) +endfunction + +function! airline#parts#define_text(key, text) + call airline#parts#define(a:key, { 'text': a:text }) +endfunction + +function! airline#parts#define_raw(key, raw) + call airline#parts#define(a:key, { 'raw': a:raw }) +endfunction + +function! airline#parts#define_minwidth(key, width) + call airline#parts#define(a:key, { 'minwidth': a:width }) +endfunction + +function! airline#parts#define_condition(key, predicate) + call airline#parts#define(a:key, { 'condition': a:predicate }) +endfunction + +function! airline#parts#define_accent(key, accent) + call airline#parts#define(a:key, { 'accent': a:accent }) +endfunction + +function! airline#parts#define_empty(keys) + for key in a:keys + call airline#parts#define_raw(key, '') + endfor +endfunction + +function! airline#parts#get(key) + return get(s:parts, a:key, {}) +endfunction + +" }}} + +function! airline#parts#mode() + return airline#util#shorten(get(w:, 'airline_current_mode', ''), 79, 1) +endfunction + +function! airline#parts#crypt() + return g:airline_detect_crypt && exists("+key") && !empty(&key) ? g:airline_symbols.crypt : '' +endfunction + +function! airline#parts#paste() + return g:airline_detect_paste && &paste ? g:airline_symbols.paste : '' +endfunction + +function! airline#parts#spell() + let spelllang = g:airline_detect_spelllang ? printf(" [%s]", toupper(substitute(&spelllang, ',', '/', 'g'))) : '' + if g:airline_detect_spell && &spell + if winwidth(0) >= 90 + return g:airline_symbols.spell . spelllang + elseif winwidth(0) >= 70 + return g:airline_symbols.spell + else + return split(g:airline_symbols.spell, '\zs')[0] + endif + endif + return '' +endfunction + +function! airline#parts#iminsert() + if g:airline_detect_iminsert && &iminsert && exists('b:keymap_name') + return toupper(b:keymap_name) + endif + return '' +endfunction + +function! airline#parts#readonly() + " only consider regular buffers (e.g. ones that represent actual files, + " but not special ones like e.g. NERDTree) + if !empty(&buftype) || airline#util#ignore_buf(bufname('%')) + return '' + endif + if &readonly && !filereadable(bufname('%')) + return '[noperm]' + else + return &readonly ? g:airline_symbols.readonly : '' + endif +endfunction + +function! airline#parts#filetype() + return winwidth(0) < 90 && strlen(&filetype) > 3 ? matchstr(&filetype, '...'). (&encoding is? 'utf-8' ? '…' : '>') : &filetype +endfunction + +function! airline#parts#ffenc() + let expected = get(g:, 'airline#parts#ffenc#skip_expected_string', '') + let bomb = &l:bomb ? '[BOM]' : '' + let ff = strlen(&ff) ? '['.&ff.']' : '' + if expected is# &fenc.bomb.ff + return '' + else + return &fenc.bomb.ff + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/section.vim b/dotfiles/.local/share/nvim/site/autoload/airline/section.vim new file mode 100644 index 0000000..7d84faf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/section.vim @@ -0,0 +1,84 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +call airline#init#bootstrap() +let s:spc = g:airline_symbols.space + +function! s:wrap_accent(part, value) + if exists('a:part.accent') + call airline#highlighter#add_accent(a:part.accent) + return '%#__accent_'.(a:part.accent).'#'.a:value.'%#__restore__#' + endif + return a:value +endfunction + +function! s:create(parts, append) + let _ = '' + for idx in range(len(a:parts)) + let part = airline#parts#get(a:parts[idx]) + let val = '' + let add_sep = get(l:, 'add_sep', 0) + + if exists('part.function') + let func = (part.function).'()' + elseif exists('part.text') + let func = '"'.(part.text).'"' + else + if a:append > 0 && idx != 0 + let val .= s:spc.g:airline_left_alt_sep.s:spc + endif + if a:append < 0 && idx != 0 + let t = '' + if !add_sep + let t = s:spc.g:airline_right_alt_sep.s:spc + endif + let val = t.val + endif + if exists('part.raw') + let _ .= s:wrap_accent(part, val.(part.raw)) + continue + else + let _ .= s:wrap_accent(part, val.a:parts[idx]) + continue + endif + endif + + let minwidth = get(part, 'minwidth', 0) + + if a:append > 0 && idx != 0 + let partval = printf('%%{airline#util#append(%s,%s)}', func, minwidth) + " will add an extra separator, if minwidth is zero + let add_sep = (minwidth == 0) + elseif a:append < 0 && idx != len(a:parts) - 1 + let partval = printf('%%{airline#util#prepend(%s,%s)}', func, minwidth) + " will add an extra separator, if minwidth is zero + let add_sep = (minwidth == 0) + else + let partval = printf('%%{airline#util#wrap(%s,%s)}', func, minwidth) + let add_sep = 0 + endif + + if exists('part.condition') + let partval = substitute(partval, '{', '\="{".(part.condition)." ? "', '') + let partval = substitute(partval, '}', ' : ""}', '') + endif + + let val .= s:wrap_accent(part, partval) + let _ .= val + endfor + return _ +endfunction + +function! airline#section#create(parts) + return s:create(a:parts, 0) +endfunction + +function! airline#section#create_left(parts) + return s:create(a:parts, 1) +endfunction + +function! airline#section#create_right(parts) + return s:create(a:parts, -1) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes.vim new file mode 100644 index 0000000..b757fe5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes.vim @@ -0,0 +1,78 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +" generates a dictionary which defines the colors for each highlight group +function! airline#themes#generate_color_map(sect1, sect2, sect3, ...) + let palette = { + \ 'airline_a': [ a:sect1[0] , a:sect1[1] , a:sect1[2] , a:sect1[3] , get(a:sect1 , 4 , '') ] , + \ 'airline_b': [ a:sect2[0] , a:sect2[1] , a:sect2[2] , a:sect2[3] , get(a:sect2 , 4 , '') ] , + \ 'airline_c': [ a:sect3[0] , a:sect3[1] , a:sect3[2] , a:sect3[3] , get(a:sect3 , 4 , '') ] , + \ } + + if a:0 > 0 + call extend(palette, { + \ 'airline_x': [ a:1[0] , a:1[1] , a:1[2] , a:1[3] , get(a:1 , 4 , '' ) ] , + \ 'airline_y': [ a:2[0] , a:2[1] , a:2[2] , a:2[3] , get(a:2 , 4 , '' ) ] , + \ 'airline_z': [ a:3[0] , a:3[1] , a:3[2] , a:3[3] , get(a:3 , 4 , '' ) ] , + \ }) + else + call extend(palette, { + \ 'airline_x': [ a:sect3[0] , a:sect3[1] , a:sect3[2] , a:sect3[3] , '' ] , + \ 'airline_y': [ a:sect2[0] , a:sect2[1] , a:sect2[2] , a:sect2[3] , '' ] , + \ 'airline_z': [ a:sect1[0] , a:sect1[1] , a:sect1[2] , a:sect1[3] , '' ] , + \ }) + endif + + return palette +endfunction + +function! airline#themes#get_highlight(group, ...) + return call('airline#highlighter#get_highlight', [a:group] + a:000) +endfunction + +function! airline#themes#get_highlight2(fg, bg, ...) + return call('airline#highlighter#get_highlight2', [a:fg, a:bg] + a:000) +endfunction + +function! airline#themes#patch(palette) + for mode in keys(a:palette) + if mode == 'accents' + continue + endif + if !has_key(a:palette[mode], 'airline_warning') + let a:palette[mode]['airline_warning'] = [ '#000000', '#df5f00', 232, 166 ] + endif + if !has_key(a:palette[mode], 'airline_error') + let a:palette[mode]['airline_error'] = [ '#000000', '#990000', 232, 160 ] + endif + if !has_key(a:palette[mode], 'airline_term') + let a:palette[mode]['airline_term'] = [ '#9cffd3', '#202020', 85, 232] + endif + endfor + + let a:palette.accents = get(a:palette, 'accents', {}) + let a:palette.accents.none = [ '', '', '', '', '' ] + let a:palette.accents.bold = [ '', '', '', '', 'bold' ] + let a:palette.accents.italic = [ '', '', '', '', 'italic' ] + + if !has_key(a:palette.accents, 'red') + let a:palette.accents.red = [ '#ff0000' , '' , 160 , '' ] + endif + if !has_key(a:palette.accents, 'green') + let a:palette.accents.green = [ '#008700' , '' , 22 , '' ] + endif + if !has_key(a:palette.accents, 'blue') + let a:palette.accents.blue = [ '#005fff' , '' , 27 , '' ] + endif + if !has_key(a:palette.accents, 'yellow') + let a:palette.accents.yellow = [ '#dfff00' , '' , 190 , '' ] + endif + if !has_key(a:palette.accents, 'orange') + let a:palette.accents.orange = [ '#df5f00' , '' , 166 , '' ] + endif + if !has_key(a:palette.accents, 'purple') + let a:palette.accents.purple = [ '#af00df' , '' , 128 , '' ] + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes/base16.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes/base16.vim new file mode 100644 index 0000000..0a7b442 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes/base16.vim @@ -0,0 +1,181 @@ +let s:improved_contrast = get(g:, 'airline_base16_improved_contrast', 0) + +" Color palette +let s:gui_dark_gray = '#202020' +let s:cterm_dark_gray = 234 +let s:gui_med_gray_hi = '#303030' +let s:cterm_med_gray_hi = 236 +let s:gui_med_gray_lo = '#3a3a3a' +let s:cterm_med_gray_lo = 237 +let s:gui_light_gray = '#505050' +let s:cterm_light_gray = 239 +let s:gui_lightlight_gray = '#8A8A8A' +let s:cterm_lightlight_gray = 245 +let s:gui_green = '#99cc99' +let s:cterm_green = 151 +let s:gui_blue = '#6a9fb5' +let s:cterm_blue = 67 +let s:gui_purple = '#aa759f' +let s:cterm_purple = 139 +let s:gui_orange = '#d28445' +let s:cterm_orange = 173 +let s:gui_red = '#ac4142' +let s:cterm_red = 131 +let s:gui_pink = '#d7afd7' +let s:cterm_pink = 182 + +if get(g:, 'airline#themes#base16#constant', 0) + let g:airline#themes#base16#palette = {} + + " Normal mode + let s:N1 = [s:gui_dark_gray, s:gui_green, s:cterm_dark_gray, s:cterm_green] + if s:improved_contrast + let s:N2 = [s:gui_lightlight_gray, s:gui_med_gray_lo, s:cterm_lightlight_gray, s:cterm_med_gray_lo] + else + + let s:N2 = [s:gui_light_gray, s:gui_med_gray_lo, s:cterm_light_gray, s:cterm_med_gray_lo] + endif + let s:N3 = [s:gui_green, s:gui_med_gray_hi, s:cterm_green, s:cterm_med_gray_hi] + let g:airline#themes#base16#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) + let g:airline#themes#base16#palette.normal_modified = { + \ 'airline_c': [s:gui_orange, s:gui_med_gray_hi, s:cterm_orange, s:cterm_med_gray_hi, ''], + \ } + + " Insert mode + let s:I1 = [s:gui_med_gray_hi, s:gui_blue, s:cterm_med_gray_hi, s:cterm_blue] + let s:I3 = [s:gui_blue, s:gui_med_gray_hi, s:cterm_blue, s:cterm_med_gray_hi] + let g:airline#themes#base16#palette.insert = airline#themes#generate_color_map(s:I1, s:N2, s:I3) + let g:airline#themes#base16#palette.insert_modified = copy(g:airline#themes#base16#palette.normal_modified) + let g:airline#themes#base16#palette.insert_paste = { + \ 'airline_a': [s:gui_dark_gray, s:gui_orange, s:cterm_dark_gray, s:cterm_orange, ''], + \ } + + " Replace mode + let g:airline#themes#base16#palette.replace = { + \ 'airline_a': [s:gui_dark_gray, s:gui_red, s:cterm_dark_gray, s:cterm_red, ''], + \ 'airline_c': [s:gui_red, s:gui_med_gray_hi, s:cterm_red, s:cterm_med_gray_hi, ''], + \ } + let g:airline#themes#base16#palette.replace_modified = copy(g:airline#themes#base16#palette.insert_modified) + + " Visual mode + let s:V1 = [s:gui_dark_gray, s:gui_pink, s:cterm_dark_gray, s:cterm_pink] + let s:V3 = [s:gui_pink, s:gui_med_gray_hi, s:cterm_pink, s:cterm_med_gray_hi] + let g:airline#themes#base16#palette.visual = airline#themes#generate_color_map(s:V1, s:N2, s:V3) + let g:airline#themes#base16#palette.visual_modified = copy(g:airline#themes#base16#palette.insert_modified) + + " Inactive window + if s:improved_contrast + let s:IA = [s:gui_dark_gray, s:gui_med_gray_hi, s:cterm_lightlight_gray, s:cterm_med_gray_hi, ''] + else + let s:IA = [s:gui_dark_gray, s:gui_med_gray_hi, s:cterm_light_gray, s:cterm_med_gray_hi, ''] + endif + let g:airline#themes#base16#palette.inactive = airline#themes#generate_color_map(s:IA, s:IA, s:IA) + let g:airline#themes#base16#palette.inactive_modified = { + \ 'airline_c': [s:gui_orange, '', s:cterm_orange, '', ''], + \ } +else + function! airline#themes#base16#refresh() + let g:airline#themes#base16#palette = {} + + let g:airline#themes#base16#palette.accents = { + \ 'red': airline#themes#get_highlight('Constant'), + \ } + + let s:N1 = airline#themes#get_highlight2(['DiffText', 'bg'], ['DiffText', 'fg'], 'bold') + let s:N2 = airline#themes#get_highlight2(['Visual', 'fg'], ['Visual', 'bg']) + let s:N3 = airline#themes#get_highlight('CursorLine') + let g:airline#themes#base16#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) + + let group = airline#themes#get_highlight('Statement') + let g:airline#themes#base16#palette.normal_modified = { + \ 'airline_c': [ group[0], '', group[2], '', '' ] + \ } + + let s:I1 = airline#themes#get_highlight2(['DiffText', 'bg'], ['DiffAdded', 'fg'], 'bold') + let s:I2 = airline#themes#get_highlight2(['DiffAdded', 'fg'], ['Normal', 'bg']) + let s:I3 = s:N3 + let g:airline#themes#base16#palette.insert = airline#themes#generate_color_map(s:I1, s:I2, s:I3) + let g:airline#themes#base16#palette.insert_modified = g:airline#themes#base16#palette.normal_modified + + let s:R1 = airline#themes#get_highlight2(['DiffText', 'bg'], ['WarningMsg', 'fg'], 'bold') + let s:R2 = s:N2 + let s:R3 = s:N3 + let g:airline#themes#base16#palette.replace = airline#themes#generate_color_map(s:R1, s:R2, s:R3) + let g:airline#themes#base16#palette.replace_modified = g:airline#themes#base16#palette.normal_modified + + let s:V1 = airline#themes#get_highlight2(['DiffText', 'bg'], ['Constant', 'fg'], 'bold') + let s:V2 = airline#themes#get_highlight2(['Constant', 'fg'], ['Normal', 'bg']) + let s:V3 = s:N3 + let g:airline#themes#base16#palette.visual = airline#themes#generate_color_map(s:V1, s:V2, s:V3) + let g:airline#themes#base16#palette.visual_modified = g:airline#themes#base16#palette.normal_modified + + " Use VertSplit's bg and default fg (reversed) for inactive statusline. + let s:VS = airline#themes#get_highlight('VertSplit') + if s:improved_contrast + let s:IA = [ s:VS[1], 'NONE', s:VS[2], s:cterm_lightlight_gray, 'reverse'] + else + let s:IA = [ s:VS[1], 'NONE', s:VS[2], 'NONE', 'reverse'] + endif + let g:airline#themes#base16#palette.inactive = + \ airline#themes#generate_color_map(s:IA, s:IA, s:IA, s:IA, s:IA, s:IA) + let s:IM = [ s:VS[1], 'NONE', s:VS[2], 'NONE', 'reverse'] + let g:airline#themes#base16#palette.inactive_modified = + \ airline#themes#generate_color_map(s:IM, s:IM, s:IM, s:IM, s:IM, s:IM) + + " Warnings + let s:WI = airline#themes#get_highlight2(['WarningMsg', 'bg'], ['WarningMsg', 'fg'], 'bold') + let g:airline#themes#base16#palette.normal.airline_warning = [ + \ s:WI[0], s:WI[1], s:WI[2], s:WI[3] + \ ] + + let g:airline#themes#base16#palette.normal_modified.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.insert.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.insert_modified.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.visual.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.visual_modified.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.replace.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + let g:airline#themes#base16#palette.replace_modified.airline_warning = + \ g:airline#themes#base16#palette.normal.airline_warning + + " Errors + let s:ER = airline#themes#get_highlight2(['ErrorMsg', 'bg'], ['ErrorMsg', 'fg'], 'bold') + let g:airline#themes#base16#palette.normal.airline_error = [ + \ s:ER[0], s:ER[1], s:ER[2], s:ER[3] + \ ] + + let g:airline#themes#base16#palette.normal_modified.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.insert.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.insert_modified.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.visual.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.visual_modified.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.replace.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + let g:airline#themes#base16#palette.replace_modified.airline_error = + \ g:airline#themes#base16#palette.normal.airline_error + + endfunction + call airline#themes#base16#refresh() +endif diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes/bubblegum.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes/bubblegum.vim new file mode 100644 index 0000000..f2378ce --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes/bubblegum.vim @@ -0,0 +1,70 @@ +" Color palette +let s:gui_dark_gray = '#303030' +let s:cterm_dark_gray = 236 +let s:gui_med_gray_hi = '#444444' +let s:cterm_med_gray_hi = 238 +let s:gui_med_gray_lo = '#3a3a3a' +let s:cterm_med_gray_lo = 237 +let s:gui_light_gray = '#b2b2b2' +let s:cterm_light_gray = 249 +let s:gui_green = '#afd787' +let s:cterm_green = 150 +let s:gui_blue = '#87afd7' +let s:cterm_blue = 110 +let s:gui_purple = '#afafd7' +let s:cterm_purple = 146 +let s:gui_orange = '#d7af5f' +let s:cterm_orange = 179 +let s:gui_red = '#d78787' +let s:cterm_red = 174 +let s:gui_pink = '#d7afd7' +let s:cterm_pink = 182 + +let g:airline#themes#bubblegum#palette = {} + +" Normal mode +let s:N1 = [s:gui_dark_gray, s:gui_green, s:cterm_dark_gray, s:cterm_green] +let s:N2 = [s:gui_light_gray, s:gui_med_gray_lo, s:cterm_light_gray, s:cterm_med_gray_lo] +let s:N3 = [s:gui_green, s:gui_med_gray_hi, s:cterm_green, s:cterm_med_gray_hi] +let g:airline#themes#bubblegum#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) +let g:airline#themes#bubblegum#palette.normal_modified = { + \ 'airline_c': [s:gui_orange, s:gui_med_gray_hi, s:cterm_orange, s:cterm_med_gray_hi, ''], + \ } + +" Insert mode +let s:I1 = [s:gui_med_gray_hi, s:gui_blue, s:cterm_med_gray_hi, s:cterm_blue] +let s:I3 = [s:gui_blue, s:gui_med_gray_hi, s:cterm_blue, s:cterm_med_gray_hi] +let g:airline#themes#bubblegum#palette.insert = airline#themes#generate_color_map(s:I1, s:N2, s:I3) +let g:airline#themes#bubblegum#palette.insert_modified = copy(g:airline#themes#bubblegum#palette.normal_modified) +let g:airline#themes#bubblegum#palette.insert_paste = { + \ 'airline_a': [s:gui_dark_gray, s:gui_orange, s:cterm_dark_gray, s:cterm_orange, ''], + \ } + +" Replace mode +let g:airline#themes#bubblegum#palette.replace = { + \ 'airline_a': [s:gui_dark_gray, s:gui_red, s:cterm_dark_gray, s:cterm_red, ''], + \ 'airline_c': [s:gui_red, s:gui_med_gray_hi, s:cterm_red, s:cterm_med_gray_hi, ''], + \ } +let g:airline#themes#bubblegum#palette.replace_modified = copy(g:airline#themes#bubblegum#palette.insert_modified) + +" Visual mode +let s:V1 = [s:gui_dark_gray, s:gui_pink, s:cterm_dark_gray, s:cterm_pink] +let s:V3 = [s:gui_pink, s:gui_med_gray_hi, s:cterm_pink, s:cterm_med_gray_hi] +let g:airline#themes#bubblegum#palette.visual = airline#themes#generate_color_map(s:V1, s:N2, s:V3) +let g:airline#themes#bubblegum#palette.visual_modified = copy(g:airline#themes#bubblegum#palette.insert_modified) + +" Inactive window +let s:IA = [s:gui_light_gray, s:gui_med_gray_hi, s:cterm_light_gray, s:cterm_med_gray_hi, ''] +let g:airline#themes#bubblegum#palette.inactive = airline#themes#generate_color_map(s:IA, s:IA, s:IA) +let g:airline#themes#bubblegum#palette.inactive_modified = { + \ 'airline_c': [s:gui_orange, '', s:cterm_orange, '', ''], + \ } + +" CtrlP +if !get(g:, 'loaded_ctrlp', 0) + finish +endif +let g:airline#themes#bubblegum#palette.ctrlp = airline#extensions#ctrlp#generate_color_map( + \ [ s:gui_orange, s:gui_med_gray_hi, s:cterm_orange, s:cterm_med_gray_hi, '' ] , + \ [ s:gui_orange, s:gui_med_gray_lo, s:cterm_orange, s:cterm_med_gray_lo, '' ] , + \ [ s:gui_dark_gray, s:gui_green, s:cterm_dark_gray, s:cterm_green, 'bold' ] ) diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes/dark.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes/dark.vim new file mode 100644 index 0000000..94f3763 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes/dark.vim @@ -0,0 +1,161 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 tw=80 + +scriptencoding utf-8 + +" Airline themes are generated based on the following concepts: +" * The section of the status line, valid Airline statusline sections are: +" * airline_a (left most section) +" * airline_b (section just to the right of airline_a) +" * airline_c (section just to the right of airline_b) +" * airline_x (first section of the right most sections) +" * airline_y (section just to the right of airline_x) +" * airline_z (right most section) +" * The mode of the buffer, as reported by the :mode() function. Airline +" converts the values reported by mode() to the following: +" * normal +" * insert +" * replace +" * visual +" * inactive +" The last one is actually no real mode as returned by mode(), but used by +" airline to style inactive statuslines (e.g. windows, where the cursor +" currently does not reside in). +" * In addition to each section and mode specified above, airline themes +" can also specify overrides. Overrides can be provided for the following +" scenarios: +" * 'modified' +" * 'paste' +" +" Airline themes are specified as a global viml dictionary using the above +" sections, modes and overrides as keys to the dictionary. The name of the +" dictionary is significant and should be specified as: +" * g:airline#themes#<theme_name>#palette +" where <theme_name> is substituted for the name of the theme.vim file where the +" theme definition resides. Airline themes should reside somewhere on the +" 'runtimepath' where it will be loaded at vim startup, for example: +" * autoload/airline/themes/theme_name.vim +" +" For this, the dark.vim, theme, this is defined as +let g:airline#themes#dark#palette = {} + +" Keys in the dictionary are composed of the mode, and if specified the +" override. For example: +" * g:airline#themes#dark#palette.normal +" * the colors for a statusline while in normal mode +" * g:airline#themes#dark#palette.normal_modified +" * the colors for a statusline while in normal mode when the buffer has +" been modified +" * g:airline#themes#dark#palette.visual +" * the colors for a statusline while in visual mode +" +" Values for each dictionary key is an array of color values that should be +" familiar for colorscheme designers: +" * [guifg, guibg, ctermfg, ctermbg, opts] +" See "help attr-list" for valid values for the "opt" value. +" +" Each theme must provide an array of such values for each airline section of +" the statusline (airline_a through airline_z). A convenience function, +" airline#themes#generate_color_map() exists to mirror airline_a/b/c to +" airline_x/y/z, respectively. + +" The dark.vim theme: +let s:airline_a_normal = [ '#00005f' , '#dfff00' , 17 , 190 ] +let s:airline_b_normal = [ '#ffffff' , '#444444' , 255 , 238 ] +let s:airline_c_normal = [ '#9cffd3' , '#202020' , 85 , 234 ] +let g:airline#themes#dark#palette.normal = airline#themes#generate_color_map(s:airline_a_normal, s:airline_b_normal, s:airline_c_normal) + +" It should be noted the above is equivalent to: +" let g:airline#themes#dark#palette.normal = airline#themes#generate_color_map( +" \ [ '#00005f' , '#dfff00' , 17 , 190 ], " section airline_a +" \ [ '#ffffff' , '#444444' , 255 , 238 ], " section airline_b +" \ [ '#9cffd3' , '#202020' , 85 , 234 ] " section airline_c +" \) +" +" In turn, that is equivalent to: +" let g:airline#themes#dark#palette.normal = { +" \ 'airline_a': [ '#00005f' , '#dfff00' , 17 , 190 ], "section airline_a +" \ 'airline_b': [ '#ffffff' , '#444444' , 255 , 238 ], "section airline_b +" \ 'airline_c': [ '#9cffd3' , '#202020' , 85 , 234 ], "section airline_c +" \ 'airline_x': [ '#9cffd3' , '#202020' , 85 , 234 ], "section airline_x +" \ 'airline_y': [ '#ffffff' , '#444444' , 255 , 238 ], "section airline_y +" \ 'airline_z': [ '#00005f' , '#dfff00' , 17 , 190 ] "section airline_z +" \} +" +" airline#themes#generate_color_map() also uses the values provided as +" parameters to create intermediary groups such as: +" airline_a_to_airline_b +" airline_b_to_airline_c +" etc... + +" Here we define overrides for when the buffer is modified. This will be +" applied after g:airline#themes#dark#palette.normal, hence why only certain keys are +" declared. +let g:airline#themes#dark#palette.normal_modified = { + \ 'airline_c': [ '#ffffff' , '#5f005f' , 255 , 53 , '' ] , + \ } + + +let s:airline_a_insert = [ '#00005f' , '#00dfff' , 17 , 45 ] +let s:airline_b_insert = [ '#ffffff' , '#005fff' , 255 , 27 ] +let s:airline_c_insert = [ '#ffffff' , '#000080' , 15 , 17 ] +let g:airline#themes#dark#palette.insert = airline#themes#generate_color_map(s:airline_a_insert, s:airline_b_insert, s:airline_c_insert) +let g:airline#themes#dark#palette.insert_modified = { + \ 'airline_c': [ '#ffffff' , '#5f005f' , 255 , 53 , '' ] , + \ } +let g:airline#themes#dark#palette.insert_paste = { + \ 'airline_a': [ s:airline_a_insert[0] , '#d78700' , s:airline_a_insert[2] , 172 , '' ] , + \ } + + +let g:airline#themes#dark#palette.replace = copy(g:airline#themes#dark#palette.insert) +let g:airline#themes#dark#palette.replace.airline_a = [ s:airline_b_insert[0] , '#af0000' , s:airline_b_insert[2] , 124 , '' ] +let g:airline#themes#dark#palette.replace_modified = g:airline#themes#dark#palette.insert_modified + + +let s:airline_a_visual = [ '#000000' , '#ffaf00' , 232 , 214 ] +let s:airline_b_visual = [ '#000000' , '#ff5f00' , 232 , 202 ] +let s:airline_c_visual = [ '#ffffff' , '#5f0000' , 15 , 52 ] +let g:airline#themes#dark#palette.visual = airline#themes#generate_color_map(s:airline_a_visual, s:airline_b_visual, s:airline_c_visual) +let g:airline#themes#dark#palette.visual_modified = { + \ 'airline_c': [ '#ffffff' , '#5f005f' , 255 , 53 , '' ] , + \ } + + +let s:airline_a_inactive = [ '#4e4e4e' , '#1c1c1c' , 239 , 234 , '' ] +let s:airline_b_inactive = [ '#4e4e4e' , '#262626' , 239 , 235 , '' ] +let s:airline_c_inactive = [ '#4e4e4e' , '#303030' , 239 , 236 , '' ] +let g:airline#themes#dark#palette.inactive = airline#themes#generate_color_map(s:airline_a_inactive, s:airline_b_inactive, s:airline_c_inactive) +let g:airline#themes#dark#palette.inactive_modified = { + \ 'airline_c': [ '#875faf' , '' , 97 , '' , '' ] , + \ } + +" For commandline mode, we use the colors from normal mode, except the mode +" indicator should be colored differently, e.g. blue on light green +let s:airline_a_commandline = [ '#0000ff' , '#0cff00' , 63 , 40 ] +let s:airline_b_commandline = [ '#ffffff' , '#444444' , 255 , 238 ] +let s:airline_c_commandline = [ '#9cffd3' , '#202020' , 85 , 234 ] +let g:airline#themes#dark#palette.commandline = airline#themes#generate_color_map(s:airline_a_commandline, s:airline_b_commandline, s:airline_c_commandline) + +" Accents are used to give parts within a section a slightly different look or +" color. Here we are defining a "red" accent, which is used by the 'readonly' +" part by default. Only the foreground colors are specified, so the background +" colors are automatically extracted from the underlying section colors. What +" this means is that regardless of which section the part is defined in, it +" will be red instead of the section's foreground color. You can also have +" multiple parts with accents within a section. +let g:airline#themes#dark#palette.accents = { + \ 'red': [ '#ff0000' , '' , 160 , '' ] + \ } + + +" Here we define the color map for ctrlp. We check for the g:loaded_ctrlp +" variable so that related functionality is loaded iff the user is using +" ctrlp. Note that this is optional, and if you do not define ctrlp colors +" they will be chosen automatically from the existing palette. +if get(g:, 'loaded_ctrlp', 0) + let g:airline#themes#dark#palette.ctrlp = airline#extensions#ctrlp#generate_color_map( + \ [ '#d7d7ff' , '#5f00af' , 189 , 55 , '' ], + \ [ '#ffffff' , '#875fd7' , 231 , 98 , '' ], + \ [ '#5f00af' , '#ffffff' , 55 , 231 , 'bold' ]) +endif diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes/gruvbox.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes/gruvbox.vim new file mode 100644 index 0000000..6862a81 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes/gruvbox.vim @@ -0,0 +1,79 @@ +" ----------------------------------------------------------------------------- +" File: gruvbox.vim +" Description: Retro groove color scheme for Airline +" Author: morhetz <morhetz@gmail.com> +" Source: https://github.com/morhetz/gruvbox +" Last Modified: 12 Aug 2017 +" ----------------------------------------------------------------------------- + +let g:airline#themes#gruvbox#palette = {} + +function! airline#themes#gruvbox#refresh() + + let M0 = airline#themes#get_highlight('Identifier') + let accents_group = airline#themes#get_highlight('Special') + let modified_group = [M0[0], '', M0[2], '', ''] + let warning_group = airline#themes#get_highlight2(['Normal', 'bg'], ['Question', 'fg']) + let error_group = airline#themes#get_highlight2(['Normal', 'bg'], ['WarningMsg', 'fg']) + + let s:N1 = airline#themes#get_highlight2(['Normal', 'bg'], ['StatusLineNC', 'bg']) + let s:N2 = airline#themes#get_highlight2(['StatusLineNC', 'bg'], ['Pmenu', 'bg']) + let s:N3 = airline#themes#get_highlight2(['StatusLineNC', 'bg'], ['CursorLine', 'bg']) + let g:airline#themes#gruvbox#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) + let g:airline#themes#gruvbox#palette.normal_modified = { 'airline_c': modified_group } + let g:airline#themes#gruvbox#palette.normal.airline_warning = warning_group + let g:airline#themes#gruvbox#palette.normal_modified.airline_warning = warning_group + let g:airline#themes#gruvbox#palette.normal.airline_error = error_group + let g:airline#themes#gruvbox#palette.normal_modified.airline_error = error_group + + let s:I1 = airline#themes#get_highlight2(['Normal', 'bg'], ['Identifier', 'fg']) + let s:I2 = s:N2 + let s:I3 = airline#themes#get_highlight2(['Normal', 'fg'], ['Pmenu', 'bg']) + let g:airline#themes#gruvbox#palette.insert = airline#themes#generate_color_map(s:I1, s:I2, s:I3) + let g:airline#themes#gruvbox#palette.insert_modified = g:airline#themes#gruvbox#palette.normal_modified + let g:airline#themes#gruvbox#palette.insert.airline_warning = g:airline#themes#gruvbox#palette.normal.airline_warning + let g:airline#themes#gruvbox#palette.insert_modified.airline_warning = g:airline#themes#gruvbox#palette.normal_modified.airline_warning + let g:airline#themes#gruvbox#palette.insert.airline_error = g:airline#themes#gruvbox#palette.normal.airline_error + let g:airline#themes#gruvbox#palette.insert_modified.airline_error = g:airline#themes#gruvbox#palette.normal_modified.airline_error + + let s:R1 = airline#themes#get_highlight2(['Normal', 'bg'], ['Structure', 'fg']) + let s:R2 = s:I2 + let s:R3 = s:I3 + let g:airline#themes#gruvbox#palette.replace = airline#themes#generate_color_map(s:R1, s:R2, s:R3) + let g:airline#themes#gruvbox#palette.replace_modified = g:airline#themes#gruvbox#palette.normal_modified + let g:airline#themes#gruvbox#palette.replace.airline_warning = g:airline#themes#gruvbox#palette.normal.airline_warning + let g:airline#themes#gruvbox#palette.replace_modified.airline_warning = g:airline#themes#gruvbox#palette.normal_modified.airline_warning + let g:airline#themes#gruvbox#palette.replace.airline_error = g:airline#themes#gruvbox#palette.normal.airline_error + let g:airline#themes#gruvbox#palette.replace_modified.airline_error = g:airline#themes#gruvbox#palette.normal_modified.airline_error + + let s:V1 = airline#themes#get_highlight2(['Normal', 'bg'], ['Question', 'fg']) + let s:V2 = s:N2 + let s:V3 = airline#themes#get_highlight2(['Normal', 'bg'], ['TabLine', 'fg']) + let g:airline#themes#gruvbox#palette.visual = airline#themes#generate_color_map(s:V1, s:V2, s:V3) + let g:airline#themes#gruvbox#palette.visual_modified = { 'airline_c': [ s:V3[0], '', s:V3[2], '', '' ] } + let g:airline#themes#gruvbox#palette.visual.airline_warning = g:airline#themes#gruvbox#palette.normal.airline_warning + let g:airline#themes#gruvbox#palette.visual_modified.airline_warning = g:airline#themes#gruvbox#palette.normal_modified.airline_warning + let g:airline#themes#gruvbox#palette.visual.airline_error = g:airline#themes#gruvbox#palette.normal.airline_error + let g:airline#themes#gruvbox#palette.visual_modified.airline_error = g:airline#themes#gruvbox#palette.normal_modified.airline_error + + let s:IA = airline#themes#get_highlight2(['TabLine', 'fg'], ['CursorLine', 'bg']) + let g:airline#themes#gruvbox#palette.inactive = airline#themes#generate_color_map(s:IA, s:IA, s:IA) + let g:airline#themes#gruvbox#palette.inactive_modified = { 'airline_c': modified_group } + + let g:airline#themes#gruvbox#palette.accents = { 'red': accents_group } + + let s:TF = airline#themes#get_highlight2(['Normal', 'bg'], ['Normal', 'bg']) + let g:airline#themes#gruvbox#palette.tabline = { + \ 'airline_tab': s:N2, + \ 'airline_tabsel': s:N1, + \ 'airline_tabtype': s:V1, + \ 'airline_tabfill': s:TF, + \ 'airline_tabhid': s:IA, + \ 'airline_tabmod': s:I1 + \ } + +endfunction + +call airline#themes#gruvbox#refresh() + +" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker: diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/themes/ultramar.vim b/dotfiles/.local/share/nvim/site/autoload/airline/themes/ultramar.vim new file mode 100644 index 0000000..5f542de --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/themes/ultramar.vim @@ -0,0 +1,70 @@ +" Color palette +let s:gui_dark_gray = '#434c5e' +let s:cterm_dark_gray = 236 +let s:gui_med_gray_hi = '#2d333f' +let s:cterm_med_gray_hi = 238 +let s:gui_med_gray_lo = '#3b4252' +let s:cterm_med_gray_lo = 237 +let s:gui_light_gray = '#e5e9f0' +let s:cterm_light_gray = 249 +let s:gui_green = '#9eba86' +let s:cterm_green = 150 +let s:gui_blue = '#81acc1' +let s:cterm_blue = 110 +let s:gui_purple = '#9c6992' +let s:cterm_purple = 146 +let s:gui_orange = '#af5539' +let s:cterm_orange = 179 +let s:gui_red = '#b73030' +let s:cterm_red = 174 +let s:gui_pink = '#b48ead' +let s:cterm_pink = 182 + +let g:airline#themes#ultramar#palette = {} + +" Normal mode +let s:N1 = [s:gui_dark_gray, s:gui_green, s:cterm_dark_gray, s:cterm_green] +let s:N2 = [s:gui_light_gray, s:gui_med_gray_lo, s:cterm_light_gray, s:cterm_med_gray_lo] +let s:N3 = [s:gui_green, s:gui_med_gray_hi, s:cterm_green, s:cterm_med_gray_hi] +let g:airline#themes#ultramar#palette.normal = airline#themes#generate_color_map(s:N1, s:N2, s:N3) +let g:airline#themes#ultramar#palette.normal_modified = { + \ 'airline_c': [s:gui_orange, s:gui_med_gray_hi, s:cterm_orange, s:cterm_med_gray_hi, ''], + \ } + +" Insert mode +let s:I1 = [s:gui_med_gray_hi, s:gui_blue, s:cterm_med_gray_hi, s:cterm_blue] +let s:I3 = [s:gui_blue, s:gui_med_gray_hi, s:cterm_blue, s:cterm_med_gray_hi] +let g:airline#themes#ultramar#palette.insert = airline#themes#generate_color_map(s:I1, s:N2, s:I3) +let g:airline#themes#ultramar#palette.insert_modified = copy(g:airline#themes#ultramar#palette.normal_modified) +let g:airline#themes#ultramar#palette.insert_paste = { + \ 'airline_a': [s:gui_dark_gray, s:gui_orange, s:cterm_dark_gray, s:cterm_orange, ''], + \ } + +" Replace mode +let g:airline#themes#ultramar#palette.replace = { + \ 'airline_a': [s:gui_dark_gray, s:gui_red, s:cterm_dark_gray, s:cterm_red, ''], + \ 'airline_c': [s:gui_red, s:gui_med_gray_hi, s:cterm_red, s:cterm_med_gray_hi, ''], + \ } +let g:airline#themes#ultramar#palette.replace_modified = copy(g:airline#themes#ultramar#palette.insert_modified) + +" Visual mode +let s:V1 = [s:gui_dark_gray, s:gui_pink, s:cterm_dark_gray, s:cterm_pink] +let s:V3 = [s:gui_pink, s:gui_med_gray_hi, s:cterm_pink, s:cterm_med_gray_hi] +let g:airline#themes#ultramar#palette.visual = airline#themes#generate_color_map(s:V1, s:N2, s:V3) +let g:airline#themes#ultramar#palette.visual_modified = copy(g:airline#themes#ultramar#palette.insert_modified) + +" Inactive window +let s:IA = [s:gui_light_gray, s:gui_med_gray_hi, s:cterm_light_gray, s:cterm_med_gray_hi, ''] +let g:airline#themes#ultramar#palette.inactive = airline#themes#generate_color_map(s:IA, s:IA, s:IA) +let g:airline#themes#ultramar#palette.inactive_modified = { + \ 'airline_c': [s:gui_orange, '', s:cterm_orange, '', ''], + \ } + +" CtrlP +if !get(g:, 'loaded_ctrlp', 0) + finish +endif +let g:airline#themes#ultramar#palette.ctrlp = airline#extensions#ctrlp#generate_color_map( + \ [ s:gui_orange, s:gui_med_gray_hi, s:cterm_orange, s:cterm_med_gray_hi, '' ] , + \ [ s:gui_orange, s:gui_med_gray_lo, s:cterm_orange, s:cterm_med_gray_lo, '' ] , + \ [ s:gui_dark_gray, s:gui_green, s:cterm_dark_gray, s:cterm_green, 'bold' ] ) diff --git a/dotfiles/.local/share/nvim/site/autoload/airline/util.vim b/dotfiles/.local/share/nvim/site/autoload/airline/util.vim new file mode 100644 index 0000000..65e123c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/airline/util.vim @@ -0,0 +1,131 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +" TODO: Try to cache winwidth(0) function +" e.g. store winwidth per window and access that, only update it, if the size +" actually changed. +scriptencoding utf-8 + +call airline#init#bootstrap() +let s:spc = g:airline_symbols.space +let s:nomodeline = (v:version > 703 || (v:version == 703 && has("patch438"))) ? '<nomodeline>' : '' + +function! airline#util#shorten(text, winwidth, minwidth, ...) + if winwidth(0) < a:winwidth && len(split(a:text, '\zs')) > a:minwidth + if get(a:000, 0, 0) + " shorten from tail + return '…'.matchstr(a:text, '.\{'.a:minwidth.'}$') + else + " shorten from beginning of string + return matchstr(a:text, '^.\{'.a:minwidth.'}').'…' + endif + else + return a:text + endif +endfunction + +function! airline#util#wrap(text, minwidth) + if a:minwidth > 0 && winwidth(0) < a:minwidth + return '' + endif + return a:text +endfunction + +function! airline#util#append(text, minwidth) + if a:minwidth > 0 && winwidth(0) < a:minwidth + return '' + endif + let prefix = s:spc == "\ua0" ? s:spc : s:spc.s:spc + return empty(a:text) ? '' : prefix.g:airline_left_alt_sep.s:spc.a:text +endfunction + +function! airline#util#warning(msg) + echohl WarningMsg + echomsg "airline: ".a:msg + echohl Normal +endfunction + +function! airline#util#prepend(text, minwidth) + if a:minwidth > 0 && winwidth(0) < a:minwidth + return '' + endif + return empty(a:text) ? '' : a:text.s:spc.g:airline_right_alt_sep.s:spc +endfunction + +if v:version >= 704 + function! airline#util#getwinvar(winnr, key, def) + return getwinvar(a:winnr, a:key, a:def) + endfunction +else + function! airline#util#getwinvar(winnr, key, def) + let winvals = getwinvar(a:winnr, '') + return get(winvals, a:key, a:def) + endfunction +endif + +if v:version >= 704 + function! airline#util#exec_funcrefs(list, ...) + for Fn in a:list + let code = call(Fn, a:000) + if code != 0 + return code + endif + endfor + return 0 + endfunction +else + function! airline#util#exec_funcrefs(list, ...) + " for 7.2; we cannot iterate the list, hence why we use range() + " for 7.3-[97, 328]; we cannot reuse the variable, hence the {} + for i in range(0, len(a:list) - 1) + let Fn{i} = a:list[i] + let code = call(Fn{i}, a:000) + if code != 0 + return code + endif + endfor + return 0 + endfunction +endif + +" Compatibility wrapper for strchars, in case this vim version does not +" have it natively +function! airline#util#strchars(str) + if exists('*strchars') + return strchars(a:str) + else + return strlen(substitute(a:str, '.', 'a', 'g')) + endif +endfunction + +function! airline#util#ignore_buf(name) + let pat = '\c\v'. get(g:, 'airline#ignore_bufadd_pat', ''). + \ get(g:, 'airline#extensions#tabline#ignore_bufadd_pat', + \ 'gundo|undotree|vimfiler|tagbar|nerd_tree|startify|!') + return match(a:name, pat) > -1 +endfunction + +function! airline#util#has_fugitive() + return exists('*fugitive#head') || exists('*FugitiveHead') +endfunction + +function! airline#util#has_lawrencium() + return exists('*lawrencium#statusline') +endfunction + +function! airline#util#has_vcscommand() + return get(g:, 'airline#extensions#branch#use_vcscommand', 0) && exists('*VCSCommandGetStatusLine') +endfunction + +function! airline#util#has_custom_scm() + return !empty(get(g:, 'airline#extensions#branch#custom_head', '')) +endfunction + +function! airline#util#doautocmd(event) + exe printf("silent doautocmd %s User %s", s:nomodeline, a:event) +endfunction + +function! airline#util#themes(match) + let files = split(globpath(&rtp, 'autoload/airline/themes/'.a:match.'*'), "\n") + return map(files, 'fnamemodify(v:val, ":t:r")') +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake.vim b/dotfiles/.local/share/nvim/site/autoload/neomake.vim new file mode 100644 index 0000000..6322a05 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake.vim @@ -0,0 +1,2582 @@ +" vim: ts=4 sw=4 et +scriptencoding utf-8 + +if !exists('s:make_id') + let s:make_id = 0 +endif +" A map of make_id to options, e.g. cwd when jobs where started. +if !exists('s:make_info') + let s:make_info = {} +endif +if !exists('s:job_id') + let s:job_id = 1 +endif +if !exists('s:jobs') + let s:jobs = {} +endif +if !exists('s:map_job_ids') + let s:map_job_ids = {} +endif + +" Errors by [maker_type][bufnr][lnum] +let s:current_errors = {'project': {}, 'file': {}} + +if !has('nvim') + let s:kill_vim_timers = {} +endif + +" A list of references to keep when profiling. +" Workaround for https://github.com/vim/vim/issues/2350, where +" https://github.com/blueyed/vader.vim/commit/e66d91dea is not enough. +let s:hack_keep_refs_for_profiling = [] + +" Can Neovim buffer output? +let s:nvim_can_buffer_output = has('nvim-0.3.0') ? 1 : 0 + +" Private function to access script-local variables during tests. +function! neomake#_get_s() abort + return s: +endfunction + +" Sentinels. +let s:unset_list = [] +let s:unset_dict = {} +let s:unset = {} + +let s:can_use_env_in_job_opts = has('patch-8.0.0902') && has('patch-8.0.1832') + +let s:is_testing = exists('g:neomake_test_messages') + +let s:async = has('nvim') + \ || has('channel') && has('job') && has('patch-8.0.0027') +function! neomake#has_async_support() abort + return s:async +endfunction + +if v:version >= 704 || (v:version == 703 && has('patch1058')) + function! s:function(name) abort + return function(a:name) + endfunction +else + " Older Vim does not handle s: function references across files. + function! s:function(name) abort + return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_'),'')) + endfunction +endif + +function! s:sort_jobs(a, b) abort + return a:a.id - a:b.id +endfunction + +function! neomake#GetJobs(...) abort + if empty(s:jobs) + return [] + endif + let jobs = copy(values(s:jobs)) + if a:0 + call filter(jobs, 'index(a:1, v:val.id) != -1') + endif + return sort(jobs, function('s:sort_jobs')) +endfunction + +function! neomake#GetJob(job_id) abort + return s:jobs[a:job_id] +endfunction + +" Not documented, only used in tests for now. +function! neomake#GetStatus() abort + return { + \ 'last_make_id': s:make_id, + \ 'make_info': s:make_info, + \ 'action_queue': g:neomake#action_queue#_s.action_queue, + \ } +endfunction + +" neomake#GetMakeOptions: not documented, only used internally for now. +" More lax when not being used in tests to avoid errors, but fail during tests. +if s:is_testing + function! neomake#GetMakeOptions(...) abort + let make_id = a:0 ? a:1 : s:make_id + try + let r = s:make_info[make_id] + catch + let msg = printf('GetMakeOptions failed: %s (in %s)', v:exception, v:throwpoint) + call vader#log(msg) + let g:neomake_test_errors += [msg] + return {'verbosity': 3} + endtry + return r + endfunction +else + function! neomake#GetMakeOptions(...) abort + let make_id = a:0 ? a:1 : s:make_id + if !has_key(s:make_info, make_id) + call neomake#log#warning('warning: missing make_info key: '.make_id.'.') + return {'verbosity': get(g:, 'neomake_verbose', 1)} + endif + return s:make_info[make_id] + endfunction +endif + +function! neomake#ListJobs() abort + if !s:async + echom 'This Vim version has no support for jobs.' + return + endif + let jobs = neomake#GetJobs() + if empty(jobs) + return + endif + echom 'make_id | job_id | name/maker' + for jobinfo in jobs + let desc = !empty(jobinfo.maker.name) && jobinfo.name != jobinfo.maker.name + \ ? jobinfo.name. ' ('.jobinfo.maker.name.')' + \ : jobinfo.name + echom printf('%7d | %6d | %s', jobinfo.make_id, jobinfo.id, desc) + endfor +endfunction + +function! neomake#CancelMake(...) abort + let make_id = a:0 ? a:1 : s:make_id + if !has_key(s:make_info, make_id) + call neomake#log#error('CancelMake: make not found: '.make_id.'.') + return 0 + endif + let bang = a:0 > 1 ? a:1 : 0 + let make_info = s:make_info[make_id] + call neomake#log#debug('Canceling make.', make_info) + let make_info.canceled = 1 + let jobs = filter(copy(values(s:jobs)), 'v:val.make_id == make_id') + call s:abort_next_makers(make_id) + for job in jobs + call neomake#CancelJob(job.id, bang) + endfor + call neomake#action_queue#clean(make_info) + " Ensure that make info gets cleaned really, e.g. if there were no jobs yet. + if has_key(s:make_info, make_id) + call s:clean_make_info(make_info, bang) + endif + return 1 +endfunction + +function! neomake#CancelAllMakes(...) abort + let bang = a:0 ? a:1 : 0 + for make_id in keys(s:make_info) + call neomake#CancelMake(make_id, bang) + endfor +endfunction + +" Returns 1 if a job was canceled, 0 otherwise. +function! neomake#CancelJob(job_id, ...) abort + let job_id = type(a:job_id) == type({}) ? a:job_id.id : +a:job_id + let remove_always = a:0 ? a:1 : 0 + let jobinfo = get(s:jobs, job_id, {}) + call neomake#log#debug('Canceling job.', jobinfo) + + call neomake#action_queue#clean(empty(jobinfo) ? {'id': job_id} : jobinfo) + + if empty(jobinfo) + call neomake#log#error('CancelJob: job not found: '.job_id.'.') + return 0 + endif + + if get(jobinfo, 'canceled', 0) + call neomake#log#info('Job was canceled already.', jobinfo) + if remove_always + call s:CleanJobinfo(jobinfo) + endif + return 0 + endif + let jobinfo.canceled = 1 + + let ret = 0 + if get(jobinfo, 'finished') + call neomake#log#debug('Removing already finished job.', jobinfo) + elseif has_key(jobinfo, 'exit_code') + call neomake#log#debug('Job exited already.', jobinfo) + elseif has_key(jobinfo.maker, 'get_list_entries') + call neomake#log#debug('Removing job for get_list_entries.', jobinfo) + elseif s:async + if has('nvim') + let job = jobinfo.nvim_job + call neomake#log#debug(printf('Stopping Neovim job: %s.', job), jobinfo) + else + let job = jobinfo.vim_job + call neomake#log#debug(printf('Stopping Vim job: %s.', job), jobinfo) + endif + if has('nvim') + try + call jobstop(job) + let ret = 1 + catch /^Vim\%((\a\+)\)\=:\(E474\|E900\):/ + call neomake#log#info(printf( + \ 'jobstop failed: %s.', v:exception), jobinfo) + endtry + else + " Use ch_status here, since job_status might be 'dead' already, + " without the exit handler being called yet. + if job_status(job) !=# 'run' + call neomake#log#info( + \ 'job_stop: job was not running anymore.', jobinfo) + else + " NOTE: might be "dead" already, but that is fine. + call job_stop(job) + let ret = 1 + if job_status(job) ==# 'run' + let timer = timer_start(1000, function('s:kill_vimjob_cb')) + let s:kill_vim_timers[timer] = jobinfo + endif + endif + endif + endif + + if ret == 0 || remove_always + call s:CleanJobinfo(jobinfo) + endif + return ret +endfunction + +function! s:kill_vimjob_cb(timer) abort + let jobinfo = s:kill_vim_timers[a:timer] + let vim_job = jobinfo.vim_job + if job_status(vim_job) ==# 'run' + call neomake#log#debug('Forcefully killing still running Vim job.', jobinfo) + call job_stop(vim_job, 'kill') + endif + unlet s:kill_vim_timers[a:timer] +endfunction + +function! neomake#CancelJobs(bang) abort + call neomake#log#debug(printf('Canceling %d jobs.', len(s:jobs))) + for job in neomake#GetJobs() + call neomake#CancelJob(job.id, a:bang) + endfor +endfunction + +function! s:handle_get_list_entries(jobinfo, ...) abort + if !a:0 + return s:pcall('s:handle_get_list_entries', [a:jobinfo]) + endif + let jobinfo = a:jobinfo + let jobinfo.serialize = 0 + let maker = jobinfo.maker + try + let entries = maker.get_list_entries(jobinfo) + catch /^\%(Vim\%((\a\+)\)\=:\%(E48\|E523\)\)\@!/ " everything, but E48/E523 (sandbox / not allowed here) + if v:exception ==# 'NeomakeTestsException' + throw v:exception + endif + call neomake#log#exception(printf( + \ 'Error during get_list_entries for %s: %s.', + \ jobinfo.maker.name, v:exception), jobinfo) + call s:CleanJobinfo(jobinfo) + return g:neomake#action_queue#processed + endtry + + if type(entries) != type([]) + call neomake#log#error(printf('The get_list_entries method for maker %s did not return a list, but: %s.', jobinfo.maker.name, string(entries)[:100]), jobinfo) + elseif !empty(entries) && type(entries[0]) != type({}) + call neomake#log#error(printf('The get_list_entries method for maker %s did not return a list of dicts, but: %s.', jobinfo.maker.name, string(entries)[:100]), jobinfo) + else + call s:ProcessEntries(jobinfo, entries) + endif + call s:CleanJobinfo(jobinfo) + return g:neomake#action_queue#processed +endfunction + +function! s:MakeJob(make_id, options) abort + let job_id = s:job_id + let s:job_id += 1 + + " Optional: + " - serialize (default: 0 for async (and get_list_entries), + " 1 for non-async) + " - serialize_abort_on_error (default: 0) + " - exit_callback (string/function, default: 0) + let jobinfo = extend(deepcopy(g:neomake#jobinfo#base), extend({ + \ 'id': job_id, + \ 'make_id': a:make_id, + \ 'name': empty(get(a:options.maker, 'name', '')) ? 'neomake_'.job_id : a:options.maker.name, + \ 'maker': a:options.maker, + \ 'bufnr': a:options.bufnr, + \ 'file_mode': a:options.file_mode, + \ 'ft': a:options.ft, + \ 'cwd': s:make_info[a:make_id].cwd, + \ }, a:options)) + + let maker = jobinfo.maker + + if has_key(maker, 'get_list_entries') + call neomake#log#info(printf( + \ '%s: getting entries via get_list_entries.', + \ maker.name), jobinfo) + let s:jobs[jobinfo.id] = jobinfo + let s:make_info[a:make_id].active_jobs += [jobinfo] + call s:handle_get_list_entries(jobinfo) + return jobinfo + endif + + call extend(jobinfo, { + \ 'output_stream': a:options.maker.output_stream, + \ 'buffer_output': a:options.maker.buffer_output, + \ }, 'keep') + + let error = '' + try + " Change to job's cwd (before args, for relative filename). + let cd_error = jobinfo.cd() + if !empty(cd_error) + throw printf("Neomake: %s: could not change to maker's cwd (%s): %s.", + \ maker.name, jobinfo.cd_from_setting, cd_error) + endif + let jobinfo.argv = maker._get_argv(jobinfo) + + call neomake#utils#hook('NeomakeJobInit', {'jobinfo': jobinfo}) + + let start_msg = s:async ? 'Starting async job' : 'Starting' + if type(jobinfo.argv) == type('') + let start_msg .= ' [string]: '.jobinfo.argv + else + let start_msg .= ': '.join(map(copy(jobinfo.argv), 'neomake#utils#shellescape(v:val)')) + endif + call neomake#log#info(start_msg.'.', jobinfo) + + let cwd = jobinfo.cwd + let changed = !empty(jobinfo.cd_back_cmd) + if changed + call neomake#log#debug('cwd: '.cwd.' (changed).', jobinfo) + else + call neomake#log#debug('cwd: '.cwd.'.', jobinfo) + endif + + let base_job_opts = {} + if has_key(jobinfo, 'filename') + if s:can_use_env_in_job_opts + let base_job_opts = { + \ 'env': { + \ 'NEOMAKE_FILE': jobinfo.filename + \ }} + else + let save_env_file = exists('$NEOMAKE_FILE') ? $NEOMAKE_FILE : s:unset + let $NEOMAKE_FILE = jobinfo.filename + endif + endif + + " Lock maker to make sure it does not get changed accidentally, but + " only with depth=1, so that a postprocess object can change itself. + lockvar 1 maker + if s:async + if has('nvim') + if jobinfo.buffer_output + let opts = extend(base_job_opts, { + \ 'stdout_buffered': 1, + \ 'stderr_buffered': 1, + \ }) + if s:nvim_can_buffer_output == 1 + let opts.on_exit = function('s:nvim_exit_handler_buffered') + else + call extend(opts, { + \ 'on_stdout': function('s:nvim_output_handler'), + \ 'on_stderr': function('s:nvim_output_handler'), + \ }) + let opts.on_exit = function('s:nvim_exit_handler') + endif + let jobinfo.jobstart_opts = opts + else + let opts = { + \ 'on_stdout': function('s:nvim_output_handler'), + \ 'on_stderr': function('s:nvim_output_handler'), + \ 'on_exit': function('s:nvim_exit_handler'), + \ } + endif + if has_key(maker, 'nvim_job_opts') + call extend(opts, maker.nvim_job_opts) + endif + if !has('nvim-0.3.0') + \ && !neomake#utils#IsRunningWindows() + \ && !has_key(opts, 'detach') + \ && !has_key(opts, 'pty') + " Always use detach to trigger setsid() with older Neovim. + let opts.detach = 1 + endif + try + let job = jobstart(jobinfo.argv, opts) + catch + let error = printf('Failed to start Neovim job: %s: %s.', + \ string(jobinfo.argv), v:exception) + endtry + if empty(error) + if job == 0 + let error = printf('Failed to start Neovim job: %s: %s.', + \ 'Job table is full or invalid arguments given', string(jobinfo.argv)) + elseif job == -1 + let error = printf('Failed to start Neovim job: %s: %s.', + \ 'Executable not found', string(jobinfo.argv)) + else + let s:map_job_ids[job] = jobinfo.id + let jobinfo.nvim_job = job + let s:jobs[jobinfo.id] = jobinfo + + if get(jobinfo, 'uses_stdin', 0) + call jobsend(job, s:make_info[a:make_id].buffer_lines) + call jobclose(job, 'stdin') + endif + endif + endif + else + " vim-async. + let opts = extend(base_job_opts, { + \ 'out_cb': function('s:vim_output_handler_stdout'), + \ 'err_cb': function('s:vim_output_handler_stderr'), + \ 'close_cb': function('s:vim_exit_handler'), + \ 'mode': 'raw', + \ }) + if has_key(maker, 'vim_job_opts') + call extend(opts, maker.vim_job_opts) + endif + try + let job = job_start(jobinfo.argv, opts) + " Get this as early as possible! + let channel_id = ch_info(job)['id'] + catch + " NOTE: not covered in tests. Vim seems to always return + " a job. Might be able to trigger this using custom opts?! + let error = printf('Failed to start Vim job: %s: %s.', + \ jobinfo.argv, v:exception) + endtry + if empty(error) + let jobinfo.vim_job = job + let s:map_job_ids[channel_id] = jobinfo.id + let s:jobs[jobinfo.id] = jobinfo + call neomake#log#debug(printf('Vim job: %s.', + \ string(job_info(job))), jobinfo) + call neomake#log#debug(printf('Vim channel: %s.', + \ string(ch_info(job))), jobinfo) + + if get(jobinfo, 'uses_stdin', 0) + call ch_sendraw(job, join(s:make_info[a:make_id].buffer_lines, "\n")) + call ch_close_in(job) + endif + endif + endif + + " Bail out on errors. + if !empty(error) + throw 'Neomake: '.error + endif + + call neomake#utils#hook('NeomakeJobStarted', {'jobinfo': jobinfo}) + else + " vim-sync. + " Use a temporary file to capture stderr. + let stderr_file = tempname() + let argv = jobinfo.argv . ' 2>'.stderr_file + + try + if get(jobinfo, 'uses_stdin', 0) + " Pass stdin to system(), but only if non-empty. + " Otherwise it might cause E677 (vim74-trusty at least). + let stdin = join(s:make_info[a:make_id].buffer_lines, "\n") + if !empty(stdin) + let output = system(argv, stdin) + else + let output = system(argv) + endif + else + let output = system(argv) + endif + catch /^Vim(let):E484:/ + throw printf('Neomake: Could not run %s: %s.', argv, v:exception) + endtry + + let jobinfo.id = job_id + let s:jobs[job_id] = jobinfo + let s:make_info[a:make_id].active_jobs += [jobinfo] + + call s:output_handler(jobinfo, split(output, '\r\?\n', 1), 'stdout', 0) + let stderr_output = readfile(stderr_file) + if !empty(stderr_output) + call s:output_handler(jobinfo, stderr_output, 'stderr', 1) + endif + call delete(stderr_file) + + call s:exit_handler(jobinfo, v:shell_error) + return jobinfo + endif + finally + call jobinfo.cd_back() + if exists('save_env_file') + call s:restore_env('NEOMAKE_FILE', save_env_file) + endif + endtry + let s:make_info[a:make_id].active_jobs += [jobinfo] + return jobinfo +endfunction + +if !s:can_use_env_in_job_opts + function! s:restore_env(var, value) abort + " Cannot unlet environment vars without patch 8.0.1832. + exe printf('let $%s = %s', a:var, string(a:value is s:unset ? '' : a:value)) + endfunction +endif + +let s:command_maker_base = copy(g:neomake#core#command_maker_base) +" Check if a temporary file is used, and set it in s:make_info in case it is. +function! s:command_maker_base._get_tempfilename(jobinfo) abort dict + let l:Supports_stdin = neomake#utils#GetSetting('supports_stdin', self, s:unset_dict, a:jobinfo.ft, a:jobinfo.bufnr) + if Supports_stdin isnot s:unset_dict + if type(Supports_stdin) == type(function('tr')) + let supports_stdin = call(Supports_stdin, [a:jobinfo], self) + else + let supports_stdin = Supports_stdin + endif + if supports_stdin + let a:jobinfo.uses_stdin = 1 + return get(self, 'tempfile_name', '-') + endif + endif + + if has_key(self, 'tempfile_name') + return self.tempfile_name + endif + + let tempfile_enabled = neomake#utils#GetSetting('tempfile_enabled', self, 1, a:jobinfo.ft, a:jobinfo.bufnr) + if !tempfile_enabled + return '' + endif + + let make_id = a:jobinfo.make_id + if !has_key(s:make_info[make_id], 'tempfile_name') + if !exists('s:pid') + let s:pid = getpid() + endif + let slash = neomake#utils#Slash() + + let dir = neomake#utils#GetSetting('tempfile_dir', self, '', a:jobinfo.ft, a:jobinfo.bufnr) + + " Use absolute path internally, which is important for removal. + let orig_fname = neomake#utils#fnamemodify(a:jobinfo.bufnr, ':p') + if empty(dir) + if empty(orig_fname) + let dir = tempname() + else + let dir = fnamemodify(orig_fname, ':h') + if filewritable(dir) != 2 + let dir = tempname() + let s:make_info[make_id].tempfile_dir = dir + call neomake#log#debug('Using temporary directory for non-writable parent directory.') + endif + endif + + if empty(orig_fname) + let filename = 'neomaketmp.'.a:jobinfo.ft + else + let filename = fnamemodify(orig_fname, ':t') + \ .'@neomake_'.s:pid.'_'.make_id + let ext = fnamemodify(orig_fname, ':e') + if !empty(ext) + let filename .= '.'.ext + endif + " Use hidden files to make e.g. pytest not trying to import it. + if filename[0] !=# '.' + let filename = '.' . filename + endif + endif + else + let dir = neomake#utils#ExpandArgs([dir], a:jobinfo)[0] + if empty(orig_fname) + let filename = 'neomaketmp.'.a:jobinfo.ft + else + let filename = fnamemodify(orig_fname, ':t') + endif + endif + + let temp_file = dir . slash . filename + let s:make_info[make_id].tempfile_name = temp_file + endif + return s:make_info[make_id].tempfile_name +endfunction + +" Get the filename to use for a:jobinfo's make/buffer. +function! s:command_maker_base._get_fname_for_buffer(jobinfo) abort + let bufnr = a:jobinfo.bufnr + let bufname = bufname(bufnr) + let temp_file = '' + let _uses_stdin = neomake#utils#GetSetting('uses_stdin', a:jobinfo.maker, s:unset_dict, a:jobinfo.ft, bufnr) + if _uses_stdin isnot s:unset_dict + let a:jobinfo.uses_stdin = _uses_stdin + let uses_stdin = _uses_stdin + call neomake#log#debug(printf('Using uses_stdin (%s) from setting.', + \ a:jobinfo.uses_stdin), a:jobinfo) + if a:jobinfo.uses_stdin + let temp_file = neomake#utils#GetSetting('tempfile_name', a:jobinfo.maker, '-', a:jobinfo.ft, bufnr) + endif + else + if empty(bufname) + let temp_file = self._get_tempfilename(a:jobinfo) + if !get(a:jobinfo, 'uses_stdin', 0) && empty(temp_file) + throw 'Neomake: no file name.' + endif + let used_for = 'unnamed' + elseif getbufvar(bufnr, '&modified') + let temp_file = self._get_tempfilename(a:jobinfo) + if !get(a:jobinfo, 'uses_stdin', 0) && empty(temp_file) + throw 'Neomake: skip_job: buffer is modified, but temporary files are disabled.' + endif + let used_for = 'modified' + elseif !filereadable(bufname) + let temp_file = self._get_tempfilename(a:jobinfo) + if !get(a:jobinfo, 'uses_stdin', 0) && empty(temp_file) + " Using ':p' as modifier is unpredictable as per doc, but OK. + throw printf('Neomake: file is not readable (%s)', fnamemodify(bufname, ':p')) + endif + let used_for = 'unreadable' + else + let bufname = fnamemodify(bufname, ':.') + let used_for = '' + endif + + let uses_stdin = get(a:jobinfo, 'uses_stdin', 0) + + if !empty(used_for) + if uses_stdin + call neomake#log#debug(printf( + \ 'Using stdin for %s buffer (%s).', used_for, temp_file), + \ a:jobinfo) + elseif !empty(temp_file) + call neomake#log#debug(printf( + \ 'Using tempfile for %s buffer: "%s".', used_for, temp_file), + \ a:jobinfo) + endif + endif + endif + + let make_info = s:make_info[a:jobinfo.make_id] + " Handle stdin when supports_stdin sets self.tempfile_name = ''. + if uses_stdin + if !has_key(make_info, 'buffer_lines') + let make_info.buffer_lines = neomake#utils#get_buffer_lines(bufnr) + endif + let bufname = temp_file + elseif !empty(temp_file) + " Use relative path for args. + let bufname = fnamemodify(temp_file, ':.') + let temp_file = fnamemodify(temp_file, ':p') + if !has_key(make_info, 'tempfiles') + let make_info.tempfiles = [temp_file] + let make_info.created_dirs = s:create_dirs_for_file(temp_file) + call neomake#utils#write_tempfile(bufnr, temp_file) + elseif temp_file !=# make_info.tempfiles[0] + call extend(make_info.created_dirs, s:create_dirs_for_file(temp_file)) + call writefile(readfile(make_info.tempfiles[0], 'b'), temp_file, 'b') + call add(make_info.tempfiles, temp_file) + endif + let a:jobinfo.tempfile = temp_file + endif + + let a:jobinfo.filename = bufname + return bufname +endfunction + +function! s:create_dirs_for_file(fpath) abort + let created_dirs = [] + let last_dir = a:fpath + while 1 + let temp_dir = fnamemodify(last_dir, ':h') + if isdirectory(temp_dir) || last_dir ==# temp_dir + break + endif + call insert(created_dirs, temp_dir) + let last_dir = temp_dir + endwhile + for dir in created_dirs + call mkdir(dir, '', 0700) + endfor + return created_dirs +endfunction + +function! s:command_maker_base._bind_args() abort dict + " Resolve args, which might be a function or dictionary. + if type(self.args) == type(function('tr')) + " Deprecated: use InitForJob + call neomake#log#warn_once(printf("Please use 'InitForJob' instead of 'args' for maker %s.", self.name), + \ printf('deprecated-args-%s', self.name)) + let args = call(self.args, []) + elseif type(self.args) == type({}) + " Deprecated: use InitForJob + call neomake#log#warn_once(printf("Please use 'InitForJob' instead of 'args.fn' for maker %s.", self.name), + \ printf('deprecated-args-fn-%s', self.name)) + let args = call(self.args.fn, [], self.args) + else + let args = copy(self.args) + endif + let self.args = args + return self +endfunction + +function! s:command_maker_base._get_argv(jobinfo) abort dict + let filename = self._get_fname_for_args(a:jobinfo) + let args_is_list = type(self.args) == type([]) + if args_is_list + let args = neomake#utils#ExpandArgs(self.args, a:jobinfo) + if !empty(filename) + call add(args, filename) + endif + elseif !empty(filename) + let args = copy(self.args) + let args .= (empty(args) ? '' : ' ').neomake#utils#shellescape(filename) + else + let args = self.args + endif + return neomake#compat#get_argv(self.exe, args, args_is_list) +endfunction + +function! s:GetMakerForFiletype(ft, maker_name) abort + for config_ft in neomake#utils#get_config_fts(a:ft) + call neomake#utils#load_ft_makers(config_ft) + let f = 'neomake#makers#ft#'.config_ft.'#'.a:maker_name + if exists('*'.f) + let maker = call(f, []) + return maker + endif + endfor + return s:unset_dict +endfunction + +function! neomake#get_maker_by_name(maker_name, ...) abort + let for_ft = a:0 ? a:1 : 0 + let ft_config = for_ft is# 0 ? &filetype : for_ft + let bufnr = bufnr('%') + if a:maker_name !~# '\v^\w+$' + throw printf('Neomake: Invalid maker name: "%s"', a:maker_name) + endif + + let maker = neomake#utils#GetSetting('maker', {'name': a:maker_name}, s:unset_dict, ft_config, bufnr) + if maker is# s:unset_dict + if a:maker_name ==# 'makeprg' + let maker = s:get_makeprg_maker() + elseif for_ft isnot# 0 + let maker = s:GetMakerForFiletype(for_ft, a:maker_name) + else + call neomake#utils#load_global_makers() + let f = 'neomake#makers#'.a:maker_name.'#'.a:maker_name + if exists('*'.f) + let maker = call(f, []) + endif + endif + endif + if type(maker) != type({}) + throw printf('Neomake: Got non-dict for maker %s: %s', + \ a:maker_name, maker) + endif + if maker isnot# s:unset_dict && !has_key(maker, 'name') + let maker.name = a:maker_name + endif + return maker +endfunction + +function! neomake#GetMaker(name_or_maker, ...) abort + let for_ft = a:0 ? a:1 : 0 + if type(a:name_or_maker) == type({}) + let maker = a:name_or_maker + if !has_key(maker, 'name') + let maker.name = 'unnamed_maker' + endif + else + let maker = neomake#get_maker_by_name(a:name_or_maker, for_ft) + if maker is# s:unset_dict + if !a:0 + " Check &filetype if no args where provided. + let maker = neomake#get_maker_by_name(a:name_or_maker, &filetype) + endif + endif + if maker is# s:unset_dict + if for_ft isnot# 0 + throw printf('Neomake: Maker not found (for %s): %s', + \ !empty(for_ft) ? 'filetype '.for_ft : 'empty filetype', + \ a:name_or_maker) + else + throw printf('Neomake: Maker not found (without filetype): %s', + \ a:name_or_maker) + endif + endif + endif + return neomake#create_maker_object(maker, a:0 ? a:1 : &filetype) +endfunction + +" NOTE: uses ft and bufnr for config only. +function! neomake#create_maker_object(maker, ft) abort + let [maker, ft, bufnr] = [a:maker, a:ft, bufnr('%')] + + " Create the maker object. + let l:GetEntries = neomake#utils#GetSetting('get_list_entries', maker, -1, ft, bufnr) + if GetEntries isnot# -1 + let maker = copy(maker) + let maker.get_list_entries = GetEntries + else + let maker = extend(copy(s:command_maker_base), copy(maker)) + endif + if !has_key(maker, 'get_list_entries') + " Set defaults for command/job based makers. + let defaults = extend( + \ copy(g:neomake#config#_defaults['maker_defaults']), + \ neomake#config#get('maker_defaults')) + call extend(defaults, { + \ 'exe': maker.name, + \ 'args': [], + \ }) + if !has_key(maker, 'process_output') && !has_key(maker, 'process_json') + call extend(defaults, { + \ 'errorformat': &errorformat, + \ }) + endif + for [key, default] in items(defaults) + let maker[key] = neomake#utils#GetSetting(key, {'name': maker.name}, get(maker, key, default), ft, bufnr, 1) + unlet default " for Vim without patch-7.4.1546 + endfor + endif + if v:profiling + call add(s:hack_keep_refs_for_profiling, maker) + endif + return maker +endfunction + +if exists('*getcompletion') + function! s:get_makers_for_pattern(pattern) abort + " Get function prefix based on pattern, until the first backslash. + let prefix = substitute(a:pattern, '\v\\.*', '', '') + + " NOTE: the pattern uses &ignorecase. + let funcs = getcompletion(prefix.'[a-z]', 'function') + call filter(funcs, 'v:val =~# a:pattern') + " Remove prefix. + call map(funcs, 'v:val['.len(prefix).':]') + " Only keep lowercase function names. + call filter(funcs, "v:val =~# '\\m^[a-z].*('") + " Remove parenthesis and #.* (for project makers). + return sort(map(funcs, "substitute(v:val, '\\v[(#].*', '', '')")) + endfunction +else + function! s:get_makers_for_pattern(pattern) abort + let funcs_output = neomake#utils#redir('fun /'.a:pattern) + return sort(map(split(funcs_output, '\n'), + \ "substitute(v:val, '\\v^.*#(.*)\\(.*$', '\\1', '')")) + endfunction +endif + +function! neomake#GetMakers(ft) abort + " Get all makers for a given filetype. This is used from completion. + " XXX: this should probably use a callback or some other more stable + " approach to get the list of makers (than looking at the lowercase + " functions)?! + + let makers = [] + " Do not use 'b:neomake_jsx_javascript_foo_maker' twice for + " ft=jsx.javascript. + let used_vars = [] + for ft in neomake#utils#get_config_fts(a:ft) + call neomake#utils#load_ft_makers(ft) + + " Add sorted list per filetype. + let add = [] + + let maker_names = s:get_makers_for_pattern('neomake#makers#ft#'.ft.'#\l') + for maker_name in maker_names + if index(makers, maker_name) == -1 && index(add, maker_name) == -1 + let add += [maker_name] + endif + endfor + + " Get makers from g:/b: variables. + for v in sort(extend(keys(g:), keys(b:))) + if index(used_vars, v) != -1 + continue + endif + let maker_name = matchstr(v, '\v^neomake_'.ft.'_\zs[0-9a-z_]+\ze_maker$') + if !empty(maker_name) + \ && index(makers, maker_name) == -1 + \ && index(add, maker_name) == -1 + let used_vars += [v] + let add += [maker_name] + endif + endfor + + " Get makers from new-style config. + for [maker_name, val] in items(neomake#config#get('ft.'.ft)) + if has_key(val, 'maker') + \ && index(makers, maker_name) == -1 + \ && index(add, maker_name) == -1 + let add += [maker_name] + endif + endfor + + call sort(add) + call extend(makers, add) + endfor + return makers +endfunction + +function! neomake#GetProjectMakers() abort + call neomake#utils#load_global_makers() + return s:get_makers_for_pattern('neomake#makers#\(ft#\)\@!\l') +endfunction + +function! neomake#GetEnabledMakers(...) abort + let file_mode = a:0 + if !file_mode + " If we have no filetype, use the global default makers. + " This variable is also used for project jobs, so it has no + " buffer local ('b:') counterpart for now. + let enabled_makers = copy(get(g:, 'neomake_enabled_makers', [])) + if empty(enabled_makers) + let makeprg_maker = s:get_makeprg_maker() + if !empty(makeprg_maker) + let makeprg_maker = neomake#GetMaker(makeprg_maker) + let makeprg_maker.auto_enabled = 1 + let enabled_makers = [makeprg_maker] + endif + else + call map(enabled_makers, "extend(neomake#GetMaker(v:val), + \ {'auto_enabled': 0}, 'error')") + endif + else + let enabled_makers = [] + let bufnr = bufnr('%') + let makers = neomake#utils#GetSetting('enabled_makers', {}, s:unset_list, a:1, bufnr) + if makers is# s:unset_list + let auto_enabled = 1 + for config_ft in neomake#utils#get_config_fts(a:1) + call neomake#utils#load_ft_makers(config_ft) + let fnname = 'neomake#makers#ft#'.config_ft.'#EnabledMakers' + if exists('*'.fnname) + try + let makers = call(fnname, []) + catch /^Vim(let):E119:/ " Not enough arguments for function + let makers = call(fnname, [{'file_mode': file_mode, 'bufnr': bufnr}]) + endtry + break + endif + endfor + else + let auto_enabled = 0 + endif + + let makers = neomake#map_makers(makers, a:1, auto_enabled) + for maker in makers + let maker.auto_enabled = auto_enabled + let enabled_makers += [maker] + endfor + endif + return enabled_makers +endfunction + +" a:1: override "open_list" setting. +function! s:HandleLoclistQflistDisplay(jobinfo, loc_or_qflist, ...) abort + let open_list_default = a:0 ? a:1 : 0 + let open_val = neomake#utils#GetSetting('open_list', a:jobinfo.maker, open_list_default, a:jobinfo.ft, a:jobinfo.bufnr) + if !open_val + return + endif + let height = neomake#utils#GetSetting('list_height', a:jobinfo.maker, 10, a:jobinfo.ft, a:jobinfo.bufnr) + if !height + return + endif + let height = min([len(a:loc_or_qflist), height]) + if a:jobinfo.file_mode + call neomake#log#debug('Handling location list: executing lwindow.', a:jobinfo) + let cmd = 'lwindow' + else + call neomake#log#debug('Handling quickfix list: executing cwindow.', a:jobinfo) + let cmd = 'botright cwindow' + endif + if open_val == 2 + let make_id = a:jobinfo.make_id + let make_info = s:make_info[make_id] + let g:neomake#core#_ignore_autocommands += 1 + try + call neomake#compat#save_prev_windows() + + let win_count = winnr('$') + exe cmd height + let new_win_count = winnr('$') + if win_count == new_win_count + " No new window, adjust height eventually. + let found = 0 + + if get(make_info, '_did_lwindow', 0) + for w in range(1, winnr('$')) + if getwinvar(w, 'neomake_window_for_make_id') == make_id + let found = w + break + endif + endfor + if found + let cmd = printf('%dresize %d', found, height) + if winheight(found) != height + call neomake#log#debug(printf( + \ 'Resizing existing quickfix window: %s.', + \ cmd), a:jobinfo) + exe cmd + endif + else + call neomake#log#debug( + \ 'Could not find corresponding quickfix window.', + \ a:jobinfo) + endif + endif + elseif new_win_count > win_count + if &filetype !=# 'qf' + call neomake#log#debug(printf( + \ 'WARN: unexpected filetype for new window: %s', + \ &filetype), a:jobinfo) + else + call neomake#log#debug(printf( + \ 'list window has been opened (old count: %d, new count: %d, height: %d).', + \ win_count, new_win_count, winheight(0)), a:jobinfo) + let w:neomake_window_for_make_id = a:jobinfo.make_id + endif + else + call neomake#log#debug(printf( + \ 'list window has been closed (old count: %d, new count: %d).', + \ win_count, new_win_count), a:jobinfo) + endif + call neomake#compat#restore_prev_windows() + let make_info._did_lwindow = 1 + finally + let g:neomake#core#_ignore_autocommands -= 1 + endtry + else + exe cmd height + endif +endfunction + +" Experimental/private wrapper. +function! neomake#_handle_list_display(jobinfo, ...) abort + if a:0 + let list = a:1 + else + let list = a:jobinfo.file_mode ? getloclist(0) : getqflist() + endif + call s:HandleLoclistQflistDisplay(a:jobinfo, list, 2) +endfunction + +" Get a maker for &makeprg. +" This could be cached, but needs to take into account / set &errorformat, +" and other settings that are handled by neomake#GetMaker. +function! s:get_makeprg_maker() abort + if empty(&makeprg) + return {} + elseif &makeprg =~# '\s' + let maker = neomake#utils#MakerFromCommand(&makeprg) + else + let maker = neomake#utils#MakerFromCommand([&makeprg]) + endif + let maker.name = 'makeprg' + " Do not append file. &makeprg should contain %/# for this instead. + let maker.append_file = 0 + return neomake#GetMaker(maker) +endfunction + +function! s:Make(options) abort + let is_automake = get(a:options, 'automake', !empty(expand('<abuf>'))) + if is_automake + if g:neomake#core#_ignore_autocommands + call neomake#log#debug(printf( + \ 'Ignoring Make through autocommand due to ignore_autocommands=%d.', g:neomake#core#_ignore_autocommands), {'winnr': winnr()}) + return [] + endif + let disabled = neomake#config#get_with_source('disabled', 0) + if disabled[0] + call neomake#log#debug(printf( + \ 'Make through autocommand disabled via %s.', disabled[1])) + return [] + endif + endif + + let s:make_id += 1 + let make_id = s:make_id + let options = extend(copy(a:options), { + \ 'file_mode': 1, + \ 'ft': &filetype, + \ }, 'keep') + let options.make_id = make_id " Deprecated. + let file_mode = options.file_mode + + " Require winid/winnr with non-current buffer in file_mode. + if has_key(options, 'bufnr') + if options.bufnr != bufnr('%') + if !has_key(options, 'winid') && !has_key(options, 'winnr') + throw 'Neomake: winid or winnr are required for non-current buffer.' + endif + endif + if !bufexists(options.bufnr) + throw printf('Neomake: buffer %d does not exist.', options.bufnr) + endif + else + let options.bufnr = bufnr('%') + endif + + " Validate winid/winnr (required for location list windows). + let file_mode_win = 0 + if file_mode + if has_key(options, 'winid') + if win_id2tabwin(options.winid) == [0, 0] + throw printf('Neomake: window id %d does not exist.', options.winid) + endif + let file_mode_win = options.winid + elseif has_key(options, 'winnr') + if winbufnr(options.winnr) == -1 + throw printf('Neomake: window %d does not exist.', options.winnr) + endif + let file_mode_win = options.winnr + elseif exists('*win_getid') + let options.winid = win_getid() + endif + elseif has_key(options, 'winid') + throw 'Neomake: do not use winid with file_mode=0.' + elseif has_key(options, 'winnr') + throw 'Neomake: do not use winnr with file_mode=0.' + endif + + lockvar 1 options + let s:make_info[make_id] = { + \ 'make_id': make_id, + \ 'cwd': getcwd(), + \ 'verbosity': get(g:, 'neomake_verbose', 1), + \ 'active_jobs': [], + \ 'finished_jobs': [], + \ 'options': options, + \ } + let make_info = s:make_info[make_id] + let bufnr = options.bufnr + if &verbose + let make_info.verbosity += &verbose + call neomake#log#debug(printf( + \ 'Adding &verbose (%d) to verbosity level: %d.', + \ &verbose, make_info.verbosity), make_info) + endif + if make_info.verbosity >= 3 + call neomake#log#debug(printf( + \ 'Calling Make with options %s.', + \ string(filter(copy(options), "index(['bufnr', 'make_id'], v:key) == -1"))), {'make_id': make_id, 'bufnr': bufnr}) + endif + + " Use pre-compiled jobs (used with automake). + if has_key(options, 'jobs') + let jobs = map(copy(options.jobs), "extend(v:val, {'make_id': make_id})") + else + if has_key(options, 'enabled_makers') + if file_mode + let makers = neomake#map_makers(options.enabled_makers, options.ft, 0) + else + let makers = neomake#map_makers(options.enabled_makers, -1, 0) + endif + else + let makers = call('neomake#GetEnabledMakers', file_mode ? [options.ft] : []) + if empty(makers) + if file_mode + let msg = printf('Nothing to make: no enabled file mode makers (filetype=%s).', options.ft) + if is_automake + call neomake#log#debug(msg, make_info) + else + call neomake#log#warning(msg, make_info) + endif + unlet s:make_info[make_id] + return [] + endif + endif + endif + let job_options = copy(options) + let job_options.make_id = make_id " Used for logging. + let jobs = neomake#core#create_jobs(job_options, makers) + endif + + if empty(jobs) + call neomake#log#debug('Nothing to make: no valid makers.', make_info) + call s:clean_make_info(make_info) + return [] + endif + let make_info.jobs = copy(jobs) + + let maker_info = join(map(copy(jobs), + \ "v:val.maker.name . (get(v:val.maker, 'auto_enabled', 0) ? ' (auto)' : '')"), ', ') + call neomake#log#debug(printf('Running makers: %s.', maker_info), make_info) + + let make_info.jobs_queue = jobs + + if file_mode + " XXX: this clears counts for job's buffer only, but we add counts for + " the entry's buffers, which might be different! + call neomake#statusline#ResetCountsForBuf(bufnr) + if g:neomake_place_signs + call neomake#signs#Reset(bufnr, 'file') + endif + else + call neomake#statusline#ResetCountsForProject() + if g:neomake_place_signs + call neomake#signs#ResetProject() + endif + endif + + " Store make_id on window (used to find window for location lists (without + " winid, but also used to check the current window via w: directly)). + if file_mode + call setwinvar(file_mode_win, 'neomake_make_ids', + \ neomake#compat#getwinvar(file_mode_win, 'neomake_make_ids', []) + [make_id]) + endif + + let use_list = get(options, 'use_list', 1) + if use_list + let any_job_uses_list = 0 + for job in jobs + if get(job.maker, 'use_list', 1) + let any_job_uses_list = 1 + break + endif + endfor + if !any_job_uses_list + let use_list = 0 + endif + endif + + if use_list + let make_info.entries_list = neomake#list#ListForMake(make_info) + + " Reuse existing location list window with automake. + if is_automake && has('patch-7.4.2200') + if file_mode + let title = get(getloclist(0, {'title': 1}), 'title') + else + let title = get(getqflist({'title': 1}), 'title') + endif + if title =~# '\V\^Neomake[auto]' + let make_info.entries_list.reset_existing_qflist = 1 + endif + endif + endif + + " Cancel any already running jobs for the makers from these jobs. + if !empty(s:jobs) + " @vimlint(EVL102, 1, l:job) + for job in jobs + let running_already = values(filter(copy(s:jobs), + \ 'v:val.maker == job.maker' + \ .' && v:val.bufnr == job.bufnr' + \ .' && v:val.file_mode == job.file_mode' + \ ." && !get(v:val, 'canceled')")) + if !empty(running_already) + let jobinfo = running_already[0] + call neomake#log#info(printf( + \ 'Canceling already running job (%d.%d) for the same maker.', + \ jobinfo.make_id, jobinfo.id), {'make_id': make_id}) + call neomake#CancelJob(jobinfo.id, 1) + endif + endfor + endif + + " Update automake tick (used to skip unchanged buffers). + call neomake#configure#_update_automake_tick(bufnr, options.ft) + + " Start all jobs in the queue (until serialized). + let jobinfos = [] + while 1 + if empty(make_info.jobs_queue) + break + endif + let jobinfo = s:handle_next_job({}) + if empty(jobinfo) + break + endif + call add(jobinfos, jobinfo) + if jobinfo.serialize + let make_info.serializing_for_job = jobinfo.id + " Break and continue through exit handler. + break + endif + endwhile + return jobinfos +endfunction + +function! s:AddExprCallback(jobinfo, lines) abort + if s:need_to_postpone_loclist(a:jobinfo) + return neomake#action_queue#add(['BufEnter', 'WinEnter'], [s:function('s:AddExprCallback'), + \ [a:jobinfo, a:lines] + a:000]) + endif + + " Create location/quickfix list and add lines to it. + let cd_error = a:jobinfo.cd() + if !empty(cd_error) + call neomake#log#debug(printf( + \ "Could not change to job's cwd (%s): %s.", + \ a:jobinfo.cd_from_setting, cd_error), a:jobinfo) + endif + + let make_list = s:make_info[a:jobinfo.make_id].entries_list + let prev_list = copy(make_list.entries) + + let added_entries = make_list.add_lines_with_efm(a:lines, a:jobinfo) + return s:ProcessEntries(a:jobinfo, added_entries, prev_list) +endfunction + +function! s:CleanJobinfo(jobinfo, ...) abort + if get(a:jobinfo, '_in_exit_handler', 0) + " Do not clean job yet. + return + endif + if !empty(a:jobinfo.pending_output) && !get(a:jobinfo, 'canceled', 0) + call neomake#log#debug( + \ 'Output left to be processed, not cleaning job yet.', a:jobinfo) + return g:neomake#action_queue#not_processed + endif + + let queued_actions = neomake#action_queue#get_queued_actions(a:jobinfo) + if !empty(queued_actions) + call neomake#log#debug(printf( + \ 'Skipping cleaning of job info because of queued actions: %s.', + \ join(queued_actions, ', ')), a:jobinfo) + return neomake#action_queue#add(['WinEnter'], [s:function('s:CleanJobinfo'), [a:jobinfo]]) + endif + + call neomake#log#debug('Cleaning jobinfo.', a:jobinfo) + let a:jobinfo.finished = 1 + + if !has_key(s:make_info, a:jobinfo.make_id) + return g:neomake#action_queue#processed + endif + let make_info = s:make_info[a:jobinfo.make_id] + + if has_key(s:jobs, get(a:jobinfo, 'id', -1)) + call remove(s:jobs, a:jobinfo.id) + call filter(s:map_job_ids, 'v:val != a:jobinfo.id') + endif + + if exists('s:kill_vim_timers') + for [timer, job] in items(s:kill_vim_timers) + if job == a:jobinfo + call timer_stop(+timer) + unlet s:kill_vim_timers[timer] + break + endif + endfor + endif + + if !get(a:jobinfo, 'canceled', 0) + \ && !get(a:jobinfo, 'failed_to_start', 0) + let make_info.finished_jobs += [a:jobinfo] + call neomake#utils#hook('NeomakeJobFinished', {'jobinfo': a:jobinfo}) + endif + + call filter(make_info.active_jobs, 'v:val != a:jobinfo') + + " Trigger cleanup (and autocommands) if all jobs have finished. + if empty(make_info.active_jobs) && empty(make_info.jobs_queue) + call s:clean_make_info(make_info) + endif + return g:neomake#action_queue#processed +endfunction + +function! s:clean_make_info(make_info, ...) abort + let make_id = a:make_info.make_id + let bang = a:0 ? a:1 : 0 + if !bang && !empty(a:make_info.active_jobs) + call neomake#log#debug(printf( + \ 'Skipping cleaning of make info: %d active jobs: %s.', + \ len(a:make_info.active_jobs), + \ string(map(copy(a:make_info.active_jobs), 'v:val.as_string()'))), + \ a:make_info) + return + endif + + " Queue cleanup in case of queued actions, e.g. NeomakeJobFinished hook. + let queued = [] + for [_, v] in g:neomake#action_queue#_s.action_queue + if has_key(v[1][0], 'id') + let jobinfo = v[1][0] + if jobinfo.make_id == make_id + let queued += ['job '.jobinfo.id] + endif + else + if v[1][0] == a:make_info + let queued += ['make '.make_id] + endif + endif + endfor + if !empty(queued) + call neomake#log#debug(printf('Queuing clean_make_info for already queued actions: %s', string(queued))) + return neomake#action_queue#add( + \ g:neomake#action_queue#any_event, + \ [s:function('s:clean_make_info'), [a:make_info]]) + endif + + if exists('*neomake#statusline#make_finished') + call neomake#statusline#make_finished(a:make_info) + endif + + if !empty(a:make_info.finished_jobs) + " Clean old signs after all jobs have finished, so that they can be + " reused, avoiding flicker and keeping them for longer in general. + if g:neomake_place_signs + if a:make_info.options.file_mode + call neomake#signs#CleanOldSigns(a:make_info.options.bufnr, 'file') + else + call neomake#signs#CleanAllOldSigns('project') + endif + endif + call s:clean_for_new_make(a:make_info) + + call neomake#EchoCurrentError(1) + call neomake#virtualtext#handle_current_error() + + if get(a:make_info, 'canceled', 0) + call neomake#log#debug('Skipping final processing for canceled make.', a:make_info) + call s:do_clean_make_info(a:make_info) + elseif has_key(a:make_info, 'entries_list') " use_list option + return s:handle_locqf_list_for_finished_jobs(a:make_info) + else + call s:handle_finished_make(a:make_info) + endif + else + call s:do_clean_make_info(a:make_info) + endif + return g:neomake#action_queue#processed +endfunction + +function! s:do_clean_make_info(make_info) abort + call neomake#log#debug('Cleaning make info.', a:make_info) + let make_id = a:make_info.make_id + + " Remove make_id from its window. + let [t, w] = neomake#core#get_tabwin_for_makeid(make_id) + if [t, w] != [-1, -1] + let make_ids = neomake#compat#gettabwinvar(t, w, 'neomake_make_ids', []) + let idx = index(make_ids, make_id) + if idx != -1 + call remove(make_ids, idx) + call settabwinvar(t, w, 'neomake_make_ids', make_ids) + endif + endif + + " Clean up temporary files and buffers. + let wipe_unlisted_buffers = get(a:make_info, '_wipe_unlisted_buffers', []) + let tempfiles = get(a:make_info, 'tempfiles') + if !empty(tempfiles) + for tempfile in tempfiles + let delete_ret = delete(tempfile) + if delete_ret == 0 + call neomake#log#debug(printf('Removing temporary file: "%s".', + \ tempfile)) + else + call neomake#log#warning(printf('Failed to remove temporary file: "%s" (%d).', + \ tempfile, delete_ret)) + endif + let bufnr_tempfile = bufnr(tempfile) + if bufnr_tempfile != -1 && !buflisted(bufnr_tempfile) + let wipe_unlisted_buffers += [bufnr_tempfile] + endif + endfor + + " Only delete the dir, if Vim supports it. + if v:version >= 705 || (v:version == 704 && has('patch1107')) + for dir in reverse(copy(get(a:make_info, 'created_dirs'))) + call delete(dir, 'd') + endfor + endif + endif + if !empty(wipe_unlisted_buffers) + if !empty(wipe_unlisted_buffers) + call neomake#compat#uniq(sort(wipe_unlisted_buffers)) + endif + call neomake#log#debug(printf('Wiping out %d unlisted/remapped buffers: %s.', + \ len(wipe_unlisted_buffers), + \ string(wipe_unlisted_buffers))) + " NOTE: needs to be silent with more than a single buffer. + exe 'silent bwipeout '.join(wipe_unlisted_buffers) + endif + + let buf_prev_makes = getbufvar(a:make_info.options.bufnr, '_neomake_automake_make_ids') + if !empty(buf_prev_makes) + call filter(buf_prev_makes, 'v:val != make_id') + call setbufvar(a:make_info.options.bufnr, '_neomake_automake_make_ids', buf_prev_makes) + endif + + unlet s:make_info[make_id] +endfunction + +function! s:handle_locqf_list_for_finished_jobs(make_info) abort + let file_mode = a:make_info.options.file_mode + let create_list = a:make_info.entries_list.need_init + + let open_val = get(g:, 'neomake_open_list', 0) + let height = open_val ? get(g:, 'neomake_list_height', 10) : 0 + if height + let close_list = create_list || empty(file_mode ? getloclist(0) : getqflist()) + else + let close_list = 0 + endif + + if file_mode + if create_list && !bufexists(a:make_info.options.bufnr) + call neomake#log#info('No buffer found for location list!', a:make_info) + let create_list = 0 + let close_list = 0 + elseif (create_list || close_list) + if index(get(w:, 'neomake_make_ids', []), a:make_info.make_id) == -1 + call neomake#log#debug( + \ 'Postponing final location list handling (in another window).', + \ a:make_info) + return neomake#action_queue#add(['WinEnter'], [s:function('s:handle_locqf_list_for_finished_jobs'), + \ [a:make_info] + a:000]) + endif + + " TODO: merge with s:need_to_postpone_output_processing. + if neomake#compat#in_completion() + call neomake#log#debug( + \ 'Postponing final location list handling during completion.', + \ a:make_info) + return neomake#action_queue#add(['CompleteDone'], [s:function('s:handle_locqf_list_for_finished_jobs'), + \ [a:make_info] + a:000]) + endif + let mode = neomake#compat#get_mode() + if index(['n', 'i'], mode) == -1 + call neomake#log#debug(printf( + \ 'Postponing final location list handling for mode "%s".', mode), + \ a:make_info) + return neomake#action_queue#add(['CursorHold', 'WinEnter'], [s:function('s:handle_locqf_list_for_finished_jobs'), + \ [a:make_info] + a:000]) + endif + endif + endif + + " Update list title. + " This has to be done currently by itself to reflect running/finished + " state properly. + if create_list || !a:make_info.entries_list.need_init + if has_key(a:make_info, 'entries_list') + call a:make_info.entries_list.finish_for_make() + endif + endif + + " Close empty list. + if close_list + if file_mode + call neomake#log#debug('Handling location list: executing lclose.', {'winnr': winnr()}) + lclose + else + call neomake#log#debug('Handling quickfix list: executing cclose.') + cclose + endif + endif + + call s:handle_finished_make(a:make_info) + + return g:neomake#action_queue#processed +endfunction + +function! s:handle_finished_make(make_info) abort + let hook_context = { + \ 'make_info': a:make_info, + \ 'make_id': a:make_info.make_id, + \ 'options': a:make_info.options, + \ 'finished_jobs': a:make_info.finished_jobs, + \ } + call neomake#utils#hook('NeomakeFinished', hook_context) + + call neomake#configure#_reset_automake_cancelations(a:make_info.options.bufnr) + + call s:do_clean_make_info(a:make_info) +endfunction + +function! neomake#VimLeave() abort + call neomake#log#debug('Calling VimLeave.') + for make_id in keys(s:make_info) + call neomake#CancelMake(make_id) + endfor +endfunction + +function! s:clean_for_new_make(make_info) abort + if get(a:make_info, 'cleaned_for_make', 0) + return + endif + " XXX: needs to handle buffers for list entries?! + " See "get_list_entries: minimal example (from doc)" in + " tests/makers.vader. + call neomake#_clean_errors(extend(copy(a:make_info.options), {'make_id': a:make_info.make_id})) + let a:make_info.cleaned_for_make = 1 +endfunction + +" a:context: dictionary with keys: +" - file_mode +" - bufnr (required for file_mode) +" - make_id (used for logging) +function! neomake#_clean_errors(context) abort + if a:context.file_mode + let bufnr = a:context.bufnr + if has_key(s:current_errors['file'], bufnr) + unlet s:current_errors['file'][bufnr] + endif + call neomake#highlights#ResetFile(bufnr) + call neomake#log#debug('File-level errors cleaned.', a:context) + else + let s:current_errors['project'] = {} + call neomake#highlights#ResetProject() + call neomake#log#debug('Project-level errors cleaned.', a:context) + endif +endfunction + +" Change to a job's cwd, if any. +" Returns: a list: +" - error (empty for success) +" - directory changed into (empty if skipped) +" - command to change back to the current workding dir (might be empty) + +" Call a:fn with a:args and queue it, in case if fails with E48/E523. +function! s:pcall(fn, args) abort + let jobinfo = a:args[0] + try + return call(a:fn, a:args + [1]) + catch /^\%(Vim\%((\a\+)\)\=:\%(E48\|E523\)\)/ " only E48/E523 (sandbox / not allowed here) + call neomake#log#debug('Error during pcall: '.v:exception.'.', jobinfo) + call neomake#log#debug(printf('(in %s)', v:throwpoint), jobinfo) + " Might throw in case of X failed attempts. + call neomake#action_queue#add(['Timer', 'WinEnter'], [s:function(a:fn), a:args]) + endtry + return g:neomake#action_queue#not_processed +endfunction + +function! s:ProcessEntries(jobinfo, entries, ...) abort + if empty(a:entries) + return + endif + if get(a:jobinfo, 'canceled') + return + endif + if s:need_to_postpone_loclist(a:jobinfo) + return neomake#action_queue#add(['BufEnter', 'WinEnter'], [s:function('s:ProcessEntries'), + \ [a:jobinfo, a:entries] + a:000]) + endif + if !a:0 || type(a:[len(a:000)]) != 0 + return s:pcall('s:ProcessEntries', [a:jobinfo, a:entries] + a:000) + endif + let file_mode = a:jobinfo.file_mode + + call neomake#log#debug(printf( + \ 'Processing %d entries.', len(a:entries)), a:jobinfo) + + let make_info = s:make_info[a:jobinfo.make_id] + let make_list = make_info.entries_list + let maker_name = a:jobinfo.maker.name + if a:0 > 1 + " Via errorformat processing, where the list has been set already. + let prev_list = a:1 + let parsed_entries = a:entries + else + " Fix entries with get_list_entries/process_output/process_json. + " @vimlint(EVL102, 1, l:default_type) + let default_type = neomake#utils#GetSetting('default_entry_type', a:jobinfo.maker, 'W', a:jobinfo.ft, a:jobinfo.bufnr) + call map(a:entries, 'extend(v:val, {' + \ . "'bufnr': str2nr(get(v:val, 'bufnr', 0))," + \ . "'lnum': str2nr(get(v:val, 'lnum', 0))," + \ . "'col': str2nr(get(v:val, 'col', 0))," + \ . "'vcol': str2nr(get(v:val, 'vcol', 0))," + \ . "'type': get(v:val, 'type', default_type)," + \ . "'nr': get(v:val, 'nr', has_key(v:val, 'text') ? -1 : 0)," + \ . "'text': get(v:val, 'text', '')," + \ . '})') + + let cd_error = a:jobinfo.cd() + if !empty(cd_error) + call neomake#log#debug(printf( + \ "Could not change to job's cwd (%s): %s.", + \ a:jobinfo.cd_from_setting, cd_error), a:jobinfo) + endif + + let prev_list = file_mode ? getloclist(0) : getqflist() + try + let parsed_entries = make_list.add_entries_for_job(a:entries, a:jobinfo) + if exists(':Assert') && !empty(a:entries) + Assert get(a:entries[0], 'text', '') !~# 'nmcfg:' + endif + finally + call a:jobinfo.cd_back() + endtry + endif + call s:clean_for_new_make(make_info) + + let counts_changed = 0 + let maker_type = file_mode ? 'file' : 'project' + let do_highlight = get(g:, 'neomake_highlight_columns', 1) + \ || get(g:, 'neomake_highlight_lines', 0) + let signs_by_bufnr = {} + let debug = neomake#utils#get_verbosity(a:jobinfo) >= 3 || !empty(get(g:, 'neomake_logfile')) || s:is_testing + let entries_with_lnum_by_bufnr = {} + let skipped_without_bufnr = [] + let skipped_without_lnum = [] + + let idx = -1 + for entry in parsed_entries + let idx += 1 + if !file_mode + if neomake#statusline#AddQflistCount(entry) + let counts_changed = 1 + endif + endif + + if !entry.bufnr + if debug + let skipped_without_bufnr += [idx] + endif + continue + endif + + if file_mode + if neomake#statusline#AddLoclistCount(entry.bufnr, entry) + let counts_changed = 1 + endif + endif + + if !entry.lnum + if debug + let skipped_without_lnum += [idx] + endif + continue + endif + + if !has_key(entries_with_lnum_by_bufnr, entry.bufnr) + let entries_with_lnum_by_bufnr[entry.bufnr] = [] + let signs_by_bufnr[entry.bufnr] = [] + endif + + if do_highlight || g:neomake_place_signs + " NOTE: only lnum/type required for signs. Similar for do_highlight?! + call add(entries_with_lnum_by_bufnr[entry.bufnr], entry) + endif + + " Track all errors by buffer and line + let entry.maker_name = maker_name + call neomake#_add_error(maker_type, entry) + endfor + + " Handle placing signs and highlights. + for [b, entries] in items(entries_with_lnum_by_bufnr) + if g:neomake_place_signs + call neomake#signs#PlaceSigns(b, entries, maker_type) + endif + if do_highlight + for entry in entries + call neomake#highlights#AddHighlight(entry, maker_type) + endfor + endif + endfor + + if !empty(skipped_without_bufnr) + call neomake#log#debug(printf('Skipped %d entries without bufnr: %s.', + \ len(skipped_without_bufnr), + \ string(map(skipped_without_bufnr, 'a:entries[v:val]'))), a:jobinfo) + endif + + if !empty(skipped_without_lnum) + call neomake#log#debug(printf( + \ 'Could not place signs for %d entries without line number: %s.', + \ len(skipped_without_lnum), + \ string(map(skipped_without_lnum, 'a:entries[v:val]'))), a:jobinfo) + endif + + let new_list = make_list.entries + if !counts_changed + let counts_changed = new_list != prev_list + endif + if counts_changed + call neomake#utils#hook('NeomakeCountsChanged', {'reset': 0, 'jobinfo': a:jobinfo}) + endif + + if has_key(a:jobinfo, '_delayed_qf_autocmd') && exists('#QuickfixCmdPost') + " NOTE: need to use :silent, since we can only check the event, but + " not the pattern - `exists()` for 'laddexpr' will not match '*'. + silent call neomake#compat#doautocmd(a:jobinfo._delayed_qf_autocmd) + unlet a:jobinfo._delayed_qf_autocmd + endif + + if !empty(new_list) + call s:HandleLoclistQflistDisplay(a:jobinfo, new_list) + endif + call neomake#highlights#ShowHighlights() + return g:neomake#action_queue#processed +endfunction + +function! s:ProcessJobOutput(jobinfo, lines, source, ...) abort + if s:need_to_postpone_loclist(a:jobinfo) + return neomake#action_queue#add(['BufEnter', 'WinEnter'], [s:function('s:ProcessJobOutput'), + \ [a:jobinfo, a:lines, a:source]]) + endif + if !a:0 + return s:pcall('s:ProcessJobOutput', [a:jobinfo, a:lines, a:source]) + endif + + let maker = a:jobinfo.maker + call neomake#log#debug(printf('Processing %d lines of output.', + \ len(a:lines)), a:jobinfo) + let cd_error = a:jobinfo.cd() + if !empty(cd_error) + call neomake#log#debug(printf( + \ "Could not change to job's cwd (%s): %s.", + \ a:jobinfo.cd_from_setting, cd_error), a:jobinfo) + endif + try + if has_key(maker, 'process_json') || has_key(maker, 'process_output') + if has_key(maker, 'process_json') + let method = 'process_json' + let output = join(a:lines, "\n") + try + let json = neomake#compat#json_decode(output) + catch + let error = printf( + \ 'Failed to decode JSON: %s (output: %s).', + \ substitute(v:exception, '^Neomake: ', '', ''), string(output)) + call neomake#log#exception(error, a:jobinfo) + return g:neomake#action_queue#not_processed + endtry + call neomake#log#debug(printf( + \ "Calling maker's process_json method with %d JSON entries.", + \ len(json)), a:jobinfo) + let entries = call(maker.process_json, [{ + \ 'json': json, + \ 'source': a:source, + \ 'jobinfo': a:jobinfo}], maker) + else + call neomake#log#debug(printf( + \ "Calling maker's process_output method with %d lines of output on %s.", + \ len(a:lines), a:source), a:jobinfo) + let method = 'process_output' + let entries = call(maker.process_output, [{ + \ 'output': a:lines, + \ 'source': a:source, + \ 'jobinfo': a:jobinfo}], maker) + endif + if type(entries) != type([]) + call neomake#log#error(printf('The %s method for maker %s did not return a list, but: %s.', + \ method, maker.name, string(entries)[:100]), a:jobinfo) + return g:neomake#action_queue#not_processed + elseif !empty(entries) && type(entries[0]) != type({}) + call neomake#log#error(printf('The %s method for maker %s did not return a list of dicts, but: %s.', + \ method, maker.name, string(entries)[:100]), a:jobinfo) + return g:neomake#action_queue#not_processed + endif + return s:ProcessEntries(a:jobinfo, entries) + endif + + " Old-school handling through errorformat. + if has_key(maker, 'mapexpr') + let neomake_bufname = fnamemodify(bufname(a:jobinfo.bufnr), ':p') + " @vimlint(EVL102, 1, l:neomake_bufdir) + let neomake_bufdir = fnamemodify(neomake_bufname, ':h') + " @vimlint(EVL102, 1, l:neomake_output_source) + let neomake_output_source = a:source + call map(a:lines, maker.mapexpr) + endif + + if !empty(a:lines) + call s:AddExprCallback(a:jobinfo, a:lines) + endif + catch /^\%(Vim\%((\a\+)\)\=:\%(E48\|E523\)\)\@!/ " everything, but E48/E523 (sandbox / not allowed here) + if v:exception ==# 'NeomakeTestsException' + throw v:exception + endif + call neomake#log#exception(printf( + \ 'Error during output processing for %s: %s.', + \ a:jobinfo.maker.name, v:exception), a:jobinfo) + return + finally + call a:jobinfo.cd_back() + endtry + return g:neomake#action_queue#processed +endfunction + +function! s:process_pending_output(jobinfo, lines, source, ...) abort + let retry_events = s:need_to_postpone_output_processing(a:jobinfo) + if empty(retry_events) + let retry_events = s:ProcessPendingOutput(a:jobinfo, a:lines, a:source) + if empty(retry_events) + return g:neomake#action_queue#processed + endif + endif + call add(a:jobinfo.pending_output, [a:lines, a:source]) + if index(neomake#action_queue#get_queued_actions(a:jobinfo), + \ ['process_pending_output', retry_events]) == -1 + return neomake#action_queue#add(retry_events, [s:function('s:process_pending_output'), [a:jobinfo, [], a:source, retry_events]]) + endif + return g:neomake#action_queue#not_processed +endfunction + +function! s:ProcessPendingOutput(jobinfo, lines, source) abort + if a:jobinfo.file_mode + let window_make_ids = get(w:, 'neomake_make_ids', []) + if index(window_make_ids, a:jobinfo.make_id) == -1 + if !bufexists(a:jobinfo.bufnr) + call neomake#log#info('No buffer found for output!', a:jobinfo) + return [] + endif + + if a:jobinfo.bufnr != bufnr('%') + call neomake#log#debug(printf('Skipped pending job output for another buffer (current=%d).', bufnr('%')), a:jobinfo) + return ['BufEnter', 'WinEnter'] + elseif neomake#core#get_tabwin_for_makeid(a:jobinfo.make_id) != [-1, -1] + call neomake#log#debug('Skipped pending job output (not in origin window).', a:jobinfo) + return ['WinEnter'] + else + call neomake#log#debug("Processing pending output for job's buffer in new window.", a:jobinfo) + let w:neomake_make_ids = add(get(w:, 'neomake_make_ids', []), a:jobinfo.make_id) + endif + endif + endif + + " Process any pending output first. + if !empty(a:jobinfo.pending_output) + let outputs = {'stdout': [], 'stderr': []} + for [lines, source] in a:jobinfo.pending_output + call extend(outputs[source], lines) + endfor + for [source, lines] in items(outputs) + if !empty(lines) + call s:ProcessJobOutput(a:jobinfo, lines, source) + endif + endfor + call neomake#log#debug(printf( + \ 'Processed %d pending outputs.', len(a:jobinfo.pending_output)), + \ a:jobinfo) + call neomake#action_queue#remove(a:jobinfo, s:function('s:process_pending_output')) + endif + + if !empty(a:lines) + call s:ProcessJobOutput(a:jobinfo, a:lines, a:source) + endif + + " Clean job if it had exited already. + if !empty(a:jobinfo.pending_output) + let a:jobinfo.pending_output = [] + if has_key(a:jobinfo, 'exit_code') + " XXX: add test (tested manually) + call s:CleanJobinfo(a:jobinfo) + endif + endif + return [] +endfunction + +" Do we need to postpone location list processing (creation and :laddexpr)? +function! s:need_to_postpone_loclist(jobinfo) abort + if !a:jobinfo.file_mode + return 0 + endif + if index(get(w:, 'neomake_make_ids', []), a:jobinfo.make_id) != -1 + return 0 + endif + call neomake#log#debug('Postponing location list processing.', a:jobinfo) + return 1 +endfunction + +" TODO: merge with s:handle_locqf_list_for_finished_jobs. +let s:has_getcmdwintype = exists('*getcmdwintype') +function! s:need_to_postpone_output_processing(jobinfo) abort + " We can only process output (change the location/quickfix list) in + " certain modes, otherwise e.g. the visual selection gets lost. + if neomake#compat#in_completion() + call neomake#log#debug('Not processing output during completion.', a:jobinfo) + return ['CompleteDone'] + endif + let mode = neomake#compat#get_mode() + if index(['n', 'i'], mode) == -1 + call neomake#log#debug('Not processing output for mode "'.mode.'".', a:jobinfo) + return ['BufEnter', 'WinEnter', 'InsertLeave', 'CursorHold', 'CursorHoldI'] + endif + if s:has_getcmdwintype && !empty(getcmdwintype()) + call neomake#log#debug('Not processing output from command-line window "'.getcmdwintype().'".', a:jobinfo) + return ['InsertLeave', 'CursorHold', 'CursorHoldI'] + endif + return [] +endfunction + +function! s:RegisterJobOutput(jobinfo, lines, source) abort + " Allow to filter output (storing the setting on the jobinfo lazily). + if !has_key(a:jobinfo, 'filter_output') + let a:jobinfo.filter_output = neomake#utils#GetSetting('filter_output', a:jobinfo.maker, '', a:jobinfo.ft, a:jobinfo.bufnr) + endif + if !empty(a:jobinfo.filter_output) + call call(a:jobinfo.filter_output, [ + \ a:lines, {'source': a:source, 'jobinfo': a:jobinfo}], + \ a:jobinfo.maker) + endif + + if empty(a:lines) + return + endif + + " Register unexpected output. + if a:jobinfo.output_stream !=# 'both' && a:jobinfo.output_stream !=# a:source + if !has_key(a:jobinfo, 'unexpected_output') + let a:jobinfo.unexpected_output = {} + endif + if !has_key(a:jobinfo.unexpected_output, a:source) + let a:jobinfo.unexpected_output[a:source] = [] + endif + let a:jobinfo.unexpected_output[a:source] += a:lines + return + endif + + let make_info = s:make_info[a:jobinfo.make_id] + if has_key(make_info, 'entries_list') " use_list option + " Process output for list processing. + call s:process_pending_output(a:jobinfo, a:lines, a:source) + endif +endfunction + +function! s:vim_output_handler(channel, output, event_type) abort + let channel_id = ch_info(a:channel)['id'] + let jobinfo = get(s:jobs, get(s:map_job_ids, channel_id, -1), {}) + if empty(jobinfo) + call neomake#log#debug(printf("warn: job '%s' not found for output on %s.", + \ a:channel, a:event_type)) + return + endif + let data = split(a:output, '\r\?\n', 1) + call s:output_handler_queued(jobinfo, data, a:event_type, 0) +endfunction + +function! s:vim_output_handler_stdout(channel, output) abort + call s:vim_output_handler(a:channel, a:output, 'stdout') +endfunction + +function! s:vim_output_handler_stderr(channel, output) abort + call s:vim_output_handler(a:channel, a:output, 'stderr') +endfunction + +function! s:vim_exit_handler(channel) abort + let channel_id = ch_info(a:channel)['id'] + let jobinfo = get(s:jobs, get(s:map_job_ids, channel_id, -1), {}) + if empty(jobinfo) + try + let job_info = job_info(ch_getjob(a:channel)) + catch /^Vim(let):E916:/ + " Might happen with older Vim (8.0.69, but not 8.0.586). + call neomake#log#debug(printf('exit: job not found: %s.', a:channel)) + return + endtry + call neomake#log#debug(printf('exit: job not found: %s (%s).', a:channel, job_info)) + return + endif + let job_info = job_info(ch_getjob(a:channel)) + + " Handle failing starts from Vim here. + let status = job_info['exitval'] + if status == 122 " Vim uses EXEC_FAILED, but only on Unix?! + let jobinfo.failed_to_start = 1 + " The error is on stderr. + let error = 'Vim job failed to run: '.substitute(join(jobinfo.stderr), '\v\s+$', '', '').'.' + let jobinfo.stderr = [] + call neomake#log#error(error) + call s:CleanJobinfo(jobinfo) + else + call s:exit_handler(jobinfo, status) + endif +endfunction + +" @vimlint(EVL108, 1) +if has('nvim-0.2.0') +" @vimlint(EVL108, 0) + function! s:nvim_output_handler(job_id, data, event_type) abort + let jobinfo = get(s:jobs, get(s:map_job_ids, a:job_id, -1), {}) + if empty(jobinfo) + call neomake#log#debug(printf('output [%s]: job %d not found.', a:event_type, a:job_id)) + return + endif + if a:data == [''] && !exists('jobinfo[a:event_type]') + " EOF in Neovim (see :h on_data). + return + endif + call s:output_handler_queued(jobinfo, copy(a:data), a:event_type, 1) + endfunction +else + " Neovim: register output from jobs as quick as possible, and trigger + " processing through a timer. + " This works around https://github.com/neovim/neovim/issues/5889). + " NOTE: a:data is never [''] here (like with other/newer Neovim + " handlers) + let s:nvim_output_handler_queue = [] + function! s:nvim_output_handler(job_id, data, event_type) abort + let jobinfo = get(s:jobs, get(s:map_job_ids, a:job_id, -1), {}) + if empty(jobinfo) + call neomake#log#debug(printf('output [%s]: job %d not found.', a:event_type, a:job_id)) + return + endif + let args = [jobinfo, copy(a:data), a:event_type, 1] + call add(s:nvim_output_handler_queue, args) + if !exists('jobinfo._nvim_in_handler') + let jobinfo._nvim_in_handler = 1 + else + let jobinfo._nvim_in_handler += 1 + endif + if !exists('s:nvim_output_handler_timer') + let s:nvim_output_handler_timer = timer_start(0, function('s:nvim_output_handler_cb')) + endif + endfunction + + function! s:nvim_output_handler_cb(_timer) abort + while !empty(s:nvim_output_handler_queue) + let args = remove(s:nvim_output_handler_queue, 0) + let jobinfo = args[0] + call call('s:output_handler', args) + let jobinfo._nvim_in_handler -= 1 + + if !jobinfo._nvim_in_handler + " Trigger previously delayed exit handler. + unlet jobinfo._nvim_in_handler + if exists('jobinfo._exited_while_in_handler') + call neomake#log#debug('Trigger delayed exit.', jobinfo) + call s:exit_handler(jobinfo, jobinfo._exited_while_in_handler) + endif + endif + endwhile + unlet! s:nvim_output_handler_timer + endfunction +endif + +" Exit handler for buffered output with Neovim. +" In this case the output gets stored on the jobstart-options dict. +function! s:nvim_exit_handler_buffered(job_id, data, _event_type) abort + let jobinfo = get(s:jobs, get(s:map_job_ids, a:job_id, -1), {}) + if empty(jobinfo) + call neomake#log#debug(printf('exit: job not found: %d.', a:job_id)) + return + endif + + for stream in ['stdout', 'stderr'] + if has_key(jobinfo.jobstart_opts, stream) + let data = copy(jobinfo.jobstart_opts[stream]) + if data == [''] + " EOF in Neovim (see :h on_data). + continue + endif + call s:output_handler(jobinfo, data, stream, 1) + endif + endfor + + call s:exit_handler(jobinfo, a:data) +endfunction + +function! s:nvim_exit_handler(job_id, data, _event_type) abort + let jobinfo = get(s:jobs, get(s:map_job_ids, a:job_id, -1), {}) + if empty(jobinfo) + call neomake#log#debug(printf('exit: job not found: %d.', a:job_id)) + return + endif + call s:exit_handler(jobinfo, a:data) +endfunction + +function! s:exit_handler(jobinfo, data) abort + let jobinfo = a:jobinfo + let jobinfo.exit_code = a:data + if get(jobinfo, 'canceled') + call neomake#log#debug('exit: job was canceled.', jobinfo) + call s:CleanJobinfo(jobinfo) + return + endif + let maker = jobinfo.maker + + if exists('jobinfo._output_while_in_handler') || exists('jobinfo._nvim_in_handler') + let jobinfo._exited_while_in_handler = a:data + call neomake#log#debug(printf('exit (delayed): %s: %s.', + \ maker.name, string(a:data)), jobinfo) + return + endif + call neomake#log#debug(printf('exit: %s: %s.', + \ maker.name, string(a:data)), jobinfo) + + let jobinfo._in_exit_handler = 1 + try + " Handle any unfinished lines from stdout/stderr callbacks. + for event_type in ['stdout', 'stderr'] + if has_key(jobinfo, event_type) + let lines = jobinfo[event_type] + if !empty(lines) + if lines[-1] ==# '' + call remove(lines, -1) + endif + if !empty(lines) + call s:RegisterJobOutput(jobinfo, lines, event_type) + endif + unlet jobinfo[event_type] + endif + endif + endfor + + if !get(jobinfo, 'failed_to_start') + let l:ExitCallback = neomake#utils#GetSetting('exit_callback', + \ extend(copy(jobinfo), maker), 0, jobinfo.ft, jobinfo.bufnr) + if ExitCallback isnot# 0 + let callback_dict = { 'status': jobinfo.exit_code, + \ 'name': maker.name, + \ 'has_next': !empty(s:make_info[jobinfo.make_id].jobs_queue) } + try + if type(ExitCallback) == type('') + let l:ExitCallback = function(ExitCallback) + endif + call call(ExitCallback, [callback_dict], jobinfo) + catch + call neomake#log#error(printf( + \ 'Error during exit_callback: %s.', v:exception), + \ jobinfo) + endtry + endif + endif + + if s:async + if has('nvim') || jobinfo.exit_code != 122 + call neomake#log#debug(printf( + \ '%s: completed with exit code %d.', + \ maker.name, jobinfo.exit_code), jobinfo) + endif + let jobinfo.finished = 1 + endif + + if has_key(jobinfo, 'unexpected_output') + redraw + for [source, output] in items(jobinfo.unexpected_output) + let msg = printf('%s: unexpected output on %s: ', maker.name, source) + call neomake#log#debug(msg . join(output, '\n') . '.', jobinfo) + + echohl WarningMsg + echom printf('Neomake: %s%s', msg, output[0]) + for line in output[1:-1] + echom line + endfor + echohl None + endfor + call neomake#log#error(printf( + \ '%s: unexpected output. See :messages for more information.', maker.name), jobinfo) + endif + finally + unlet jobinfo._in_exit_handler + endtry + call s:handle_next_job(jobinfo) +endfunction + +function! s:output_handler_queued(jobinfo, data, event_type, trim_CR) abort + let jobinfo = a:jobinfo + if exists('jobinfo._output_while_in_handler') + call neomake#log#debug(printf('Queuing: %s: %s: %s.', + \ a:event_type, jobinfo.maker.name, string(a:data)), jobinfo) + let jobinfo._output_while_in_handler += [[jobinfo, a:data, a:event_type, a:trim_CR]] + return + else + let jobinfo._output_while_in_handler = [] + endif + + call s:output_handler(jobinfo, a:data, a:event_type, a:trim_CR) + + " Process queued events that might have arrived by now. + " The attribute might be unset here, since output_handler might have + " been interrupted. + if exists('jobinfo._output_while_in_handler') + while has_key(jobinfo, '_output_while_in_handler') && !empty(jobinfo._output_while_in_handler) + let args = remove(jobinfo._output_while_in_handler, 0) + call call('s:output_handler', args) + endwhile + unlet! jobinfo._output_while_in_handler + endif + " Trigger previously delayed exit handler. + if exists('jobinfo._exited_while_in_handler') + call neomake#log#debug('Trigger delayed exit.', jobinfo) + call s:exit_handler(jobinfo, jobinfo._exited_while_in_handler) + endif +endfunction + +function! s:output_handler(jobinfo, data, event_type, trim_CR) abort + let jobinfo = a:jobinfo + call neomake#log#debug(printf('output on %s: %s.', + \ a:event_type, string(a:data)), jobinfo) + if get(jobinfo, 'canceled') + call neomake#log#debug('Ignoring output (job was canceled).', jobinfo) + return + endif + let data = copy(a:data) + if a:trim_CR && !empty(a:data) + call map(data, "substitute(v:val, '\\r$', '', '')") + endif + let last_event_type = get(jobinfo, 'event_type', a:event_type) + + " data is a list of 'lines' read. Each element *after* the first + " element represents a newline. + if has_key(jobinfo, a:event_type) + let jobinfo[a:event_type][-1] .= data[0] + call extend(jobinfo[a:event_type], data[1:]) + else + let jobinfo[a:event_type] = data + endif + + if !jobinfo.buffer_output || last_event_type !=# a:event_type + let lines = jobinfo[a:event_type][:-2] + let jobinfo[a:event_type] = jobinfo[a:event_type][-1:] + + if !empty(lines) + call s:RegisterJobOutput(jobinfo, lines, a:event_type) + endif + endif +endfunction + +function! s:abort_next_makers(make_id) abort + let jobs_queue = s:make_info[a:make_id].jobs_queue + if !empty(jobs_queue) + let next_makers = join(map(copy(jobs_queue), 'v:val.maker.name'), ', ') + call neomake#log#info('Aborting next makers: '.next_makers.'.', {'make_id': a:make_id}) + let s:make_info[a:make_id].aborted_jobs = copy(s:make_info[a:make_id].jobs_queue) + let s:make_info[a:make_id].jobs_queue = [] + endif +endfunction + +function! s:handle_next_job(prev_jobinfo) abort + let make_id = get(a:prev_jobinfo, 'make_id', s:make_id) + if !has_key(s:make_info, make_id) + return {} + endif + let make_info = s:make_info[make_id] + + if !empty(a:prev_jobinfo) + let status = get(a:prev_jobinfo, 'exit_code', 0) + if status != 0 && index([122, 127], status) == -1 + " TODO: mark maker.exe as non-executable with status 127, and + " maybe re-introduce a wrapper for `executable()` to handle it. + " Ref: https://github.com/neomake/neomake/issues/1699 + if neomake#utils#GetSetting('serialize_abort_on_error', a:prev_jobinfo.maker, 0, a:prev_jobinfo.ft, a:prev_jobinfo.bufnr) + let a:prev_jobinfo.aborted = 1 + call s:abort_next_makers(make_id) + call s:CleanJobinfo(a:prev_jobinfo) + return {} + endif + endif + call s:CleanJobinfo(a:prev_jobinfo) + if !has_key(s:make_info, make_id) + " Last job was cleaned. + return {} + endif + + let serializing_for_job = get(make_info, 'serializing_for_job') + if serializing_for_job + if serializing_for_job != a:prev_jobinfo.id + call neomake#log#debug(printf('waiting for job %d to finish.', serializing_for_job)) + return {} + endif + unlet make_info.serializing_for_job + endif + endif + + " Create job from the start of the queue, returning it. + while !empty(make_info.jobs_queue) + let options = remove(make_info.jobs_queue, 0) + let maker = options.maker + if empty(maker) + continue + endif + + " Serialization of jobs, always for non-async Vim. + if !has_key(options, 'serialize') + if !s:async || neomake#utils#GetSetting('serialize', maker, 0, options.ft, options.bufnr) + let options.serialize = 1 + else + let options.serialize = 0 + endif + endif + try + let jobinfo = s:MakeJob(make_id, options) + catch /^Neomake: / + let log_context = extend(options, {'make_id': make_id}) + if v:exception =~# '\v^Neomake: skip_job: ' + let msg = substitute(v:exception, '^Neomake: skip_job: ', '', '') + call neomake#log#debug(printf('Skipping job: %s', msg), log_context) + else + let error = substitute(v:exception, '^Neomake: ', '', '') + call neomake#log#exception(error, log_context) + + if options.serialize + if neomake#utils#GetSetting('serialize_abort_on_error', maker, 0, options.ft, options.bufnr) + call s:abort_next_makers(make_id) + break + endif + endif + endif + continue + endtry + if !empty(jobinfo) + return jobinfo + endif + endwhile + + " Cleanup make info, but only if there are no queued actions. + for [_, v] in g:neomake#action_queue#_s.action_queue + if v[1][0] == make_info + call neomake#log#debug('Skipping cleaning of make info for queued actions.', make_info) + return {} + endif + endfor + call s:clean_make_info(make_info) + return {} +endfunction + +function! neomake#_add_error(maker_type, entry) abort + if !has_key(s:current_errors[a:maker_type], a:entry.bufnr) + let s:current_errors[a:maker_type][a:entry.bufnr] = {} + endif + if !has_key(s:current_errors[a:maker_type][a:entry.bufnr], a:entry.lnum) + let s:current_errors[a:maker_type][a:entry.bufnr][a:entry.lnum] = [a:entry] + else + call add(s:current_errors[a:maker_type][a:entry.bufnr][a:entry.lnum], a:entry) + endif +endfunction + +function! neomake#get_nearest_error() abort + let buf = bufnr('%') + let ln = line('.') + let ln_errors = [] + + for maker_type in ['file', 'project'] + let buf_errors = get(s:current_errors[maker_type], buf, {}) + let ln_errors += get(buf_errors, ln, []) + endfor + + if empty(ln_errors) + return {} + endif + + if len(ln_errors) > 1 + call sort(ln_errors, function('neomake#utils#sort_by_col')) + endif + return ln_errors[0] +endfunction + +function! neomake#GetCurrentErrorMsg() abort + let entry = neomake#get_nearest_error() + if empty(entry) + return '' + endif + let r = entry.maker_name . ': ' . entry.text + let suffix = entry.type . (entry.nr != -1 ? entry.nr : '') + if !empty(suffix) + let r .= ' ('.suffix.')' + endif + return r +endfunction + +function! neomake#EchoCurrentError(...) abort + if !get(g:, 'neomake_echo_current_error', 1) + return + endif + " a:1 might be a timer from the VimResized event. + let force = a:0 ? a:1 : 0 + + let message = neomake#GetCurrentErrorMsg() + if empty(message) + if exists('s:neomake_last_echoed_error') + echon '' + unlet s:neomake_last_echoed_error + endif + return + endif + if !force && exists('s:neomake_last_echoed_error') + \ && s:neomake_last_echoed_error == message + return + endif + let s:neomake_last_echoed_error = message + call neomake#utils#WideMessage(message) +endfunction + +function! neomake#CursorMoved() abort + call neomake#EchoCurrentError() + call neomake#virtualtext#handle_current_error() +endfunction + +function! s:cursormoved_delayed_cb(...) abort + if getpos('.') == s:cursormoved_last_pos + call neomake#CursorMoved() + endif +endfunction +function! neomake#CursorMovedDelayed() abort + if exists('s:cursormoved_timer') + call timer_stop(s:cursormoved_timer) + endif + let delay = get(g:, 'neomake_cursormoved_delay', 100) + let s:cursormoved_timer = timer_start(delay, function('s:cursormoved_delayed_cb')) + let s:cursormoved_last_pos = getpos('.') +endfunction + +function! neomake#Make(file_mode_or_options, ...) abort + if type(a:file_mode_or_options) == type({}) + return s:Make(a:file_mode_or_options) + endif + + let file_mode = a:file_mode_or_options + let options = {'file_mode': file_mode} + if file_mode + let options.ft = &filetype + endif + if a:0 + if !empty(a:1) + let maker_names = a:1 + " Split names on non-breaking space (annotation from completion). + call map(maker_names, "type(v:val) == 1 ? split(v:val, ' (')[0] : v:val") + let options.enabled_makers = a:1 + endif + if a:0 > 1 + let options.exit_callback = a:2 + endif + endif + return map(copy(s:Make(options)), 'v:val.id') +endfunction + +function! neomake#ShCommand(bang, sh_command, ...) abort + let maker = neomake#utils#MakerFromCommand(a:sh_command) + let maker.name = 'sh: '.a:sh_command + let maker.errorformat = '%m' + let maker.default_entry_type = '' + let options = { + \ 'enabled_makers': [maker], + \ 'file_mode': 0, + \ 'output_stream': 'both', + \ 'buffer_output': !a:bang, + \ } + if a:0 + call extend(options, a:1) + endif + let jobinfos = s:Make(options) + return empty(jobinfos) ? -1 : jobinfos[0].id +endfunction + +function! neomake#Sh(sh_command, ...) abort + " Deprecated, but documented. + let options = a:0 ? { 'exit_callback': a:1 } : {} + return neomake#ShCommand(0, a:sh_command, options) +endfunction + +function! neomake#map_makers(makers, ft, auto_enabled) abort + let makers = [] + let errors = [] + let get_args = a:ft is# -1 ? [] : [a:ft] + for maker in a:makers + try + let m = call('neomake#GetMaker', [maker] + get_args) + catch /^Neomake: / + call add(errors, substitute(v:exception, '^Neomake: ', '', '').'.') + unlet maker " vim73/vim-trusty + continue + endtry + call add(makers, m) + unlet maker " vim73/vim-trusty + endfor + if !empty(errors) + let log_context = get(s:make_info, s:make_id, {}) + for error in errors + if a:auto_enabled + call neomake#log#debug(error, log_context) + else + call neomake#log#error(error, log_context) + endif + endfor + endif + return makers +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/action_queue.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/action_queue.vim new file mode 100644 index 0000000..4fc3fc1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/action_queue.vim @@ -0,0 +1,307 @@ +if !exists('s:action_queue') + let s:action_queue = [] +endif +if !exists('s:action_queue_registered_events') + let s:action_queue_registered_events = [] +endif +let s:action_queue_timer_timeouts = get(g:, 'neomake_action_queue_timeouts', {1: 100, 2: 200, 3: 500}) + +let g:neomake#action_queue#processed = {} +let g:neomake#action_queue#not_processed = {} +let g:neomake#action_queue#any_event = [] + +let g:neomake#action_queue#_s = s: + +function! s:actionname(funcref) abort + let s = string(a:funcref) + let r = matchstr(s, '\v^^function\(''\zs.*\ze''\)$') + if empty(r) + return s + endif + return substitute(r, '\v^(\<SNR\>\d+_|s:)', '', '') +endfunction + +" Queue an action to be processed later for autocmd a:event or through a timer +" for a:event=Timer. +" It will call a:data[0], with a:data[1] as args (where the first should be +" a jobinfo object). The callback should return 1 if it was successful, +" with 0 it will be re-queued. +" When called recursively (queuing the same event/data again, it will be +" re-queued also). +function! neomake#action_queue#add(events, data) abort + let job_or_make_info = a:data[1][0] + if a:events is# g:neomake#action_queue#any_event + call neomake#log#debug(printf('Queuing action %s for any event.', + \ s:actionname(a:data[0])), job_or_make_info) + else + call neomake#log#debug(printf('Queuing action %s for %s.', + \ s:actionname(a:data[0]), join(a:events, ', ')), job_or_make_info) + endif + + for event in a:events + if event ==# 'Timer' + if !has_key(job_or_make_info, 'action_queue_timer_tries') + let job_or_make_info.action_queue_timer_tries = {'count': 1, 'data': a:data[0]} + else + let job_or_make_info.action_queue_timer_tries.count += 1 + endif + if has_key(s:action_queue_timer_timeouts, job_or_make_info.action_queue_timer_tries.count) + let timeout = s:action_queue_timer_timeouts[job_or_make_info.action_queue_timer_tries.count] + else + throw printf('Neomake: Giving up handling Timer callbacks after %d attempts. Please report this. See :messages for more information.', len(s:action_queue_timer_timeouts)) + endif + if has('timers') + if exists('s:action_queue_timer') + call timer_stop(s:action_queue_timer) + endif + let s:action_queue_timer = timer_start(timeout, function('s:process_action_queue_timer_cb')) + call neomake#log#debug(printf( + \ 'Retrying Timer event in %dms (timer %d).', + \ timeout, s:action_queue_timer), job_or_make_info) + else + call neomake#log#debug('Retrying Timer event on CursorHold(I).', job_or_make_info) + if !exists('#neomake_event_queue#CursorHold') + let s:action_queue_registered_events += ['CursorHold', 'CursorHoldI'] + augroup neomake_event_queue + exe 'autocmd CursorHold,CursorHoldI * call s:process_action_queue('''.event.''')' + augroup END + endif + endif + else + if !exists('#neomake_event_queue#'.event) + let s:action_queue_registered_events += [event] + augroup neomake_event_queue + exe 'autocmd '.event.' * call s:process_action_queue('''.event.''')' + augroup END + endif + endif + endfor + call add(s:action_queue, [a:events, a:data]) + return g:neomake#action_queue#not_processed +endfunction + +" Remove any queued actions for a jobinfo or make_info object. +function! neomake#action_queue#clean(job_or_make_info) abort + let len_before = len(s:action_queue) + call filter(s:action_queue, 'v:val[1][1][0] != a:job_or_make_info') + let removed = len_before - len(s:action_queue) + if removed + call s:clean_action_queue_events() + call neomake#log#debug(printf( + \ 'Removed %d action queue entries.', + \ removed), a:job_or_make_info) + endif +endfunction + +" Remove given action for a jobinfo or make_info object. +function! neomake#action_queue#remove(job_or_make_info, action) abort + let len_before = len(s:action_queue) + call filter(s:action_queue, 'v:val[1][1][0] != a:job_or_make_info || v:val[1][0] != a:action') + let removed = len_before - len(s:action_queue) + if removed + call s:clean_action_queue_events() + call neomake#log#debug(printf( + \ 'Removed %d action queue entries for %s.', + \ removed, s:actionname(a:action)), a:job_or_make_info) + endif +endfunction + +function! s:process_action_queue_timer_cb(...) abort + call neomake#log#debug(printf( + \ 'action queue: callback for Timer queue (%d).', s:action_queue_timer)) + unlet s:action_queue_timer + call s:process_action_queue('Timer') +endfunction + +function! s:process_action_queue(event) abort + let queue = s:action_queue + let q_for_this_event = [] + let i = 0 + if g:neomake#core#_ignore_autocommands + call neomake#log#debug(printf('action queue: skip processing for %s (ignore_autocommands=%d).', + \ a:event, g:neomake#core#_ignore_autocommands), + \ {'bufnr': bufnr('%'), 'winnr': winnr()}) + return + endif + for [events, v] in queue + if index(events, a:event) != -1 || events is# g:neomake#action_queue#any_event + call add(q_for_this_event, [i, v]) + endif + let i += 1 + endfor + call neomake#log#debug(printf('action queue: processing for %s (%d items).', + \ a:event, len(q_for_this_event)), {'bufnr': bufnr('%'), 'winnr': winnr()}) + + let processed = [] + let removed = 0 + let stop_processing = {'make_id': [], 'job_id': []} + for [idx_q_for_this_event, data] in q_for_this_event + let job_or_make_info = data[1][0] + let current_event = remove(queue, idx_q_for_this_event - removed) + let removed += 1 + + let make_id_job_id = {} " make_id/job_id relevant to re-queue following. + if has_key(job_or_make_info, 'make_id') + if has_key(job_or_make_info, 'options') + let make_id_job_id = { + \ 'make_id': job_or_make_info.make_id, + \ } + else + let make_id_job_id = { + \ 'make_id': job_or_make_info.make_id, + \ 'job_id': job_or_make_info.id, + \ } + endif + endif + + " Skip/re-queue entries for same make/job. + let skip = 0 + for [prop_name, prop_value] in items(make_id_job_id) + if index(stop_processing[prop_name], prop_value) != -1 + call neomake#log#debug(printf('action queue: skipping %s for not processed %s.', + \ s:actionname(data[0]), prop_name), job_or_make_info) + call add(queue, current_event) + let skip = 1 + break + endif + endfor + if skip + continue + endif + + call neomake#log#debug(printf('action queue: calling %s.', + \ s:actionname(data[0])), job_or_make_info) + let queue_before_call = copy(queue) + try + " Call the queued action. On failure they should have requeued + " themselves already. + let rv = call(data[0], data[1]) + catch + if v:exception =~# '^Neomake: ' + let error = substitute(v:exception, '^Neomake: ', '', '') + else + let error = printf('Error during action queue processing: %s.', + \ v:exception) + endif + call neomake#log#exception(error, job_or_make_info) + + " Cancel job in case its action failed to get re-queued after X + " attempts. + if has_key(job_or_make_info, 'id') + call neomake#CancelJob(job_or_make_info.id) + endif + continue + endtry + if rv is# g:neomake#action_queue#processed + let processed += [data] + continue + endif + + if rv is# g:neomake#action_queue#not_processed + if a:event !=# 'Timer' && has_key(job_or_make_info, 'action_queue_timer_tries') + call neomake#log#debug('s:process_action_queue: decrementing timer tries for non-Timer event.', job_or_make_info) + let job_or_make_info.action_queue_timer_tries.count -= 1 + endif + + " Requeue any entries for the same job. + let i = 0 + for q in queue_before_call + for [prop_name, prop_value] in items(make_id_job_id) + " Assert current_event != q + if get(q[1][1][0], prop_name) == prop_value + call neomake#log#debug(printf('action queue: re-queuing %s for not processed %s.', + \ s:actionname(q[1][0]), prop_name), job_or_make_info) + call add(queue, remove(queue, i)) + let i -= 1 + break + endif + endfor + let i += 1 + endfor + for [prop_name, prop_value] in items(make_id_job_id) + call add(stop_processing[prop_name], prop_value) + endfor + else + let args_str = neomake#utils#Stringify(data[1]) + throw printf('Internal Neomake error: hook function %s(%s) returned unexpected value (%s)', data[0], args_str, rv) + endif + endfor + call neomake#log#debug(printf('action queue: processed %d items.', + \ len(processed)), {'bufnr': bufnr('%')}) + + call s:clean_action_queue_events() +endfunction + +if has('timers') + function! s:get_left_events() abort + let r = {} + for [events, _] in s:action_queue + for event in events + let r[event] = 1 + endfor + endfor + return keys(r) + endfunction +else + function! s:get_left_events() abort + let r = {} + for [events, _] in s:action_queue + for event in events + if event ==# 'Timer' + let r['CursorHold'] = 1 + let r['CursorHoldI'] = 1 + else + let r[event] = 1 + endif + endfor + endfor + return keys(r) + endfunction +endif + +function! neomake#action_queue#get_queued_actions(jobinfo) abort + " Check if there are any queued actions for this job. + let queued_actions = [] + for [events, v] in s:action_queue + if v[1][0] == a:jobinfo + let queued_actions += [[s:actionname(v[0]), events]] + endif + endfor + return queued_actions +endfunction + +function! s:clean_action_queue_events() abort + let left_events = s:get_left_events() + + if empty(left_events) + if exists('#neomake_event_queue') + autocmd! neomake_event_queue + augroup! neomake_event_queue + endif + else + let clean_events = [] + for event in s:action_queue_registered_events + if index(left_events, event) == -1 + let clean_events += [event] + endif + endfor + if !empty(clean_events) + augroup neomake_event_queue + for event in clean_events + if exists('#neomake_event_queue#'.event) + exe 'au! '.event + endif + endfor + augroup END + endif + endif + let s:action_queue_registered_events = left_events + + if index(left_events, 'Timer') == -1 + if exists('s:action_queue_timer') + call timer_stop(s:action_queue_timer) + unlet s:action_queue_timer + endif + endif +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/cmd.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/cmd.vim new file mode 100644 index 0000000..35806dc --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/cmd.vim @@ -0,0 +1,192 @@ +scriptencoding utf8 + +let s:last_completion = [] +function! neomake#cmd#complete_makers(ArgLead, CmdLine, ...) abort + if a:CmdLine !~# '\s' + " Just 'Neomake!' without following space. + return [' '] + endif + + " Filter only by name before non-breaking space. + let filter_name = split(a:ArgLead, ' ', 1)[0] + + let file_mode = a:CmdLine =~# '\v^(Neomake|NeomakeFile)\s' + + let compl_info = [bufnr('%'), &filetype, a:CmdLine] + if empty(&filetype) + let maker_names = neomake#GetProjectMakers() + else + let maker_names = neomake#GetMakers(&filetype) + + " Prefer (only) makers for the current filetype. + if file_mode + if !empty(filter_name) + call filter(maker_names, 'v:val[:len(filter_name)-1] ==# filter_name') + endif + if empty(maker_names) || s:last_completion == compl_info + call extend(maker_names, neomake#GetProjectMakers()) + endif + else + call extend(maker_names, neomake#GetProjectMakers()) + endif + endif + + " Only display executable makers. + let makers = [] + for maker_name in maker_names + try + let maker = neomake#GetMaker(maker_name) + catch /^Neomake: / + let error = substitute(v:exception, '^Neomake: ', '', '').'.' + call neomake#log#debug(printf('Could not get maker %s: %s', + \ maker_name, error)) + continue + endtry + if type(get(maker, 'exe', 0)) != type('') || executable(maker.exe) + let makers += [[maker_name, maker]] + endif + endfor + + " Append maker.name if it differs, uses non-breaking-space. + let r = [] + for [maker_name, maker] in makers + if maker.name !=# maker_name + \ && (empty(a:ArgLead) || stridx(maker_name, a:ArgLead) != 0) + let r += [printf('%s (%s)', maker_name, maker.name)] + else + let r += [maker_name] + endif + endfor + + let s:last_completion = compl_info + if !empty(filter_name) + call filter(r, 'v:val[:len(filter_name)-1] ==# filter_name') + endif + return r +endfunction + +function! neomake#cmd#complete_jobs(...) abort + return join(map(neomake#GetJobs(), "v:val.id.': '.v:val.maker.name"), "\n") +endfunction + +function! s:is_neomake_list(list) abort + if empty(a:list) + return 0 + endif + return a:list[0].text =~# ' nmcfg:{.\{-}}$' +endfunction + +function! neomake#cmd#clean(file_mode) abort + let buf = bufnr('%') + call neomake#_clean_errors({ + \ 'file_mode': a:file_mode, + \ 'bufnr': buf, + \ }) + if a:file_mode + if s:is_neomake_list(getloclist(0)) + call setloclist(0, [], 'r') + lclose + endif + call neomake#signs#ResetFile(buf) + call neomake#statusline#ResetCountsForBuf(buf) + else + if s:is_neomake_list(getqflist()) + call setqflist([], 'r') + cclose + endif + call neomake#signs#ResetProject() + call neomake#statusline#ResetCountsForProject() + endif + call neomake#EchoCurrentError(1) +endfunction + +" Enable/disable/toggle commands. {{{ +function! s:handle_disabled_status(scope, disabled) abort + if a:scope is# g: + if a:disabled + if exists('#neomake') + autocmd! neomake + augroup! neomake + endif + call neomake#configure#disable_automake() + else + call neomake#setup#setup_autocmds() + endif + elseif a:scope is# t: + let buffers = neomake#compat#uniq(sort(tabpagebuflist())) + if a:disabled + for b in buffers + call neomake#configure#disable_automake_for_buffer(b) + endfor + else + for b in buffers + call neomake#configure#enable_automake_for_buffer(b) + endfor + endif + elseif a:scope is# b: + let bufnr = bufnr('%') + if a:disabled + call neomake#configure#disable_automake_for_buffer(bufnr) + else + call neomake#configure#enable_automake_for_buffer(bufnr) + endif + endif + call neomake#cmd#display_status() + call neomake#configure#automake() + call neomake#statusline#clear_cache() +endfunction + +function! neomake#cmd#disable(scope) abort + let old = get(get(a:scope, 'neomake', {}), 'disabled', -1) + if old ==# 1 + return + endif + call neomake#config#set_dict(a:scope, 'neomake.disabled', 1) + call s:handle_disabled_status(a:scope, 1) +endfunction + +function! neomake#cmd#enable(scope) abort + let old = get(get(a:scope, 'neomake', {}), 'disabled', -1) + if old != 1 + return + endif + call neomake#config#set_dict(a:scope, 'neomake.disabled', 0) + call s:handle_disabled_status(a:scope, 0) +endfunction + +function! neomake#cmd#toggle(scope) abort + let new = !get(get(a:scope, 'neomake', {}), 'disabled', 0) + if new + call neomake#config#set_dict(a:scope, 'neomake.disabled', 1) + call s:handle_disabled_status(a:scope, 1) + else + call neomake#config#unset_dict(a:scope, 'neomake.disabled') + call s:handle_disabled_status(a:scope, 0) + endif +endfunction + +function! neomake#cmd#display_status() abort + let [disabled, source] = neomake#config#get_with_source('disabled', 0) + let msg = 'Neomake is ' . (disabled ? 'disabled' : 'enabled') + if source !=# 'default' + let msg .= ' ('.source.')' + endif + + " Add information from different scopes (if explicitly configured there). + for [scope_name, scope] in [['buffer', b:], ['tab', t:], ['global', g:]] + if scope_name ==# source + continue + endif + let disabled = get(get(scope, 'neomake', {}), 'disabled', -1) + if disabled != -1 + let msg .= printf(' [%s: %s]', scope_name, disabled ? 'disabled' : 'enabled') + endif + endfor + let msg .= '.' + + echom msg + call neomake#log#debug(msg) +endfunction +" }}} + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/compat.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/compat.vim new file mode 100644 index 0000000..d558bf7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/compat.vim @@ -0,0 +1,322 @@ +" Compatibility wrappers for different (Neo)Vim versions and platforms. + +if neomake#utils#IsRunningWindows() + let g:neomake#compat#dev_null = 'NUL' +else + let g:neomake#compat#dev_null = '/dev/null' +endif + +if v:version >= 704 + function! neomake#compat#getbufvar(buf, key, def) abort + return getbufvar(a:buf, a:key, a:def) + endfunction + function! neomake#compat#getwinvar(win, key, def) abort + return getwinvar(a:win, a:key, a:def) + endfunction +else + function! neomake#compat#getbufvar(buf, key, def) abort + return get(getbufvar(a:buf, ''), a:key, a:def) + endfunction + function! neomake#compat#getwinvar(win, key, def) abort + return get(getwinvar(a:win, ''), a:key, a:def) + endfunction +endif + +unlockvar neomake#compat#json_true +unlockvar neomake#compat#json_false +unlockvar neomake#compat#json_null +unlockvar neomake#compat#json_none + +if exists('v:none') + let neomake#compat#json_none = v:none +else + let neomake#compat#json_none = [] +endif + +if exists('*json_decode') + let neomake#compat#json_true = v:true + let neomake#compat#json_false = v:false + let neomake#compat#json_null = v:null + + if has('nvim') + function! neomake#compat#json_decode(json) abort + if a:json is# '' + " Prevent Neovim from throwing E474: Attempt to decode a blank string. + return g:neomake#compat#json_none + endif + return json_decode(a:json) + endfunction + else + function! neomake#compat#json_decode(json) abort + return json_decode(a:json) + endfunction + endif +else + let neomake#compat#json_true = 1 + let neomake#compat#json_false = 0 + function! s:json_null() abort + endfunction + let neomake#compat#json_null = [function('s:json_null')] + + " Via Syntastic (https://github.com/vim-syntastic/syntastic/blob/6fb14d624b6081459360fdbba743f82cf84c8f92/autoload/syntastic/preprocess.vim#L576-L607), + " based on https://github.com/MarcWeber/vim-addon-json-encoding/blob/master/autoload/json_encoding.vim. + " @vimlint(EVL102, 1, l:true) + " @vimlint(EVL102, 1, l:false) + " @vimlint(EVL102, 1, l:null) + function! neomake#compat#json_decode(json) abort " {{{2 + if a:json ==# '' + return g:neomake#compat#json_none + endif + + " The following is inspired by https://github.com/MarcWeber/vim-addon-manager and + " http://stackoverflow.com/questions/17751186/iterating-over-a-string-in-vimscript-or-parse-a-json-file/19105763#19105763 + " A hat tip to Marc Weber for this trick + " Replace newlines, which eval() does not like. + let json = substitute(a:json, "\n", '', 'g') + if substitute(json, '\v\"%(\\.|[^"\\])*\"|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g') !~# "[^,:{}[\\] \t]" + " JSON artifacts + let true = g:neomake#compat#json_true + let false = g:neomake#compat#json_false + let null = g:neomake#compat#json_null + + try + let object = eval(json) + catch + throw 'Neomake: Failed to parse JSON input: '.v:exception + endtry + else + throw 'Neomake: Failed to parse JSON input: invalid input' + endif + + return object + endfunction " }}}2 + " @vimlint(EVL102, 0, l:true) + " @vimlint(EVL102, 0, l:false) + " @vimlint(EVL102, 0, l:null) +endif + +lockvar neomake#compat#json_true +lockvar neomake#compat#json_false +lockvar neomake#compat#json_null + +if exists('*uniq') + function! neomake#compat#uniq(l) abort + return uniq(a:l) + endfunction +else + function! neomake#compat#uniq(l) abort + let n = len(a:l) + if n < 2 + return a:l + endif + let prev = a:l[0] + let idx = 1 + while idx < n + if a:l[idx] ==# prev && type(a:l[idx]) == type(prev) + call remove(a:l, idx) + let n -= 1 + else + let prev = a:l[idx] + let idx += 1 + endif + endwhile + return a:l + endfunction +endif + +if exists('*reltimefloat') + function! neomake#compat#reltimefloat() abort + return reltimefloat(reltime()) + endfunction +else + function! neomake#compat#reltimefloat() abort + let t = split(reltimestr(reltime()), '\V.') + return str2float(t[0] . '.' . t[1]) + endfunction +endif + +" Wrapper around systemlist() that supports a list for a:cmd. +" It returns an empty string on error. +" NOTE: Neovim before 0.2.0 would throw an error (which is caught), but it +" does not set v:shell_error! +function! neomake#compat#systemlist(cmd) abort + if empty(a:cmd) + return [] + endif + if has('nvim') && exists('*systemlist') + " @vimlint(EVL108, 1) + if !has('nvim-0.2.0') + try + return systemlist(a:cmd) + catch /^Vim\%((\a\+)\)\=:E902/ + return '' + endtry + endif + " @vimlint(EVL108, 0) + return systemlist(a:cmd) + endif + + if type(a:cmd) == type([]) + let cmd = join(map(a:cmd, 'neomake#utils#shellescape(v:val)')) + else + let cmd = a:cmd + endif + if exists('*systemlist') + return systemlist(cmd) + endif + return split(system(cmd), '\n') +endfunction + +function! neomake#compat#globpath_list(path, pattern, suf) abort + if v:version >= 705 || (v:version == 704 && has('patch279')) + return globpath(a:path, a:pattern, a:suf, 1) + endif + return split(globpath(a:path, a:pattern, a:suf), '\n') +endfunction + +function! neomake#compat#glob_list(pattern) abort + if v:version <= 703 + return split(glob(a:pattern, 1), '\n') + endif + return glob(a:pattern, 1, 1) +endfunction + +if neomake#utils#IsRunningWindows() + " Windows needs a shell to handle PATH/%PATHEXT% etc. + function! neomake#compat#get_argv(exe, args, args_is_list) abort + let prefix = &shell.' '.&shellcmdflag.' ' + if a:args_is_list + if a:exe ==# &shell && get(a:args, 0) ==# &shellcmdflag + " Remove already existing &shell/&shellcmdflag from e.g. NeomakeSh. + let argv = join(a:args[1:]) + else + let argv = join(map(copy([a:exe] + a:args), 'neomake#utils#shellescape(v:val)')) + endif + else + let argv = a:exe . (empty(a:args) ? '' : ' '.a:args) + if argv[0:len(prefix)-1] ==# prefix + return argv + endif + endif + return prefix.argv + endfunction +elseif has('nvim') + function! neomake#compat#get_argv(exe, args, args_is_list) abort + if a:args_is_list + return [a:exe] + a:args + endif + return a:exe . (empty(a:args) ? '' : ' '.a:args) + endfunction +elseif neomake#has_async_support() " Vim-async. + function! neomake#compat#get_argv(exe, args, args_is_list) abort + if a:args_is_list + return [a:exe] + a:args + endif + " Use a shell to handle argv properly (Vim splits at spaces). + let argv = a:exe . (empty(a:args) ? '' : ' '.a:args) + return [&shell, &shellcmdflag, argv] + endfunction +else + " Vim (synchronously), via system(). + function! neomake#compat#get_argv(exe, args, args_is_list) abort + if a:args_is_list + return join(map(copy([a:exe] + a:args), 'neomake#utils#shellescape(v:val)')) + endif + return a:exe . (empty(a:args) ? '' : ' '.a:args) + endfunction +endif + +if v:version >= 704 || (v:version == 703 && has('patch831')) + function! neomake#compat#gettabwinvar(t, w, v, d) abort + return gettabwinvar(a:t, a:w, a:v, a:d) + endfunction +else + " Wrapper around gettabwinvar that has no default (older Vims). + function! neomake#compat#gettabwinvar(t, w, v, d) abort + let r = gettabwinvar(a:t, a:w, a:v) + if r is# '' + unlet r + let r = a:d + endif + return r + endfunction +endif + +" Not really necessary for now, but allows to overwriting and extending. +if exists('*nvim_get_mode') + function! neomake#compat#get_mode() abort + let mode = nvim_get_mode() + return mode.mode + endfunction +else + function! neomake#compat#get_mode() abort + return mode(1) + endfunction +endif + +function! neomake#compat#in_completion() abort + if pumvisible() + return 1 + endif + if has('patch-8.0.0283') + let mode = mode(1) + if mode[1] ==# 'c' || mode[1] ==# 'x' + return 1 + endif + endif + return 0 +endfunction + +let s:prev_windows = [] +if exists('*win_getid') + function! neomake#compat#save_prev_windows() abort + call add(s:prev_windows, [win_getid(winnr('#')), win_getid(winnr())]) + endfunction + + function! neomake#compat#restore_prev_windows() abort + " Go back, maintaining the '#' window (CTRL-W_p). + let [aw_id, pw_id] = remove(s:prev_windows, 0) + let pw = win_id2win(pw_id) + if !pw + call neomake#log#debug(printf( + \ 'Cannot restore previous windows (previous window with ID %d not found).', + \ pw_id)) + elseif winnr() != pw + let aw = win_id2win(aw_id) + if aw + exec aw . 'wincmd w' + endif + exec pw . 'wincmd w' + endif + endfunction +else + function! neomake#compat#save_prev_windows() abort + call add(s:prev_windows, [winnr('#'), winnr()]) + endfunction + + function! neomake#compat#restore_prev_windows() abort + " Go back, maintaining the '#' window (CTRL-W_p). + let [aw, pw] = remove(s:prev_windows, 0) + if pw > winnr('$') + call neomake#log#debug(printf( + \ 'Cannot restore previous windows (%d > %d).', + \ pw, winnr('$'))) + elseif winnr() != pw + if aw + exec aw . 'wincmd w' + endif + exec pw . 'wincmd w' + endif + endfunction +endif + +if v:version >= 704 || (v:version == 703 && has('patch442')) + function! neomake#compat#doautocmd(event) abort + exec 'doautocmd <nomodeline> ' . a:event + endfunction +else + function! neomake#compat#doautocmd(event) abort + exec 'doautocmd ' . a:event + endfunction +endif +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/config.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/config.vim new file mode 100644 index 0000000..5f03cd1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/config.vim @@ -0,0 +1,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 diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/configure.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/configure.vim new file mode 100644 index 0000000..f802d7f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/configure.vim @@ -0,0 +1,785 @@ +" Default settings, setup in global config dict. +let s:default_settings = { + \ 'ignore_filetypes': ['startify'], + \ } +let g:neomake = get(g:, 'neomake', {}) +let g:neomake.automake = get(g:neomake, 'automake', {}) +call extend(g:neomake.automake, s:default_settings, 'keep') + +if !exists('s:timer_info') + let s:timer_info = {} + let s:timer_by_bufnr = {} +endif + +let s:default_delay = has('timers') ? 500 : 0 + +" A mapping of configured buffers with cached settings (maker_jobs). +let s:configured_buffers = {} +" A list of configured/used autocommands. +let s:registered_events = [] + +" TextChanged gets triggered in this case when loading a buffer (Vim +" issue #2742). +let s:need_to_skip_first_textchanged = !has('nvim-0.3.2') && has('patch-8.0.1494') && !has('patch-8.0.1633') + + +" TODO: allow for namespaces, and prefer 'automake' here. +" TODO: handle bufnr! (getbufvar) +function! s:get_setting(name, default) abort + return get(get(b:, 'neomake', {}), a:name, + \ get(get(t:, 'neomake', {}), a:name, + \ get(get(g:, 'neomake', {}), a:name, a:default))) +endfunction + + +function! s:debug_log(msg, ...) abort + let context = {'bufnr': bufnr('%')} + if a:0 + call extend(context, a:1) + endif + call neomake#log#debug(printf('automake: %s.', a:msg), context) +endfunction + +" Check if buffer's tick (or ft) changed. +function! s:tick_changed(context) abort + let bufnr = +a:context.bufnr + let ft = get(a:context, 'ft', getbufvar(bufnr, '&filetype')) + let prev_tick = getbufvar(bufnr, '_neomake_automake_tick') + let r = 1 + if empty(prev_tick) + call s:debug_log('tick changed (new)') + else + let cur_tick = [getbufvar(bufnr, 'changedtick'), ft] + if cur_tick == prev_tick + call s:debug_log('tick is unchanged') + return 0 + endif + + " NOTE: every write (BufWritePost) increments b:changedtick. + if a:context.event ==# 'BufWritePost' + let adjusted_prev_tick = [prev_tick[0]+1, prev_tick[1]] + if adjusted_prev_tick == cur_tick + let r = 0 + call setbufvar(bufnr, '_neomake_automake_tick', adjusted_prev_tick) + call s:debug_log('tick is unchanged with BufWritePost adjustment') + endif + endif + endif + return r +endfunction + +function! neomake#configure#_update_automake_tick(bufnr, ft) abort + if has_key(s:configured_buffers, a:bufnr) + let tick = getbufvar(a:bufnr, 'changedtick') + call s:debug_log('updating tick: '.tick) + call setbufvar(a:bufnr, '_neomake_automake_tick', [tick, a:ft]) + endif +endfunction + +function! neomake#configure#_reset_automake_cancelations(bufnr) abort + if has_key(s:configured_buffers, a:bufnr) + call setbufvar(a:bufnr, '_neomake_cancelations', [0, 0]) + endif +endfunction + +function! s:update_cancel_rate(bufnr, via_timer) abort + let canceled = getbufvar(a:bufnr, '_neomake_cancelations', [0, 0]) + if a:via_timer + let canceled[0] += 1 + else + let canceled[1] += 1 + endif + call setbufvar(a:bufnr, '_neomake_cancelations', canceled) + return canceled +endfunction + +function! s:handle_changed_buffer(make_id, event) abort + " Cleanup always. + if exists('b:_neomake_automake_changed_context') + let [make_id, prev_tick, changedtick, context] = b:_neomake_automake_changed_context + + if s:need_to_skip_first_textchanged && a:event ==# 'TextChanged' + if !get(b:, '_neomake_seen_TextChanged', 0) + call s:debug_log('ignoring first TextChanged') + let b:_neomake_seen_TextChanged = 1 + return + endif + endif + + if changedtick == b:changedtick + call s:debug_log(printf('handle_changed_buffer: %s: tick was not changed', a:event)) + return + endif + + unlet b:_neomake_automake_changed_context + augroup neomake_automake_abort + au! * <buffer> + augroup END + else + return + endif + + if make_id != a:make_id + call neomake#log#warning(printf('automake: handle_changed_buffer: mismatched make_id: %d != %d.', make_id, a:make_id)) + return + endif + + let window_make_ids = get(w:, 'neomake_make_ids', []) + if index(window_make_ids, a:make_id) == -1 + return + endif + + call setbufvar(context.bufnr, '_neomake_automake_tick', prev_tick) + call filter(b:_neomake_automake_make_ids, 'v:val != '.a:make_id) + call s:update_cancel_rate(context.bufnr, 0) + + call s:debug_log(printf('buffer was changed (%s), canceling make', a:event), {'make_id': a:make_id}) + call neomake#CancelMake(a:make_id) + + if a:event ==# 'TextChangedI' + call s:debug_log('queueing make restart for InsertLeave', {'make_id': a:make_id}) + let b:_neomake_postponed_automake_context = [1, context] + augroup neomake_automake_retry + au! * <buffer> + autocmd InsertLeave <buffer> call s:do_postponed_automake(2) + augroup END + elseif context.delay + call s:debug_log(printf('restarting timer for original event %s', context.event), {'make_id': a:make_id}) + if has_key(context, '_via_timer_cb') + unlet context._via_timer_cb + endif + if has_key(context, 'pos') + unlet context.pos + endif + call s:neomake_do_automake(context) + else + call s:debug_log(printf('restarting for original event (%s) without delay', context.event)) + call s:neomake_do_automake(context) + endif +endfunction + +function! s:neomake_do_automake(context) abort + let bufnr = +a:context.bufnr + + if !get(a:context, '_via_timer_cb') && a:context.delay + if exists('s:timer_by_bufnr[bufnr]') + let timer = s:timer_by_bufnr[bufnr] + call s:stop_timer(timer) + call s:debug_log(printf('stopped existing timer: %d', timer), {'bufnr': bufnr}) + call s:update_cancel_rate(bufnr, 1) + endif + if !s:tick_changed(a:context) + call s:debug_log('buffer was not changed', {'bufnr': bufnr}) + return + endif + + " Cancel any already running automake runs. + let prev_make_ids = getbufvar(bufnr, '_neomake_automake_make_ids') + if !empty(prev_make_ids) + call s:debug_log(printf('stopping previous make runs: %s', join(prev_make_ids, ', '))) + for prev_make_id in prev_make_ids + call neomake#CancelMake(prev_make_id) + endfor + let canceled = s:update_cancel_rate(bufnr, 0) + else + let canceled = getbufvar(bufnr, '_neomake_cancelations', [0, 0]) + endif + + let delay = a:context.delay + + " Increase delay for canceled/restarted timers, and canceled makes. + " IDEA: take into account the mean duration of this make run. + if canceled[0] || canceled[1] + let [mult_timers, mult_makes, max_delay] = neomake#config#get('automake.cancelation_delay', [0.2, 0.5, 3000], {'bufnr': bufnr}) + let cancel_rate = 1 + (canceled[0]*mult_timers + canceled[1]*mult_makes) + let delay = min([max_delay, float2nr(ceil(delay * cancel_rate))]) + call s:debug_log(printf('increasing delay (%d/%d canceled timers/makes, rate=%.2f): %d => %d/%d', canceled[0], canceled[1], cancel_rate, a:context.delay, delay, max_delay)) + endif + + let timer = timer_start(delay, function('s:automake_delayed_cb')) + let s:timer_info[timer] = a:context + if !has_key(a:context, 'pos') + let s:timer_info[timer].pos = s:get_position_context() + endif + let s:timer_by_bufnr[bufnr] = timer + call s:debug_log(printf('started timer (%dms): %d', delay, timer), + \ {'bufnr': a:context.bufnr}) + return + endif + + let ft = getbufvar(bufnr, '&filetype') + let event = a:context.event + + call s:debug_log('neomake_do_automake: '.event, {'bufnr': bufnr}) + if !s:tick_changed({'event': event, 'bufnr': bufnr, 'ft': ft}) + call s:debug_log('buffer was not changed', {'bufnr': bufnr}) + return + endif + let prev_tick = getbufvar(bufnr, '_neomake_automake_tick') + + call s:debug_log(printf('enabled makers: %s', join(map(copy(a:context.maker_jobs), 'v:val.maker.name'), ', '))) + let make_options = { + \ 'file_mode': 1, + \ 'jobs': deepcopy(a:context.maker_jobs), + \ 'ft': ft, + \ 'automake': 1} + let jobinfos = neomake#Make(make_options) + + let started_jobs = filter(copy(jobinfos), "!get(v:val, 'finished', 0)") + call s:debug_log(printf('started jobs: %s', string(map(copy(started_jobs), 'v:val.id')))) + if !empty(started_jobs) + let make_id = jobinfos[0].make_id + call setbufvar(bufnr, '_neomake_automake_make_ids', + \ neomake#compat#getbufvar(bufnr, '_neomake_automake_make_ids', []) + [make_id]) + + " Setup buffer autocmd to cancel/restart make for changed buffer. + let events = [] + for event in ['TextChangedI', 'TextChanged'] + if a:context.event !=# event + call add(events, event) + endif + endfor + call setbufvar(bufnr, '_neomake_automake_changed_context', [make_id, prev_tick, getbufvar(bufnr, 'changedtick'), a:context]) + augroup neomake_automake_abort + exe printf('au! * <buffer=%d>', bufnr) + for event in events + exe printf('autocmd %s <buffer=%d> call s:handle_changed_buffer(%s, %s)', + \ event, bufnr, string(make_id), string(event)) + endfor + augroup END + endif +endfunction + +function! s:get_position_context() abort + let w = exists('*win_getid') ? win_getid() : winnr() + return [w, getpos('.'), neomake#compat#get_mode()] +endfunction + +function! s:automake_delayed_cb(timer) abort + let timer_info = s:timer_info[a:timer] + unlet s:timer_info[a:timer] + unlet s:timer_by_bufnr[timer_info.bufnr] + + if !bufexists(timer_info.bufnr) + call s:debug_log(printf('buffer does not exist anymore for timer %d', a:timer), + \ {'bufnr': timer_info.bufnr}) + return + endif + + call s:debug_log(printf('callback for timer %d (via %s)', string(a:timer), timer_info.event), + \ {'bufnr': timer_info.bufnr}) + + let bufnr = bufnr('%') + if timer_info.bufnr != bufnr + call s:debug_log(printf('buffer changed: %d => %d, queueing make restart for BufEnter,WinEnter', + \ timer_info.bufnr, bufnr)) + let restart_context = copy(timer_info) + call setbufvar(restart_context.bufnr, '_neomake_postponed_automake_context', [1, restart_context]) + let b:_neomake_postponed_automake_context = [1, restart_context] + augroup neomake_automake_retry + exe 'au! * <buffer='.timer_info.bufnr.'>' + exe 'autocmd BufEnter,WinEnter <buffer='.restart_context.bufnr.'> call s:do_postponed_automake(2)' + augroup END + return + endif + + if neomake#compat#in_completion() + call s:debug_log('postponing automake during completion') + if has_key(timer_info, 'pos') + unlet timer_info.pos + endif + let b:_neomake_postponed_automake_context = [0, timer_info] + + augroup neomake_automake_retry + au! * <buffer> + autocmd CompleteDone <buffer> call s:do_postponed_automake(1) + autocmd InsertLeave <buffer> call s:do_postponed_automake(2) + augroup END + return + endif + + " Verify context/position is the same. + " This is meant to give an additional delay after e.g. TextChanged. + " Only events with delay are coming here, so this does not affect + " BufWritePost etc typically. + if !empty(timer_info.pos) + let current_context = s:get_position_context() + if current_context != timer_info.pos + if current_context[2] != timer_info.pos[2] + " Mode was changed. + if current_context[2][0] ==# 'i' && timer_info.event !=# 'TextChangedI' + " Changed to insert mode, trigger on InsertLeave. + call s:debug_log(printf('context/position changed: %s => %s, restarting on InsertLeave', + \ string(timer_info.pos), string(current_context))) + let context = copy(timer_info) + let context.delay = 0 + unlet context.pos + call s:update_cancel_rate(bufnr, 1) + let b:_neomake_postponed_automake_context = [1, context] + augroup neomake_automake_retry + au! * <buffer> + autocmd InsertLeave <buffer> call s:do_postponed_automake(2) + augroup END + return + endif + endif + call s:debug_log(printf('context/position changed: %s => %s, restarting', + \ string(timer_info.pos), string(current_context))) + unlet timer_info.pos + call s:update_cancel_rate(bufnr, 1) + call s:neomake_do_automake(timer_info) + return + endif + endif + " endif + + let context = copy(timer_info) + let context._via_timer_cb = 1 + call s:neomake_do_automake(context) +endfunction + +function! s:do_postponed_automake(step) abort + if exists('b:_neomake_postponed_automake_context') + let context = b:_neomake_postponed_automake_context + + if context[0] == a:step - 1 + if a:step == 2 + call s:debug_log('re-starting postponed automake') + let context[1].pos = s:get_position_context() + call s:neomake_do_automake(context[1]) + else + let context[0] = a:step + return + endif + else + call s:debug_log('postponed automake: unexpected step '.a:step.', cleaning up') + endif + unlet b:_neomake_postponed_automake_context + else + call s:debug_log('missing context information for postponed automake') + endif + " Cleanup. + augroup neomake_automake_retry + autocmd! * <buffer> + augroup END +endfunction + +" Parse/get events dict from args. +" a:config: config dict to write into. +" a:string_or_dict_config: a string or dict describing the config. +" a:1: default delay. +function! s:parse_events_from_args(config, string_or_dict_config, ...) abort + " Get default delay from a:1. + if a:0 + if has('timers') + let delay = a:1 + else + if a:1 != 0 + call neomake#log#warning('automake: timer support is required for delayed events.') + endif + let delay = 0 + endif + else + let delay = s:default_delay + endif + + if type(a:string_or_dict_config) == type({}) + let events = copy(a:string_or_dict_config) + + " Validate events. + for [event, config] in items(events) + if !exists('##'.event) + call neomake#log#error(printf( + \ 'automake: event %s does not exist.', event)) + unlet events[event] + continue + endif + + if get(config, 'delay', 0) && !has('timers') + call neomake#log#error(printf( + \ 'automake: timer support is required for automaking, removing event %s.', + \ event)) + unlet events[event] + endif + endfor + call neomake#config#set_dict(a:config, 'automake.events', events) + if a:0 + let a:config.automake_delay = a:1 + endif + else + " Map string config to events dict. + let modes = a:string_or_dict_config + let events = {} + let default_with_delay = {} + + " Insert mode. + if modes =~# 'i' + if exists('##TextChangedI') && has('timers') + let events['TextChangedI'] = default_with_delay + else + call s:debug_log('using CursorHoldI instead of TextChangedI') + let events['CursorHoldI'] = (delay != 0 ? {'delay': 0} : {}) + endif + endif + " Normal mode. + if modes =~# 'n' + if exists('##TextChanged') && has('timers') + let events['TextChanged'] = default_with_delay + if !has_key(events, 'TextChangedI') + " Run when leaving insert mode, since only TextChangedI would be triggered + " for `ciw` etc. + let events['InsertLeave'] = default_with_delay + endif + else + call s:debug_log('using CursorHold instead of TextChanged') + let events['CursorHold'] = (delay != 0 ? {'delay': 0} : {}) + let events['InsertLeave'] = (delay != 0 ? {'delay': 0} : {}) + endif + endif + " On writes. + if modes =~# 'w' + let events['BufWritePost'] = (delay != 0 ? {'delay': 0} : {}) + endif + " On reads. + if modes =~# 'r' + let events['BufWinEnter'] = {} + let events['FileType'] = {} + + " When a file was changed outside of Vim. + " TODO: test + let events['FileChangedShellPost'] = {} + " XXX: FileType might work better, at least when wanting to skip filetypes. + " let events['FileType'] = {'delay': a:0 > 1 ? delay : 0} + endif + endif + + call neomake#config#set_dict(a:config, 'automake.events', events) + if a:0 + let a:config.automake_delay = delay + endif +endfunction + +" Setup automake for buffer (current, or options.bufnr). +" a:1: delay +" a:2: options ('bufnr', 'makers') / or list of makers TODO +function! neomake#configure#automake_for_buffer(string_or_dict_config, ...) abort + let options = {} + if a:0 + let options.delay = a:1 + endif + let bufnr = bufnr('%') + if a:0 > 1 + if type(a:2) == type([]) + let options.makers = a:2 + else + call extend(options, a:2) + if has_key(options, 'bufnr') + let bufnr = options.bufnr + unlet options.bufnr + endif + endif + endif + return call('s:configure_buffer', [bufnr, a:string_or_dict_config, options]) +endfunction + +" Workaround for getbufvar not having support for defaults. +function! s:getbufvar(bufnr, name, default) abort + let b_dict = getbufvar(+a:bufnr, '') + if empty(b_dict) + " NOTE: it is an empty string for non-existing buffers. + return a:default + endif + return get(b_dict, a:name, a:default) +endfunction + +function! s:is_buffer_ignored(bufnr) abort + " TODO: blacklist/whitelist. + let bufnr = +a:bufnr + let buftype = getbufvar(bufnr, '&buftype') + if !empty(buftype) + call s:debug_log(printf('ignoring buffer with buftype=%s', buftype), {'bufnr': bufnr}) + return 1 + endif + + let ft = getbufvar(bufnr, '&filetype') + if index(neomake#config#get('automake.ignore_filetypes', []), ft) != -1 + call s:debug_log(printf('ignoring buffer with filetype=%s', ft), {'bufnr': bufnr}) + return 1 + endif +endfunction + +if exists('##OptionSet') + function! s:update_buffer_options() abort + let bufnr = bufnr('%') + call s:maybe_reconfigure_buffer(bufnr) + endfunction + augroup neomake_automake_update + au! + au OptionSet buftype call s:update_buffer_options() + augroup END +endif + +" a:1: string or dict describing the events +" a:2: options ('delay', 'makers') +function! s:configure_buffer(bufnr, ...) abort + let bufnr = +a:bufnr + let ft = getbufvar(bufnr, '&filetype') + let config = s:getbufvar(bufnr, 'neomake', {}) + let old_config = deepcopy(config) + if a:0 + let args = [config, a:1] + if a:0 > 1 && has_key(a:2, 'delay') + let args += [a:2.delay] + endif + call call('s:parse_events_from_args', args) + call setbufvar(bufnr, 'neomake', config) + + let implicit_config = {'custom': 1, 'ignore': 0} + else + let implicit_config = {'custom': 0, 'ignore': s:is_buffer_ignored(bufnr)} + endif + + " Register the buffer, and remember if it is custom. + if has_key(s:configured_buffers, bufnr) + let old_registration = copy(get(s:configured_buffers, bufnr, {})) + call extend(s:configured_buffers[bufnr], implicit_config, 'force') + else + let s:configured_buffers[bufnr] = implicit_config + + augroup neomake_automake_clean + autocmd BufWipeout <buffer> call s:neomake_automake_clean(expand('<abuf>')) + augroup END + endif + + if implicit_config.ignore + return s:configured_buffers[bufnr] + endif + + let s:configured_buffers[bufnr].events_config = neomake#config#get('automake.events', {}) + + " Create jobs. + let options = a:0 > 1 ? a:2 : {} + if has_key(options, 'makers') + let makers = neomake#map_makers(options.makers, ft, 0) + let source = 'options' + else + let [makers, source] = neomake#config#get_with_source('automake.enabled_makers') + if makers is g:neomake#config#undefined + unlet makers + let makers = neomake#GetEnabledMakers(ft) + else + let makers = neomake#map_makers(makers, ft, 0) + endif + endif + let options = {'file_mode': 1, 'ft': ft, 'bufnr': bufnr, 'automake': 1} + let jobs = neomake#core#create_jobs(options, makers) + let s:configured_buffers[bufnr].maker_jobs = jobs + call s:debug_log(printf('configured buffer for ft=%s (%s)', + \ ft, empty(jobs) ? 'no enabled makers' : join(map(copy(jobs), 'v:val.maker.name'), ', ').' ('.source.')'), {'bufnr': bufnr}) + if old_config != config + call s:debug_log('resetting tick because of config changes') + call setbufvar(bufnr, '_neomake_automake_tick', []) + elseif exists('old_registration') + if old_registration != s:configured_buffers[bufnr] + call s:debug_log('resetting tick because of registration changes') + call setbufvar(bufnr, '_neomake_automake_tick', []) + endif + else + call s:debug_log('setting tick for new buffer') + call setbufvar(bufnr, '_neomake_automake_tick', []) + endif + + if a:0 + " Setup autocommands etc (when called manually)?! + call neomake#configure#automake() + endif + return config +endfunction + +function! s:maybe_reconfigure_buffer(bufnr) abort + if has_key(s:configured_buffers, a:bufnr) && !s:configured_buffers[a:bufnr].custom + call s:configure_buffer(a:bufnr) + endif +endfunction + +" Called from autocommands. +function! s:neomake_automake(event, bufnr) abort + let disabled = neomake#config#get_with_source('disabled', 0) + if disabled[0] + call s:debug_log(printf('disabled (%s)', disabled[1])) + return + endif + let bufnr = +a:bufnr + + if has_key(s:configured_buffers, bufnr) + let buffer_config = s:configured_buffers[bufnr] + else + " Register the buffer, and remember that it's automatic. + let buffer_config = s:configure_buffer(bufnr) + endif + if get(buffer_config, 'ignore', 0) + " NOTE: might be too verbose. + call s:debug_log('buffer is ignored') + return + endif + + if s:need_to_skip_first_textchanged && a:event ==# 'TextChanged' + if !getbufvar(bufnr, '_neomake_seen_TextChanged', 0) + call s:debug_log('ignoring first TextChanged') + call setbufvar(bufnr, '_neomake_seen_TextChanged', 1) + return + endif + endif + + call s:debug_log(printf('handling event %s', a:event), {'bufnr': bufnr}) + + if empty(s:configured_buffers[bufnr].maker_jobs) + call s:debug_log('no enabled makers', {'bufnr': bufnr}) + return + endif + + call s:debug_log(printf('automake for event %s', a:event), {'bufnr': bufnr}) + let config = s:configured_buffers[bufnr].events_config + if !has_key(config, a:event) + call s:debug_log('event is not registered', {'bufnr': bufnr}) + return + endif + let config = config[a:event] + + let event = a:event + let bufnr = +a:bufnr + " TODO: rename to neomake.automake.delay + let delay = get(config, 'delay', s:get_setting('automake_delay', s:default_delay)) + let context = { + \ 'delay': delay, + \ 'bufnr': bufnr, + \ 'event': a:event, + \ 'maker_jobs': s:configured_buffers[bufnr].maker_jobs, + \ } + if event ==# 'BufWinEnter' + " Ignore context, so that e.g. with vim-stay restoring the view + " (cursor position), it will still be triggered. + let context.pos = [] + endif + call s:neomake_do_automake(context) +endfunction + +function! s:stop_timer(timer) abort + let timer_info = s:timer_info[a:timer] + unlet s:timer_info[a:timer] + unlet s:timer_by_bufnr[timer_info.bufnr] + call timer_stop(+a:timer) +endfunction + +function! s:stop_timers() abort + let timers = keys(s:timer_info) + if !empty(timers) + call s:debug_log(printf('stopping timers: %s', join(timers, ', '))) + for timer in timers + call s:stop_timer(timer) + endfor + endif +endfunction + +function! neomake#configure#reset_automake() abort + for bufnr in keys(s:configured_buffers) + call s:neomake_automake_clean(bufnr) + endfor + let s:registered_events = [] + call s:stop_timers() + call neomake#configure#automake() +endfunction + +function! s:neomake_automake_clean(bufnr) abort + if has_key(s:timer_by_bufnr, a:bufnr) + let timer = s:timer_by_bufnr[a:bufnr] + call s:stop_timer(timer) + call s:debug_log('stopped timer for cleaned buffer: '.timer) + endif + if has_key(s:configured_buffers, a:bufnr) + unlet s:configured_buffers[a:bufnr] + augroup neomake_automake_clean + exe printf('au! * <buffer=%d>', a:bufnr) + augroup END + endif +endfunction + +function! neomake#configure#disable_automake() abort + call s:debug_log('disabling globally') + call s:stop_timers() +endfunction + +function! neomake#configure#disable_automake_for_buffer(bufnr) abort + call s:debug_log(printf('disabling buffer %d', a:bufnr)) + if has_key(s:timer_by_bufnr, a:bufnr) + let timer = s:timer_by_bufnr[a:bufnr] + call s:stop_timer(timer) + call s:debug_log('stopped timer for buffer: '.timer) + endif + if has_key(s:configured_buffers, a:bufnr) + let s:configured_buffers[a:bufnr].disabled = 1 + endif +endfunction + +function! neomake#configure#enable_automake_for_buffer(bufnr) abort + if exists('s:configured_buffers[a:bufnr].disabled') + call s:debug_log(printf('Re-enabled buffer %d', a:bufnr)) + unlet s:configured_buffers[a:bufnr].disabled + endif +endfunction + +function! neomake#configure#reset_automake_for_buffer(...) abort + let bufnr = a:0 ? +a:1 : bufnr('%') + call s:neomake_automake_clean(bufnr) +endfunction + +function! neomake#configure#automake(...) abort + call s:debug_log(printf('configuring automake: %s', string(a:000))) + if !exists('g:neomake') + let g:neomake = {} + endif + if a:0 + call call('s:parse_events_from_args', [g:neomake] + a:000) + endif + + let disabled_globally = get(get(g:, 'neomake', {}), 'disabled', 0) + if disabled_globally + let s:registered_events = [] + else + let s:registered_events = keys(get(get(g:neomake, 'automake', {}), 'events', {})) + endif + " Keep custom configured buffers. + call filter(s:configured_buffers, 'v:val.custom') + for b in keys(s:configured_buffers) + if empty(s:configured_buffers[b].maker_jobs) + continue + endif + if get(s:configured_buffers[b], 'disabled', 0) + continue + endif + let b_cfg = neomake#config#get('b:automake.events', {}) + for event_config in items(b_cfg) + let event = event_config[0] + if index(s:registered_events, event) == -1 + call add(s:registered_events, event) + endif + endfor + endfor + call s:debug_log('registered events: '.join(s:registered_events, ', ')) + + augroup neomake_automake + au! + for event in s:registered_events + exe 'autocmd '.event." * call s:neomake_automake('".event."', expand('<abuf>'))" + endfor + augroup END + if empty(s:registered_events) + augroup! neomake_automake + endif +endfunction + +augroup neomake_automake_base + au! + autocmd FileType * call s:maybe_reconfigure_buffer(expand('<abuf>')) +augroup END +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/core.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/core.vim new file mode 100644 index 0000000..b61a351 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/core.vim @@ -0,0 +1,120 @@ +let g:neomake#core#valid_maker_name_pattern = '\v^\w+$' + +let g:neomake#core#_ignore_autocommands = 0 + +function! neomake#core#create_jobs(options, makers) abort + let args = [a:options, a:makers] + let jobs = call('s:bind_makers_for_job', args) + return jobs +endfunction + +" Map/bind a:makers to a list of job options, using a:options. +function! s:bind_makers_for_job(options, makers) abort + let r = [] + for maker in a:makers + let options = copy(a:options) + try + let maker = neomake#core#instantiate_maker(maker, options, 1) + catch /^Neomake: skip_job: / + let msg = substitute(v:exception, '^Neomake: skip_job: ', '', '') + call neomake#log#debug(printf('%s: skipping job: %s.', + \ maker.name, msg), options) + continue + catch /^Neomake: / + let error = substitute(v:exception, '^Neomake: ', '', '').'.' + call neomake#log#error(error, options) + continue + endtry + if !empty(maker) + let options.maker = maker + let r += [options] + endif + endfor + return r +endfunction + +function! neomake#core#instantiate_maker(maker, options, check_exe) abort + let maker = a:maker + let options = a:options + let ft = get(options, 'ft', '') + let bufnr = get(options, 'bufnr', '') + + " Call InitForJob function in maker object, if any. + let l:Init = neomake#utils#GetSetting('InitForJob', maker, g:neomake#config#undefined, ft, bufnr) + if empty(Init) + " Deprecated: should use InitForJob instead. + if has_key(maker, 'fn') + unlet Init " vim73 + let l:Init = maker.fn + call neomake#log#warn_once(printf("Please use 'InitForJob' instead of 'fn' for maker %s.", maker.name), + \ printf('deprecated-fn-%s', maker.name)) + endif + endif + if !empty(Init) + let returned_maker = call(Init, [options], maker) + if returned_maker isnot# 0 + " This conditional assignment allows to both return a copy + " (factory), while also can be used as a init method. + let maker = returned_maker + endif + endif + + if has_key(maker, '_bind_args') + call maker._bind_args() + if type(maker.exe) != type('') + let error = printf('Non-string given for executable of maker %s: type %s', + \ maker.name, type(maker.exe)) + if !get(maker, 'auto_enabled', 0) + throw 'Neomake: '.error + endif + call neomake#log#debug(error.'.', options) + return {} + endif + if a:check_exe && !executable(maker.exe) + if get(maker, 'auto_enabled', 0) + call neomake#log#debug(printf( + \ 'Exe (%s) of auto-configured maker %s is not executable, skipping.', maker.exe, maker.name), options) + else + let error = printf('Exe (%s) of maker %s is not executable', maker.exe, maker.name) + throw 'Neomake: '.error + endif + return {} + endif + endif + return maker +endfunction + +" Base class for command makers. +let g:neomake#core#command_maker_base = {} + +function! g:neomake#core#command_maker_base._get_fname_for_args(jobinfo) abort dict + " Append file? (defaults to jobinfo.file_mode, project/global makers should set it to 0) + let append_file = neomake#utils#GetSetting('append_file', self, a:jobinfo.file_mode, a:jobinfo.ft, a:jobinfo.bufnr) + " Use/generate a filename? (defaults to 1 if tempfile_name is set) + let uses_filename = append_file || neomake#utils#GetSetting('uses_filename', self, has_key(self, 'tempfile_name'), a:jobinfo.ft, a:jobinfo.bufnr) + if append_file || uses_filename + let filename = self._get_fname_for_buffer(a:jobinfo) + if append_file + return filename + endif + endif + return '' +endfunction + +function! g:neomake#core#command_maker_base._get_argv(_jobinfo) abort dict + return neomake#compat#get_argv(self.exe, self.args, type(self.args) == type([])) +endfunction + +" Get tabnr and winnr for a given make ID. +function! neomake#core#get_tabwin_for_makeid(make_id) abort + let curtab = tabpagenr() + for t in [curtab] + range(1, curtab-1) + range(curtab+1, tabpagenr('$')) + for w in range(1, tabpagewinnr(t, '$')) + if index(neomake#compat#gettabwinvar(t, w, 'neomake_make_ids', []), a:make_id) != -1 + return [t, w] + endif + endfor + endfor + return [-1, -1] +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/debug.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/debug.vim new file mode 100644 index 0000000..66abcaf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/debug.vim @@ -0,0 +1,273 @@ +" Debug/feedback helpers. + +function! neomake#debug#pprint(d, ...) abort + return call('s:pprint', [a:d] + a:000) +endfunction + +function! s:pprint(v, ...) abort + let indent = a:0 ? a:1 : '' + if type(a:v) ==# type({}) + if empty(a:v) + return '{}' + endif + let r = "{\n" + for [k, l:V] in items(a:v) + let r .= printf("%s %s: %s,\n", + \ indent, + \ string(k), + \ s:pprint(neomake#utils#fix_self_ref(V), indent . ' ')) + unlet V " old-vim + endfor + let r .= indent.'}' + return r + elseif type(a:v) ==# type([]) + if empty(a:v) + return '[]' + endif + let r = '['."\n".join(map(copy(a:v), 'indent." ".s:pprint(v:val, indent." ")'), ",\n").",\n".indent.']' + return r + endif + return string(a:v) +endfunction + +function! neomake#debug#validate_maker(maker) abort + let issues = {'errors': [], 'warnings': []} + + if has_key(a:maker, 'process_json') && has_key(a:maker, 'process_output') + let issues.warnings += ['maker has process_json and process_output, but only process_json will be used.'] + let check_process = ['process_json'] + else + let check_process = ['process_json', 'process_output'] + endif + + for f in check_process + if has_key(a:maker, f) + if has_key(a:maker, 'mapexpr') + let issues.warnings += [printf( + \ 'maker has mapexpr, but only %s will be used.', + \ f)] + endif + if has_key(a:maker, 'postprocess') + let issues.warnings += [printf( + \ 'maker has postprocess, but only %s will be used.', + \ f)] + endif + if has_key(a:maker, 'errorformat') + let issues.warnings += [printf( + \ 'maker has errorformat, but only %s will be used.', + \ f)] + endif + endif + endfor + + try + let maker = neomake#core#instantiate_maker(a:maker, {}, 0) + if !executable(maker.exe) + let t = get(maker, 'auto_enabled', 0) ? 'warnings' : 'errors' + let issues[t] += [printf("maker's exe (%s) is not executable.", maker.exe)] + endif + catch /^Neomake: / + let issues.errors += [substitute(v:exception, '^Neomake: ', '', '').'.'] + endtry + + if has_key(a:maker, 'name') + if a:maker.name !~# g:neomake#core#valid_maker_name_pattern + call add(issues['errors'], printf( + \ 'Invalid maker name: %s (should match %s)', + \ string(a:maker.name), + \ string(g:neomake#core#valid_maker_name_pattern))) + endif + endif + + return issues +endfunction + +" Optional arg: ft +function! s:get_makers_info(...) abort + let maker_names = call('neomake#GetEnabledMakers', a:000) + if empty(maker_names) + return ['None.'] + endif + let maker_defaults = g:neomake#config#_defaults['maker_defaults'] + let r = [] + for maker_name in maker_names + let maker = call('neomake#GetMaker', [maker_name] + a:000) + let r += [' - '.maker.name] + let r += map(s:get_maker_info(maker, maker_defaults), "' '.v:val") + endfor + return r +endfunction + +function! s:get_maker_info(maker, ...) abort + let maker_defaults = a:0 ? a:1 : {} + let maker = a:maker + let r = [] + for [k, l:V] in sort(copy(items(maker))) + if k !=# 'name' && k !=# 'ft' && k !~# '^_' + if !has_key(maker_defaults, k) + \ || type(V) != type(maker_defaults[k]) + \ || V !=# maker_defaults[k] + let r += [' - '.k.': '.string(V)] + endif + endif + unlet V " vim73 + endfor + + let issues = neomake#debug#validate_maker(maker) + if !empty(issues) + for type in sort(copy(keys(issues))) + let items = issues[type] + if !empty(items) + let r += [' - '.toupper(type) . ':'] + for issue in items + let r += [' - ' . issue] + endfor + endif + endfor + endif + + if type(maker.exe) == type('') && executable(maker.exe) + let version_arg = get(maker, 'version_arg', '--version') + let exe = exists('*exepath') ? exepath(maker.exe) : maker.exe + let version_output = neomake#compat#systemlist([exe, version_arg]) + if empty(version_output) + let version_output = [printf( + \ 'failed to get version information (%s)', + \ v:shell_error)] + endif + let r += [printf(' - version information (%s %s): %s', + \ exe, + \ version_arg, + \ join(version_output, "\n "))] + endif + return r +endfunction + +function! s:get_fts_with_makers() abort + return neomake#compat#uniq(sort(map(split(globpath(escape(&runtimepath, ' '), + \ 'autoload/neomake/makers/ft/*.vim'), "\n"), + \ 'fnamemodify(v:val, ":t:r")'))) +endfunction + +function! neomake#debug#get_maker_info(maker_name) abort + let source = '' + let maker = neomake#get_maker_by_name(a:maker_name, &filetype) + if empty(maker) + let maker = neomake#get_maker_by_name(a:maker_name) + if empty(maker) + let fts = filter(s:get_fts_with_makers(), 'v:val != &filetype') + for ft in fts + let maker = neomake#get_maker_by_name(a:maker_name, ft) + if !empty(maker) + let source = 'filetype '.ft + break + endif + endfor + else + let source = 'project maker' + endif + endif + if empty(maker) + call neomake#log#error(printf('Maker not found: %s.', a:maker_name)) + return [] + endif + let maker = neomake#create_maker_object(maker, &filetype) + return [maker.name . (empty(source) ? '' : ' ('.source.')')] + \ + s:get_maker_info(maker) +endfunction + +function! neomake#debug#display_info(...) abort + let bang = a:0 ? a:1 : 0 + if a:0 > 1 + let maker_name = a:2 + let lines = neomake#debug#get_maker_info(maker_name) + else + let lines = neomake#debug#_get_info_lines() + endif + if bang + try + call setreg('+', join(lines, "\n"), 'l') + catch + call neomake#log#error(printf( + \ 'Could not set clipboard: %s.', v:exception)) + return + endtry + echom 'Copied Neomake info to clipboard ("+).' + else + echon join(lines, "\n") + endif +endfunction + +function! s:trim(s) abort + return substitute(a:s, '\v^[ \t\r\n]+|[ \t\r\n]+$', '', 'g') +endfunction + +function! neomake#debug#_get_info_lines() abort + let r = [] + let ft = &filetype + + let r += ['#### Neomake debug information'] + let r += [''] + let r += ['Async support: '.neomake#has_async_support()] + let r += ['Current filetype: '.ft] + let r += ['Windows: '.neomake#utils#IsRunningWindows()] + let r += ['[shell, shellcmdflag, shellslash]: '.string([&shell, &shellcmdflag, &shellslash])] + let r += [join(map(split(neomake#utils#redir('verb set makeprg?'), '\n'), 's:trim(v:val)'), ', ')] + + let r += [''] + let r += ['##### Enabled makers'] + let r += [''] + let r += ['For the current filetype ("'.ft.'", used with :Neomake):'] + let r += s:get_makers_info(ft) + if empty(ft) + let r += ['NOTE: the current buffer does not have a filetype.'] + else + let conf_ft = neomake#utils#get_ft_confname(ft) + let r += ['NOTE: you can define g:neomake_'.conf_ft.'_enabled_makers' + \ .' to configure it (or b:neomake_'.conf_ft.'_enabled_makers).'] + endif + let r += [''] + let r += ['For the project (used with :Neomake!):'] + let r += s:get_makers_info() + let r += ['NOTE: you can define g:neomake_enabled_makers to configure it.'] + let r += [''] + let r += ['Default maker settings:'] + for [k, v] in items(neomake#config#get('maker_defaults')) + let r += [' - '.k.': '.string(v)] + unlet! v " Fix variable type mismatch with Vim 7.3. + endfor + let r += [''] + let r += ['##### Settings'] + let r += [''] + let r += ['###### New-style (dict, overrides old-style)'] + let r += [''] + let r += ['```'] + + let r += ['g:neomake: '.(exists('g:neomake') ? s:pprint(g:neomake) : 'unset')] + let r += ['b:neomake: '.(exists('b:neomake') ? s:pprint(b:neomake) : 'unset')] + let r += ['```'] + let r += [''] + let r += ['###### Old-style'] + let r += [''] + let r += ['```'] + for [k, V] in sort(items(filter(copy(g:), "v:key =~# '^neomake_'"))) + let r += ['g:'.k.' = '.string(V)] + unlet! V " Fix variable type mismatch with Vim 7.3. + endfor + let r += [''] + let r += ['```'] + let r += ["\n"] + let r += ['#### :version'] + let r += [''] + let r += ['```'] + let r += split(neomake#utils#redir('version'), '\n') + let r += ['```'] + let r += [''] + let r += ['#### :messages'] + let r += [''] + let r += ['```'] + let r += split(neomake#utils#redir('messages'), '\n') + let r += ['```'] + return r +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/highlights.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/highlights.vim new file mode 100644 index 0000000..cdc416a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/highlights.vim @@ -0,0 +1,155 @@ +" vim: ts=4 sw=4 et + +let s:highlights = {'file': {}, 'project': {}} +let s:highlight_types = { + \ 'E': 'NeomakeError', + \ 'W': 'NeomakeWarning', + \ 'I': 'NeomakeInfo', + \ 'M': 'NeomakeMessage' + \ } + +let s:nvim_api = exists('*nvim_buf_add_highlight') + +" Used in tests. +function! neomake#highlights#_get() abort + return s:highlights +endfunction + +if s:nvim_api + function! s:InitBufHighlights(type, buf) abort + if !bufexists(a:buf) + " The buffer might be wiped by now: prevent 'Invalid buffer id'. + return + endif + if has_key(s:highlights[a:type], a:buf) + call nvim_buf_clear_highlight(a:buf, s:highlights[a:type][a:buf], 0, -1) + else + let s:highlights[a:type][a:buf] = nvim_buf_add_highlight(a:buf, 0, '', 0, 0, -1) + endif + endfunction + + function! s:reset(type, buf) abort + if has_key(s:highlights[a:type], a:buf) + call nvim_buf_clear_highlight(a:buf, s:highlights[a:type][a:buf], 0, -1) + unlet s:highlights[a:type][a:buf] + endif + endfunction +else + function! s:InitBufHighlights(type, buf) abort + let s:highlights[a:type][a:buf] = { + \ 'NeomakeError': [], + \ 'NeomakeWarning': [], + \ 'NeomakeInfo': [], + \ 'NeomakeMessage': [] + \ } + endfunction + + function! s:reset(type, buf) abort + if has_key(s:highlights[a:type], a:buf) + unlet s:highlights[a:type][a:buf] + call neomake#highlights#ShowHighlights() + endif + endfunction +endif + +function! neomake#highlights#ResetFile(buf) abort + call s:reset('file', a:buf) +endfunction +function! neomake#highlights#ResetProject(...) abort + if a:0 " deprecated a:buf + call neomake#log#warn_once('neomake#highlights#ResetProject does not use a:buf anymore.', + \ 'deprecated-highlight-resetproject') + endif + for buf in keys(s:highlights['project']) + call s:reset('project', +buf) + endfor +endfunction + +function! neomake#highlights#AddHighlight(entry, type) abort + " Some makers use line 0 for file warnings (which cannot be highlighted, + " e.g. cpplint with "no copyright" warnings). + if a:entry.lnum == 0 + return + endif + + if !has_key(s:highlights[a:type], a:entry.bufnr) + call s:InitBufHighlights(a:type, a:entry.bufnr) + endif + let hi = get(s:highlight_types, toupper(a:entry.type), 'NeomakeError') + + if a:entry.col > 0 && get(g:, 'neomake_highlight_columns', 1) + let length = get(a:entry, 'length', 1) + if s:nvim_api + call nvim_buf_add_highlight(a:entry.bufnr, s:highlights[a:type][a:entry.bufnr], hi, a:entry.lnum - 1, a:entry.col - 1, a:entry.col + length - 1) + else + call add(s:highlights[a:type][a:entry.bufnr][hi], [a:entry.lnum, a:entry.col, length]) + endif + elseif get(g:, 'neomake_highlight_lines', 0) + if s:nvim_api + call nvim_buf_add_highlight(a:entry.bufnr, s:highlights[a:type][a:entry.bufnr], hi, a:entry.lnum - 1, 0, -1) + else + call add(s:highlights[a:type][a:entry.bufnr][hi], a:entry.lnum) + endif + endif +endfunction + +if s:nvim_api + function! neomake#highlights#ShowHighlights() abort + endfunction +else + function! neomake#highlights#ShowHighlights() abort + if exists('w:neomake_highlights') + for highlight in w:neomake_highlights + try + call matchdelete(highlight) + catch /^Vim\%((\a\+)\)\=:E803/ + endtry + endfor + endif + let w:neomake_highlights = [] + + let buf = bufnr('%') + for type in ['file', 'project'] + for [hi, locs] in items(filter(copy(get(s:highlights[type], buf, {})), '!empty(v:val)')) + if exists('*matchaddpos') + call add(w:neomake_highlights, matchaddpos(hi, locs)) + else + for loc in locs + if len(loc) == 1 + call add(w:neomake_highlights, matchadd(hi, '\%' . loc[0] . 'l')) + else + call add(w:neomake_highlights, matchadd(hi, '\%' . loc[0] . 'l\%' . loc[1] . 'c.\{' . loc[2] . '}')) + endif + endfor + endif + endfor + endfor + endfunction +endif + +function! neomake#highlights#DefineHighlights() abort + for [group, link] in items({ + \ 'NeomakeError': 'SpellBad', + \ 'NeomakeWarning': 'SpellCap', + \ 'NeomakeInfo': 'NeomakeWarning', + \ 'NeomakeMessage': 'NeomakeWarning' + \ }) + if !neomake#utils#highlight_is_defined(group) + exe 'highlight link '.group.' '.link + endif + endfor +endfunction + +function! s:wipe_highlights(bufnr) abort + for type in ['file', 'project'] + if has_key(s:highlights[type], a:bufnr) + unlet s:highlights[type][a:bufnr] + endif + endfor +endfunction +augroup neomake_highlights + au! + autocmd BufWipeout * call s:wipe_highlights(expand('<abuf>')) +augroup END + +call neomake#highlights#DefineHighlights() diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/jobinfo.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/jobinfo.vim new file mode 100644 index 0000000..278a3f5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/jobinfo.vim @@ -0,0 +1,87 @@ +let s:jobinfo_base = { + \ 'cd_back_cmd': '', + \ 'pending_output': [], + \ } +function! s:jobinfo_base.get_pid() abort + if has_key(self, 'vim_job') + let info = job_info(self.vim_job) + if info.status ==# 'run' + return info.process + endif + return -1 + endif + try + return jobpid(self.nvim_job) + catch /^Vim(return):E900:/ + return -1 + endtry +endfunction + +function! s:jobinfo_base.as_string() abort + let extra = [] + for k in ['canceled', 'finished'] + if get(self, k, 0) + let extra += [k] + endif + endfor + return printf('Job %d: %s%s', self.id, self.name, + \ empty(extra) ? '' : ' ['.join(extra, ', ').']') +endfunction + +function! s:jobinfo_base.cd_back() abort + if !empty(self.cd_back_cmd) + exe self.cd_back_cmd + let self.cd_back_cmd = '' + endif +endfunction + +function! s:jobinfo_base.cd(...) abort + if a:0 + if has_key(self, 'cd_from_setting') + call neomake#log#debug(printf( + \ 'jobinfo.cd(): keeping cwd from setting: %s.', + \ string(self.cd_from_setting)), self) + return '' + endif + let dir = a:1 + else + let maker = self.maker + let dir = neomake#utils#GetSetting('cwd', maker, '', self.ft, self.bufnr, 1) + if !empty(dir) + let self.cd_from_setting = dir + endif + endif + + if dir !=# '' + if dir[0:1] ==# '%:' + let dir = neomake#utils#fnamemodify(self.bufnr, dir[1:]) + else + let dir = expand(dir, 1) + endif + let dir = fnamemodify(dir, ':p') + " NOTE: need to keep trailing backslash with "/" and "X:\" on Windows. + if dir !=# '/' && dir[-1:] ==# neomake#utils#Slash() && dir[-2] !=# ':' + let dir = dir[:-2] + endif + else + let dir = get(self, 'cwd', $HOME) + endif + + let cur_wd = getcwd() + if dir !=# cur_wd + let [cd_error, cd_back_cmd] = neomake#utils#temp_cd(dir, cur_wd) + if !empty(cd_error) + call neomake#log#debug(printf('jobinfo.cd(): error when trying to change cwd to %s: %s.', + \ dir, cd_error)) + return cd_error + endif + let self.cwd = dir + let self.cd_back_cmd = cd_back_cmd + else + let self.cwd = cur_wd + endif + return '' +endfunction + +let g:neomake#jobinfo#base = s:jobinfo_base +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/list.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/list.vim new file mode 100644 index 0000000..120b665 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/list.vim @@ -0,0 +1,1020 @@ +scriptencoding utf-8 +" Create a List object from a quickfix/location list. +" TODO: (optionally?) add entries sorted? (errors first, grouped by makers (?) etc) + +let s:can_set_qf_title = has('patch-7.4.2200') +let s:can_set_qf_context = has('patch-8.0.0590') +let s:can_set_qf_items = has('patch-8.0.0657') +let s:has_support_for_qfid = has('patch-8.0.1023') +let s:use_efm_parsing = has('patch-8.0.1040') " 'efm' in setqflist/getqflist + +" Do we need to replace (instead of append) the location/quickfix list, for +" :lwindow to not open it with only invalid entries?! +" Without patch-7.4.379 this does not work though, and a new list needs to +" be created (which is not done). +" @vimlint(EVL108, 1) +let s:needs_to_replace_qf_for_lwindow = has('patch-7.4.379') + \ && (!has('patch-7.4.1752') || (has('nvim') && !has('nvim-0.2.0'))) +" @vimlint(EVL108, 0) +let s:needs_to_init_qf_for_lwindow = !has('patch-8.1.0622') + +function! neomake#list#ListForMake(make_info) abort + let type = a:make_info.options.file_mode ? 'loclist' : 'quickfix' + let list = neomake#list#List(type) + let list.make_info = a:make_info + if type ==# 'loclist' + let info = get(w:, '_neomake_info', {}) + let info['loclist'] = list + let w:_neomake_info = info + else + let info = get(g:, '_neomake_info', {}) + let info['qflist'] = list + let g:_neomake_info = info + endif + return list +endfunction + +" a:type: "loclist" or "quickfix" +function! neomake#list#List(type) abort + let list = deepcopy(s:base_list) + let list.type = a:type + " Display debug messages about changed entries. + let list.debug = get(g:, 'neomake_debug_list', + \ exists('g:neomake_test_messages') + \ || !empty(get(g:, 'neomake_logfile')) + \ || neomake#utils#get_verbosity() >= 3) + return list +endfunction + +" Internal base list implementation. +let s:base_list = { + \ 'need_init': 1, + \ 'entries': [], + \ } +" Info about contained jobs. +let s:base_list.job_entries = {} +let s:base_list.maker_info_by_jobid = {} + +function! s:base_list.sort_by_location() dict abort + let entries = get(self, '_sorted_entries_by_location', copy(self.entries)) + let self._sorted_entries_by_location = sort(entries, 's:cmp_listitem_loc') + return self._sorted_entries_by_location +endfunction + +" a:1: optional jobinfo +function! s:base_list.add_entries(entries, ...) dict abort + let idx = len(self.entries) + if a:0 && !has_key(self.job_entries, a:1.id) + let self.job_entries[a:1.id] = [] + let self.maker_info_by_jobid[a:1.id] = a:1.maker + endif + for entry in a:entries + let idx += 1 + let e = extend(copy(entry), {'nmqfidx': idx}) + if a:0 + call add(self.job_entries[a:1.id], e) + let e.job_id = a:1.id + endif + call add(self.entries, e) + endfor + if self.debug + let indexes = map(copy(self.entries), 'v:val.nmqfidx') + if len(neomake#compat#uniq(sort(copy(indexes)))) != len(indexes) + call neomake#log#error(printf('Duplicate qf indexes in list entries: %s.', + \ string(indexes))) + endif + endif + " Sort if it was sorted before. + if has_key(self, '_sorted_entries_by_location') + call extend(self._sorted_entries_by_location, a:entries) + call self.sort_by_location() + endif +endfunction + +" Add entries for a job (non-efm method). +function! s:base_list.add_entries_for_job(entries, jobinfo) dict abort + let tempfiles = get(self.make_info, 'tempfiles', []) + if !empty(tempfiles) + let mapped = 0 + for e in a:entries + if has_key(e, 'filename') && get(e, 'bufnr', 0) == 0 + if index(tempfiles, e.filename) != -1 + unlet e.filename + let e.bufnr = a:jobinfo.bufnr + let mapped += 1 + endif + endif + endfor + if mapped + call neomake#log#debug(printf('Mapped %d bufnrs from temporary files.', mapped), a:jobinfo) + endif + endif + return self._appendlist(a:entries, a:jobinfo) +endfunction + +function! neomake#list#get_title(prefix, bufnr, maker_info) abort + let prefix = 'Neomake' + if !empty(a:prefix) + let prefix .= '['.a:prefix.']' + endif + if a:bufnr + let bufname = bufname(a:bufnr) + if empty(bufname) + let bufname = 'buf:'.a:bufnr + else + let bufname = pathshorten(bufname) + endif + let maker_info = bufname + if empty(a:maker_info) + let maker_info = bufname + else + let maker_info = bufname.' ('.a:maker_info.')' + endif + else + let maker_info = a:maker_info + endif + let title = prefix + if !empty(maker_info) + let title = prefix.': '.maker_info + endif + return title +endfunction + +function! s:base_list._get_title() abort + let maker_info = [] + for job in self.make_info.finished_jobs + let info = job.maker.name + let ok = 1 + if get(job, 'aborted', 0) + let info .= '!' + let ok = 0 + endif + if has_key(self.job_entries, job.id) + let c = len(self.job_entries[job.id]) + let info .= '('.c.')' + let ok = 0 + endif + if ok + let info .= '✓' + endif + call add(maker_info, info) + endfor + for job in self.make_info.active_jobs + let info = job.maker.name + let info .= '...' + if has_key(self.job_entries, job.id) + let c = len(self.job_entries[job.id]) + let info .= '('.c.')' + endif + call add(maker_info, info) + endfor + for job in self.make_info.jobs_queue + let info = job.maker.name + let info .= '?' + call add(maker_info, info) + endfor + for job in get(self.make_info, 'aborted_jobs', []) + let info = job.maker.name + let info .= '-' + call add(maker_info, info) + endfor + let maker_info_str = join(maker_info, ', ') + if self.type ==# 'loclist' + let bufnr = self.make_info.options.bufnr + else + let bufnr = 0 + endif + if get(self.make_info.options, 'automake') + let prefix = 'auto' + elseif self.make_info.options.file_mode + let prefix = 'file' + else + let prefix = 'project' + endif + return neomake#list#get_title(prefix, bufnr, maker_info_str) +endfunction + +function! s:base_list.finish_for_make() abort + if self.need_init + if self.type ==# 'loclist' + call neomake#log#debug('Cleaning location list.', self.make_info) + else + call neomake#log#debug('Cleaning quickfix list.', self.make_info) + endif + call self._call_qf_fn('set', [], ' ') + else + " Set title, but only if list window is still valid. + if s:has_support_for_qfid + let valid = self._has_valid_qf() + elseif self.type ==# 'loclist' + let valid = self._get_loclist_win(1) != -1 + else + let valid = 1 + endif + if !valid + call neomake#log#debug('list: finish: list is not valid anymore.', self.make_info) + return + endif + call self.set_title() + endif +endfunction + +function! s:base_list._call_qf_fn(action, ...) abort + let fns_args = call(self._get_fn_args, [a:action] + a:000, self) + + if a:action ==# 'get' + let [fn, args] = fns_args[0] + if s:has_support_for_qfid + let args[-1].items = 1 + if self.debug + call neomake#log#debug(printf('list: call: "get", returning items: %s.', string(fns_args))) + endif + return call(fn, args).items + endif + if self.debug + call neomake#log#debug(printf('list: call: "get": %s.', string(fns_args))) + endif + return call(fn, args) + endif + + for fns in fns_args + let [fn, args] = fns + + if self.debug + if a:action ==# 'set' + let log_args = deepcopy(args) + " Only display 5 items. + if self.type ==# 'loclist' + let log_args[1] = neomake#utils#shorten_list_for_log(log_args[1], 5) + else + let log_args[0] = neomake#utils#shorten_list_for_log(log_args[0], 5) + endif + " Massage options dict. + if type(log_args[-1]) == type({}) + let neomake_context = get(get(log_args[-1], 'context', {}), 'neomake', {}) + if !empty(neomake_context) + for [k, v] in items(neomake_context) + if k ==# 'make_info' + " Fixes self-ref, and makes it much shorter. + let neomake_context[k] = 'make_id='.v.make_id + endif + endfor + endif + " Only display 5 items. + if has_key(log_args[-1], 'items') + let log_args[-1].items = neomake#utils#shorten_list_for_log(log_args[-1].items, 5) + endif + endif + call neomake#log#debug(printf('list: call: set: %s.', string(log_args))) + else + call neomake#log#debug(printf('list: call: "%s": %s.', a:action, string(args))) + endif + endif + + call call(fn, args, self) + endfor + + " Get qfid. + if self.need_init + if a:action ==# 'set' && s:has_support_for_qfid + if self.type ==# 'loclist' + let loclist_win = self._get_loclist_win() + let self.qfid = getloclist(loclist_win, {'id': 0}).id + else + let self.qfid = getqflist({'id': 0}).id + endif + if self.debug + call neomake#log#debug(printf('list: got qfid (action=%s): %s.', a:action, self.qfid)) + endif + endif + let self.need_init = 0 + endif +endfunction + +function! s:base_list.set_title() abort + if s:can_set_qf_title + call self._call_qf_fn('title', self._get_title()) + endif +endfunction + +" Check if quickfix list is still valid, which might not be the case anymore +" if more than 10 new lists have been opened etc. +" Returns -1 without suffort for quickfix ids. +function! s:base_list._has_valid_qf() abort + if !s:has_support_for_qfid + return -1 + endif + + if self.type ==# 'loclist' + let loclist_win = self._get_loclist_win(1) + if loclist_win is -1 + return 0 + endif + if !get(getloclist(loclist_win, {'id': self.qfid}), 'id') + return 0 + endif + else + if !get(getqflist({'id': self.qfid}), 'id') + return 0 + endif + endif + return 1 +endfunction + +" Get winnr/winid to be used with loclist functions. +" a:1: return -1 instead of throwing when no window could be found? +function! s:base_list._get_loclist_win(...) abort + if !has_key(self, 'make_info') + throw 'cannot handle type=loclist without make_info' + endif + let loclist_win = 0 + let make_id = self.make_info.make_id + " NOTE: prefers using 0 for when winid is not supported with + " setloclist() yet (vim74-xenial). + if index(get(w:, 'neomake_make_ids', []), make_id) == -1 + if has_key(self.make_info.options, 'winid') + let loclist_win = self.make_info.options.winid + else + let [t, w] = neomake#core#get_tabwin_for_makeid(make_id) + if [t, w] == [-1, -1] + if a:0 && a:1 + return -1 + endif + throw printf('Neomake: could not find location list for make_id %d.', make_id) + endif + if t != tabpagenr() + if a:0 && a:1 + return -1 + endif + throw printf('Neomake: trying to use location list from another tab (current=%d != target=%d).', tabpagenr(), t) + endif + let loclist_win = w + endif + endif + return loclist_win +endfunction + +" Return a list of commands to be called. +" action: "get", "set", "init", "title" +" a:000: optional args (for set/init/title) +function! s:base_list._get_fn_args(action, ...) abort + if self.type ==# 'loclist' + if a:action ==# 'get' + let fn = 'getloclist' + else + let fn = 'setloclist' + endif + else + if a:action ==# 'get' + let fn = 'getqflist' + else + let fn = 'setqflist' + endif + endif + + if self.type ==# 'loclist' + let args = [self._get_loclist_win()] + else + let args = [] + endif + + let options = {} + if !self.need_init + let valid = self._has_valid_qf() + if valid == 1 + let options.id = self.qfid + elseif valid == 0 + if self.type ==# 'loclist' + let loclist_win = args[0] + throw printf('Neomake: qfid %d for location list (%d) has become invalid.', self.qfid, loclist_win) + else + throw printf('Neomake: qfid %d for quickfix list has become invalid.', self.qfid) + endif + endif + endif + + if a:action ==# 'title' + call extend(args, [[], 'a']) + if exists('*vader#assert#true') + call vader#assert#true(s:can_set_qf_title) + endif + let options.title = a:1 + else + call extend(args, a:000) + if a:action ==# 'set' + if exists('*vader#assert#equal') + call vader#assert#equal(len(a:000), 2) + endif + if s:can_set_qf_items + let options.items = a:1 + let args[-2] = [] + endif + endif + endif + if !empty(options) + call add(args, options) + endif + + let r = [] + if a:action ==# 'set' + if self.need_init && get(self, 'reset_existing_qflist') + if self.type ==# 'loclist' + let args[2] = 'r' " action + else + let args[1] = 'r' " action + endif + if self.type ==# 'loclist' + let msg = 'Reusing location list for entries.' + else + let msg = 'Reusing quickfix list for entries.' + endif + call neomake#log#debug(msg, self.make_info) + endif + + " Experimental: set make_info into context. + " This is used to access make info from the qf window itself. + if self.need_init && s:can_set_qf_context + let options.context = {'neomake': {'make_info': self.make_info}} + endif + + " Handle setting title, which gets done initially and when maker + " names are updated. This has to be done in a separate call + " without patch-8.0.0657. + if s:can_set_qf_title + let title = self._get_title() + if s:can_set_qf_items + if type(args[-1]) != type({}) + call add(args, {'title': title, 'items': args[1]}) + else + let args[-1].title = title + endif + else + " Update title after actual call. + call add(r, [fn, args]) + + if self.type ==# 'loclist' + let args = [args[0], [], 'a', {'title': title}] + else + let args = [[], 'a', {'title': title}] + endif + endif + endif + endif + call add(r, [fn, args]) + return r +endfunction + +function! s:mark_entry_with_nmcfg(entry, maker_info) abort + let maker_name = a:maker_info.name + let config = { + \ 'name': maker_name, + \ 'short': get(a:maker_info, 'short_name', maker_name[:3]), + \ } + let marker_entry = copy(a:entry) + let marker_entry.text .= printf(' nmcfg:%s', string(config)) + return marker_entry +endfunction + +function! s:base_list._replace_qflist_entries(entries) abort + let set_entries = a:entries + + " Handle nmcfg markers when setting all entries without jobinfo. + if neomake#quickfix#is_enabled() + let set_entries = copy(set_entries) + let prev_job_id = 0 + + " Handle re-setting all entries. This is meant to be used later + " for replacing the whole list. + let i = 0 + for e in set_entries + if e.job_id != prev_job_id + let maker_info = self.maker_info_by_jobid[e.job_id] + let set_entries[i] = s:mark_entry_with_nmcfg(e, maker_info) + let prev_job_id = e.job_id + endif + let i += 1 + endfor + endif + + call self._set_qflist_entries(set_entries, 'r') +endfunction + +function! s:base_list._set_qflist_entries(entries, action) abort + let action = a:action + if self.need_init && !get(self, 'reset_existing_qflist') + if self.type ==# 'loclist' + let msg = 'Creating location list for entries.' + else + let msg = 'Creating quickfix list for entries.' + endif + call neomake#log#debug(msg, self.make_info) + + if s:needs_to_init_qf_for_lwindow + " Clean list without autocommands (customqf etc) to avoid + " flicker. This is only to work around a Vim bug anyway. + noautocmd call self._call_qf_fn('set', [], ' ') + else + let action = ' ' + endif + endif + call self._call_qf_fn('set', a:entries, action) +endfunction + +function! s:base_list._get_qflist_entries() abort + return self._call_qf_fn('get') +endfunction + +" Append entries to location/quickfix list. +function! s:base_list._appendlist(entries, jobinfo) abort + call neomake#log#debug(printf('Adding %d list entries.', len(a:entries)), self.make_info) + + let set_entries = a:entries + let action = 'a' + if !self.need_init + let action = 'a' + if s:needs_to_replace_qf_for_lwindow || neomake#quickfix#is_enabled() + " Need to replace whole list with customqf to trigger FileType + " autocmd (which is not done for action='a'). + " This should be enhanced to only format new entries instead + " later, but needs support for changing non-current buffer lines. + let action = 'r' + if self.type ==# 'loclist' + let set_entries = self._get_qflist_entries() + set_entries + else + let set_entries = getqflist() + set_entries + endif + endif + endif + + " Add marker for custom quickfix to the first (new) entry. + let needs_custom_qf_marker = neomake#quickfix#is_enabled() + if needs_custom_qf_marker + if action ==# 'a' + let prev_idx = 0 + else + let prev_idx = len(self.entries) + endif + let set_entries = copy(set_entries) + let set_entries[prev_idx] = s:mark_entry_with_nmcfg(set_entries[prev_idx], a:jobinfo.maker) + endif + + " NOTE: need to fetch (or pre-parse with new patch) to get updated bufnr etc. + call self._set_qflist_entries(set_entries, action) + let added = self._get_qflist_entries()[len(self.entries) :] + + if needs_custom_qf_marker + " Remove marker that should only be in the quickfix list. + let added[0].text = substitute(added[0].text, ' nmcfg:{.\{-}}$', '', '') + endif + + if self.debug && added != a:entries + let diff = neomake#list#_diff_new_entries(a:entries, added) + if !empty(diff) + for [k, v] in items(diff) + " TODO: handle valid=1 being added? + call neomake#log#debug(printf( + \ 'Entry %d differs after adding: %s.', + \ k+1, + \ string(v)), + \ a:jobinfo) + endfor + endif + endif + + let parsed_entries = copy(a:entries) + let idx = 0 + for e in added + if parsed_entries[idx].bufnr != e.bufnr + call neomake#log#debug(printf( + \ 'Updating entry bufnr: %s => %s.', + \ a:entries[idx].bufnr, e.bufnr)) + let parsed_entries[idx].bufnr = e.bufnr + endif + let idx += 1 + endfor + + call self.add_entries(parsed_entries, a:jobinfo) + return parsed_entries +endfunction + +function! neomake#list#_diff_new_entries(orig, new) abort + if a:orig == a:new + return {} + endif + let i = 0 + let r = {} + for new in a:new + let orig = copy(get(a:orig, i, {})) + for [k, v] in items({'pattern': '', 'module': '', 'valid': 1}) + if has_key(new, k) + let orig[k] = v + endif + endfor + if new != orig + " 'removed': {'length': 4, 'filename': 'from.rs', + " 'maker_name': 'cargo'}} + let new = copy(new) + for k in ['length', 'maker_name'] + if has_key(orig, k) + let new[k] = orig[k] + endif + endfor + let diff = neomake#utils#diff_dict(orig, new) + if !empty(diff) + let r[i] = diff + endif + endif + let i += 1 + endfor + return r +endfunction + +" Add raw lines using errorformat. +" This either pre-parses them with newer versions, or uses +" :laddexpr/:caddexpr. +function! s:base_list.add_lines_with_efm(lines, jobinfo) dict abort + let maker = a:jobinfo.maker + let file_mode = self.type ==# 'loclist' + + if s:use_efm_parsing + let efm = a:jobinfo.maker.errorformat + let parsed_entries = get(getqflist({'lines': a:lines, 'efm': efm}), 'items', -1) + if parsed_entries is -1 + call neomake#log#error(printf('Failed to get items via efm-parsing. Invalid errorformat? (%s)', efm), a:jobinfo) + let parsed_entries = getqflist({'lines': a:lines, 'efm': &errorformat}).items + endif + if empty(parsed_entries) + return [] + endif + else + if self.need_init + if self.type ==# 'loclist' + let msg = 'Creating location list.' + else + let msg = 'Creating quickfix list.' + endif + call neomake#log#debug(msg, self.make_info) + call self._call_qf_fn('set', [], ' ') + endif + let olderrformat = &errorformat + try + let &errorformat = maker.errorformat + catch + call neomake#log#error(printf('Failed to set errorformat (%s): %s.', string(maker.errorformat), v:exception), a:jobinfo) + endtry + try + if file_mode + let cmd = 'laddexpr' + else + let cmd = 'caddexpr' + endif + let a:jobinfo._delayed_qf_autocmd = 'QuickfixCmdPost '.cmd + let cmd = 'noautocmd '.cmd.' a:lines' + if self.debug + call neomake#log#debug(printf('list: exe: %s (with %d lines).', cmd, len(a:lines)), a:jobinfo) + endif + exe cmd + finally + let &errorformat = olderrformat + call a:jobinfo.cd_back() + endtry + + let new_list = self._get_qflist_entries() + let parsed_entries = new_list[len(self.entries) :] + if empty(parsed_entries) + return [] + endif + endif + + let l:Postprocess = neomake#utils#GetSetting('postprocess', maker, [], a:jobinfo.ft, a:jobinfo.bufnr) + if type(Postprocess) != type([]) + let postprocessors = [Postprocess] + else + let postprocessors = Postprocess + endif + + let default_type = 'unset' + + let entries = [] + let changed_entries = {} + let removed_entries = [] + let different_bufnrs = {} + let bufnr_from_temp = {} + let bufnr_from_stdin = {} + let tempfile_bufnrs = has_key(self.make_info, 'tempfiles') ? map(copy(self.make_info.tempfiles), 'bufnr(v:val)') : [] + let uses_stdin = get(a:jobinfo, 'uses_stdin', 0) + + let entry_idx = -1 + for entry in parsed_entries + let entry_idx += 1 + let before = copy(entry) + " Handle unlisted buffers via tempfiles and uses_stdin. + if entry.bufnr && entry.bufnr != a:jobinfo.bufnr + \ && (!empty(tempfile_bufnrs) || uses_stdin) + let map_bufnr = index(tempfile_bufnrs, entry.bufnr) + if map_bufnr != -1 + let entry.bufnr = a:jobinfo.bufnr + let map_bufnr = tempfile_bufnrs[map_bufnr] + if !has_key(bufnr_from_temp, map_bufnr) + let bufnr_from_temp[map_bufnr] = [] + endif + let bufnr_from_temp[map_bufnr] += [entry_idx+1] + elseif uses_stdin + if !buflisted(entry.bufnr) && bufexists(entry.bufnr) + if !has_key(bufnr_from_stdin, entry.bufnr) + let bufnr_from_stdin[entry.bufnr] = [] + endif + let bufnr_from_stdin[entry.bufnr] += [entry_idx+1] + let entry.bufnr = a:jobinfo.bufnr + endif + endif + endif + if self.debug && entry.bufnr && entry.bufnr != a:jobinfo.bufnr + if !has_key(different_bufnrs, entry.bufnr) + let different_bufnrs[entry.bufnr] = 1 + else + let different_bufnrs[entry.bufnr] += 1 + endif + endif + if !empty(postprocessors) + let g:neomake_postprocess_context = {'jobinfo': a:jobinfo} + try + for l:F in postprocessors + if type(F) == type({}) + call call(F.fn, [entry], F) + else + call call(F, [entry], maker) + endif + unlet! F " vim73 + endfor + finally + unlet! g:neomake_postprocess_context " Might be unset already with sleep in postprocess. + endtry + endif + if entry != before + let changed_entries[entry_idx] = entry + if self.debug + " Ignore bufnr changes for tempfiles/stdin (logged together + " later). + let diff = neomake#utils#diff_dict(before, entry) + let changed_bufnr = get(get(diff, 'changed', {}), 'bufnr', []) + if !empty(changed_bufnr) && ( + \ has_key(bufnr_from_temp, changed_bufnr[0]) + \ || has_key(bufnr_from_stdin, changed_bufnr[0])) + unlet diff.changed.bufnr + if empty(diff.changed) + unlet diff.changed + endif + endif + if !empty(diff) + call neomake#log#debug(printf( + \ 'Modified list entry %d (postprocess): %s.', + \ entry_idx + 1, + \ substitute(string(diff), '\n', '\\n', 'g')), + \ a:jobinfo) + endif + endif + endif + + if entry.valid <= 0 + if entry.valid < 0 || maker.remove_invalid_entries + call insert(removed_entries, entry_idx) + let entry_copy = copy(entry) + call neomake#log#debug(printf( + \ 'Removing invalid entry: %s (%s).', + \ remove(entry_copy, 'text'), + \ string(entry_copy)), a:jobinfo) + continue + endif + endif + + if empty(entry.type) && entry.valid + if default_type ==# 'unset' + let default_type = neomake#utils#GetSetting('default_entry_type', maker, 'W', a:jobinfo.ft, a:jobinfo.bufnr) + endif + if !empty(default_type) + let entry.type = default_type + let changed_entries[entry_idx] = entry + endif + endif + call add(entries, entry) + endfor + + if !s:use_efm_parsing + let new_index = len(self.entries) + " Add marker for custom quickfix to the first (new) entry. + if neomake#quickfix#is_enabled() + let changed_entries[0] = s:mark_entry_with_nmcfg(entries[0], maker) + endif + + if !empty(changed_entries) || !empty(removed_entries) + " Need to update/replace current list. + let list = self._get_qflist_entries() + if !empty(changed_entries) + for k in keys(changed_entries) + let list[new_index + k] = changed_entries[k] + endfor + endif + if !empty(removed_entries) + for k in removed_entries + call remove(list, new_index + k) + endfor + endif + call self._set_qflist_entries(list, 'r') + endif + endif + + if !empty(bufnr_from_temp) || !empty(bufnr_from_stdin) + if !has_key(self.make_info, '_wipe_unlisted_buffers') + let self.make_info._wipe_unlisted_buffers = [] + endif + let self.make_info._wipe_unlisted_buffers += keys(bufnr_from_stdin) + keys(bufnr_from_stdin) + if !empty(bufnr_from_temp) + for [tempbuf, entries_idx] in items(bufnr_from_temp) + let log_entries_idx = join(neomake#utils#shorten_list_for_log(entries_idx, 50), ', ') + call neomake#log#debug(printf( + \ 'Used bufnr from temporary buffer %d (%s) for %d entries: %s.', + \ tempbuf, + \ bufname(+tempbuf), + \ len(entries_idx), + \ log_entries_idx), a:jobinfo) + endfor + endif + if !empty(bufnr_from_stdin) + for [tempbuf, entries_idx] in items(bufnr_from_stdin) + let log_entries_idx = join(neomake#utils#shorten_list_for_log(entries_idx, 50), ', ') + call neomake#log#debug(printf( + \ 'Used bufnr from stdin buffer %d (%s) for %d entries: %s.', + \ tempbuf, + \ bufname(+tempbuf), + \ len(entries_idx), + \ log_entries_idx), a:jobinfo) + endfor + endif + endif + if !empty(different_bufnrs) + call neomake#log#debug(printf('WARN: seen entries with bufnr different from jobinfo.bufnr (%d): %s, current bufnr: %d.', a:jobinfo.bufnr, string(different_bufnrs), bufnr('%'))) + endif + + if empty(entries) + return [] + endif + + if s:use_efm_parsing + call self._appendlist(entries, a:jobinfo) + else + call self.add_entries(entries, a:jobinfo) + endif + return entries +endfunction + +" Get the current location or quickfix list. +function! neomake#list#get() abort + let winnr = winnr() + let win_info = neomake#compat#getwinvar(winnr, '_neomake_info', {}) + if has_key(win_info, 'loclist') + return win_info['loclist'] + endif + let info = get(g:, '_neomake_info', {}) + if has_key(info, 'qflist') + return info['qflist'] + endif + return {} +endfunction + +function! neomake#list#get_loclist(...) abort + let winnr = a:0 ? a:1 : winnr() + let info = neomake#compat#getwinvar(winnr, '_neomake_info', {}) + if !has_key(info, 'loclist') + " Create a new list, not bound to a job. + call neomake#log#debug('Creating new List object.') + let list = neomake#list#List('loclist') + call list.add_entries(getloclist(winnr)) + let info['loclist'] = list + call setwinvar(winnr, '_neomake_info', info) + endif + return info['loclist'] +endfunction + +" TODO: save project-maker quickfix list. +function! neomake#list#get_qflist() abort + let info = get(g:, '_neomake_info', {}) + if !has_key(info, 'qflist') + " Create a new list, not bound to a job. + call neomake#log#debug('Creating new List object.') + let list = neomake#list#List('quickfix') + call list.add_entries(getqflist()) + let info['qflist'] = list + let g:_neomake_info = info + endif + return info['qflist'] +endfunction + +function! s:get_list(file_mode) abort + if a:file_mode + let list = neomake#list#get_loclist() + let g:unimpaired_prevnext = ['NeomakePrevLoclist', 'NeomakeNextLoclist'] + else + let list = neomake#list#get_qflist() + let g:unimpaired_prevnext = ['NeomakePrevQuickfix', 'NeomakeNextQuickfix'] + endif + return list +endfunction + +function! neomake#list#next(c, ...) abort + let file_mode = a:0 ? a:1 : 1 + let list = s:get_list(file_mode) + call s:goto_nearest(list, a:c == 0 ? 1 : a:c) +endfunction + +function! neomake#list#prev(c, ...) abort + let file_mode = a:0 ? a:1 : 1 + let list = s:get_list(file_mode) + call s:goto_nearest(list, a:c == 0 ? -1 : -a:c) +endfunction + +" TODO: global / already used somewhere else? / config +let g:neomake#list#type_prio = { + \ 'E': 0, + \ 'W': 1, + \ 'I': 2, + \ } + +" TODO: allow to customize via own callback(s)? +function! s:cmp_listitem_loc(a, b) abort + let buf_diff = a:a.bufnr - a:b.bufnr + if buf_diff + return buf_diff + endif + + if exists('*vader#assert#not_equal') + call vader#assert#not_equal(a:a.bufnr, -1) + call vader#assert#not_equal(a:b.bufnr, -1) + endif + + let lnum_diff = a:a.lnum - a:b.lnum + if lnum_diff + return lnum_diff + endif + + let col_diff = a:a.col - a:b.col + if col_diff + return col_diff + endif + + let prio = g:neomake#list#type_prio + return get(prio, a:a.type, 99) - get(prio, a:b.type, 99) +endfunction + +function! s:goto_nearest(list, offset) abort + let [lnum, col] = getpos('.')[1:2] + if a:offset == 0 + throw 'a:offset must not be 0' + endif + + if !has_key(a:list, '_sorted_entries_by_location') + call a:list.sort_by_location() + endif + let entries = a:list._sorted_entries_by_location + if a:offset < 0 + call reverse(entries) + endif + + let c = a:offset + let step = a:offset > 0 ? 1 : -1 + let found = 0 + for item in entries + if (a:offset > 0 && (item.lnum > lnum || (item.lnum == lnum && item.col > col))) + \ || (a:offset < 0 && (item.lnum < lnum || (item.lnum == lnum && item.col < col))) + let c -= step + let found = item.nmqfidx + if c == 0 + break + endif + endif + endfor + + if found + if a:list.type ==# 'loclist' + if exists('*vader#assert#equal') + " @vimlint(EVL102, 1, l:ll_item) + let ll_item = getloclist(0)[found-1] + call vader#assert#equal([ll_item.bufnr, ll_item.lnum], [item.bufnr, item.lnum]) + endif + execute 'll '.found + else + if exists('*vader#assert#equal') + " @vimlint(EVL102, 1, l:cc_item) + let cc_item = getqflist()[found-1] + call vader#assert#equal([cc_item.bufnr, cc_item.lnum], [item.bufnr, item.lnum]) + endif + execute 'cc '.found + endif + elseif c > 0 + call neomake#log#error('No more next items.') + elseif c < 0 + call neomake#log#error('No more previous items.') + endif +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/log.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/log.vim new file mode 100644 index 0000000..4e8e6bf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/log.vim @@ -0,0 +1,171 @@ +let s:level_to_name = {0: 'error ', 1: 'warning', 2: 'verbose', 3: 'debug '} +let s:name_to_level = {'error': 0, 'warning': 1, 'verbose': 2, 'debug': 3} +let s:short_level_to_name = {0: 'E', 1: 'W', 2: 'V', 3: 'D'} +let s:is_testing = exists('g:neomake_test_messages') +let s:pid = getpid() + +let s:last_msg_ts = neomake#compat#reltimefloat() + +function! s:reltime_lastmsg() abort + let cur = neomake#compat#reltimefloat() + let diff = (cur - s:last_msg_ts) + let s:last_msg_ts = neomake#compat#reltimefloat() + + if diff < 0.01 + return ' ' + elseif diff < 10 + let format = '+%.2f' + elseif diff < 100 + let format = '+%.1f' + elseif diff < 100 + let format = ' +%.0f' + elseif diff < 1000 + let format = ' +%.0f' + else + let format = '+%.0f' + endif + return printf(format, diff) +endfunction + +function! s:log(level, msg, ...) abort + let context = a:0 ? a:1 : {} + let verbosity = neomake#utils#get_verbosity(context) + let logfile = get(g:, 'neomake_logfile', '') + + if !s:is_testing && verbosity < a:level && empty(logfile) + return + endif + + if a:0 + if has_key(a:1, 'options') + let context = copy(a:1.options) + let context.make_id = a:1.make_id + else + let context = copy(a:1) + endif + let msg = printf('[%s.%s:%s:%d] %s', + \ get(context, 'make_id', '-'), + \ get(context, 'id', '-'), + \ get(context, 'bufnr', get(context, 'file_mode', 0) ? '?' : '-'), + \ get(context, 'winnr', winnr()), + \ a:msg) + else + let msg = a:msg + endif + + " Use Vader's log for messages during tests. + " @vimlint(EVL104, 1, l:timediff) + if s:is_testing && (verbosity >= a:level || get(g:, 'neomake_test_log_all_messages', 0)) + let timediff = s:reltime_lastmsg() + if timediff !=# ' ' + let test_msg = '['.s:short_level_to_name[a:level].' '.timediff.']: '.msg + else + let test_msg = '['.s:level_to_name[a:level].']: '.msg + endif + + if exists('*vader#log') + " Might not exist with rpcrequest-based nvim test, or throw errors + " if called too early. + call vader#log(test_msg) + endif + " Only keep context entries that are relevant for / used in the message. + let context = a:0 + \ ? extend(filter(copy(context), "index(['id', 'make_id', 'bufnr', 'winnr'], v:key) != -1"), {'winnr': winnr()}, 'keep') + \ : {} + call add(g:neomake_test_messages, [a:level, a:msg, context]) + if index(['.', '!', ')', ']'], a:msg[-1:-1]) == -1 + let g:neomake_test_errors += ['Log msg does not end with punctuation: "'.a:msg.'".'] + endif + elseif verbosity >= a:level + redraw + if verbosity > 2 + echom 'Neomake: '.msg + else + if a:level ==# 0 + echohl ErrorMsg + else + echohl WarningMsg + endif + " Use message without context for non-debug msgs. + echom 'Neomake: '.a:msg + echohl None + endif + endif + if !empty(logfile) + if !exists('s:logfile_writefile_opts') + " Use 'append' with writefile, but only if it is available. Otherwise, just + " overwrite the file. 'S' is used to disable fsync in Neovim + " (https://github.com/neovim/neovim/pull/6427). + if has('patch-7.4.503') + let s:logfile_writefile_opts = 'aS' + else + let s:logfile_writefile_opts = '' + redraw + echohl WarningMsg + echom 'Neomake: appending to the logfile is not supported in your Vim version.' + echohl NONE + endif + endif + + let time = strftime('%H:%M:%S') + if !exists('timediff') + let timediff = s:reltime_lastmsg() + endif + try + call writefile([printf('%s %s [%s %s] %s', + \ time, s:pid, s:short_level_to_name[a:level], timediff, msg)], + \ logfile, s:logfile_writefile_opts) + catch + unlet g:neomake_logfile + call neomake#log#error(printf('Error when trying to write to logfile %s: %s. Unsetting g:neomake_logfile.', logfile, v:exception)) + endtry + endif + " @vimlint(EVL104, 0, l:timediff) +endfunction + +function! neomake#log#error(...) abort + call call('s:log', [0] + a:000) +endfunction + +function! neomake#log#warning(...) abort + call call('s:log', [1] + a:000) +endfunction + +function! neomake#log#info(...) abort + call call('s:log', [2] + a:000) +endfunction + +function! neomake#log#debug(...) abort + call call('s:log', [3] + a:000) +endfunction + +function! neomake#log#debug_obj(msg, obj) abort + if s:is_testing || neomake#utils#get_verbosity() >= 3 || !empty(get(g:, 'neomake_logfile', '')) + call neomake#log#debug(a:msg.': '.neomake#utils#Stringify(a:obj).'.') + endif +endfunction + +function! neomake#log#exception(error, ...) abort + let log_context = a:0 ? a:1 : {'bufnr': bufnr('%')} + redraw + echom printf('Neomake error in: %s', v:throwpoint) + call neomake#log#error(a:error, log_context) + call neomake#log#debug(printf('(in %s)', v:throwpoint), log_context) +endfunction + +let s:warned = {} +function! neomake#log#warn_once(msg, key) abort + if !has_key(s:warned, a:key) + let s:warned[a:key] = 1 + echohl WarningMsg + redraw | echom 'Neomake: ' . a:msg + echohl None + let v:warningmsg = 'Neomake: '.a:msg + call neomake#log#debug('Neomake warning: '.a:msg) + endif +endfunction + +function! neomake#log#reset_warnings() abort + let s:warned = {} +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/cabal.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/cabal.vim new file mode 100644 index 0000000..070b2a5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/cabal.vim @@ -0,0 +1,15 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#cabal#cabal() abort + let errorformat = join([ + \ '%A%f:%l:%c:', + \ '%A%f:%l:%c: %m', + \ '%+C %m', + \ '%-Z%[%^ ]', + \ ], ',') + return { + \ 'exe': 'cabal', + \ 'args': ['build'], + \ 'errorformat': errorformat + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/clippy.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/clippy.vim new file mode 100644 index 0000000..6f2a8a3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/clippy.vim @@ -0,0 +1,39 @@ +" vim: ts=4 sw=4 et + +" Yet to be determined +let s:rustup_has_nightly = get(g:, 'neomake_clippy_rustup_has_nightly', -1) + +function! neomake#makers#clippy#clippy() abort + " When rustup and a nightly toolchain is installed, that is used. + " Otherwise, the default cargo exectuable is used. If this is not part + " of a nightly rust, this will fail. + if s:rustup_has_nightly == -1 + if !executable('rustup') + let s:rustup_has_nightly = 0 + call system('rustc --version | grep -q "\-nightly"') + if v:shell_error + call neomake#log#warning('Clippy requires a nightly rust installation.') + endif + else + call system('rustup show | grep -q "^nightly-"') + let s:rustup_has_nightly = !v:shell_error + endif + endif + + let cargo_maker = neomake#makers#ft#rust#cargo() + let json_args = ['--message-format=json', '--quiet'] + + if s:rustup_has_nightly + return { + \ 'exe': 'rustup', + \ 'args': ['run', 'nightly', 'cargo', 'clippy'] + json_args, + \ 'process_output': cargo_maker.process_output, + \ } + else + return { + \ 'exe': 'cargo', + \ 'args': ['clippy'] + json_args, + \ 'process_output': cargo_maker.process_output, + \ } + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ada.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ada.vim new file mode 100644 index 0000000..822da3c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ada.vim @@ -0,0 +1,14 @@ +function! neomake#makers#ft#ada#EnabledMakers() abort + return ['gcc'] +endfunction + +function! neomake#makers#ft#ada#gcc() abort + return { + \ 'args': ['-c', '-x', 'ada', '-gnatc'], + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%f:%l:%c: %m,' . + \ '%f:%l: %m' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/angular.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/angular.vim new file mode 100644 index 0000000..8c2f2d9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/angular.vim @@ -0,0 +1,9 @@ +function! neomake#makers#ft#angular#SupersetOf() abort + return 'javascript' +endfunction + +function! neomake#makers#ft#angular#EnabledMakers() abort + return ['jshint', 'eslint', 'jscs'] +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ansible.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ansible.vim new file mode 100644 index 0000000..a1a001f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ansible.vim @@ -0,0 +1,17 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#ansible#EnabledMakers() abort + return ['ansiblelint', 'yamllint'] +endfunction + +function! neomake#makers#ft#ansible#yamllint() abort + return neomake#makers#ft#yaml#yamllint() +endfunction + +function! neomake#makers#ft#ansible#ansiblelint() abort + return { + \ 'exe': 'ansible-lint', + \ 'args': ['-p', '--nocolor'], + \ 'errorformat': '%f:%l: [%tANSIBLE%n] %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/apiblueprint.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/apiblueprint.vim new file mode 100644 index 0000000..2e91b42 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/apiblueprint.vim @@ -0,0 +1,16 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#apiblueprint#EnabledMakers() abort + return executable('drafter') ? ['drafter'] : [] +endfunction + +function! neomake#makers#ft#apiblueprint#drafter() abort + " Drafter only operates on a single file at a time, and therefore doesn't + " bother to print out a file name with each error. We need to attach this + " so that the quickfix list can function properly. + return { + \ 'args': ['-l', '-u'], + \ 'errorformat': '%f: %t%[%^:]\\+: (%n) %m; line %l\, column %c%.%#', + \ 'mapexpr': 'neomake_bufname . ": " . v:val' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/applescript.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/applescript.vim new file mode 100644 index 0000000..71a00f1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/applescript.vim @@ -0,0 +1,11 @@ +function! neomake#makers#ft#applescript#EnabledMakers() abort + return ['osacompile'] +endfunction + +function! neomake#makers#ft#applescript#osacompile() abort + return { + \ 'args': ['-o', g:neomake#compat#dev_null], + \ 'errorformat': '%f:%l: %trror: %m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/asciidoc.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/asciidoc.vim new file mode 100644 index 0000000..4d53751 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/asciidoc.vim @@ -0,0 +1,28 @@ +function! neomake#makers#ft#asciidoc#SupersetOf() abort + return 'text' +endfunction + +function! neomake#makers#ft#asciidoc#EnabledMakers() abort + let makers = executable('asciidoctor') ? ['asciidoctor'] : ['asciidoc'] + return makers + neomake#makers#ft#text#EnabledMakers() +endfunction + +function! neomake#makers#ft#asciidoc#asciidoc() abort + return { + \ 'errorformat': + \ '%E%\w%\+: %tRROR: %f: line %l: %m,' . + \ '%E%\w%\+: %tRROR: %f: %m,' . + \ '%E%\w%\+: FAILED: %f: line %l: %m,' . + \ '%E%\w%\+: FAILED: %f: %m,' . + \ '%W%\w%\+: %tARNING: %f: line %l: %m,' . + \ '%W%\w%\+: %tARNING: %f: %m,' . + \ '%W%\w%\+: DEPRECATED: %f: line %l: %m,' . + \ '%W%\w%\+: DEPRECATED: %f: %m', + \ 'args': ['-o', g:neomake#compat#dev_null], + \ } +endfunction + +function! neomake#makers#ft#asciidoc#asciidoctor() abort + return neomake#makers#ft#asciidoc#asciidoc() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/beancount.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/beancount.vim new file mode 100644 index 0000000..95eb31a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/beancount.vim @@ -0,0 +1,12 @@ +function! neomake#makers#ft#beancount#EnabledMakers() abort + return ['bean_check'] +endfunction + +function! neomake#makers#ft#beancount#bean_check() abort + return { + \ 'exe': 'bean-check', + \ 'errorformat': '%E%f:%l:%m', + \ 'postprocess': function('neomake#postprocess#compress_whitespace'), + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/bib.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/bib.vim new file mode 100644 index 0000000..e3a9602 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/bib.vim @@ -0,0 +1,16 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#bib#EnabledMakers() abort + return [] +endfunction + +function! neomake#makers#ft#bib#bibtex() abort + return { + \ 'exe': 'bibtex', + \ 'args': ['-terse', '%:r'], + \ 'append_file': 0, + \ 'uses_filename': 0, + \ 'errorformat': '%E%m---line %l of file %f', + \ 'cwd': '%:p:h' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/c.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/c.vim new file mode 100644 index 0000000..1d0cda8 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/c.vim @@ -0,0 +1,110 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#c#EnabledMakers() abort + let makers = executable('clang') ? ['clang', 'clangtidy', 'clangcheck'] : ['gcc'] + call add(makers, 'checkpatch') + call add(makers, 'cppcheck') + return makers +endfunction + +let g:neomake#makers#ft#c#project_root_files = ['configure', 'CMakeLists.txt'] + +function! neomake#makers#ft#c#clang() abort + " as a single-file maker, include the current directory in the default + " search path + return { + \ 'args': ['-fsyntax-only', '-Wall', '-Wextra', '-I./'], + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%I%f:%l:%c: note: %m,' . + \ '%f:%l:%c: %m,'. + \ '%f:%l: %trror: %m,'. + \ '%f:%l: %tarning: %m,'. + \ '%I%f:%l: note: %m,'. + \ '%f:%l: %m' + \ } +endfunction + +function! neomake#makers#ft#c#clangcheck() abort + return { + \ 'exe': 'clang-check', + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%I%f:%l:%c: note: %m,' . + \ '%f:%l:%c: %m,'. + \ '%f:%l: %trror: %m,'. + \ '%f:%l: %tarning: %m,'. + \ '%I%f:%l: note: %m,'. + \ '%f:%l: %m', + \ } +endfunction + +function! neomake#makers#ft#c#gcc() abort + " as a single-file maker, include the current directory in the default + " search path + return { + \ 'args': ['-fsyntax-only', '-Wall', '-Wextra', '-I./'], + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%-G%f:%l: %#error: %#(Each undeclared identifier is reported only%.%#,' . + \ '%-G%f:%l: %#error: %#for each function it appears%.%#,' . + \ '%-GIn file included%.%#,' . + \ '%-G %#from %f:%l\,,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%I%f:%l:%c: note: %m,' . + \ '%f:%l:%c: %m,' . + \ '%f:%l: %trror: %m,' . + \ '%f:%l: %tarning: %m,'. + \ '%I%f:%l: note: %m,'. + \ '%f:%l: %m', + \ } +endfunction + +" The -p option followed by the path to the build directory should be set in +" the maker's arguments. That directory should contain the compile command +" database (compile_commands.json). +function! neomake#makers#ft#c#clangtidy() abort + return { + \ 'exe': 'clang-tidy', + \ 'errorformat': + \ '%E%f:%l:%c: fatal error: %m,' . + \ '%E%f:%l:%c: error: %m,' . + \ '%W%f:%l:%c: warning: %m,' . + \ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' . + \ '%E%m', + \ 'short_name': 'ctdy', + \ } +endfunction + +function! neomake#makers#ft#c#checkpatch() abort + return { + \ 'exe': 'checkpatch.pl', + \ 'args': ['--no-summary', '--no-tree', '--terse', '--file'], + \ 'errorformat': + \ '%f:%l: %tARNING: %m,' . + \ '%f:%l: %tRROR: %m', + \ } +endfunction + +function! neomake#makers#ft#c#cppcheck() abort + " Uses --force to avoid: + " nofile:0:0:information:Too many #ifdef configurations - cppcheck only checks 12 configurations. + " NOTE: '--language=c' should be the first args, it gets replaced in + " neomake#makers#ft#cpp#cppcheck. + return { + \ 'args': ['--language=c', '--quiet', '--enable=warning', '--force', + \ '--template="{file}:{line}:{column}:{severity}:{message}"'], + \ 'errorformat': + \ 'nofile:0:0:%trror:%m,' . + \ '%f:%l:%c:%trror:%m,' . + \ 'nofile:0:0:%tarning:%m,'. + \ '%f:%l:%c:%tarning:%m,'. + \ 'nofile:0:0:%tnformation:%m,'. + \ '%f:%l:%c:%tnformation:%m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cf3.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cf3.vim new file mode 100644 index 0000000..7826fc6 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cf3.vim @@ -0,0 +1,14 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#cf3#EnabledMakers() abort + return ['cfpromises'] +endfunction + +function! neomake#makers#ft#cf3#cfpromises() abort + return { + \ 'exe': 'cf-promises', + \ 'args': ['-cf'], + \ 'errorformat': + \ '%E%f:%l:%c: error: %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/chef.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/chef.vim new file mode 100644 index 0000000..805a070 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/chef.vim @@ -0,0 +1,23 @@ +function! neomake#makers#ft#chef#SupersetOf() abort + return 'ruby' +endfunction + +function! neomake#makers#ft#chef#EnabledMakers() abort + let ruby_makers = neomake#makers#ft#ruby#EnabledMakers() + return ruby_makers + ['foodcritic', 'cookstyle'] +endfunction + +function! neomake#makers#ft#chef#foodcritic() abort + return { + \ 'errorformat': '%WFC%n: %m: %f:%l', + \ } +endfunction + +function! neomake#makers#ft#chef#cookstyle() abort + return { + \ 'args': ['-f', 'emacs'], + \ 'errorformat': '%f:%l:%c: %t: %m', + \ 'postprocess': function('neomake#makers#ft#ruby#RubocopEntryProcess'), + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/coffee.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/coffee.vim new file mode 100644 index 0000000..67c6cc3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/coffee.vim @@ -0,0 +1,15 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#coffee#EnabledMakers() abort + return ['coffeelint'] +endfunction + +function! neomake#makers#ft#coffee#coffeelint() abort + return { + \ 'args': ['--reporter=csv'], + \ 'errorformat': '%f\,%l\,%\d%#\,%trror\,%m,' . + \ '%f\,%l\,%trror\,%m,' . + \ '%f\,%l\,%\d%#\,%tarn\,%m,' . + \ '%f\,%l\,%tarn\,%m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cpp.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cpp.vim new file mode 100644 index 0000000..0cfa877 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cpp.vim @@ -0,0 +1,50 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#cpp#EnabledMakers() abort + let makers = executable('clang++') ? ['clang', 'clangtidy', 'clangcheck'] : ['gcc'] + call add(makers, 'cppcheck') + return makers +endfunction + +function! neomake#makers#ft#cpp#clang() abort + let maker = neomake#makers#ft#c#clang() + let maker.exe = 'clang++' + let maker.args += ['-std=c++1z'] + return maker +endfunction + +function! neomake#makers#ft#cpp#gcc() abort + let maker = neomake#makers#ft#c#gcc() + let maker.exe = 'g++' + let maker.args += ['-std=c++1z'] + return maker +endfunction + +function! neomake#makers#ft#cpp#clangtidy() abort + return neomake#makers#ft#c#clangtidy() +endfunction + +function! neomake#makers#ft#cpp#clangcheck() abort + return neomake#makers#ft#c#clangcheck() +endfunction + +function! neomake#makers#ft#cpp#cppcheck() abort + let maker = neomake#makers#ft#c#cppcheck() + let maker.args[0] = '--language=c++' + return maker +endfunction + +function! neomake#makers#ft#cpp#cpplint() abort + return { + \ 'exe': executable('cpplint') ? 'cpplint' : 'cpplint.py', + \ 'args': ['--verbose=3'], + \ 'errorformat': + \ '%A%f:%l: %m [%t],' . + \ '%-G%.%#', + \ 'postprocess': function('neomake#makers#ft#cpp#CpplintEntryProcess') + \ } +endfunction + +function! neomake#makers#ft#cpp#CpplintEntryProcess(entry) abort + let a:entry.type = str2nr(a:entry.type) < 5 ? 'W' : 'E' +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/crystal.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/crystal.vim new file mode 100644 index 0000000..b570c74 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/crystal.vim @@ -0,0 +1,25 @@ +function! neomake#makers#ft#crystal#EnabledMakers() abort + return ['crystal', 'ameba'] +endfunction + +function! neomake#makers#ft#crystal#crystal() abort + " from vim-crystal + return { + \ 'args': ['run', '--no-color', '--no-codegen'], + \ 'errorformat': + \ '%ESyntax error in line %l: %m,'. + \ '%ESyntax error in %f:%l: %m,'. + \ '%EError in %f:%l: %m,'. + \ '%C%p^,'. + \ '%-C%.%#' + \ } +endfunction + +function! neomake#makers#ft#crystal#ameba() abort + " from vim-crystal + return { + \ 'args': ['--format', 'flycheck'], + \ 'errorformat': '%f:%l:%c: %t: %m' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cs.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cs.vim new file mode 100644 index 0000000..6457cff --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cs.vim @@ -0,0 +1,22 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#cs#EnabledMakers() abort + return ['mcs'] +endfunction + +function! neomake#makers#ft#cs#mcs() abort + return { + \ 'args': ['--parse', '--unsafe'], + \ 'errorformat': '%f(%l\,%c): %trror %m', + \ } +endfunction + +function! neomake#makers#ft#cs#msbuild() abort + return { + \ 'exe': 'msbuild', + \ 'args': ['-nologo', '-v:q', '-property:GenerateFullPaths=true', neomake#utils#FindGlobFile('*.sln')], + \ 'errorformat': '%E%f(%l\,%c): error CS%n: %m [%.%#],'. + \ '%W%f(%l\,%c): warning CS%n: %m [%.%#]', + \ 'append_file' : 0, + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/css.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/css.vim new file mode 100644 index 0000000..3afbccd --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/css.vim @@ -0,0 +1,35 @@ +scriptencoding utf8 + +function! neomake#makers#ft#css#EnabledMakers() abort + return ['csslint', 'stylelint'] +endfunction + +function! neomake#makers#ft#css#csslint() abort + return { + \ 'args': ['--format=compact'], + \ 'errorformat': + \ '%-G,'. + \ '%-G%f: lint free!,'. + \ '%f: line %l\, col %c\, %trror - %m,'. + \ '%f: line %l\, col %c\, %tarning - %m,'. + \ '%f: line %l\, col %c\, %m,'. + \ '%f: %tarning - %m' + \ } +endfunction + +function! neomake#makers#ft#css#stylelint() abort + let maker = { + \ 'errorformat': + \ '%-P%f,'. + \ '%W%*\s%l:%c%*\s✖ %m,'. + \ '%-Q,'. + \ '%+EError: No configuration provided for %f,%-C %.%#' + \ } + + function! maker.postprocess(entry) abort + let a:entry.text = substitute(a:entry.text, '\v\s\s+(.{-})\s*$', ' [\1]', 'g') + endfunction + + return maker +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cuda.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cuda.vim new file mode 100644 index 0000000..0fbf6c9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/cuda.vim @@ -0,0 +1,15 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#cuda#EnabledMakers() abort + return ['nvcc'] +endfunction + +function! neomake#makers#ft#cuda#nvcc() abort + return { + \ 'exe': 'nvcc', + \ 'errorformat': + \ '%f\(%l\): %trror: %m,'. + \ '%f\(%l\): %tarning: %m,'. + \ '%f\(%l\): %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/d.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/d.vim new file mode 100644 index 0000000..5206a8d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/d.vim @@ -0,0 +1,92 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#d#EnabledMakers() abort + " dmd, ldmd, and gdmd all share a common CLI. + " Ordered in efficiency of compiler + for m in ['dmd', 'ldmd', 'gdmd'] + if executable(m) + return [m] + endif + endfor + return [] +endfunction + +function! s:findDubRoot() abort + "Look upwards for a dub.json or dub.sdl to find the root + "I did it like this because it's the only cross platform way I know of + let tmp_file = findfile('dub.json', '.;') + if empty(tmp_file) + let tmp_file = findfile('dub.sdl', '.;') + endif + return tmp_file +endfunction + +function! s:UpdateDub() abort + "Add dub directories + let s:dubImports = [] + let tmp_file = s:findDubRoot() + if executable('dub') && !empty(tmp_file) + let tmp_dir = fnamemodify(tmp_file,':p:h') + let dubCmd = 'dub describe --data=import-paths --annotate ' + \ .'--skip-registry=all --vquiet --data-list --root=' + let output = system(dubCmd . tmp_dir) + if(v:shell_error == 0 && !empty(output)) + " Is \n portable? + let s:dubImports = split(output, '\n') + call map(s:dubImports, "'-I' . v:val") + endif + endif +endfunction + +"GDMD does not adhere to dmd's flags or output, but to GCC's. +"This is for LDMD and dmd only. +function! s:DmdStyleMaker(args) abort + "Updating dub paths each make might be slow? + call s:UpdateDub() + let args = ['-w', '-wi', '-c', '-o-', '-vcolumns'] + a:args + s:dubImports + return { + \ 'args': args, + \ 'errorformat': + \ '%f(%l\,%c): %trror: %m,' . + \ '%f(%l): %trror: %m,' . + \ '%f(%l\,%c): %tarning: %m,' . + \ '%f(%l): %tarning: %m,' . + \ '%f(%l\,%c): Deprecation: %m,' . + \ '%f(%l): Deprecation: %m,', + \ } +endfunction + +function! neomake#makers#ft#d#dmd() abort + let args = [] + if exists('g:neomake_d_dmd_args_conf') + call add(args, '-conf=' . expand(g:neomake_d_dmd_args_conf)) + endif + return s:DmdStyleMaker(args) +endfunction + +function! neomake#makers#ft#d#ldmd() abort + let args = [] + if exists('g:neomake_d_ldmd_args_conf') + call add(args, '-conf=' . expand(g:neomake_d_ldmd_args_conf)) + endif + return s:DmdStyleMaker(args) +endfunction + +function! neomake#makers#ft#d#gdmd() abort + let args = ['-c', '-o-', '-fsyntax-only', s:UpdateDub()] + return { + \ 'args': args, + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%-G%f:%l: %#error: %#(Each undeclared identifier is reported only%.%#,' . + \ '%-G%f:%l: %#error: %#for each function it appears%.%#,' . + \ '%-GIn file included%.%#,' . + \ '%-G %#from %f:%l\,,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%f:%l:%c: %m,' . + \ '%f:%l: %trror: %m,' . + \ '%f:%l: %tarning: %m,'. + \ '%f:%l: %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/docbk.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/docbk.vim new file mode 100644 index 0000000..dceffac --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/docbk.vim @@ -0,0 +1,8 @@ +function! neomake#makers#ft#docbk#EnabledMakers() abort + return ['xmllint'] +endfunction + +function! neomake#makers#ft#docbk#xmllint() abort + return neomake#makers#ft#xml#xmllint() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/dockerfile.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/dockerfile.vim new file mode 100644 index 0000000..a6d767f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/dockerfile.vim @@ -0,0 +1,13 @@ +function! neomake#makers#ft#dockerfile#EnabledMakers() abort + return ['hadolint'] +endfunction + +function! neomake#makers#ft#dockerfile#hadolint() abort + return { + \ 'output_stream': 'stdout', + \ 'uses_stdin': 1, + \ 'args': ['--format', 'tty'], + \ 'errorformat': '%f:%l %m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elixir.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elixir.vim new file mode 100644 index 0000000..4de652e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elixir.vim @@ -0,0 +1,72 @@ +" vim: ts=4 sw=4 et + +" Credo error types. +" F -> Refactoring opportunities +" W -> Warnings +" C -> Convention violation +" D -> Software design suggestions +" R -> Readability suggestions +" Map structure {CredoError: NeomakeType, ...} +let s:neomake_elixir_credo_config_typemap = { + \ 'F': 'W', + \ 'C': 'W', + \ 'D': 'I', + \ 'R': 'I'} + +function! neomake#makers#ft#elixir#PostprocessEnforceMaxBufferLine(entry) abort + let buffer_lines = str2nr(line('$')) + if (buffer_lines < a:entry.lnum) + let a:entry.lnum = buffer_lines + endif +endfunction + +function! neomake#makers#ft#elixir#PostprocessCredo(entry) abort + let type = toupper(a:entry.type) + let type_map = extend(s:neomake_elixir_credo_config_typemap, + \ get(g:, 'neomake_elixir_credo_config_typemap', {})) + if has_key(type_map, type) + let a:entry.type = type_map[type] + endif +endfunction + +function! neomake#makers#ft#elixir#EnabledMakers() abort + return ['mix'] +endfunction + +function! neomake#makers#ft#elixir#elixir() abort + return { + \ 'errorformat': + \ '%E** %s %f:%l: %m,'. + \ '%W%f:%l: warning: %m' + \ } +endfunction + +function! neomake#makers#ft#elixir#credo() abort + return { + \ 'exe': 'mix', + \ 'args': ['credo', 'list', '--format=oneline'], + \ 'postprocess': function('neomake#makers#ft#elixir#PostprocessCredo'), + \ 'errorformat': + \'[%t] %. %f:%l:%c %m,' . + \'[%t] %. %f:%l %m' + \ } +endfunction + +function! neomake#makers#ft#elixir#mix() abort + return { + \ 'exe' : 'mix', + \ 'args': ['compile', '--warnings-as-errors'], + \ 'postprocess': function('neomake#makers#ft#elixir#PostprocessEnforceMaxBufferLine'), + \ 'errorformat': + \ '** %s %f:%l: %m,'. + \ '%Ewarning: %m,%C %f:%l,%Z' + \ } +endfunction + +function! neomake#makers#ft#elixir#dogma() abort + return { + \ 'exe': 'mix', + \ 'args': ['dogma', '--format=flycheck'], + \ 'errorformat': '%E%f:%l:%c: %.: %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elm.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elm.vim new file mode 100644 index 0000000..fe1d2f6 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/elm.vim @@ -0,0 +1,53 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#elm#EnabledMakers() abort + return ['elmMake'] +endfunction + +function! neomake#makers#ft#elm#elmMake() abort + return { + \ 'exe': 'elm-make', + \ 'args': ['--report=json', '--output=' . g:neomake#compat#dev_null], + \ 'process_output': function('neomake#makers#ft#elm#ElmMakeProcessOutput') + \ } +endfunction + +function! neomake#makers#ft#elm#ElmMakeProcessOutput(context) abort + let errors = [] + " output will be a List, containing either: + " 1) A success message + " 2) A string holding a JSON array for both warnings and errors + + for line in a:context.output + if line[0] ==# '[' + let decoded = neomake#compat#json_decode(line) + for item in decoded + if get(item, 'type', '') ==# 'warning' + let code = 'W' + else + let code = 'E' + endif + + let compiler_error = item['tag'] + let message = item['overview'] + let filename = item['file'] + let region_start = item['region']['start'] + let region_end = item['region']['end'] + let row = region_start['line'] + let col = region_start['column'] + let length = region_end['column'] - region_start['column'] + + let error = { + \ 'text': compiler_error . ' : ' . message, + \ 'type': code, + \ 'lnum': row, + \ 'col': col, + \ 'length': length, + \ 'filename': filename, + \ } + call add(errors, error) + endfor + endif + endfor + return errors +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/erlang.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/erlang.vim new file mode 100644 index 0000000..a554098 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/erlang.vim @@ -0,0 +1,72 @@ + +function! neomake#makers#ft#erlang#EnabledMakers() abort + return ['erlc'] +endfunction + +function! neomake#makers#ft#erlang#erlc() abort + let maker = { + \ 'errorformat': + \ '%W%f:%l: Warning: %m,' . + \ '%E%f:%l: %m' + \ } + function! maker.InitForJob(_jobinfo) abort + let self.args = neomake#makers#ft#erlang#GlobPaths() + endfunction + return maker +endfunction + +if !exists('g:neomake_erlang_erlc_target_dir') + let g:neomake_erlang_erlc_target_dir = tempname() +endif + +function! neomake#makers#ft#erlang#GlobPaths() abort + " Find project root directory. + let rebar_config = neomake#utils#FindGlobFile('rebar.config') + if !empty(rebar_config) + let root = fnamemodify(rebar_config, ':h') + else + " At least try with CWD + let root = getcwd() + endif + let root = fnamemodify(root, ':p') + let build_dir = root . '_build' + let ebins = [] + if isdirectory(build_dir) + " Pick the rebar3 profile to use + let default_profile = expand('%') =~# '_SUITE.erl$' ? 'test' : 'default' + let profile = get(b:, 'neomake_erlang_erlc_rebar3_profile', default_profile) + let ebins += neomake#compat#glob_list(build_dir . '/' . profile . '/lib/*/ebin') + let target_dir = build_dir . '/neomake' + else + let target_dir = get(b:, 'neomake_erlang_erlc_target_dir', + \ get(g:, 'neomake_erlang_erlc_target_dir')) + endif + " If <root>/_build doesn't exist it might be a rebar2/erlang.mk project + if isdirectory(root . 'deps') + let ebins += neomake#compat#glob_list(root . 'deps/*/ebin') + endif + " Set g:neomake_erlang_erlc_extra_deps in a project-local .vimrc, e.g.: + " let g:neomake_erlang_erlc_extra_deps = ['deps.local'] + " Or just b:neomake_erlang_erlc_extra_deps in a specific buffer. + let extra_deps_dirs = get(b:, 'neomake_erlang_erlc_extra_deps', + \ get(g:, 'neomake_erlang_erlc_extra_deps')) + if !empty(extra_deps_dirs) + for extra_deps in extra_deps_dirs + if extra_deps[-1] !=# '/' + let extra_deps .= '/' + endif + let ebins += neomake#compat#glob_list(extra_deps . '*/ebin') + endfor + endif + let args = ['-pa', 'ebin', '-I', 'include', '-I', 'src'] + for ebin in ebins + let args += [ '-pa', ebin, + \ '-I', substitute(ebin, 'ebin$', 'include', '') ] + endfor + if !isdirectory(target_dir) + call mkdir(target_dir, 'p') + endif + let args += ['-o', target_dir] + return args +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fish.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fish.vim new file mode 100644 index 0000000..429afcc --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fish.vim @@ -0,0 +1,16 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#fish#EnabledMakers() abort + return ['fish'] +endfunction + +function! neomake#makers#ft#fish#fish() abort + return { + \ 'args': ['-n'], + \ 'errorformat': + \ '%C%f (line %l): %s,'. + \ '%-Gfish: %.%#,'. + \ '%Z%p^,'. + \ '%E%m' + \} +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fortran.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fortran.vim new file mode 100644 index 0000000..828bba9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/fortran.vim @@ -0,0 +1,32 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#fortran#EnabledMakers() abort + return ['gfortran'] +endfunction + +" Using the errorformat from syntastic +function! neomake#makers#ft#fortran#ifort() abort + return { + \ 'args': ['-syntax-only', '-warn'], + \ 'errorformat': + \ '%E%f(%l): error #%n: %m,'. + \ '%W%f(%l): warning #%n: %m,'. + \ '%W%f(%l): remark #%n: %m,'. + \ '%-Z%p^,'. + \ '%-G%.%#', + \ } +endfunction + +" Using the errorformat from syntastic +function! neomake#makers#ft#fortran#gfortran() abort + return { + \ 'args': ['-fsyntax-only', '-Wall', '-Wextra'], + \ 'errorformat': + \ '%-C %#,'. + \ '%-C %#%.%#,'. + \ '%A%f:%l%[.:]%c:,'. + \ '%Z%\m%\%%(Fatal %\)%\?%trror: %m,'. + \ '%Z%tarning: %m,'. + \ '%-G%.%#', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/go.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/go.vim new file mode 100644 index 0000000..ac53730 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/go.vim @@ -0,0 +1,84 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#go#EnabledMakers() abort + let makers = ['go'] + if executable('golangci-lint') + call add(makers, 'golangci_lint') + elseif executable('gometalinter') + call add(makers, 'gometalinter') + else + call extend(makers, ['golint', 'govet']) + endif + return makers +endfunction + +function! neomake#makers#ft#go#go() abort + return { + \ 'args': [ + \ 'test', '-c', + \ '-o', g:neomake#compat#dev_null, + \ ], + \ 'append_file': 0, + \ 'cwd': '%:h', + \ 'serialize': 1, + \ 'serialize_abort_on_error': 1, + \ 'errorformat': + \ '%W%f:%l: warning: %m,' . + \ '%E%f:%l:%c:%m,' . + \ '%E%f:%l:%m,' . + \ '%C%\s%\+%m,' . + \ '%-G%.%#\\\[no test files],' . + \ '%-G#%.%#', + \ 'postprocess': function('neomake#postprocess#compress_whitespace'), + \ 'version_arg': 'version', + \ } +endfunction + +function! neomake#makers#ft#go#golint() abort + " golint's issues are informational, as they're stylistic (not bugs) + return { + \ 'errorformat': + \ '%I%f:%l:%c: %m,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#go#govet() abort + return { + \ 'exe': 'go', + \ 'args': ['vet'], + \ 'append_file': 0, + \ 'cwd': '%:h', + \ 'errorformat': + \ '%Evet: %.%\+: %f:%l:%c: %m,' . + \ '%W%f:%l: %m,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#go#gometalinter() abort + " Only run a subset of gometalinter for speed, users can override with: + " let g:neomake_go_gometalinter_args = ['--disable-all', '--enable=X', ...] + " + " All linters are only warnings, the go compiler will report errors + return { + \ 'args': ['--disable-all', '--enable=errcheck', '--enable=megacheck', '--vendor'], + \ 'append_file': 0, + \ 'cwd': '%:h', + \ 'errorformat': + \ '%f:%l:%c:%t%*[^:]: %m,' . + \ '%f:%l::%t%*[^:]: %m' + \ } +endfunction + +function! neomake#makers#ft#go#golangci_lint() abort + return { + \ 'exe': 'golangci-lint', + \ 'args': ['run', '--out-format=line-number', '--print-issued-lines=false'], + \ 'output_stream': 'stdout', + \ 'append_file': 0, + \ 'cwd': '%:h', + \ 'errorformat': + \ '%f:%l:%c: %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haml.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haml.vim new file mode 100644 index 0000000..df79b38 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haml.vim @@ -0,0 +1,13 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#haml#EnabledMakers() abort + return ['hamllint'] +endfunction + +function! neomake#makers#ft#haml#hamllint() abort + return { + \ 'exe': 'haml-lint', + \ 'args': ['--no-color'], + \ 'errorformat': '%f:%l [%t] %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haskell.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haskell.vim new file mode 100644 index 0000000..64a5227 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haskell.vim @@ -0,0 +1,169 @@ +unlet! s:makers +unlet! s:uses_cabal + +function! neomake#makers#ft#haskell#EnabledMakers() abort + if !exists('s:makers') + " cache whether each maker is available, to avoid lots of (UI blocking) + " system calls + " TODO: figure out how to do all this configuration async instead of + " caching it--that would allow the user to change directories from + " within vim and recalculate maker availability without restarting vim + let commands = ['ghc-mod', 'hdevtools', 'hlint', 'liquid'] + let s:makers = [] + let s:jobs = [] + for command in commands + " stack may be able to find a maker binary that's not on the normal + " path so check for that first + if executable('stack') + " run the maker command using stack to see whether stack can + " find it use the help flag to run the maker command without + " doing anything + let stack_command = [ + \ 'stack' + \ , 'exec' + \ , '--' + \ , command + \ , '--help' + \ ] + if has('nvim') + let job_id = jobstart( + \ stack_command, + \ { 'command': command + \ , 'on_exit': function('s:CheckStackMakerAsync') + \ }) + if job_id > 0 + call add(s:jobs, job_id) + endif + else + call extend(stack_command, ['> /dev/null 2>&1;', 'echo $?']) + if system(join(stack_command, ' ')) == 0 + call add(s:makers, substitute(command, '-', '', 'g')) + endif + endif + elseif executable(command) " no stack bin so check for maker bin + call add(s:makers, substitute(command, '-', '', 'g')) + endif + endfor + if has('nvim') + call jobwait(s:jobs) + endif + endif + return s:makers +endfunction + +function! neomake#makers#ft#haskell#hdevtools() abort + let params = { + \ 'exe': 'hdevtools', + \ 'args': ['check', '-g-Wall'], + \ 'mapexpr': s:CleanUpSpaceAndBackticks(), + \ 'errorformat': + \ '%-Z %#,'. + \ '%W%f:%l:%v: Warning: %m,'. + \ '%W%f:%l:%v: Warning:,'. + \ '%E%f:%l:%v: %m,'. + \ '%E%>%f:%l:%v:,'. + \ '%+C %#%m,'. + \ '%W%>%f:%l:%v:,'. + \ '%+C %#%tarning: %m,' + \ } + " hdevtools needs the GHC-PACKAGE-PATH environment variable to exist + " when running on a project WITHOUT a cabal file, but it needs the + " GHC-PACKAGE-PATH to NOT exist when running on a with a project WITH + " a cabal file + if !exists('s:uses_cabal') + let s:uses_cabal = 0 + if executable('stack') + let output = neomake#compat#systemlist(['stack', '--verbosity', 'silent', 'path', '--project-root']) + if !empty(output) + let rootdir = output[0] + if !empty(glob(rootdir . '/*.cabal')) + let s:uses_cabal = 1 + endif + endif + endif + endif + if s:uses_cabal + let params['stackexecargs'] = ['--no-ghc-package-path'] + endif + return s:TryStack(params) +endfunction + +function! neomake#makers#ft#haskell#ghcmod() abort + " This filters out newlines, which is what neovim gives us instead of the + " null bytes that ghc-mod sometimes spits out. + let mapexpr = 'substitute(v:val, "\n", "", "g")' + return s:TryStack({ + \ 'exe': 'ghc-mod', + \ 'args': ['check'], + \ 'mapexpr': mapexpr, + \ 'errorformat': + \ '%-G%\s%#,' . + \ '%f:%l:%c:%trror: %m,' . + \ '%f:%l:%c:%tarning: %m,'. + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%E%f:%l:%c:%m,' . + \ '%E%f:%l:%c:,' . + \ '%Z%m' + \ }) +endfunction + +function! neomake#makers#ft#haskell#HlintEntryProcess(entry) abort + " Postprocess hlint output to make it more readable as a single line + let a:entry.text = substitute(a:entry.text, '\v(Found:)\s*\n', ' | \1', 'g') + let a:entry.text = substitute(a:entry.text, '\v(Why not:)\s*\n', ' | \1', 'g') + let a:entry.text = substitute(a:entry.text, '^No hints$', '', 'g') + call neomake#postprocess#compress_whitespace(a:entry) +endfunction + +function! neomake#makers#ft#haskell#hlint() abort + return s:TryStack({ + \ 'exe': 'hlint', + \ 'postprocess': function('neomake#makers#ft#haskell#HlintEntryProcess'), + \ 'args': [], + \ 'errorformat': + \ '%E%f:%l:%v: Error: %m,' . + \ '%W%f:%l:%v: Warning: %m,' . + \ '%I%f:%l:%v: Suggestion: %m,' . + \ '%C%m' + \ }) +endfunction + +function! neomake#makers#ft#haskell#liquid() abort + return s:TryStack({ + \ 'exe': 'liquid', + \ 'args': [], + \ 'mapexpr': s:CleanUpSpaceAndBackticks(), + \ 'errorformat': + \ '%E %f:%l:%c-%.%#Error: %m,' . + \ '%C%.%#|%.%#,' . + \ '%C %#^%#,' . + \ '%C%m,' + \ }) +endfunction + +function! s:CheckStackMakerAsync(_job_id, data, _event) dict abort + if a:data == 0 + call add(s:makers, substitute(self.command, '-', '', 'g')) + endif +endfunction + +function! s:TryStack(maker) abort + if executable('stack') + if !has_key(a:maker, 'stackexecargs') + let a:maker['stackexecargs'] = [] + endif + let a:maker['args'] = + \ ['--verbosity', 'silent', 'exec'] + \ + a:maker['stackexecargs'] + \ + ['--', a:maker['exe']] + \ + a:maker['args'] + let a:maker['exe'] = 'stack' + endif + return a:maker +endfunction + +function! s:CleanUpSpaceAndBackticks() abort + return 'substitute(substitute(v:val, " \\{2,\\}", " ", "g"), "`", "''", "g")' +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haxe.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haxe.vim new file mode 100644 index 0000000..9fd07ec --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/haxe.vim @@ -0,0 +1,11 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#haxe#EnabledMakers() abort + return ['haxe'] +endfunction + +function! neomake#makers#ft#haxe#haxe() abort + return { + \ 'errorformat': '%E%f:%l: characters %c-%n : %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/help.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/help.vim new file mode 100644 index 0000000..c573cef --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/help.vim @@ -0,0 +1,40 @@ +let s:makers = ['writegood'] + +let s:slash = neomake#utils#Slash() +let s:vimhelplint_exe = '' +if executable('vimhelplint') + let s:vimhelplint_exe = 'vimhelplint' +else + let s:neomake_root = expand('<sfile>:p:h:h:h:h:h', 1) + if !empty(glob(join([s:neomake_root, 'build', 'vimhelplint'], s:slash))) + let s:vimhelplint_exe = join([s:neomake_root, 'contrib', 'vimhelplint'], s:slash) + endif +endif +if !empty(s:vimhelplint_exe) + let s:makers += ['vimhelplint'] +endif + +function! neomake#makers#ft#help#EnabledMakers() abort + return s:makers +endfunction + +function! neomake#makers#ft#help#vimhelplint() abort + " NOTE: does not support/uses arg from wrapper script (i.e. no support for + " tempfiles). It will use the arg only to expand/glob `*.txt` + " (which does not include the hidden tempfile). + return { + \ 'exe': s:vimhelplint_exe, + \ 'errorformat': '%f:%l:%c:%trror:%n:%m,%f:%l:%c:%tarning:%n:%m', + \ 'postprocess': function('neomake#postprocess#generic_length'), + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#help#proselint() abort + return neomake#makers#ft#text#proselint() +endfunction + +function! neomake#makers#ft#help#writegood() abort + return neomake#makers#ft#text#writegood() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/html.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/html.vim new file mode 100644 index 0000000..6100175 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/html.vim @@ -0,0 +1,20 @@ +function! neomake#makers#ft#html#tidy() abort + " NOTE: could also have info items, but those are skipped with -e/-q, e.g. + " 'line 7 column 1 - Info: value for attribute "id" missing quote marks'. + return { + \ 'args': ['-e', '-q', '--gnu-emacs', 'true'], + \ 'errorformat': '%W%f:%l:%c: Warning: %m', + \ } +endfunction + +function! neomake#makers#ft#html#htmlhint() abort + return { + \ 'args': ['--format', 'unix', '--nocolor'], + \ 'errorformat': '%f:%l:%c: %m,%-G,%-G%*\d problems', + \ } +endfunction + +function! neomake#makers#ft#html#EnabledMakers() abort + return ['tidy', 'htmlhint'] +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/idris.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/idris.vim new file mode 100644 index 0000000..5d95edb --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/idris.vim @@ -0,0 +1,25 @@ +function! neomake#makers#ft#idris#EnabledMakers() abort + return ['idris'] +endfunction + +function! neomake#makers#ft#idris#Postprocess(entry) abort + call neomake#postprocess#compress_whitespace(a:entry) + " Extract length from the beginning of the entry ('-4:When checking left hand side of xor:'). + if a:entry.text =~# '\v^\d+:' + let end = 0 + a:entry.text " cast to int + let a:entry.length = end - a:entry.col + let a:entry.text = substitute(a:entry.text, '\v^([^:]+:){2} ', '', '') + endif +endfunction + +function! neomake#makers#ft#idris#idris() abort + return { + \ 'exe': 'idris', + \ 'args': ['--check', '--warn', '--total', '--warnpartial', '--warnreach'], + \ 'errorformat': + \ '%E%f:%l:%c:%.%#,%-C %#%m,%-C%.%#,'. + \ '%E%f:%l:%c-%m,%-C %#%m,%-C%.%#', + \ 'postprocess': function('neomake#makers#ft#idris#Postprocess'), + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jade.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jade.vim new file mode 100644 index 0000000..c747950 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jade.vim @@ -0,0 +1,13 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#jade#EnabledMakers() abort + return ['jadelint'] +endfunction + +function! neomake#makers#ft#jade#jadelint() abort + return { + \ 'exe': 'jade-lint', + \ 'args': ['--reporter', 'inline'], + \ 'errorformat': '%f:%l:%c %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jasmine.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jasmine.vim new file mode 100644 index 0000000..56e0a4f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jasmine.vim @@ -0,0 +1,9 @@ +function! neomake#makers#ft#jasmine#SupersetOf() abort + return 'javascript' +endfunction + +function! neomake#makers#ft#jasmine#EnabledMakers() abort + return ['jshint', 'eslint', 'jscs'] +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java.vim new file mode 100644 index 0000000..1c09bda --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java.vim @@ -0,0 +1,396 @@ +"============================================================================ +"File: java.vim +"Description: Syntax checking plugin for neomake +"Maintainer: Wang Shidong <wsdjeg at outlook dot com> +"License: This program is free software. It comes without any warranty, +" to the extent permitted by applicable law. You can redistribute +" it and/or modify it under the terms of the Do What The Fuck You +" Want To Public License, Version 2, as published by Sam Hocevar. +" See http://sam.zoy.org/wtfpl/COPYING for more details. +"============================================================================ + +let s:save_cpo = &cpoptions +set cpoptions&vim + +if exists('g:loaded_neomake_java_javac_maker') + finish +endif +let g:loaded_neomake_java_javac_maker = 1 + +let g:neomake_java_javac_maven_pom_tags = ['build', 'properties'] +let g:neomake_java_javac_maven_pom_properties = {} +let s:is_windows = has('win32') || has('win64') || has('win16') || has('dos32') || has('dos16') +if s:is_windows + let s:fsep = ';' + let s:psep = '\' +else + let s:fsep = ':' + let s:psep = '/' +endif +let g:neomake_java_checker_home = fnamemodify(expand('<sfile>'), ':p:h:gs?\\?/?') + +" custom options +let g:neomake_java_javac_executable = + \ get(g:, 'neomake_java_javac_executable', 'javac') + +let g:neomake_java_maven_executable = + \ get(g:, 'neomake_java_maven_executable', 'mvn') + +let g:neomake_java_gradle_executable = + \ get(g:, 'neomake_java_gradle_executable', s:is_windows? '.\gradlew.bat' : './gradlew') + +let g:neomake_java_ant_executable = + \ get(g:, 'neomake_java_ant_executable', 'ant') + +let g:neomake_java_checkstyle_executable = + \ get(g:, 'neomake_java_checkstyle_executable', 'checkstyle') + +let g:neomake_java_javac_options = + \ get(g:, 'neomake_java_javac_options', ['-Xlint']) + +let g:neomake_java_maven_options = + \ get(g:, 'neomake_java_maven_options', '') + +let g:neomake_java_javac_classpath = + \ get(g:, 'neomake_java_javac_classpath', '') + +let g:neomake_java_javac_outputdir = + \ get(g:, 'neomake_java_javac_outputdir', '') + +let g:neomake_java_checkstyle_xml = + \ get(g:, 'neomake_java_checkstyle_xml', '/usr/share/checkstyle/google_checks.xml') + +let g:neomake_java_javac_delete_output = + \ get(g:, 'neomake_java_javac_delete_output', 1) + +let g:neomake_java_javac_autoload_maven_classpath = + \ get(g:, 'neomake_java_javac_autoload_maven_classpath', 1) + +let g:neomake_java_javac_autoload_gradle_classpath = + \ get(g:, 'neomake_java_javac_autoload_gradle_classpath', 1) + +let g:neomake_java_javac_autoload_ant_classpath = + \ get(g:, 'neomake_java_javac_autoload_ant_classpath', 1) + +let g:neomake_java_javac_autoload_eclipse_classpath = + \ get(g:, 'neomake_java_javac_autoload_eclipse_classpath', 1) + +let g:neomake_java_javac_maven_pom_ftime = + \ get(g:, 'neomake_java_javac_maven_pom_ftime', {}) + +let g:neomake_java_javac_maven_pom_classpath = + \ get(g:, 'neomake_java_javac_maven_pom_classpath', {}) + +let g:neomake_java_javac_gradle_ftime = + \ get(g:, 'neomake_java_javac_gradle_ftime', {}) + +let g:neomake_java_javac_gradle_classpath = + \ get(g:, 'neomake_java_javac_gradle_classpath', {}) + +let g:neomake_java_javac_ant_ftime = + \ get(g:, 'neomake_java_javac_ant_ftime', {}) + +let g:neomake_java_javac_ant_classpath = + \ get(g:, 'neomake_java_javac_ant_classpath', {}) + + +let s:has_maven = executable(expand(g:neomake_java_maven_executable, 1)) +let s:has_gradle = executable(expand(g:neomake_java_gradle_executable, 1)) +let s:has_ant = executable(expand(g:neomake_java_ant_executable, 1)) + +function! s:tmpdir() abort + let tempdir = tempname() + call mkdir(tempdir, 'p', 0700) + return tempdir +endfunction + +function! s:ClassSep() abort + return (s:is_windows || has('win32unix')) ? ';' : ':' +endfunction + +function! s:shescape(string) abort + return neomake#utils#shellescape(a:string) +endfunction + +function! s:AddToClasspath(classpath, path) abort + if a:path ==# '' + return a:classpath + endif + return (a:classpath !=# '') ? a:classpath . s:ClassSep() . a:path : a:path +endfunction + +" @vimlint(EVL103, 1, a:classpathFile) +function! s:ReadClassPathFile(classpathFile) abort + let cp = '' + let file = g:neomake_java_checker_home. s:psep. 'java'. s:psep. 'classpath.py' + if has('python3') + execute 'py3file' file + py3 import vim + py3 vim.command("let cp = '%s'" % os.pathsep.join(ReadClasspathFile(vim.eval('a:classpathFile'))).replace('\\', '/')) + elseif has('python') + execute 'pyfile' file + py import vim + py vim.command("let cp = '%s'" % os.pathsep.join(ReadClasspathFile(vim.eval('a:classpathFile'))).replace('\\', '/')) + endif + return cp +endfunction +" @vimlint(EVL103, 0, a:classpathFile) + +function! neomake#makers#ft#java#EnabledMakers() abort + let makers = [] + if executable(expand(g:neomake_java_javac_executable, 1)) + call add(makers, g:neomake_java_javac_executable) + endif + if executable(expand(g:neomake_java_checkstyle_executable, 1)) + call add(makers, g:neomake_java_checkstyle_executable) + endif + return makers +endfunction + +function! neomake#makers#ft#java#javac() abort + let javac_opts = extend([], g:neomake_java_javac_options) + + let output_dir = '' + if g:neomake_java_javac_delete_output + let output_dir = s:tmpdir() + let javac_opts = extend(javac_opts, ['-d', s:shescape(output_dir)]) + endif + + let javac_classpath = get(g:, 'neomake_java_javac_classpath', '') + + if s:has_maven && g:neomake_java_javac_autoload_maven_classpath && empty(javac_classpath) + if !g:neomake_java_javac_delete_output + let javac_opts = extend(javac_opts, ['-d', s:shescape(s:MavenOutputDirectory())]) + endif + let javac_classpath = s:AddToClasspath(javac_classpath, s:GetMavenClasspath()) + endif + + if s:has_gradle && g:neomake_java_javac_autoload_gradle_classpath && empty(javac_classpath) + if !g:neomake_java_javac_delete_output + let javac_opts = extend(javac_opts, ['-d', s:shescape(s:GradleOutputDirectory())]) + endif + let javac_classpath = s:AddToClasspath(javac_classpath, s:GetGradleClasspath()) + endif + + if s:has_ant && g:neomake_java_javac_autoload_ant_classpath && empty(javac_classpath) + let javac_classpath = s:AddToClasspath(javac_classpath, s:GetAntClasspath()) + endif + + if (has('python') || has('python3')) && empty(javac_classpath) + let classpathFile = fnamemodify(findfile('.classpath', escape(expand('.'), '*[]?{}, ') . ';'), ':p') + if !empty(classpathFile) && filereadable(classpathFile) + let javac_classpath = s:ReadClassPathFile(classpathFile) + endif + endif + + if javac_classpath !=# '' + let javac_opts = extend(javac_opts, ['-cp', javac_classpath]) + endif + + return { + \ 'args': javac_opts, + \ 'exe': g:neomake_java_javac_executable, + \ 'errorformat': + \ '%E%f:%l: error: %m,'. + \ '%W%f:%l: warning: %m,'. + \ '%E%f:%l: %m,'. + \ '%Z%p^,'. + \ '%-G%.%#', + \ 'version_arg': '-version' + \ } +endfunction + +function! neomake#makers#ft#java#checkstyle() abort + return { + \ 'args': ['-c', g:neomake_java_checkstyle_xml], + \ 'exe': g:neomake_java_checkstyle_executable, + \ 'errorformat': + \ '%-GStarting audit...,'. + \ '%-GAudit done.,'. + \ '%-GPicked up _JAVA_OPTIONS:%.%#,'. + \ '[%t%*[^]]] %f:%l:%c: %m [%s],'. + \ '[%t%*[^]]] %f:%l: %m [%s]', + \ 'version_arg': '-v' + \ } +endfunction + +function! s:findFileInParent(what, where) abort " {{{2 + let old_suffixesadd = &suffixesadd + let &suffixesadd = '' + let file = findfile(a:what, escape(a:where, ' ') . ';') + let &suffixesadd = old_suffixesadd + return file +endfunction " }}}2 + +function! s:GetMavenProperties() abort " {{{2 + let mvn_properties = {} + let pom = s:findFileInParent('pom.xml', expand('%:p:h', 1)) + if s:has_maven && filereadable(pom) + if !has_key(g:neomake_java_javac_maven_pom_properties, pom) + let mvn_cmd = s:shescape(expand(g:neomake_java_maven_executable, 1)) . + \ ' -f ' . s:shescape(pom) . + \ ' ' . g:neomake_java_maven_options + let mvn_is_managed_tag = 1 + let mvn_settings_output = split(system(mvn_cmd . ' help:effective-pom'), "\n") + let current_path = 'project' + for line in mvn_settings_output + let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\s*$') + if mvn_is_managed_tag && !empty(matches) + let mvn_is_managed_tag = index(g:neomake_java_javac_maven_pom_tags, matches[1]) >= 0 + let current_path .= '.' . matches[1] + else + let matches = matchlist(line, '\m^\s*</\([a-zA-Z0-9\-\.]\+\)>\s*$') + if !empty(matches) + let mvn_is_managed_tag = index(g:neomake_java_javac_maven_pom_tags, matches[1]) < 0 + let current_path = substitute(current_path, '\m\.' . matches[1] . '$', '', '') + else + let matches = matchlist(line, '\m^\s*<\([a-zA-Z0-9\-\.]\+\)>\(.\+\)</[a-zA-Z0-9\-\.]\+>\s*$') + if mvn_is_managed_tag && !empty(matches) + let mvn_properties[current_path . '.' . matches[1]] = matches[2] + endif + endif + endif + endfor + let g:neomake_java_javac_maven_pom_properties[pom] = mvn_properties + endif + return g:neomake_java_javac_maven_pom_properties[pom] + endif + return mvn_properties +endfunction " }}}2 + +function! s:GetMavenClasspath() abort " {{{2 + let pom = s:findFileInParent('pom.xml', expand('%:p:h', 1)) + if s:has_maven && filereadable(pom) + if !has_key(g:neomake_java_javac_maven_pom_ftime, pom) || g:neomake_java_javac_maven_pom_ftime[pom] != getftime(pom) + let mvn_cmd = s:shescape(expand(g:neomake_java_maven_executable, 1)) . + \ ' -f ' . s:shescape(pom) . + \ ' ' . g:neomake_java_maven_options + let mvn_classpath_output = split(system(mvn_cmd . ' dependency:build-classpath -DincludeScope=test'), "\n") + let mvn_classpath = '' + let class_path_next = 0 + + for line in mvn_classpath_output + if class_path_next == 1 + let mvn_classpath = substitute(line, "\r", '', 'g') + break + endif + if stridx(line, 'Dependencies classpath:') >= 0 + let class_path_next = 1 + endif + endfor + + let mvn_properties = s:GetMavenProperties() + + let output_dir = get(mvn_properties, 'project.build.outputDirectory', join(['target', 'classes'], s:psep)) + let mvn_classpath = s:AddToClasspath(mvn_classpath, output_dir) + + let test_output_dir = get(mvn_properties, 'project.build.testOutputDirectory', join(['target', 'test-classes'], s:psep)) + let mvn_classpath = s:AddToClasspath(mvn_classpath, test_output_dir) + + let g:neomake_java_javac_maven_pom_ftime[pom] = getftime(pom) + let g:neomake_java_javac_maven_pom_classpath[pom] = mvn_classpath + endif + return g:neomake_java_javac_maven_pom_classpath[pom] + endif + return '' +endfunction " }}}2 + +function! s:MavenOutputDirectory() abort " {{{2 + let pom = s:findFileInParent('pom.xml', expand('%:p:h', 1)) + if s:has_maven && filereadable(pom) + let mvn_properties = s:GetMavenProperties() + let output_dir = get(mvn_properties, 'project.properties.build.dir', getcwd()) + + let src_main_dir = get(mvn_properties, 'project.build.sourceDirectory', join(['src', 'main', 'java'], s:psep)) + let src_test_dir = get(mvn_properties, 'project.build.testsourceDirectory', join(['src', 'test', 'java'], s:psep)) + if stridx(expand('%:p:h', 1), src_main_dir) >= 0 + let output_dir = get(mvn_properties, 'project.build.outputDirectory', join ([output_dir, 'target', 'classes'], s:psep)) + endif + if stridx(expand('%:p:h', 1), src_test_dir) >= 0 + let output_dir = get(mvn_properties, 'project.build.testOutputDirectory', join([output_dir, 'target', 'test-classes'], s:psep)) + endif + + if has('win32unix') + let output_dir = substitute(system('cygpath -m ' . s:shescape(output_dir)), "\n", '', 'g') + endif + return output_dir + endif + return '.' +endfunction " }}}2 + +function! s:GradleOutputDirectory() abort + let gradle_build = s:findFileInParent('build.gradle', expand('%:p:h', 1)) + let items = split(gradle_build, s:psep) + if len(items)==1 + return join(['build', 'intermediates', 'classes', 'debug'], s:psep) + endif + let outputdir = '' + for i in items + if i !=# 'build.gradle' + let outputdir .= i . s:psep + endif + endfor + return outputdir . join(['build', 'intermediates', 'classes', 'debug'], s:psep) +endf + +function! s:GetGradleClasspath() abort + let gradle = s:findFileInParent('build.gradle', expand('%:p:h', 1)) + if s:has_gradle && filereadable(gradle) + if !has_key(g:neomake_java_javac_gradle_ftime, gradle) || g:neomake_java_javac_gradle_ftime[gradle] != getftime(gradle) + try + let f = tempname() + if s:is_windows + let gradle_cmd = '.\gradlew.bat' + else + let gradle_cmd = './gradlew' + endif + call writefile(["allprojects{apply from: '" . g:neomake_java_checker_home . s:psep. 'java'. s:psep. "classpath.gradle'}"], f) + let ret = system(gradle_cmd . ' -q -I ' . shellescape(f) . ' classpath' ) + if v:shell_error == 0 + let cp = filter(split(ret, "\n"), "v:val =~# '^CLASSPATH:'")[0][10:] + if filereadable(getcwd() . s:psep . 'build.gradle') + let out_putdir = neomake#compat#globpath_list(getcwd(), join( + \ ['**', 'build', 'intermediates', 'classes', 'debug'], + \ s:psep), 0) + for classes in out_putdir + let cp .= s:ClassSep() . classes + endfor + endif + else + let cp = '' + endif + catch + finally + call delete(f) + endtry + let g:neomake_java_javac_gradle_ftime[gradle] = getftime(gradle) + let g:neomake_java_javac_gradle_classpath[gradle] = cp + endif + return g:neomake_java_javac_gradle_classpath[gradle] + endif + return '' +endf + +function! s:GetAntClasspath() abort + let ant = s:findFileInParent('build.xml', expand('%:p:h', 1)) + if s:has_ant && filereadable(ant) + if !has_key(g:neomake_java_javac_ant_ftime, ant) || g:neomake_java_javac_ant_ftime[ant] != getftime(ant) + try + let ant_cmd = 'ant classpath -f build.xml -S -q' + let cp = system(ant_cmd) + if v:shell_error != 0 + let cp = '' + endif + catch + endtry + let g:neomake_java_javac_ant_ftime[ant] = getftime(ant) + let g:neomake_java_javac_ant_classpath[ant] = cp + endif + return g:neomake_java_javac_ant_classpath[ant] + endif + return '' +endf + +let &cpoptions = s:save_cpo +unlet s:save_cpo +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.gradle b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.gradle new file mode 100644 index 0000000..f548c0d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.gradle @@ -0,0 +1,46 @@ +task classpath << { + + String finalFileContents = "" + HashSet<String> classpathFiles = new HashSet<String>() + for (proj in allprojects) { + + def exploded = proj.getBuildDir().absolutePath + File.separator + "intermediates" + File.separator + "exploded-aar" + def listFiles = new File(exploded) + if (listFiles.exists()) { + listFiles.eachFileRecurse(){ file -> + if (file.name.endsWith(".jar")){ + classpathFiles += file + } + } + } + + def rjava = proj.getBuildDir().absolutePath + File.separator + "intermediates" + File.separator + "classes" + File.separator + "debug" + def rFiles = new File(rjava) + if (rFiles.exists()) { + classpathFiles += rFiles + } + + for (conf in proj.configurations) { + for (dependency in conf) { + if (dependency.name.endsWith("aar")){ + } else { + classpathFiles += dependency + } + } + } + if (proj.hasProperty("android")){ + classpathFiles += proj.android.bootClasspath + } + + if (proj.hasProperty("sourceSets")) { + + for (srcSet in proj.sourceSets) { + for (dir in srcSet.java.srcDirs) { + classpathFiles += dir.absolutePath + } + } + } + } + def paths = classpathFiles.join(File.pathSeparator) + println "CLASSPATH:" + paths +} diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.py b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.py new file mode 100644 index 0000000..5a7ea8d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/java/classpath.py @@ -0,0 +1,15 @@ +import os +from xml.etree.ElementTree import * + + +def ReadClasspathFile(fn): + cp = [] + for a in parse(fn).findall('classpathentry'): + kind = a.get('kind') + if kind == 'src' and 'output' in a.keys(): + cp.append(os.path.abspath(a.get('output'))) + elif kind == 'lib' and 'path' in a.keys(): + cp.append(os.path.abspath(a.get('path'))) + elif kind == 'output' and 'path' in a.keys(): + cp.append(os.path.abspath(a.get('path'))) + return cp diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/javascript.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/javascript.vim new file mode 100644 index 0000000..7bb379f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/javascript.vim @@ -0,0 +1,119 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#javascript#EnabledMakers() abort + return ['jshint', 'jscs', + \ executable('eslint_d') ? 'eslint_d' : 'eslint', + \] +endfunction + +function! neomake#makers#ft#javascript#tsc() abort + return neomake#makers#ft#typescript#tsc() +endfunction + +function! neomake#makers#ft#javascript#gjslint() abort + return { + \ 'args': ['--nodebug_indentation', '--nosummary', '--unix_mode', '--nobeep'], + \ 'errorformat': '%f:%l:(New Error -%\\?\%n) %m,' . + \ '%f:%l:(-%\\?%n) %m,' . + \ '%-G1 files checked,' . + \ ' no errors found.,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#javascript#jshint() abort + return { + \ 'args': ['--verbose'], + \ 'errorformat': '%A%f: line %l\, col %v\, %m \(%t%*\d\),%-G,%-G%\\d%\\+ errors', + \ 'postprocess': function('neomake#postprocess#generic_length'), + \ } +endfunction + +function! neomake#makers#ft#javascript#jscs() abort + return { + \ 'args': ['--no-colors', '--reporter', 'inline'], + \ 'errorformat': '%E%f: line %l\, col %c\, %m', + \ } +endfunction + +function! neomake#makers#ft#javascript#eslint() abort + let maker = { + \ 'args': ['--format=compact'], + \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' . + \ '%W%f: line %l\, col %c\, Warning - %m,%-G,%-G%*\d problems%#', + \ 'cwd': '%:p:h', + \ 'output_stream': 'stdout', + \ } + + function! maker.supports_stdin(_jobinfo) abort + let self.args += ['--stdin', '--stdin-filename=%:p'] + let self.tempfile_name = '' + return 1 + endfunction + + return maker +endfunction + +function! neomake#makers#ft#javascript#eslint_d() abort + return neomake#makers#ft#javascript#eslint() +endfunction + +function! neomake#makers#ft#javascript#standard() abort + return { + \ 'args': ['-v'], + \ 'errorformat': '%W %f:%l:%c: %m,%-Gstandard: %.%#' + \ } +endfunction + +function! neomake#makers#ft#javascript#semistandard() abort + return { + \ 'errorformat': '%W %f:%l:%c: %m' + \ } +endfunction + +function! neomake#makers#ft#javascript#rjsx() abort + return { + \ 'exe': 'emacs', + \ 'args': ['%t','--quick','--batch','--eval=' + \ .'(progn(setq package-load-list ''((js2-mode t)(rjsx-mode t)))(package-initialize)(require ''rjsx-mode)' + \ .' (setq js2-include-node-externs t js2-include-rhino-externs t js2-include-browser-externs t js2-strict-missing-semi-warning nil)' + \ .' (rjsx-mode)(js2-reparse)(js2-display-error-list)' + \ .' (princ(replace-regexp-in-string "^" (concat buffer-file-name " ")' + \ .' (with-current-buffer "*js-lint*" (buffer-substring-no-properties(point-min)(point-max)))))(terpri))'], + \ 'errorformat': '%f line %l: %m,%-G%.%#', + \ 'append_file': 0, + \ } +endfunction + +function! neomake#makers#ft#javascript#flow() abort + return { + \ 'args': ['--from=vim', '--show-all-errors'], + \ 'errorformat': + \ '%-GNo errors!,' + \ .'%EFile "%f"\, line %l\, characters %c-%m,' + \ .'%trror: File "%f"\, line %l\, characters %c-%m,' + \ .'%C%m,%Z', + \ 'postprocess': function('neomake#makers#ft#javascript#FlowProcess') + \ } +endfunction + +function! neomake#makers#ft#javascript#FlowProcess(entry) abort + let lines = split(a:entry.text, '\n') + if !empty(lines) + let a:entry.text = join(lines[1:]) + let a:entry.length = lines[0] - a:entry.col + 1 + endif +endfunction + +function! neomake#makers#ft#javascript#xo() abort + return { + \ 'args': ['--compact'], + \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' . + \ '%W%f: line %l\, col %c\, Warning - %m', + \ } +endfunction + +function! neomake#makers#ft#javascript#stylelint() abort + return neomake#makers#ft#css#stylelint() +endfunction + diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/json.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/json.vim new file mode 100644 index 0000000..89a38e0 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/json.vim @@ -0,0 +1,38 @@ +function! neomake#makers#ft#json#EnabledMakers() abort + return ['jsonlint'] +endfunction + +function! neomake#makers#ft#json#jsonlintpy() abort + return { + \ 'exe': 'jsonlint-py', + \ 'args': ['--strict'], + \ 'errorformat': + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,', + \ } +endfunction + +function! neomake#makers#ft#json#jsonlint() abort + return { + \ 'args': ['--compact'], + \ 'errorformat': + \ '%ELine %l:%c,'. + \ '%Z\\s%#Reason: %m,'. + \ '%C%.%#,'. + \ '%f: line %l\, col %c\, %m,'. + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#json#eslint() abort + let maker = neomake#makers#ft#javascript#eslint() + let maker.args += ['--plugin', 'json'] + return maker +endfunction + +function! neomake#makers#ft#json#eslint_d() abort + let maker = neomake#makers#ft#javascript#eslint_d() + let maker.args += ['--plugin', 'json'] + return maker +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jsx.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jsx.vim new file mode 100644 index 0000000..38d3cc3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/jsx.vim @@ -0,0 +1,17 @@ +function! neomake#makers#ft#jsx#SupersetOf() abort + return 'javascript' +endfunction + +function! neomake#makers#ft#jsx#EnabledMakers() abort + return ['jshint', executable('eslint_d') ? 'eslint_d' : 'eslint'] +endfunction + +function! neomake#makers#ft#jsx#jsxhint() abort + return neomake#makers#ft#javascript#jshint() +endfunction + +function! neomake#makers#ft#jsx#stylelint() abort + return neomake#makers#ft#css#stylelint() +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/julia.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/julia.vim new file mode 100644 index 0000000..a6fed9f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/julia.vim @@ -0,0 +1,24 @@ +function! neomake#makers#ft#julia#EnabledMakers() abort + return ['lint'] +endfunction + +function! neomake#makers#ft#julia#lint() abort + return { +\ 'errorformat': '%f:%l %t%*[^ ] %m', +\ 'exe': 'julia', +\ 'args': ['-e', ' +\ try +\ using Lint +\ catch +\ println("$(basename(ARGS[1])):1 E999 Install Lint.jl: Pkg.add(""Lint"")"); +\ exit(1) +\ end; +\ r = lintfile(ARGS[1]); +\ if !isempty(r) +\ display(r); +\ exit(1) +\ end +\ '] +\ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/kotlin.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/kotlin.vim new file mode 100644 index 0000000..d7273e3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/kotlin.vim @@ -0,0 +1,12 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#kotlin#EnabledMakers() abort + return ['ktlint'] +endfunction + +function! neomake#makers#ft#kotlin#ktlint() abort + return { + \ 'errorformat': '%E%f:%l:%c: %m', + \ } +endfunction + diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/less.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/less.vim new file mode 100644 index 0000000..51ba941 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/less.vim @@ -0,0 +1,19 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#less#EnabledMakers() abort + return executable('stylelint') ? ['stylelint'] : ['lessc'] +endfunction + +function! neomake#makers#ft#less#lessc() abort + return { + \ 'args': ['--lint', '--no-color'], + \ 'errorformat': + \ '%m in %f on line %l\, column %c:,' . + \ '%m in %f:%l:%c,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#less#stylelint() abort + return neomake#makers#ft#css#stylelint() +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lex.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lex.vim new file mode 100644 index 0000000..7dafebf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lex.vim @@ -0,0 +1,11 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#lex#EnabledMakers() abort + return ['flex'] +endfunction + +function! neomake#makers#ft#lex#flex() abort + return { + \ 'errorformat': '%f:%l: %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lua.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lua.vim new file mode 100644 index 0000000..c0e6bce --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/lua.vim @@ -0,0 +1,33 @@ +function! neomake#makers#ft#lua#EnabledMakers() abort + return executable('luacheck') ? ['luacheck'] : ['luac'] +endfunction + +" luacheck: postprocess: use pattern (%s) for end column. +function! neomake#makers#ft#lua#PostprocessLuacheck(entry) abort + let end_col = matchstr(a:entry.pattern, '\v\d+') + if !empty(end_col) + let a:entry.length = end_col - a:entry.col + 1 + else + echom 'luacheck: no end_col: '.string(a:entry) + endif + let a:entry.pattern = '' +endfunction + +function! neomake#makers#ft#lua#luacheck() abort + " cwd: luacheck looks for .luacheckrc upwards from there. + return { + \ 'args': ['--no-color', '--formatter=plain', '--ranges', '--codes', '--filename', '%:p'], + \ 'cwd': '%:p:h', + \ 'errorformat': '%E%f:%l:%c-%s: \(%t%n\) %m', + \ 'postprocess': function('neomake#makers#ft#lua#PostprocessLuacheck'), + \ 'supports_stdin': 1, + \ } +endfunction + +function! neomake#makers#ft#lua#luac() abort + return { + \ 'args': ['-p'], + \ 'errorformat': '%*\f: %#%f:%l: %m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/mail.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/mail.vim new file mode 100644 index 0000000..54cd09e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/mail.vim @@ -0,0 +1,8 @@ +function! neomake#makers#ft#mail#EnabledMakers() abort + return ['proselint'] +endfunction + +function! neomake#makers#ft#mail#proselint() abort + return neomake#makers#ft#text#proselint() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/markdown.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/markdown.vim new file mode 100644 index 0000000..1146488 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/markdown.vim @@ -0,0 +1,97 @@ +function! neomake#makers#ft#markdown#SupersetOf() abort + return 'text' +endfunction + +function! neomake#makers#ft#markdown#EnabledMakers() abort + let makers = executable('mdl') ? ['mdl'] : ['markdownlint'] + if executable('vale') | let makers += ['vale'] | endif + return makers + neomake#makers#ft#text#EnabledMakers() +endfunction + +function! neomake#makers#ft#markdown#mdl() abort + let maker = { + \ + \ 'errorformat': + \ '%W%f:%l: %m,%-G%.%#', + \ 'output_stream': 'stdout', + \ } + function! maker.postprocess(entry) abort + if a:entry.text[0:1] ==# 'MD' + let [code, text] = split(a:entry.text, '\v^MD\d+\zs ') + let a:entry.nr = str2nr(code[2:]) + let a:entry.text = printf('%s (%s)', text, code) + endif + return a:entry + endfunction + return maker +endfunction + +function! neomake#makers#ft#markdown#markdownlint() abort + return { + \ 'errorformat': '%f: %l: %m' + \ } +endfunction + +let s:alex_supports_stdin = {} +function! neomake#makers#ft#markdown#alex() abort + let maker = { + \ 'errorformat': + \ '%P%f,' + \ .'%-Q,' + \ .'%*[ ]%l:%c-%*\d:%n%*[ ]%tarning%*[ ]%m,' + \ .'%-G%.%#' + \ } + + function! maker.supports_stdin(_jobinfo) abort + let exe = exists('*exepath') ? exepath(self.exe) : self.exe + let support = get(s:alex_supports_stdin, exe, -1) + if support == -1 + let ver = neomake#compat#systemlist(['alex', '--version']) + let ver_split = split(ver[0], '\.') + if len(ver_split) > 1 && (ver_split[0] > 0 || +ver_split[1] >= 6) + let support = 1 + else + let support = 0 + endif + let s:alex_supports_stdin[exe] = support + call neomake#log#debug('alex: stdin support: '.support.'.') + endif + if support + let self.args += ['--stdin'] + let self.tempfile_name = '' + endif + return support + endfunction + + return maker +endfunction + +function! neomake#makers#ft#markdown#ProcessVale(context) abort + let entries = [] + for [filename, items] in items(a:context['json']) + for data in items + let entry = { + \ 'maker_name': 'vale', + \ 'filename': filename, + \ 'text': data.Message, + \ 'lnum': data.Line, + \ 'col': data.Span[0], + \ 'length': data.Span[1] - data.Span[0] + 1, + \ 'type': toupper(data.Severity[0]) + \ } + call add(entries, entry) + endfor + endfor + return entries +endfunction + +function! neomake#makers#ft#markdown#vale() abort + return { + \ 'args': [ + \ '--no-wrap', + \ '--output', 'JSON' + \ ], + \ 'process_json': function('neomake#makers#ft#markdown#ProcessVale') + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/matlab.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/matlab.vim new file mode 100644 index 0000000..f208be6 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/matlab.vim @@ -0,0 +1,15 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#matlab#EnabledMakers() abort + return ['mlint'] +endfunction + +function! neomake#makers#ft#matlab#mlint() abort + return { + \ 'args': ['-id'], + \ 'mapexpr': "neomake_bufname.':'.v:val", + \ 'errorformat': + \ '%f:L %l (C %c): %m,'. + \ '%f:L %l (C %c-%*[0-9]): %m,', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/moon.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/moon.vim new file mode 100644 index 0000000..486bea7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/moon.vim @@ -0,0 +1,15 @@ +function! neomake#makers#ft#moon#EnabledMakers() abort + return ['moonc'] +endfunction + +function! neomake#makers#ft#moon#moonc() abort + return { + \ 'args': ['-l'], + \ 'errorformat': + \ '%-G,' . + \ '%-G>%#,' . + \ '%+P%f,'. + \ 'line\ %l:\ %m' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/neomake_tests.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/neomake_tests.vim new file mode 100644 index 0000000..4d06e7a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/neomake_tests.vim @@ -0,0 +1,58 @@ +if !exists('g:neomake_test_messages') + " Only use it during tests. + finish +endif + +function! neomake#makers#ft#neomake_tests#EnabledMakers() abort + return get(b:, 'neomake_test_enabledmakers', + \ get(g:, 'neomake_test_enabledmakers', + \ ['maker_without_exe', 'nonexisting'])) +endfunction + +function! neomake#makers#ft#neomake_tests#maker_without_exe() abort + return {} +endfunction + +function! neomake#makers#ft#neomake_tests#maker_with_nonstring_exe() abort + return {'exe': function('tr')} +endfunction + +function! neomake#makers#ft#neomake_tests#echo_maker() abort + return { + \ 'exe': 'printf', + \ 'args': 'neomake_tests_echo_maker', + \ 'errorformat': '%m', + \ 'append_file': 0, + \ } +endfunction + +function! neomake#makers#ft#neomake_tests#echo_args() abort + return { + \ 'exe': 'echo', + \ 'errorformat': '%m', + \ } +endfunction + +function! neomake#makers#ft#neomake_tests#true() abort + return {} +endfunction + +function! neomake#makers#ft#neomake_tests#error_maker() abort + return { + \ 'exe': 'printf', + \ 'args': ['%s:1:error_msg_1'], + \ 'errorformat': '%E%f:%l:%m', + \ 'append_file': 1, + \ 'short_name': 'errmkr', + \ } +endfunction + +function! neomake#makers#ft#neomake_tests#process_output_error() abort + let maker = {'exe': 'echo', 'args': 'output', 'append_file': 0} + + function! maker.process_output(...) abort + return [{'valid': 1, 'text': 'error', 'lnum': 1, 'bufnr': bufnr('%')}] + endfunction + return maker +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nim.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nim.vim new file mode 100644 index 0000000..68b72a3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nim.vim @@ -0,0 +1,16 @@ +function! neomake#makers#ft#nim#EnabledMakers() abort + return ['nim'] +endfunction + +function! neomake#makers#ft#nim#nim() abort + return { + \ 'exe': 'nim', + \ 'args': ['--listFullPaths', '--verbosity:0', '--colors:off', + \ '-c', 'check'], + \ 'errorformat': + \ '%I%f(%l\, %c) Hint: %m,' . + \ '%W%f(%l\, %c) Warning: %m,' . + \ '%E%f(%l\, %c) Error: %m' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nix.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nix.vim new file mode 100644 index 0000000..f239789 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/nix.vim @@ -0,0 +1,14 @@ +" vim: ts=4 sw=4 et +" +function! neomake#makers#ft#nix#EnabledMakers() abort + return ['nix_instantiate'] +endfunction + +function! neomake#makers#ft#nix#nix_instantiate() abort + return { + \ 'exe': 'nix-instantiate', + \ 'args': ['--parse-only'], + \ 'errorformat': 'error: %m at %f:%l:%c' + \ } +endfunction + diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/node.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/node.vim new file mode 100644 index 0000000..a6cd321 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/node.vim @@ -0,0 +1,9 @@ +function! neomake#makers#ft#node#SupersetOf() abort + return 'javascript' +endfunction + +function! neomake#makers#ft#node#EnabledMakers() abort + return ['jshint', 'eslint', 'jscs'] +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/objc.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/objc.vim new file mode 100644 index 0000000..5b093f4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/objc.vim @@ -0,0 +1,55 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#objc#EnabledMakers() abort + let makers = ['clang', 'clangtidy', 'clangcheck'] + return makers +endfunction + +function! neomake#makers#ft#objc#clang() abort + " We will enable ARC and disable warnings about unused parameters because + " it is quite common in Cocoa not to use every method parameter. + return { + \ 'args': ['-fsyntax-only', '-fobjc-arc', '-Wall', '-Wextra', '-Wno-unused-parameter'], + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%I%f:%l:%c: note: %m,' . + \ '%f:%l:%c: %m,'. + \ '%f:%l: %trror: %m,'. + \ '%f:%l: %tarning: %m,'. + \ '%I%f:%l: note: %m,'. + \ '%f:%l: %m' + \ } +endfunction + +" The -p option followed by the path to the build directory should be set in +" the maker's arguments. That directory should contain the compile command +" database (compile_commands.json). +function! neomake#makers#ft#objc#clangtidy() abort + return { + \ 'exe': 'clang-tidy', + \ 'errorformat': + \ '%E%f:%l:%c: fatal error: %m,' . + \ '%E%f:%l:%c: error: %m,' . + \ '%W%f:%l:%c: warning: %m,' . + \ '%-G%\m%\%%(LLVM ERROR:%\|No compilation database found%\)%\@!%.%#,' . + \ '%E%m', + \ } +endfunction + +function! neomake#makers#ft#objc#clangcheck() abort + return { + \ 'exe': 'clang-check', + \ 'errorformat': + \ '%-G%f:%s:,' . + \ '%f:%l:%c: %trror: %m,' . + \ '%f:%l:%c: %tarning: %m,' . + \ '%I%f:%l:%c: note: %m,' . + \ '%f:%l:%c: %m,'. + \ '%f:%l: %trror: %m,'. + \ '%f:%l: %tarning: %m,'. + \ '%I%f:%l: note: %m,'. + \ '%f:%l: %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pandoc.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pandoc.vim new file mode 100644 index 0000000..ae56b04 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pandoc.vim @@ -0,0 +1,8 @@ +function! neomake#makers#ft#pandoc#SupersetOf() abort + return 'markdown' +endfunction + +function! neomake#makers#ft#pandoc#EnabledMakers() abort + return neomake#makers#ft#markdown#EnabledMakers() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/perl.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/perl.vim new file mode 100644 index 0000000..da07694 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/perl.vim @@ -0,0 +1,34 @@ +" vim: ts=4 sw=4 et +function! neomake#makers#ft#perl#EnabledMakers() abort + return ['perl', 'perlcritic'] +endfunction + +function! neomake#makers#ft#perl#perlcritic() abort + return { + \ 'args' : ['--quiet', '--nocolor', '--verbose', + \ '\\%f:\\%l:\\%c:(\\%s) \\%m (\\%e)\\n'], + \ 'errorformat': '%f:%l:%c:%m,' + \} +endfunction + +function! neomake#makers#ft#perl#perl() abort + return { + \ 'args' : ['-c', '-X', '-Mwarnings'], + \ 'errorformat': '%-G%.%#had too many errors.,' + \ . '%-G%.%#had compilation errors.,' + \ . '%-G%.%#syntax OK,' + \ . '%m at %f line %l.,' + \ . '%+E%.%# at %f line %l\,%.%#,' + \ . '%+C%.%#', + \ 'postprocess': function('neomake#makers#ft#perl#PerlEntryProcess'), + \} +endfunction + +function! neomake#makers#ft#perl#PerlEntryProcess(entry) abort + let extramsg = substitute(a:entry.pattern, '\^\\V', '', '') + let extramsg = substitute(extramsg, '\\\$', '', '') + + if !empty(extramsg) + let a:entry.text .= ' ' . extramsg + endif +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/php.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/php.vim new file mode 100644 index 0000000..7edefa3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/php.vim @@ -0,0 +1,72 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#php#EnabledMakers() abort + return ['php', 'phpmd', 'phpcs', 'phpstan'] +endfunction + +function! neomake#makers#ft#php#php() abort + return { + \ 'args': ['-l', '-d', 'display_errors=1', '-d', 'log_errors=0', + \ '-d', 'xdebug.cli_color=0'], + \ 'errorformat': + \ '%-GNo syntax errors detected in%.%#,'. + \ '%EParse error: %#syntax error\, %m in %f on line %l,'. + \ '%EParse error: %m in %f on line %l,'. + \ '%EFatal error: %m in %f on line %l,'. + \ '%-G\s%#,'. + \ '%-GErrors parsing %.%#', + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#php#phpcs() abort + let args = ['--report=csv', '-q'] + + "Add standard argument if one is set. + if exists('g:neomake_php_phpcs_args_standard') + call add(args, '--standard=' . expand(g:neomake_php_phpcs_args_standard)) + endif + + return { + \ 'args': args, + \ 'errorformat': + \ '%-GFile\,Line\,Column\,Type\,Message\,Source\,Severity%.%#,'. + \ '"%f"\,%l\,%c\,%t%*[a-zA-Z]\,"%m"\,%*[a-zA-Z0-9_.-]\,%*[0-9]%.%#', + \ } +endfunction + +function! neomake#makers#ft#php#phpmd() abort + return { + \ 'args': ['%t', 'text', 'codesize,design,unusedcode,naming'], + \ 'append_file': 0, + \ 'errorformat': '%W%f:%l%\s%\s%#%m' + \ } +endfunction + +function! neomake#makers#ft#php#phpstan() abort + " PHPStan normally considers 0 to be the default level, so that is used here as the default: + let maker = { + \ 'args': ['analyse', '--error-format', 'raw', '--no-progress', '--level', get(g:, 'neomake_phpstan_level', 0)], + \ 'errorformat': '%E%f:%l:%m', + \ } + " Check for the existence of a default PHPStan project configuration file. + " Technically PHPStan does not have a concept of a default filename for a + " project configuration file, but phpstan.neon is the filename shown in the + " example in the PHPStan documentation, so this is the default name expected + " by Neomake. + let phpStanConfigFilePath = neomake#utils#FindGlobFile('phpstan.neon') + if !empty(phpStanConfigFilePath) + call extend(maker.args, ['-c', phpStanConfigFilePath]) + endif + return maker +endfunction + +function! neomake#makers#ft#php#psalm() abort + let maker = { + \ 'args': [ + \ '--output-format=pylint' + \ ], + \ 'errorformat': '%A%f:%l:%\s[%t%n]%\s%m', + \ } + return maker +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/proto.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/proto.vim new file mode 100644 index 0000000..fcff577 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/proto.vim @@ -0,0 +1,12 @@ +function! neomake#makers#ft#proto#EnabledMakers() abort + return ['prototool'] +endfunction + +function! neomake#makers#ft#proto#prototool() abort + return { + \ 'exe': 'prototool', + \ 'args': ['lint'], + \ 'errorformat': '%f:%l:%c:%m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pug.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pug.vim new file mode 100644 index 0000000..53f2214 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/pug.vim @@ -0,0 +1,13 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#pug#EnabledMakers() abort + return ['puglint'] +endfunction + +function! neomake#makers#ft#pug#puglint() abort + return { + \ 'exe': 'pug-lint', + \ 'args': ['--reporter', 'inline'], + \ 'errorformat': '%f:%l:%c %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/puppet.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/puppet.vim new file mode 100644 index 0000000..c7a467d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/puppet.vim @@ -0,0 +1,29 @@ +function! neomake#makers#ft#puppet#EnabledMakers() abort + return ['puppet', 'puppetlint'] +endfunction + +function! neomake#makers#ft#puppet#puppetlint() abort + return { + \ 'exe': 'puppet-lint', + \ 'args': ['--log-format', '%%{path}:%%{line}:%%{column}:%%{kind}:[%%{check}] %%{message}'], + \ 'errorformat': '%f:%l:%c:%t%*[a-zA-Z]:%m', + \ 'short_name': 'pupl', + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#puppet#puppet() abort + return { + \ 'args': ['parser', 'validate', '--color=false'], + \ 'errorformat': + \ '%-Gerr: Try ''puppet help parser validate'' for usage,' . + \ '%-GError: Try ''puppet help parser validate'' for usage,' . + \ '%t%*[a-zA-Z]: %m at %f:%l:%c,' . + \ '%t%*[a-zA-Z]: %m at %f:%l,'. + \ '%t%*[a-zA-Z]: Could not parse for environment production: %m (file: %f\, line: %l\, column: %c),' . + \ '%t%*[a-zA-Z]: Could not parse for environment production: %m (file: %f)', + \ 'short_name': 'pupp', + \ 'output_stream': 'stderr', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/purescript.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/purescript.vim new file mode 100644 index 0000000..a26a40f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/purescript.vim @@ -0,0 +1,63 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#purescript#EnabledMakers() abort + return ['pulp'] +endfunction + +function! neomake#makers#ft#purescript#pulp() abort + " command is `pulp build --no-psa -- --json-errors` + " as indicated in https://github.com/nwolverson/atom-ide-purescript/issues/136 + let maker = { + \ 'args': ['build', '--no-psa', '--', '--json-errors'], + \ 'append_file': 0, + \ 'process_output': function('neomake#makers#ft#purescript#PSProcessOutput'), + \ } + + " Find project root, since files are reported relative to it. + let bower_file = neomake#utils#FindGlobFile('bower.json') + if !empty(bower_file) + let maker.cwd = fnamemodify(bower_file, ':h') + endif + + return maker +endfunction + +function! neomake#makers#ft#purescript#PSProcessOutput(context) abort + let errors = [] + for line in a:context.output + if line[0] !=# '{' + continue + endif + let decoded = neomake#compat#json_decode(line) + for [key, values] in items(decoded) + let code = key ==# 'warnings' ? 'W' : 'E' + for item in values + let compiler_error = item['errorCode'] + let message = item['message'] + let position = item['position'] + let filename = item['filename'] + if position is g:neomake#compat#json_null + let row = 1 + let col = 1 + let end_col = 1 + let length = 1 + else + let row = position['startLine'] + let col = position['startColumn'] + let end_col = position['endColumn'] + let length = end_col - col + endif + + call add(errors, { + \ 'text': compiler_error . ' : ' . message, + \ 'type': code, + \ 'lnum': row, + \ 'col': col, + \ 'length': length, + \ 'filename': filename, + \ }) + endfor + endfor + endfor + return errors +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python.vim new file mode 100644 index 0000000..d8c8369 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python.vim @@ -0,0 +1,419 @@ +" vim: ts=4 sw=4 et + +if !exists('s:compile_script') + let s:slash = neomake#utils#Slash() + let s:compile_script = expand('<sfile>:p:h', 1).s:slash.'python'.s:slash.'compile.py' +endif + +function! neomake#makers#ft#python#EnabledMakers() abort + let makers = ['python', 'frosted'] + if executable('pylama') + call add(makers, 'pylama') + else + if executable('flake8') + call add(makers, 'flake8') + else + call extend(makers, ['pyflakes', 'pycodestyle', 'pydocstyle']) + endif + call add(makers, 'pylint') " Last because it is the slowest + endif + return makers +endfunction + +let neomake#makers#ft#python#project_root_files = ['setup.cfg', 'tox.ini'] + +function! neomake#makers#ft#python#DetectPythonVersion() abort + let output = neomake#compat#systemlist('python -V 2>&1') + if v:shell_error + call neomake#log#error(printf( + \ 'Failed to detect Python version: %s.', + \ join(output))) + let s:python_version = [-1, -1, -1] + else + let s:python_version = split(split(output[0])[1], '\.') + endif +endfunction + +let s:ignore_python_warnings = [ + \ '\v[\/]inspect.py:\d+: Warning:', + \ '\v^.{-}:\d+: FutureWarning:', + \ ] + +" Filter Python warnings (the warning and the following line). +" To be used as a funcref with filter(). +function! s:filter_py_warning(v) abort + if s:filter_next_py_warning + let s:filter_next_py_warning = 0 + " Only keep (expected) lines starting with two spaces. + return a:v[0:1] !=# ' ' + endif + for pattern in s:ignore_python_warnings + if a:v =~# pattern + let s:filter_next_py_warning = 1 + return 0 + endif + endfor + return 1 +endfunction + +function! neomake#makers#ft#python#FilterPythonWarnings(lines, context) abort + if a:context.source ==# 'stderr' + let s:filter_next_py_warning = 0 + call filter(a:lines, 's:filter_py_warning(v:val)') + endif +endfunction + +function! neomake#makers#ft#python#pylint() abort + let maker = { + \ 'args': [ + \ '--output-format=text', + \ '--msg-template="{path}:{line}:{column}:{C}: [{symbol}] {msg} [{msg_id}]"', + \ '--reports=no' + \ ], + \ 'errorformat': + \ '%A%f:%l:%c:%t: %m,' . + \ '%A%f:%l: %m,' . + \ '%A%f:(%l): %m,' . + \ '%-Z%p^%.%#,' . + \ '%-G%.%#', + \ 'output_stream': 'stdout', + \ 'postprocess': [ + \ function('neomake#postprocess#generic_length'), + \ function('neomake#makers#ft#python#PylintEntryProcess'), + \ ]} + function! maker.filter_output(lines, context) abort + if a:context.source ==# 'stderr' + call filter(a:lines, "v:val !=# 'No config file found, using default configuration' && v:val !~# '^Using config file '") + endif + call neomake#makers#ft#python#FilterPythonWarnings(a:lines, a:context) + endfunction + return maker +endfunction + +function! neomake#makers#ft#python#PylintEntryProcess(entry) abort + if a:entry.type ==# 'F' " Fatal error which prevented further processing + let type = 'E' + elseif a:entry.type ==# 'E' " Error for important programming issues + let type = 'E' + elseif a:entry.type ==# 'W' " Warning for stylistic or minor programming issues + let type = 'W' + elseif a:entry.type ==# 'R' " Refactor suggestion + let type = 'W' + elseif a:entry.type ==# 'C' " Convention violation + let type = 'W' + elseif a:entry.type ==# 'I' " Informations + let type = 'I' + else + let type = '' + endif + let a:entry.type = type + " Pylint uses 0-indexed columns, vim uses 1-indexed columns + let a:entry.col += 1 +endfunction + +function! neomake#makers#ft#python#flake8() abort + let maker = { + \ 'args': ['--format=default'], + \ 'errorformat': + \ '%E%f:%l: could not compile,%-Z%p^,' . + \ '%A%f:%l:%c: %t%n %m,' . + \ '%A%f:%l: %t%n %m,' . + \ '%-G%.%#', + \ 'postprocess': function('neomake#makers#ft#python#Flake8EntryProcess'), + \ 'short_name': 'fl8', + \ 'output_stream': 'stdout', + \ 'filter_output': function('neomake#makers#ft#python#FilterPythonWarnings'), + \ } + + function! maker.supports_stdin(jobinfo) abort + let self.args += ['--stdin-display-name', '%:p'] + + let bufpath = bufname(a:jobinfo.bufnr) + if !empty(bufpath) + let bufdir = fnamemodify(bufpath, ':p:h') + if stridx(bufdir, getcwd()) != 0 + " The buffer is not below the current dir, so let's cd for lookup + " of config files etc. + " This avoids running into issues with flake8's per-file-ignores, + " which is handled not relative to the config file currently + " (https://gitlab.com/pycqa/flake8/issues/517). + call a:jobinfo.cd(bufdir) + endif + endif + return 1 + endfunction + return maker +endfunction + +function! neomake#makers#ft#python#Flake8EntryProcess(entry) abort + if a:entry.type ==# 'F' " pyflakes + " Ref: http://flake8.pycqa.org/en/latest/user/error-codes.html + if a:entry.nr > 400 && a:entry.nr < 500 + if a:entry.nr == 407 + let type = 'E' " 'an undefined __future__ feature name was imported' + else + let type = 'W' + endif + elseif a:entry.nr == 841 + let type = 'W' + else + let type = 'E' + endif + elseif a:entry.type ==# 'E' && a:entry.nr >= 900 " PEP8 runtime errors (E901, E902) + let type = 'E' + elseif a:entry.type ==# 'E' || a:entry.type ==# 'W' " PEP8 errors & warnings + let type = 'W' + elseif a:entry.type ==# 'N' || a:entry.type ==# 'D' " Naming (PEP8) & docstring (PEP257) conventions + let type = 'W' + elseif a:entry.type ==# 'C' || a:entry.type ==# 'T' " McCabe complexity & todo notes + let type = 'I' + elseif a:entry.type ==# 'I' " keep at least 'I' from isort (I1), could get style subtype?! + let type = a:entry.type + else + let type = '' + endif + + let token_pattern = '\v''\zs[^'']+\ze' + if a:entry.type ==# 'F' && (a:entry.nr == 401 || a:entry.nr == 811) + " Special handling for F401 (``module`` imported but unused) and + " F811 (redefinition of unused ``name`` from line ``N``). + " The unused column is incorrect for import errors and redefinition + " errors. + let token = matchstr(a:entry.text, token_pattern) + if !empty(token) + let view = winsaveview() + call cursor(a:entry.lnum, a:entry.col) + " The number of lines to give up searching afterwards + let search_lines = 5 + + if searchpos('\<from\>', 'cnW', a:entry.lnum)[1] == a:entry.col + " for 'from xxx.yyy import zzz' the token looks like + " xxx.yyy.zzz, but only the zzz part should be highlighted. So + " this discards the module part + let token = split(token, '\.')[-1] + + " Also the search should be started at the import keyword. + " Otherwise for 'from os import os' the first os will be + " found. This moves the cursor there. + call search('\<import\>', 'cW', a:entry.lnum + search_lines) + endif + + " Search for the first occurrence of the token and highlight in + " the next couple of lines and change the lnum and col to that + " position. + " Don't match entries surrounded by dots, even though + " it ends a word, we want to find a full identifier. It also + " matches all seperators such as spaces and newlines with + " backslashes until it knows for sure the previous real character + " was not a dot. + let ident_pos = searchpos('\(\.\(\_s\|\\\)*\)\@<!\<' . + \ token . '\>\(\(\_s\|\\\)*\.\)\@!', + \ 'cnW', + \ a:entry.lnum + search_lines) + if ident_pos[1] > 0 + let a:entry.lnum = ident_pos[0] + let a:entry.col = ident_pos[1] + endif + + call winrestview(view) + + let a:entry.length = strlen(token) + endif + else + call neomake#postprocess#generic_length_with_pattern(a:entry, token_pattern) + + " Special processing for F821 (undefined name) in f-strings. + if !has_key(a:entry, 'length') && a:entry.type ==# 'F' && a:entry.nr == 821 + let token = matchstr(a:entry.text, token_pattern) + if !empty(token) + " Search for '{token}' in reported and following lines. + " It seems like for the first line it is correct already (i.e. + " flake8 reports the column therein), but we still test there + " to be sure. + " https://gitlab.com/pycqa/flake8/issues/407 + let line = get(getbufline(a:entry.bufnr, a:entry.lnum), 0, '') + " NOTE: uses byte offset, starting at col means to start after + " the opening quote. + let pattern = '\V\C{\.\{-}\zs'.escape(token, '\').'\>' + let pos = match(line, pattern, a:entry.col) + if pos == -1 + let line_offset = 0 + while line_offset < 10 + let line_offset += 1 + let line = get(getbufline(a:entry.bufnr, a:entry.lnum + line_offset), 0, '') + let pos = match(line, pattern) + if pos != -1 + let a:entry.lnum = a:entry.lnum + line_offset + break + endif + endwhile + endif + if pos > 0 + let a:entry.col = pos + 1 + let a:entry.length = strlen(token) + endif + endif + endif + endif + + let a:entry.text = a:entry.type . a:entry.nr . ' ' . a:entry.text + let a:entry.type = type + " Reset "nr" to Avoid redundancy with neomake#GetCurrentErrorMsg. + " TODO: This is rather bad, since "nr" itself can be useful. + " This should rather use the entry via Neomake's list, and then a + " new property like "current_error_text" could be used. + " Or with the maker being available a callback could be used. + let a:entry.nr = -1 +endfunction + +function! neomake#makers#ft#python#pyflakes() abort + return { + \ 'errorformat': + \ '%E%f:%l: could not compile,' . + \ '%-Z%p^,'. + \ '%E%f:%l:%c: %m,' . + \ '%E%f:%l: %m,' . + \ '%-G%.%#', + \ } +endfunction + +function! neomake#makers#ft#python#pycodestyle() abort + if !exists('s:_pycodestyle_exe') + " Use the preferred exe to avoid deprecation warnings. + let s:_pycodestyle_exe = executable('pycodestyle') ? 'pycodestyle' : 'pep8' + endif + return { + \ 'exe': s:_pycodestyle_exe, + \ 'errorformat': '%f:%l:%c: %m', + \ 'postprocess': function('neomake#makers#ft#python#Pep8EntryProcess') + \ } +endfunction + +" Note: pep8 has been renamed to pycodestyle, but is kept also as alias. +function! neomake#makers#ft#python#pep8() abort + return neomake#makers#ft#python#pycodestyle() +endfunction + +function! neomake#makers#ft#python#Pep8EntryProcess(entry) abort + if a:entry.text =~# '^E9' " PEP8 runtime errors (E901, E902) + let a:entry.type = 'E' + elseif a:entry.text =~# '^E113' " unexpected indentation (IndentationError) + let a:entry.type = 'E' + else " Everything else is a warning + let a:entry.type = 'W' + endif +endfunction + +function! neomake#makers#ft#python#pydocstyle() abort + if !exists('s:_pydocstyle_exe') + " Use the preferred exe to avoid deprecation warnings. + let s:_pydocstyle_exe = executable('pydocstyle') ? 'pydocstyle' : 'pep257' + endif + return { + \ 'exe': s:_pydocstyle_exe, + \ 'errorformat': + \ '%W%f:%l %.%#:,' . + \ '%+C %m', + \ 'postprocess': function('neomake#postprocess#compress_whitespace'), + \ } +endfunction + +" Note: pep257 has been renamed to pydocstyle, but is kept also as alias. +function! neomake#makers#ft#python#pep257() abort + return neomake#makers#ft#python#pydocstyle() +endfunction + +function! neomake#makers#ft#python#PylamaEntryProcess(entry) abort + if a:entry.nr == -1 + " Get number from the beginning of text. + let nr = matchstr(a:entry.text, '\v^\u\zs\d+') + if !empty(nr) + let a:entry.nr = nr + 0 + endif + endif + if a:entry.type ==# 'C' && a:entry.text =~# '\v\[%(pycodestyle|pep8)\]$' + call neomake#makers#ft#python#Pep8EntryProcess(a:entry) + elseif a:entry.type ==# 'D' " pydocstyle/pep257 + let a:entry.type = 'W' + elseif a:entry.type ==# 'C' && a:entry.nr == 901 " mccabe + let a:entry.type = 'I' + elseif a:entry.type ==# 'R' " Radon + let a:entry.type = 'W' + endif +endfunction + +function! neomake#makers#ft#python#pylama() abort + let maker = { + \ 'args': ['--format', 'parsable'], + \ 'errorformat': '%f:%l:%c: [%t] %m', + \ 'postprocess': function('neomake#makers#ft#python#PylamaEntryProcess'), + \ 'output_stream': 'stdout', + \ } + " Pylama looks for the config only in the current directory. + " Therefore we change to where the config likely is. + " --options could be used to pass a config file, but we cannot be sure + " which one really gets used. + let ini_file = neomake#utils#FindGlobFile('{pylama.ini,setup.cfg,tox.ini,pytest.ini}') + if !empty(ini_file) + let maker.cwd = fnamemodify(ini_file, ':h') + endif + return maker +endfunction + +function! neomake#makers#ft#python#python() abort + return { + \ 'args': [s:compile_script], + \ 'errorformat': '%E%f:%l:%c: %m', + \ 'serialize': 1, + \ 'serialize_abort_on_error': 1, + \ 'output_stream': 'stdout', + \ 'short_name': 'py', + \ } +endfunction + +function! neomake#makers#ft#python#frosted() abort + return { + \ 'args': [ + \ '-vb' + \ ], + \ 'errorformat': + \ '%f:%l:%c:%m,' . + \ '%E%f:%l: %m,' . + \ '%-Z%p^,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#python#vulture() abort + return { + \ 'errorformat': '%f:%l: %m', + \ } +endfunction + +" --fast-parser: adds experimental support for async/await syntax +" --silent-imports: replaced by --ignore-missing-imports +function! neomake#makers#ft#python#mypy() abort + let args = ['--check-untyped-defs', '--ignore-missing-imports'] + + " Append '--py2' to args with Python 2 for Python 2 mode. + if !exists('s:python_version') + call neomake#makers#ft#python#DetectPythonVersion() + endif + if s:python_version[0] ==# '2' + call add(args, '--py2') + endif + + return { + \ 'args': args, + \ 'errorformat': + \ '%E%f:%l: error: %m,' . + \ '%W%f:%l: warning: %m,' . + \ '%I%f:%l: note: %m', + \ } +endfunction + +function! neomake#makers#ft#python#py3kwarn() abort + return { + \ 'errorformat': '%W%f:%l:%c: %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python/compile.py b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python/compile.py new file mode 100755 index 0000000..d211673 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/python/compile.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from __future__ import print_function +from sys import argv, exit + + +if len(argv) != 2: + exit(64) + +try: + compile(open(argv[1]).read(), argv[1], 'exec', 0, 1) +except SyntaxError as err: + print('%s:%s:%s: %s' % (err.filename, err.lineno, err.offset, err.msg)) + exit(1) diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/r.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/r.vim new file mode 100644 index 0000000..59f488a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/r.vim @@ -0,0 +1,17 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#r#EnabledMakers() abort + return ['lintr'] +endfunction + +function! neomake#makers#ft#r#lintr() abort + return { + \ 'exe': 'R', + \ 'args': ['--slave', '--no-restore', '--no-save', '-e lintr::lint("%t")'], + \ 'append_file': 0, + \ 'errorformat': + \ '%W%f:%l:%c: style: %m,' . + \ '%W%f:%l:%c: warning: %m,' . + \ '%E%f:%l:%c: error: %m,' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/racket.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/racket.vim new file mode 100644 index 0000000..fc7145a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/racket.vim @@ -0,0 +1,32 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#racket#EnabledMakers() abort + return ['raco'] +endfunction + +" This is the same form of syntax-checking used by DrRacket as well. The +" downside is that it will only catch the first error, but none of the +" subsequent ones. This is due to how evaluation in Racket works. +" +" About the error format: raco will print the first line as +" <file>:<line>:<column> <message> +" Every successive line will be indented by two spaces: +" in: <keyword> +" context...: +" <file>:<line>:<column>: <keyword> +" The last pattern will be repeated as often as necessary. Example: +" foo.rkt:4:1: dfine: unbound identifier in modulemessage +" in: dfine +" context...: +" /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:34:15: loop +" /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt:10:2: show-program +" /usr/local/Cellar/racket/6.5/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt: [running body] +" /usr/local/Cellar/minimal-racket/6.6/share/racket/collects/raco/raco.rkt: [running body] +" /usr/local/Cellar/minimal-racket/6.6/share/racket/collects/raco/main.rkt: [running body] +function! neomake#makers#ft#racket#raco() abort + return { + \ 'exe': 'raco', + \ 'args': ['expand'], + \ 'errorformat': '%-G %.%#,%E%f:%l:%c: %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rst.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rst.vim new file mode 100644 index 0000000..a7874ec --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rst.vim @@ -0,0 +1,89 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#rst#SupersetOf() abort + return 'text' +endfunction + +" Get Sphinx source dir for the current buffer (determined by looking for +" conf.py, typically in docs/ or doc/). +" Caches the value in a buffer-local setting. +function! s:get_sphinx_srcdir() abort + let srcdir = neomake#config#get('sphinx.source_dir') + if srcdir isnot# g:neomake#config#undefined + return srcdir + endif + + let r = '' + let project_root = neomake#utils#get_project_root() + let bufname = bufname('%') + if empty(bufname) + call neomake#log#debug('sphinx: skipping setting of source_dir for empty bufname.', {'bufnr': bufnr('%')}) + return '' + endif + let f = findfile('conf.py', printf('%s;%s', fnamemodify(bufname, ':p:h'), project_root)) + if !empty(f) + let r = fnamemodify(f, ':p:h') + endif + call neomake#log#debug(printf('sphinx: setting b:neomake.sphinx.source_dir=%s.', string(r)), {'bufnr': bufnr('%')}) + call neomake#config#set('b:sphinx.source_dir', r) + return r +endfunction + +function! neomake#makers#ft#rst#EnabledMakers() abort + if executable('sphinx-build') && !empty(s:get_sphinx_srcdir()) + return ['sphinx'] + endif + return ['rstlint', 'rstcheck'] +endfunction + +function! neomake#makers#ft#rst#rstlint() abort + return { + \ 'exe': 'rst-lint', + \ 'errorformat': + \ '%ESEVERE %f:%l %m,'. + \ '%EERROR %f:%l %m,'. + \ '%WWARNING %f:%l %m,'. + \ '%IINFO %f:%l %m,'. + \ '%C%m', + \ 'postprocess': function('neomake#postprocess#compress_whitespace'), + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#rst#rstcheck() abort + return { + \ 'errorformat': + \ '%I%f:%l: (INFO/1) %m,'. + \ '%W%f:%l: (WARNING/2) %m,'. + \ '%E%f:%l: (ERROR/3) %m,'. + \ '%E%f:%l: (SEVERE/4) %m', + \ } +endfunction + +function! neomake#makers#ft#rst#sphinx() abort + " TODO: + " - project mode (after cleanup branch) + let srcdir = s:get_sphinx_srcdir() + if empty(srcdir) + throw 'Neomake: sphinx: could not find conf.py (you can configure sphinx.source_dir)' + endif + if !exists('s:sphinx_cache') + let s:sphinx_cache = tempname() + endif + " NOTE: uses '%Z%m,%-G%.%#' instead of '%C%m,%-G' to include next line in + " multiline errors (fixed in 7.4.203). + return { + \ 'exe': 'sphinx-build', + \ 'args': ['-n', '-E', '-q', '-N', '-b', 'dummy', srcdir, s:sphinx_cache], + \ 'append_file': 0, + \ 'errorformat': + \ '%f:%l: %tARNING: %m,' . + \ '%EWARNING: %f:%l: (SEVER%t/4) %m,' . + \ '%EWARNING: %f:%l: (%tRROR/3) %m,' . + \ '%EWARNING: %f:%l: (%tARNING/2) %m,' . + \ '%Z%m,' . + \ '%-G%.%#', + \ 'output_stream': 'stderr', + \ 'postprocess': function('neomake#postprocess#compress_whitespace'), + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ruby.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ruby.vim new file mode 100644 index 0000000..ceb6a46 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/ruby.vim @@ -0,0 +1,90 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#ruby#EnabledMakers() abort + return ['flog', 'mri', 'rubocop', 'reek', 'rubylint'] +endfunction + +function! neomake#makers#ft#ruby#rubocop() abort + return { + \ 'args': ['--format', 'emacs', '--force-exclusion', '--display-cop-names'], + \ 'errorformat': '%f:%l:%c: %t: %m,%E%f:%l: %m', + \ 'postprocess': function('neomake#makers#ft#ruby#RubocopEntryProcess'), + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#ruby#RubocopEntryProcess(entry) abort + if a:entry.type ==# 'F' " Fatal error which prevented further processing + let a:entry.type = 'E' + elseif a:entry.type ==# 'E' " Error for important programming issues + let a:entry.type = 'E' + elseif a:entry.type ==# 'W' " Warning for stylistic or minor programming issues + let a:entry.type = 'W' + elseif a:entry.type ==# 'R' " Refactor suggestion + let a:entry.type = 'W' + elseif a:entry.type ==# 'C' " Convention violation + let a:entry.type = 'I' + endif +endfunction + +function! neomake#makers#ft#ruby#rubylint() abort + return { + \ 'exe': 'ruby-lint', + \ 'args': ['--presenter', 'syntastic'], + \ 'errorformat': '%f:%t:%l:%c: %m', + \ } +endfunction + +function! neomake#makers#ft#ruby#mri() abort + let errorformat = '%-G%\m%.%#warning: %\%%(possibly %\)%\?useless use of == in void context,' + let errorformat .= '%-G%\%.%\%.%\%.%.%#,' + let errorformat .= + \ '%-GSyntax OK,'. + \ '%E%f:%l: syntax error\, %m,'. + \ '%Z%p^,'. + \ '%W%f:%l: warning: %m,'. + \ '%Z%p^,'. + \ '%W%f:%l: %m,'. + \ '%-C%.%#' + + return { + \ 'exe': 'ruby', + \ 'args': ['-c', '-T1', '-w'], + \ 'errorformat': errorformat, + \ 'output_stream': 'both', + \ } +endfunction + +function! neomake#makers#ft#ruby#jruby() abort + let errorformat = + \ '%-GSyntax OK for %f,'. + \ '%ESyntaxError in %f:%l: syntax error\, %m,'. + \ '%Z%p^,'. + \ '%W%f:%l: warning: %m,'. + \ '%Z%p^,'. + \ '%W%f:%l: %m,'. + \ '%-C%.%#' + + return { + \ 'exe': 'jruby', + \ 'args': ['-c', '-T1', '-w'], + \ 'errorformat': errorformat + \ } +endfunction + +function! neomake#makers#ft#ruby#reek() abort + return { + \ 'args': ['--format', 'text', '--single-line'], + \ 'errorformat': '%W%f:%l: %m', + \ } +endfunction + +function! neomake#makers#ft#ruby#flog() abort + return { + \ 'errorformat': + \ '%W%m %f:%l-%c,' . + \ '%-G\s%#,' . + \ '%-G%.%#: flog total,' . + \ '%-G%.%#: flog/method average,' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rust.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rust.vim new file mode 100644 index 0000000..71ddec1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/rust.vim @@ -0,0 +1,233 @@ +function! neomake#makers#ft#rust#EnabledMakers() abort + return ['cargo'] +endfunction + +function! neomake#makers#ft#rust#rustc() abort + return { + \ 'errorformat': + \ '%-Gerror: aborting due to previous error,'. + \ '%-Gerror: aborting due to %\\d%\\+ previous errors,'. + \ '%-Gerror: Could not compile `%s`.,'. + \ '%Eerror[E%n]: %m,'. + \ '%Eerror: %m,'. + \ '%Wwarning: %m,'. + \ '%Inote: %m,'. + \ '%-Z\ %#-->\ %f:%l:%c,'. + \ '%G\ %#\= %*[^:]: %m,'. + \ '%G\ %#|\ %#%\\^%\\+ %m,'. + \ '%I%>help:\ %#%m,'. + \ '%Z\ %#%m,'. + \ '%-G%.%#', + \ } +endfunction + +function! s:get_cargo_workspace_root() abort + if !exists('b:_neomake_cargo_workspace') + let cmd = 'cargo metadata --no-deps --format-version 1' + let [cd_error, cd_back_cmd] = neomake#utils#temp_cd(expand('%:h')) + if !empty(cd_error) + call neomake#log#debug(printf( + \ 's:get_cargo_workspace_root: failed to cd to buffer directory: %s.', + \ cd_error)) + endif + let output = system(cmd) + if !empty(cd_back_cmd) + exe cd_back_cmd + endif + if v:shell_error + call neomake#log#debug(printf( + \ 'Failed to get cargo metadata for workspace using %s.', + \ string(cmd))) + let b:_neomake_cargo_workspace = '' + else + let json = neomake#compat#json_decode(output) + let b:_neomake_cargo_workspace = json['workspace_root'] + endif + endif + return b:_neomake_cargo_workspace +endfunction + +function! s:get_cargo_maker_cwd(default) abort + let cargo_workspace_root = s:get_cargo_workspace_root() + if !empty(cargo_workspace_root) + return cargo_workspace_root + endif + + let cargo_toml = neomake#utils#FindGlobFile('Cargo.toml') + if !empty(cargo_toml) + return fnamemodify(cargo_toml, ':h') + endif + + return a:default +endfunction + +function! neomake#makers#ft#rust#cargotest() abort + " NOTE: duplicates are removed due to https://github.com/rust-lang/cargo/issues/5128. + let maker = { + \ 'exe': 'cargo', + \ 'args': ['test', '%:t:r', '--quiet'], + \ 'append_file': 0, + \ 'uses_filename': 0, + \ 'postprocess': copy(g:neomake#postprocess#remove_duplicates), + \ 'errorformat': + \ '%-G,' . + \ '%-Gtest %s,' . + \ '%-Grunning %\\d%# test%s,' . + \ '%-Gfailures:%s,' . + \ '%-G----%s,' . + \ '%-G%.%#--verbose%s,' . + \ '%-G%.%#--explain%s,' . + \ '%-Gerror: aborting due to previous error,' . + \ '%-G%\ %#error: aborting due to %\\d%#%\ %#previous errors,' . + \ '%E%\ %#error[E%n]:\ %m,' . + \ '%E%\ %#error:\ %m,' . + \ '%I%\ %#note:\ %m,'. + \ '%W%\ %#warning:\ %m,' . + \ '%-Z%\ %#-->\ %f:%l:%c,' . + \ '%-G%\\d%# %#|\ %s,' . + \ '%-G%\\d%# %#|,' . + \ '%-G\ %#\= %*[^:]:\ %m,'. + \ '%E%\ %#%m,' . + \ '%G%\ %#%s%\\,,' . + \ '%Z%\ %#%s%\\,%\\s%f:%l:%c' + \ } + + function! maker.InitForJob(_jobinfo) abort + if !has_key(self, 'cwd') + let self.cwd = s:get_cargo_maker_cwd('%:p:h') + return self + endif + endfunction + return maker +endfunction + +function! neomake#makers#ft#rust#cargo() abort + let maker_command = get(b:, 'neomake_rust_cargo_command', + \ get(g:, 'neomake_rust_cargo_command', ['check'])) + let maker = { + \ 'args': maker_command + ['--message-format=json', '--quiet'], + \ 'append_file': 0, + \ 'process_output': function('neomake#makers#ft#rust#CargoProcessOutput'), + \ } + + function! maker.InitForJob(_jobinfo) abort + if !has_key(self, 'cwd') + let self.cwd = s:get_cargo_maker_cwd('%:p:h') + return self + endif + endfunction + return maker +endfunction + +" NOTE: does not use process_json, since cargo outputs multiple JSON root +" elements per line. +function! neomake#makers#ft#rust#CargoProcessOutput(context) abort + let errors = [] + for line in a:context['output'] + if line[0] !=# '{' + continue + endif + + let decoded = neomake#compat#json_decode(line) + let data = get(decoded, 'message', -1) + if type(data) != type({}) || empty(data['spans']) + continue + endif + + let error = {'maker_name': 'cargo'} + let code_dict = get(data, 'code', -1) + if code_dict is g:neomake#compat#json_null + if get(data, 'level', '') ==# 'warning' + let error.type = 'W' + else + let error.type = 'E' + endif + else + let error.type = code_dict['code'][0] + let error.nr = code_dict['code'][1:] + endif + + let span = data.spans[0] + for candidate_span in data.spans + if candidate_span.is_primary + let span = candidate_span + break + endif + endfor + + let expanded = 0 + let has_expansion = type(span.expansion) == type({}) + \ && type(span.expansion.span) == type({}) + \ && type(span.expansion.def_site_span) == type({}) + + if span.file_name =~# '^<.*>$' && has_expansion + let expanded = 1 + call neomake#makers#ft#rust#FillErrorFromSpan(error, + \ span.expansion.span) + else + call neomake#makers#ft#rust#FillErrorFromSpan(error, span) + endif + + let error.text = data.message + let detail = span.label + let children = data.children + if type(detail) == type('') && !empty(detail) + let error.text = error.text . ': ' . detail + elseif !empty(children) && has_key(children[0], 'message') + let error.text = error.text . '. ' . children[0].message + endif + + call add(errors, error) + + if has_expansion && !expanded + let error = copy(error) + call neomake#makers#ft#rust#FillErrorFromSpan(error, + \ span.expansion.span) + call add(errors, error) + endif + + for child in children[1:] + if !has_key(child, 'message') + continue + endif + + let info = deepcopy(error) + let info.type = 'I' + let info.text = child.message + call neomake#postprocess#compress_whitespace(info) + if has_key(child, 'rendered') + \ && !(child.rendered is g:neomake#compat#json_null) + let info.text = info.text . ': ' . child.rendered + endif + + if len(child.spans) + let span = child.spans[0] + if span.file_name =~# '^<.*>$' + \ && type(span.expansion) == type({}) + \ && type(span.expansion.span) == type({}) + \ && type(span.expansion.def_site_span) == type({}) + call neomake#makers#ft#rust#FillErrorFromSpan(info, + \ span.expansion.span) + else + call neomake#makers#ft#rust#FillErrorFromSpan(info, span) + endif + let detail = span.label + if type(detail) == type('') && len(detail) + let info.text = info.text . ': ' . detail + endif + endif + + call add(errors, info) + endfor + endfor + return errors +endfunction + +function! neomake#makers#ft#rust#FillErrorFromSpan(error, span) abort + let a:error.filename = a:span.file_name + let a:error.col = a:span.column_start + let a:error.lnum = a:span.line_start + let a:error.length = a:span.byte_end - a:span.byte_start +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scala.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scala.vim new file mode 100644 index 0000000..0899881 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scala.vim @@ -0,0 +1,40 @@ +" vim: ts=4 sw=4 et +function! neomake#makers#ft#scala#EnabledMakers() abort + " use let g:neomake_scala_enabled_makers = ['fsc','scalastyle'] for fsc + let makers = ['scalac', 'scalastyle'] + return makers +endfunction + +function! neomake#makers#ft#scala#fsc() abort + return { + \ 'args': [ + \ '-Ystop-after:parser' + \ ], + \ 'errorformat': + \ '%E%f:%l: %trror: %m,' . + \ '%Z%p^,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#scala#scalac() abort + return { + \ 'args': [ + \ '-Ystop-after:parser' + \ ], + \ 'errorformat': + \ '%E%f:%l: %trror: %m,' . + \ '%Z%p^,' . + \ '%-G%.%#' + \ } +endfunction + +function! neomake#makers#ft#scala#scalastyle() abort + return { + \ 'errorformat': + \ '%trror file=%f message=%m line=%l column=%c,' . + \ '%trror file=%f message=%m line=%l,' . + \ '%tarning file=%f message=%m line=%l column=%c,' . + \ '%tarning file=%f message=%m line=%l' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scss.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scss.vim new file mode 100644 index 0000000..e33ea6f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/scss.vim @@ -0,0 +1,25 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#scss#EnabledMakers() abort + return executable('stylelint') ? ['stylelint'] : executable('sass-lint') ? ['sasslint'] : ['scsslint'] +endfunction + +function! neomake#makers#ft#scss#sasslint() abort + return { + \ 'exe': 'sass-lint', + \ 'args': ['--no-exit', '--verbose', '--format', 'compact'], + \ 'errorformat': neomake#makers#ft#javascript#eslint()['errorformat'] + \ } +endfunction + +function! neomake#makers#ft#scss#scsslint() abort + return { + \ 'exe': 'scss-lint', + \ 'errorformat': '%A%f:%l:%v [%t] %m,' . + \ '%A%f:%l [%t] %m' + \ } +endfunction + +function! neomake#makers#ft#scss#stylelint() abort + return neomake#makers#ft#css#stylelint() +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/serpent.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/serpent.vim new file mode 100644 index 0000000..eff20ba --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/serpent.vim @@ -0,0 +1,13 @@ +function! neomake#makers#ft#serpent#EnabledMakers() abort + return ['serplint'] +endfunction + +function! neomake#makers#ft#serpent#serplint() abort + return { + \ 'exe': 'serplint', + \ 'args': [], + \ 'errorformat': + \ '%f:%l:%c %t%n %m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sh.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sh.vim new file mode 100644 index 0000000..00889b9 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sh.vim @@ -0,0 +1,86 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#sh#EnabledMakers() abort + return ['sh', 'shellcheck'] +endfunction + +let s:shellcheck = { + \ 'args': ['-fgcc', '-x'], + \ 'errorformat': + \ '%f:%l:%c: %trror: %m [SC%n],' . + \ '%f:%l:%c: %tarning: %m [SC%n],' . + \ '%I%f:%l:%c: Note: %m [SC%n]', + \ 'output_stream': 'stdout', + \ 'short_name': 'SC', + \ 'cwd': '%:h', + \ } + +function! neomake#makers#ft#sh#shellcheck() abort + let maker = deepcopy(s:shellcheck) + + let line1 = getline(1) + if match(line1, '\v^#!.*<%(sh|dash|bash|ksh)') < 0 + \ && match(line1, '\v^#\s*shellcheck\s+shell\=') < 0 + " shellcheck does not read the shebang by itself. + let ext = expand('%:e') + if ext ==# 'ksh' + let maker.args += ['-s', 'ksh'] + elseif ext ==# 'sh' + if exists('g:is_sh') + let maker.args += ['-s', 'sh'] + elseif exists('g:is_posix') || exists('g:is_kornshell') + let maker.args += ['-s', 'ksh'] + else + let maker.args += ['-s', 'bash'] + endif + else + let maker.args += ['-s', 'bash'] + endif + endif + return maker +endfunction + +function! neomake#makers#ft#sh#checkbashisms() abort + return { + \ 'args': ['-fx'], + \ 'errorformat': + \ '%-Gscript %f is already a bash script; skipping,' . + \ '%Eerror: %f: %m\, opened in line %l,' . + \ '%Eerror: %f: %m,' . + \ '%Ecannot open script %f for reading: %m,' . + \ '%Wscript %f %m,%C%.# lines,' . + \ '%Wpossible bashism in %f line %l (%m):,%C%.%#,%Z.%#,' . + \ '%-G%.%#', + \ 'output_stream': 'stderr', + \ } +endfunction + +function! neomake#makers#ft#sh#sh() abort + let shebang = matchstr(getline(1), '^#!\s*\zs.*$') + if !empty(shebang) + let l = split(shebang) + let exe = l[0] + let args = l[1:] + ['-n'] + else + let exe = '/usr/bin/env' + let args = ['sh', '-n'] + endif + + " NOTE: the format without "line" is used by dash. + return { + \ 'exe': exe, + \ 'args': args, + \ 'errorformat': + \ '%E%f: line %l: %m,' . + \ '%E%f: %l: %m', + \ 'output_stream': 'stderr', + \} +endfunction + +function! neomake#makers#ft#sh#dash() abort + return { + \ 'args': ['-n'], + \ 'errorformat': '%E%f: %l: %m', + \ 'output_stream': 'stderr', + \} +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/slim.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/slim.vim new file mode 100644 index 0000000..931f57f --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/slim.vim @@ -0,0 +1,13 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#slim#EnabledMakers() abort + return ['slimlint'] +endfunction + +function! neomake#makers#ft#slim#slimlint() abort + return { + \ 'exe': 'slim-lint', + \ 'args': ['--no-color'], + \ 'errorformat': '%f:%l [%t] %m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sml.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sml.vim new file mode 100644 index 0000000..46e0bd0 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sml.vim @@ -0,0 +1,19 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#sml#EnabledMakers() abort + return ['smlnj'] +endfunction + +" This comes straight out of syntastic. +function! neomake#makers#ft#sml#smlnj() abort + return { + \ 'exe': 'sml', + \ 'errorformat': + \ '%E%f:%l%\%.%c %trror: %m,' . + \ '%E%f:%l%\%.%c-%\d%\+%\%.%\d%\+ %trror: %m,' . + \ '%W%f:%l%\%.%c %tarning: %m,' . + \ '%W%f:%l%\%.%c-%\d%\+%\%.%\d%\+ %tarning: %m,' . + \ '%C%\s%\+%m,' . + \ '%-G%.%#' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/solidity.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/solidity.vim new file mode 100644 index 0000000..200e910 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/solidity.vim @@ -0,0 +1,16 @@ +function! neomake#makers#ft#solidity#EnabledMakers() abort + return ['solium', 'solhint'] +endfunction + +function! neomake#makers#ft#solidity#solium() abort + return { + \ 'args': ['--reporter', 'gcc', '--file'], + \ 'errorformat': + \ '%f:%l:%c: %t%s: %m', + \ } +endfunction + +function! neomake#makers#ft#solidity#solhint() abort + return neomake#makers#ft#javascript#eslint() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spar.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spar.vim new file mode 100644 index 0000000..9efe7a1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spar.vim @@ -0,0 +1,13 @@ +function! neomake#makers#ft#spar#EnabledMakers() abort + return ['spar'] +endfunction + +function! neomake#makers#ft#spar#spar() abort + return { + \ 'args': ['-g', '-c'], + \ 'errorformat': + \ '%f:%l:%c: %m', + \ 'nvim_job_opts': {'pty': 1} + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spec.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spec.vim new file mode 100644 index 0000000..2723340 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/spec.vim @@ -0,0 +1,16 @@ +function! neomake#makers#ft#spec#EnabledMakers() abort + return ['rpmlint'] +endfunction + +function! neomake#makers#ft#spec#rpmlint() abort + return { + \ 'errorformat': + \ '%E%f:%l: E: %m,' . + \ '%E%f: E: %m,' . + \ '%W%f:%l: W: %m,' . + \ '%W%f: W: %m,' . + \ '%-G%.%#' + \ } +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sql.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sql.vim new file mode 100644 index 0000000..bdbfdfa --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/sql.vim @@ -0,0 +1,13 @@ +function! neomake#makers#ft#sql#EnabledMakers() abort + return ['sqlint'] +endfunction + +function! neomake#makers#ft#sql#sqlint() abort + return { + \ 'errorformat': + \ '%E%f:%l:%c:ERROR %m,' . + \ '%W%f:%l:%c:WARNING %m,' . + \ '%C %m' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/stylus.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/stylus.vim new file mode 100644 index 0000000..113a194 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/stylus.vim @@ -0,0 +1,16 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#stylus#EnabledMakers() abort + return ['stylint'] +endfunction + +function! neomake#makers#ft#stylus#stylint() abort + return { + \ 'errorformat': + \ '%WWarning: %m,' . + \ '%EError: %m,' . + \ '%-Csee file: %f for the original selector,' . + \ '%CFile: %f,' . + \ '%ZLine: %l:%.%#' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/swift.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/swift.vim new file mode 100644 index 0000000..76bb440 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/swift.vim @@ -0,0 +1,54 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#swift#EnabledMakers() abort + if !empty(s:get_swiftpm_config()) + return ['swiftpm'] + endif + return ['swiftc'] +endfunction + +function! s:get_swiftpm_config() abort + return neomake#utils#FindGlobFile('Package.swift') +endfunction + +function! s:get_swiftpm_base_maker() abort + let maker = { + \ 'exe': 'swift', + \ 'append_file': 0, + \ 'errorformat': + \ '%E%f:%l:%c: error: %m,' . + \ '%E%f:%l: error: %m,' . + \ '%W%f:%l:%c: warning: %m,' . + \ '%Z%\s%#^~%#,' . + \ '%-G%.%#', + \ } + let config = s:get_swiftpm_config() + if !empty(config) + let maker.cwd = fnamemodify(config, ':h') + endif + return maker +endfunction + +function! neomake#makers#ft#swift#swiftpm() abort + let maker = s:get_swiftpm_base_maker() + let maker.args = ['build', '--build-tests'] + return maker +endfunction + +function! neomake#makers#ft#swift#swiftpmtest() abort + let maker = s:get_swiftpm_base_maker() + let maker.args = ['test'] + return maker +endfunction + +function! neomake#makers#ft#swift#swiftc() abort + " `export SDKROOT="$(xcodebuild -version -sdk macosx Path)"` + return { + \ 'args': ['-parse'], + \ 'errorformat': + \ '%E%f:%l:%c: error: %m,' . + \ '%W%f:%l:%c: warning: %m,' . + \ '%Z%\s%#^~%#,' . + \ '%-G%.%#', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tcl.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tcl.vim new file mode 100644 index 0000000..76c5af4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tcl.vim @@ -0,0 +1,15 @@ +function! neomake#makers#ft#tcl#EnabledMakers() abort + return ['nagelfar'] +endfunction + +function! neomake#makers#ft#tcl#nagelfar() abort + return { + \ 'exe': 'nagelfar', + \ 'args': ['-H'], + \ 'errorformat': + \ '%I%f: %l: N %m,' . + \ '%f: %l: %t %m,' . + \ '%-GChecking file %f' + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tex.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tex.vim new file mode 100644 index 0000000..9fca53b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tex.vim @@ -0,0 +1,69 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#tex#EnabledMakers() abort + return ['chktex', 'lacheck', 'rubberinfo', 'proselint'] +endfunction + +function! neomake#makers#ft#tex#chktex() abort + let maker = { + \ 'args': [], + \ 'errorformat': + \ '%EError %n in %f line %l: %m,' . + \ '%WWarning %n in %f line %l: %m,' . + \ '%WMessage %n in %f line %l: %m,' . + \ '%Z%p^,' . + \ '%-G%.%#' + \ } + let rcfile = neomake#utils#FindGlobFile('.chktexrc') + if !empty(rcfile) + let maker.args += ['-l', fnamemodify(rcfile, ':h')] + endif + return maker +endfunction + +function! neomake#makers#ft#tex#lacheck() abort + return { + \ 'errorformat': + \ '%-G** %f:,' . + \ '%E"%f"\, line %l: %m' + \ } +endfunction + +function! neomake#makers#ft#tex#rubber() abort + return { + \ 'args': ['--pdf', '-f', '--warn=all'], + \ 'errorformat': + \ '%f:%l: %m,' . + \ '%f: %m' + \ } +endfunction + +function! neomake#makers#ft#tex#rubberinfo() abort + return { + \ 'exe': 'rubber-info', + \ 'errorformat': + \ '%f:%l: %m,' . + \ '%f:%l-%\d%\+: %m,' . + \ '%f: %m' + \ } +endfunction + +function! neomake#makers#ft#tex#latexrun() abort + return { + \ 'args': ['--color', 'never'], + \ 'errorformat': + \ '%f:%l: %m' + \ } +endfunction + +function! neomake#makers#ft#tex#pdflatex() abort + return { + \ 'exe': 'pdflatex', + \ 'args': ['-shell-escape', '-file-line-error', '-interaction', 'nonstopmode'], + \ 'errorformat': '%E%f:%l: %m' + \ } +endfunction + +function! neomake#makers#ft#tex#proselint() abort + return neomake#makers#ft#text#proselint() +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/text.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/text.vim new file mode 100644 index 0000000..a1ebe0a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/text.vim @@ -0,0 +1,30 @@ +function! neomake#makers#ft#text#EnabledMakers() abort + " No makers enabled by default, since text is used as fallback often. + return [] +endfunction + +function! neomake#makers#ft#text#proselint() abort + return { + \ 'errorformat': '%W%f:%l:%c: %m', + \ 'postprocess': function('neomake#postprocess#generic_length'), + \ } +endfunction + +function! neomake#makers#ft#text#PostprocessWritegood(entry) abort + let a:entry.col += 1 + if a:entry.text[0] ==# '"' + let matchend = match(a:entry.text, '\v^[^"]+\zs"', 1) + if matchend != -1 + let a:entry.length = matchend - 1 + endif + endif +endfunction + +function! neomake#makers#ft#text#writegood() abort + return { + \ 'args': ['--parse'], + \ 'errorformat': '%W%f:%l:%c:%m,%C%m,%-G', + \ 'postprocess': function('neomake#makers#ft#text#PostprocessWritegood'), + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/toml.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/toml.vim new file mode 100644 index 0000000..d314911 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/toml.vim @@ -0,0 +1,15 @@ +function! neomake#makers#ft#toml#EnabledMakers() abort + return ['tomlcheck'] +endfunction + +function! neomake#makers#ft#toml#tomlcheck() abort + return { + \ 'args': ['-f'], + \ 'errorformat': + \ '%E%f:%l:%c:,' . + \ '%E%m' + \ } +endfunction + +" vim: et sw=4 ts=4 +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tsx.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tsx.vim new file mode 100644 index 0000000..2a31b4d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/tsx.vim @@ -0,0 +1,15 @@ +function! neomake#makers#ft#tsx#SupersetOf() abort + return 'typescript' +endfunction + +function! neomake#makers#ft#tsx#EnabledMakers() abort + return ['tsc', 'tslint'] +endfunction + +function! neomake#makers#ft#tsx#tsc() abort + let config = neomake#makers#ft#typescript#tsc() + let config.args = config.args + ['--jsx', 'preserve'] + return config +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/typescript.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/typescript.vim new file mode 100644 index 0000000..4d011b7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/typescript.vim @@ -0,0 +1,45 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#typescript#EnabledMakers() abort + return ['tsc', 'tslint'] +endfunction + +function! neomake#makers#ft#typescript#tsc() abort + " tsc should not be passed a single file. + let maker = { + \ 'args': ['--noEmit', '--watch', 'false', '--pretty', 'false'], + \ 'append_file': 0, + \ 'errorformat': + \ '%E%f %#(%l\,%c): error %m,' . + \ '%E%f %#(%l\,%c): %m,' . + \ '%Eerror %m,' . + \ '%C%\s%\+%m' + \ } + let config = neomake#utils#FindGlobFile('tsconfig.json') + if !empty(config) + let maker.args += ['--project', config] + endif + return maker +endfunction + +function! neomake#makers#ft#typescript#tslint() abort + " NOTE: output format changed in tslint 5.12.0. + let maker = { + \ 'args': ['-t', 'prose'], + \ 'errorformat': '%-G,' + \ .'%EERROR: %f:%l:%c - %m,' + \ .'%WWARNING: %f:%l:%c - %m,' + \ .'%EERROR: %f[%l\, %c]: %m,' + \ .'%WWARNING: %f[%l\, %c]: %m', + \ } + let config = neomake#utils#FindGlobFile('tsconfig.json') + if !empty(config) + let maker.args += ['--project', config] + let maker.cwd = fnamemodify(config, ':h') + endif + return maker +endfunction + +function! neomake#makers#ft#typescript#eslint() abort + return neomake#makers#ft#javascript#eslint() +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/verilog.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/verilog.vim new file mode 100644 index 0000000..78d9189 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/verilog.vim @@ -0,0 +1,16 @@ +function! neomake#makers#ft#verilog#EnabledMakers() abort + return ['iverilog'] +endfunction + +function! neomake#makers#ft#verilog#iverilog() abort + return { + \ 'args' : ['-tnull', '-Wall', '-y./'], + \ 'cwd' : '%:h', + \ 'errorformat' : '%f:%l: %trror: %m,' . + \ '%f:%l: %tarning: %m,' . + \ '%E%f:%l: : %m,' . + \ '%W%f:%l: : %m,' . + \ '%f:%l: %m', + \ } +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vhdl.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vhdl.vim new file mode 100644 index 0000000..dffa813 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vhdl.vim @@ -0,0 +1,12 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#vhdl#EnabledMakers() abort + return ['ghdl'] +endfunction + +function! neomake#makers#ft#vhdl#ghdl() abort + return { + \ 'args' : ['-s'], + \ 'errorformat' : '%E%f:%l:%c: %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vim.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vim.vim new file mode 100644 index 0000000..8cd1318 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vim.vim @@ -0,0 +1,87 @@ +function! neomake#makers#ft#vim#EnabledMakers() abort + return ['vint'] +endfunction + +let s:slash = neomake#utils#Slash() +let s:neomake_root = expand('<sfile>:p:h:h:h:h:h', 1) + +let s:vint_supports_stdin = {} + +function! neomake#makers#ft#vim#neomake_checks() abort + let maker = { + \ 'exe': join([s:neomake_root, 'contrib', 'vim-checks'], s:slash), + \ 'errorformat': '%f:%l: %m', + \ } + + return maker +endfunction + +function! neomake#makers#ft#vim#vint() abort + let args = ['--style-problem', '--no-color', + \ '-f', '{file_path}:{line_number}:{column_number}:{severity}:{description} ({policy_name})'] + + if has('nvim') + call add(args, '--enable-neovim') + endif + + let maker = { + \ 'args': args, + \ 'errorformat': '%I%f:%l:%c:style_problem:%m,' + \ .'%f:%l:%c:%t%*[^:]:E%n: %m,' + \ .'%f:%l:%c:%t%*[^:]:%m', + \ 'output_stream': 'stdout', + \ 'postprocess': { + \ 'fn': function('neomake#postprocess#generic_length'), + \ 'pattern': '\v%(^:|%([^:]+: ))\zs(\S+)', + \ }} + + function! maker.supports_stdin(_jobinfo) abort + let exe = exists('*exepath') ? exepath(self.exe) : self.exe + let support = get(s:vint_supports_stdin, exe, -1) + if support == -1 + let ver = neomake#compat#systemlist(['vint', '--version']) + let ver_split = split(ver[0], '\.') + if len(ver_split) > 1 && (ver_split[0] > 0 || +ver_split[1] >= 4) + let support = 1 + else + let support = 0 + endif + let s:vint_supports_stdin[exe] = support + call neomake#log#debug('vint: stdin support: '.support.'.') + endif + if support + let self.args += ['--stdin-display-name', '%:.'] + endif + return support + endfunction + return maker +endfunction + +function! neomake#makers#ft#vim#vimlint() abort + return { + \ 'args': ['-u'], + \ 'errorformat': '%f:%l:%c:%trror: EVL%n: %m,' + \ . '%f:%l:%c:%tarning: EVL%n: %m,' + \ . '%f:%l:%c:%t%*[^:]: EVP_%#E%#%n: %m', + \ 'postprocess': function('neomake#makers#ft#vim#PostprocessVimlint'), + \ 'output_stream': 'stdout', + \ } +endfunction + +function! neomake#makers#ft#vim#PostprocessVimlint(entry) abort + let m = matchlist(a:entry.text, '\v`\zs[^`]{-}\ze`') + if empty(m) + return + endif + + " Ensure that the text is there. + let l = len(m[0]) + let line = getline(a:entry.lnum) + if line[a:entry.col-1 : a:entry.col-2+l] == m[0] + let a:entry.length = l + elseif m[0][0:1] ==# 'l:' && line[a:entry.col-1 : a:entry.col-4+l] == m[0][2:] + " Ignore implicit 'l:' prefix. + let a:entry.length = l - 2 + endif +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vue.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vue.vim new file mode 100644 index 0000000..d9f5303 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/vue.vim @@ -0,0 +1,28 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#vue#EnabledMakers() abort + return ['eslint', 'standard'] +endfunction + +function! neomake#makers#ft#vue#eslint() abort + let maker = neomake#makers#ft#javascript#eslint() + call extend(get(maker, 'args', []), ['--plugin', 'html']) + return maker +endfunction + +function! neomake#makers#ft#vue#eslint_d() abort + return neomake#makers#ft#vue#eslint() +endfunction + +function! neomake#makers#ft#vue#standard() abort + let maker = neomake#makers#ft#javascript#standard() + call extend(get(maker, 'args', []), ['--plugin', 'html']) + return maker +endfunction + +function! neomake#makers#ft#vue#semistandard() abort + let maker = neomake#makers#ft#javascript#semistandard() + call extend(get(maker, 'args', []), ['--plugin', 'html']) + return maker +endfunction + diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xml.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xml.vim new file mode 100644 index 0000000..75b6996 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xml.vim @@ -0,0 +1,25 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#xml#EnabledMakers() abort + return ['xmllint'] +endfunction + +function! neomake#makers#ft#xml#xmllint() abort + let args = ['--xinclude', '--postvalid', '--noout'] + + return { + \ 'args': args, + \ 'supports_stdin': 1, + \ 'errorformat': + \ '%E%f:%l: error : %m,' . + \ '%-G%f:%l: validity error : Validation failed: no DTD found %m,' . + \ '%W%f:%l: warning : %m,' . + \ '%W%f:%l: validity warning : %m,' . + \ '%E%f:%l: validity error : %m,' . + \ '%E%f:%l: parser error : %m,' . + \ '%E%f:%l: %m,' . + \ '%-Z%p^,' . + \ '%-C%.%#,' . + \ '%-G%.%#', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xslt.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xslt.vim new file mode 100644 index 0000000..61bcf02 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/xslt.vim @@ -0,0 +1,8 @@ +function! neomake#makers#ft#xslt#EnabledMakers() abort + return ['xmllint'] +endfunction + +function! neomake#makers#ft#xslt#xmllint() abort + return neomake#makers#ft#xml#xmllint() +endfunction +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yacc.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yacc.vim new file mode 100644 index 0000000..8a2edd5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yacc.vim @@ -0,0 +1,17 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#yacc#EnabledMakers() abort + return ['bison'] +endfunction + +function! neomake#makers#ft#yacc#bison() abort + return { + \ 'errorformat': + \ '%E%f:%l%.%v-%.%\{-}: %trror: %m,' . + \ '%E%f:%l%.%v: %trror: %m,' . + \ '%W%f:%l%.%v-%.%\{-}: %tarning: %m,' . + \ '%W%f:%l%.%v: %tarning: %m,' . + \ '%I%f:%l%.%v-%.%\{-}: %\s%\+%m,' . + \ '%I%f:%l%.%v: %\s%\+%m' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yaml.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yaml.vim new file mode 100644 index 0000000..338ca8c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/yaml.vim @@ -0,0 +1,12 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#yaml#EnabledMakers() abort + return ['yamllint'] +endfunction + +function! neomake#makers#ft#yaml#yamllint() abort + return { + \ 'args': ['-f', 'parsable'], + \ 'errorformat': '%E%f:%l:%c: [error] %m,%W%f:%l:%c: [warning] %m', + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/zsh.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/zsh.vim new file mode 100644 index 0000000..a63e365 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/ft/zsh.vim @@ -0,0 +1,19 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#ft#zsh#EnabledMakers() abort + return ['zsh'] +endfunction + +" Note: newer versions of shellcheck do not support zsh. +function! neomake#makers#ft#zsh#shellcheck() abort + let maker = neomake#makers#ft#sh#shellcheck() + let maker.args += ['--shell', 'zsh'] + return maker +endfunction + +function! neomake#makers#ft#zsh#zsh() abort + return { + \ 'args': ['-n'], + \ 'errorformat': '%E%f:%l: %m' + \} +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/gradle.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/gradle.vim new file mode 100644 index 0000000..de892a7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/gradle.vim @@ -0,0 +1,28 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#gradle#gradle() abort + let g:gradleBin = filereadable('./gradlew') ? './gradlew' : 'gradle' + + return { + \ 'exe': g:gradleBin, + \ 'append_file': 0, + \ 'args': ['assemble', '--daemon'], + \ 'errorformat': '\%+ATask\ %.%#\ not\ found\ %.%#.,'. + \'%EExecution\ failed\ for\ task\ %m,'. + \'findbugs:\ %tarning\ %f:%l:%c\ %m,'. + \'pmd:\ %tarning\ %f:%l:%c\ %m,'. + \'checkstyle:\ %tarning\ %f:%l:%c\ %m,'. + \'lint:\ %tarning\ %f:%l:%c\ %m,'. + \'%A>\ %f:%l:%c:\ %trror:\ %m,'. + \'%A>\ %f:%l:%c:\ %tarning:\ %m,'. + \'%A%f:%l:\ %trror:\ %m,'. + \'%A%f:%l:\ %tarning:\ %m,'. + \'%A%f:%l:\ %trror\ -\ %m,'. + \'%A%f:%l:\ %tarning\ -\ %m,'. + \'%E%f:%l\ :\ %m,'. + \'%C>\ %m,'. + \'%-G%p^,'. + \'%+G\ \ %.%#,'. + \'%-G%.%#' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/mvn.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/mvn.vim new file mode 100644 index 0000000..cac2a80 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/mvn.vim @@ -0,0 +1,9 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#mvn#mvn() abort + return { + \ 'exe': 'mvn', + \ 'args': ['install'], + \ 'errorformat': '[%tRROR]\ %f:[%l]\ %m,%-G%.%#' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/makers/sbt.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/sbt.vim new file mode 100644 index 0000000..93e233b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/makers/sbt.vim @@ -0,0 +1,13 @@ +" vim: ts=4 sw=4 et + +function! neomake#makers#sbt#sbt() abort + return { + \ 'exe': 'sbt', + \ 'args': ['-Dsbt.log.noformat=true', 'compile'], + \ 'errorformat': + \ '%E[%trror]\ %f:%l:%c:\ %m,' . + \ '%-Z[error]\ %p^,' . + \ '%-C%.%#,' . + \ '%-G%.%#' + \ } +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/postprocess.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/postprocess.vim new file mode 100644 index 0000000..d92a897 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/postprocess.vim @@ -0,0 +1,77 @@ +" Generic postprocessor to add `length` to `a:entry`. +" The pattern can be overridden on `self` and should adhere to this: +" - the matched word should be returned as the whole match (you can use \zs +" and \ze). +" - enclosing patterns should be returned as \1 and \2, where \1 is used as +" offset when the first entry did not match. +" See tests/postprocess.vader for tests/examples. +" See neomake#postprocess#generic_length_with_pattern for a non-dict variant. +function! neomake#postprocess#generic_length(entry) abort dict + if a:entry.lnum > 0 && a:entry.col + let pattern = get(self, 'pattern', '\v(["''`])\zs[^\1]{-}\ze(\1)') + let start = 0 + let best = 0 + while 1 + let m = matchlist(a:entry.text, pattern, start) + if empty(m) + break + endif + let l = len(m[0]) + if l > best + " Ensure that the text is there. + let line = get(getbufline(a:entry.bufnr, a:entry.lnum), 0, '') + if line[a:entry.col-1 : a:entry.col-2+l] == m[0] + let best = l + endif + endif + if exists('*matchstrpos') " vim73 + let pos = matchstrpos(a:entry.text, pattern, start) + if pos[1] == -1 + break + endif + let start += pos[2] + len(m[2]) + else + break + endif + endwhile + if best + let a:entry.length = best + endif + endif +endfunction + +" Wrapper to call neomake#process#generic_length (a dict function). +function! neomake#postprocess#generic_length_with_pattern(entry, pattern) abort + let this = {'pattern': a:pattern} + return call('neomake#postprocess#generic_length', [a:entry], this) +endfunction + +" Deprecated: renamed to neomake#postprocess#generic_length. +function! neomake#postprocess#GenericLengthPostprocess(entry) abort dict + return neomake#postprocess#generic_length(a:entry) +endfunction + +function! neomake#postprocess#compress_whitespace(entry) abort + let text = a:entry.text + let text = substitute(text, "\001", '', 'g') + let text = substitute(text, '\r\?\n', ' ', 'g') + let text = substitute(text, '\m\s\{2,}', ' ', 'g') + let text = substitute(text, '\m^\s\+', '', '') + let text = substitute(text, '\m\s\+$', '', '') + let a:entry.text = text +endfunction + +let g:neomake#postprocess#remove_duplicates = {} +function! g:neomake#postprocess#remove_duplicates.fn(entry) abort + if exists('self._seen_entries') + if index(self._seen_entries, a:entry) != -1 + let a:entry.valid = -1 + else + call add(self._seen_entries, a:entry) + endif + else + let self._seen_entries = [a:entry] + endif +endfunction +lockvar g:neomake#postprocess#remove_duplicates " Needs to be copied. +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/quickfix.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/quickfix.vim new file mode 100644 index 0000000..8e22836 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/quickfix.vim @@ -0,0 +1,363 @@ +" vim: ts=4 sw=4 et +scriptencoding utf-8 + +let s:is_enabled = 0 + +let s:match_base_priority = 10 + +" args: a:1: force enabling? (used in tests and for VimEnter callback) +function! neomake#quickfix#enable(...) abort + if has('vim_starting') && !(a:0 && a:1) + " Delay enabling for our FileType autocommand to happen as late as + " possible, since placing signs triggers a redraw, and together with + " vim-qf_resize this causes flicker. + " https://github.com/vim/vim/issues/2763 + augroup neomake_qf + autocmd! + autocmd VimEnter * call neomake#quickfix#enable(1) + augroup END + return + endif + call neomake#log#debug('enabling custom quickfix list handling.') + let s:is_enabled = 1 + augroup neomake_qf + autocmd! + autocmd FileType qf call neomake#quickfix#FormatQuickfix() + augroup END + if &filetype ==# 'qf' + call neomake#quickfix#FormatQuickfix() + endif +endfunction + +function! neomake#quickfix#disable() abort + call neomake#log#debug('disabling custom quickfix list handling.') + let s:is_enabled = 0 + if &filetype ==# 'qf' + call neomake#quickfix#FormatQuickfix() + endif + if exists('#neomake_qf') + autocmd! neomake_qf + augroup! neomake_qf + endif +endfunction + +function! neomake#quickfix#is_enabled() abort + return s:is_enabled +endfunction + +function! s:cursor_moved() abort + if b:neomake_start_col + if col('.') <= b:neomake_start_col + 1 + call cursor(line('.'), b:neomake_start_col + 2) + endif + + if exists('w:_neomake_cursor_match_id') + silent! call matchdelete(w:_neomake_cursor_match_id) + endif + if exists('*matchaddpos') + let w:_neomake_cursor_match_id = matchaddpos('neomakeCursorListNr', + \ [[line('.'), (b:neomake_start_col - b:neomake_number_len) + 2, b:neomake_number_len]], + \ s:match_base_priority+3) + else + let w:_neomake_cursor_match_id = matchadd('neomakeCursorListNr', + \ '\%' . line('.') . 'c' + \. '\%' . ((b:neomake_start_col - b:neomake_number_len) + 2) . 'c' + \. '.\{' . b:neomake_number_len . '}', + \ s:match_base_priority+3) + endif + endif +endfunction + +function! s:set_qf_lines(lines) abort + let ul = &l:undolevels + setlocal modifiable nonumber undolevels=-1 + + call setline(1, a:lines) + + let &l:undolevels = ul + setlocal nomodifiable nomodified +endfunction + +function! s:clean_qf_annotations() abort + call neomake#log#debug('cleaning qf annotations.', {'bufnr': bufnr('%')}) + if exists('b:_neomake_qf_orig_lines') + call s:set_qf_lines(b:_neomake_qf_orig_lines) + unlet b:_neomake_qf_orig_lines + endif + unlet b:neomake_qf + augroup neomake_qf + autocmd! * <buffer> + augroup END + + call s:clean_matches() +endfunction + +function! s:clean_matches() abort + if exists('w:_neomake_maker_match_id') + silent! call matchdelete(w:_neomake_maker_match_id) + endif + if exists('w:_neomake_gutter_match_id') + silent! call matchdelete(w:_neomake_gutter_match_id) + endif + if exists('w:_neomake_bufname_match_id') + silent! call matchdelete(w:_neomake_bufname_match_id) + endif + if exists('w:_neomake_cursor_match_id') + silent! call matchdelete(w:_neomake_cursor_match_id) + endif + call neomake#signs#ResetFile(bufnr('%')) +endfunction + +function! neomake#quickfix#FormatQuickfix() abort + let buf = bufnr('%') + if !s:is_enabled || &filetype !=# 'qf' + if exists('b:neomake_qf') + call s:clean_qf_annotations() + endif + return + endif + + let src_buf = 0 + if has('patch-7.4.2215') + let is_loclist = getwininfo(win_getid())[0].loclist + if is_loclist + let qflist = getloclist(0) + else + let qflist = getqflist() + endif + else + let is_loclist = 1 + let qflist = getloclist(0) + if empty(qflist) + let is_loclist = 0 + let qflist = getqflist() + endif + endif + + if empty(qflist) || qflist[0].text !~# ' nmcfg:{.\{-}}$' + if exists('b:neomake_qf') + call neomake#log#debug('Resetting custom qf for non-Neomake change.') + call s:clean_qf_annotations() + endif + return + endif + + if is_loclist + let b:neomake_qf = 'file' + let src_buf = qflist[0].bufnr + else + let b:neomake_qf = 'project' + endif + + let lines = [] + let signs = [] + let i = 0 + let lnum_width = 0 + let col_width = 0 + let maker_width = 0 + let nmcfg = {} + let makers = {} + + for item in qflist + " Look for marker at end of entry. + if item.text[-1:] ==# '}' + let idx = strridx(item.text, ' nmcfg:{') + if idx != -1 + let config = item.text[idx+7:] + try + let nmcfg = eval(config) + if !has_key(makers, nmcfg.name) + let makers[nmcfg.name] = 0 + endif + let item.text = idx == 0 ? '' : item.text[:(idx-1)] + catch + call neomake#log#exception(printf( + \ 'Error when evaluating nmcfg (%s): %s.', + \ config, v:exception)) + endtry + endif + endif + + " Count entries. + if !empty(nmcfg) + let makers[nmcfg.name] += 1 + endif + + let item.maker_name = get(nmcfg, 'short', '????') + let maker_width = max([len(item.maker_name), maker_width]) + + if item.lnum + let lnum_width = max([len(item.lnum), lnum_width]) + let col_width = max([len(item.col), col_width]) + endif + + let i += 1 + endfor + + let syntax = keys(makers) + if src_buf + for ft in split(neomake#compat#getbufvar(src_buf, '&filetype', ''), '\.') + if !empty(ft) && index(syntax, ft) == -1 + call add(syntax, ft) + endif + endfor + endif + if get(b:, '_neomake_cur_syntax', []) != syntax + runtime! syntax/neomake/qf.vim + for name in syntax + execute 'runtime! syntax/neomake/'.name.'.vim ' + \ . 'syntax/neomake/'.name.'/*.vim' + endfor + let b:_neomake_cur_syntax = syntax + endif + + if maker_width + lnum_width + col_width > 0 + let b:neomake_start_col = maker_width + lnum_width + col_width + 2 + let b:neomake_number_len = lnum_width + col_width + 2 + let blank_col = repeat(' ', lnum_width + col_width + 1) + else + let b:neomake_start_col = 0 + let b:neomake_number_len = 0 + let blank_col = '' + endif + + " Count number of different buffers and cache their names. + let buffers = neomake#compat#uniq(sort( + \ filter(map(copy(qflist), 'v:val.bufnr'), 'v:val != 0'))) + let buffer_names = {} + if len(buffers) > 1 + for b in buffers + let bufname = bufname(b) + if empty(bufname) + let bufname = 'buf:'.b + else + let bufname = fnamemodify(bufname, ':t') + if len(bufname) > 15 + let bufname = bufname[0:13].'…' + endif + endif + let buffer_names[b] = bufname + endfor + endif + + let i = 1 + let last_bufnr = -1 + for item in qflist + if item.lnum + call add(signs, {'lnum': i, 'bufnr': buf, 'type': item.type}) + endif + let i += 1 + + let text = item.text + if item.bufnr != 0 && !empty(buffer_names) + if last_bufnr != item.bufnr + let text = printf('[%s] %s', buffer_names[item.bufnr], text) + let last_bufnr = item.bufnr + endif + endif + + if !item.lnum + call add(lines, printf('%*s %s %s', + \ maker_width, item.maker_name, + \ blank_col, text)) + else + call add(lines, printf('%*s %*s:%*s %s', + \ maker_width, item.maker_name, + \ lnum_width, item.lnum, + \ col_width, item.col ? item.col : '-', + \ text)) + endif + endfor + + if !exists('b:_neomake_qf_orig_lines') + let b:_neomake_qf_orig_lines = getbufline('%', 1, '$') + endif + call s:set_qf_lines(lines) + + if exists('+breakindent') + " Keeps the text aligned with the fake gutter. + setlocal breakindent linebreak + let &breakindentopt = 'shift:'.(b:neomake_start_col + 1) + endif + + call neomake#signs#Reset(buf, 'file') + call neomake#signs#PlaceSigns(buf, signs, 'file') + + call s:add_window_matches(maker_width) + + augroup neomake_qf + autocmd! * <buffer> + autocmd CursorMoved <buffer> call s:cursor_moved() + + " Annotate in new window, e.g. with "tab sp". + " It keeps the syntax there, so should also have the rest. + " This happens on Neovim already through CursorMoved being invoked + " always then. + if exists('##WinNew') + exe 'autocmd WinNew <buffer> call s:add_window_matches('.maker_width.')' + endif + + " Clear matches when opening another buffer in the same window, with + " the original window/buffer still being visible (e.g. in another + " tab). + autocmd BufLeave <buffer> call s:on_bufleave() + augroup END + + " Set title. + " Fallback without patch-7.4.2200, fix for without 8.0.1831. + if !has('patch-7.4.2200') || !exists('w:quickfix_title') || w:quickfix_title[0] ==# ':' + let maker_info = [] + for [maker, c] in items(makers) + call add(maker_info, maker.'('.c.')') + endfor + let maker_info_str = join(maker_info, ', ') + if is_loclist + let prefix = 'file' + else + let prefix = 'project' + endif + let w:quickfix_title = neomake#list#get_title(prefix, src_buf, maker_info_str) + endif +endfunction + +function! s:on_bufleave() abort + let s:left_winnr = winnr() + augroup neomake_qf + autocmd BufEnter * call s:on_bufenter_after_bufleave() + augroup END +endfunction + +function! s:on_bufenter_after_bufleave() abort + if winnr() == s:left_winnr + call s:clean_matches() + endif + unlet s:left_winnr + augroup neomake_qf + autocmd! BufEnter + augroup END +endfunction + +function! s:add_window_matches(maker_width) abort + if !b:neomake_start_col + return + endif + if exists('w:_neomake_maker_match_id') + silent! call matchdelete(w:_neomake_maker_match_id) + endif + let w:_neomake_maker_match_id = matchadd('neomakeMakerName', + \ '.*\%<'.(a:maker_width + 1).'c', + \ s:match_base_priority+1) + if exists('w:_neomake_gutter_match_id') + silent! call matchdelete(w:_neomake_gutter_match_id) + endif + let w:_neomake_gutter_match_id = matchadd('neomakeListNr', + \ '\%>'.(a:maker_width).'c' + \ .'.*\%<'.(b:neomake_start_col + 2).'c', + \ s:match_base_priority+2) + if exists('w:_neomake_bufname_match_id') + silent! call matchdelete(w:_neomake_bufname_match_id) + endif + let w:_neomake_bufname_match_id = matchadd('neomakeBufferName', + \ '.*\%<'.(a:maker_width + 1).'c', + \ s:match_base_priority+3) +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/setup.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/setup.vim new file mode 100644 index 0000000..e0c5298 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/setup.vim @@ -0,0 +1,37 @@ +if has('signs') + let g:neomake_place_signs = get(g:, 'neomake_place_signs', 1) +else + let g:neomake_place_signs = 0 + lockvar g:neomake_place_signs +endif + +function! neomake#setup#define_highlights() abort + if g:neomake_place_signs + call neomake#signs#DefineHighlights() + endif + if get(g:, 'neomake_highlight_columns', 1) + \ || get(g:, 'neomake_highlight_lines', 0) + call neomake#highlights#DefineHighlights() + endif +endfunction + +function! neomake#setup#setup_autocmds() abort + augroup neomake + au! + if !exists('*nvim_buf_add_highlight') + autocmd BufEnter * call neomake#highlights#ShowHighlights() + endif + if has('timers') + autocmd CursorMoved * call neomake#CursorMovedDelayed() + " Force-redraw display of current error after resizing Vim, which appears + " to clear the previously echoed error. + autocmd VimResized * call timer_start(100, function('neomake#EchoCurrentError')) + else + autocmd CursorHold,CursorHoldI * call neomake#CursorMoved() + endif + autocmd VimLeave * call neomake#VimLeave() + autocmd ColorScheme * call neomake#setup#define_highlights() + augroup END +endfunction + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/signs.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/signs.vim new file mode 100644 index 0000000..fb96934 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/signs.vim @@ -0,0 +1,289 @@ +" vim: ts=4 sw=4 et +scriptencoding utf-8 + +if !has('signs') + call neomake#log#error('Trying to load signs.vim, without +signs.') + finish +endif + +let s:base_sign_id = 5000 +let s:placed_signs = {'project': {}, 'file': {}} +let s:last_placed_signs = {'project': {}, 'file': {}} + +exe 'sign define neomake_invisible' + +" Reset signs placed by a :Neomake! call +function! neomake#signs#ResetProject() abort + for buf in keys(s:placed_signs.project) + call neomake#signs#Reset(buf, 'project') + call neomake#signs#CleanOldSigns(buf, 'project') + endfor +endfunction + +" Reset signs placed by a :Neomake call in a buffer +function! neomake#signs#ResetFile(bufnr) abort + call neomake#signs#Reset(a:bufnr, 'file') + call neomake#signs#CleanOldSigns(a:bufnr, 'file') +endfunction + +function! neomake#signs#Reset(bufnr, type) abort + if has_key(s:placed_signs[a:type], a:bufnr) + " Clean any lingering, already retired signs. + call neomake#signs#CleanOldSigns(a:bufnr, a:type) + let s:last_placed_signs[a:type][a:bufnr] = s:placed_signs[a:type][a:bufnr] + unlet s:placed_signs[a:type][a:bufnr] + endif +endfunction + +let s:sign_order = {'neomake_file_err': 0, 'neomake_file_warn': 1, + \ 'neomake_file_info': 2, 'neomake_file_msg': 3, + \ 'neomake_project_err': 4, 'neomake_project_warn': 5, + \ 'neomake_project_info': 6, 'neomake_project_msg': 7} + +" Get the defined signs for a:bufnr. +" It returns a dictionary with line numbers as keys. +" If there are multiple entries for a line only the first (visible) entry is +" returned. +function! neomake#signs#by_lnum(bufnr) abort + let bufnr = a:bufnr + 0 + if !bufexists(bufnr) + return {} + endif + + let r = {} + if exists('*sign_getplaced') " patch-8.1.0614 + for sign in sign_getplaced(bufnr)[0].signs + if has_key(r, sign.lnum) + continue + endif + let r[sign.lnum] = [sign.id, sign.name] + endfor + return r + endif + + let signs_output = split(neomake#utils#redir('sign place buffer='.a:bufnr), '\n') + + " Originally via ALE. + " Matches output like : + " line=4 id=1 name=neomake_err + " строка=1 id=1000001 имя=neomake_err + " 行=1 識別子=1000001 名前=neomake_err + " línea=12 id=1000001 nombre=neomake_err + " riga=1 id=1000001, nome=neomake_err + for line in reverse(signs_output[2:]) + " XXX: does not really match "name=" + " (broken by patch-8.1.0614, but handled above) + let sign_type = line[strridx(line, '=')+1:] + if sign_type[0:7] ==# 'neomake_' + let lnum_idx = stridx(line, '=') + let lnum = line[lnum_idx+1:] + 0 + if lnum + let sign_id = line[stridx(line, '=', lnum_idx+1)+1:] + 0 + let r[lnum] = [sign_id, sign_type] + endif + endif + endfor + return r +endfunction + +let s:entry_to_sign_type = {'W': 'warn', 'I': 'info', 'M': 'msg'} + +" Place signs for list a:entries in a:bufnr for a:type ('file' or 'project'). +" List items in a:entries need to have a "type" and "lnum" (non-zero) property. +function! neomake#signs#PlaceSigns(bufnr, entries, type) abort + " Query the list of currently placed signs. + " This allows to cope with movements, e.g. when lines were added. + let placed_signs = neomake#signs#by_lnum(a:bufnr) + + let entries_by_linenr = {} + for entry in a:entries + let lnum = entry.lnum + let sign_type = printf('neomake_%s_%s', + \ a:type, + \ get(s:entry_to_sign_type, toupper(entry.type), 'err')) + if !exists('entries_by_linenr[lnum]') + \ || s:sign_order[entries_by_linenr[lnum]] + \ > s:sign_order[sign_type] + let entries_by_linenr[lnum] = sign_type + endif + endfor + + let place_new = [] + let log_context = {'bufnr': a:bufnr} + let count_reused = 0 + for [lnum, sign_type] in items(entries_by_linenr) + let existing_sign = get(placed_signs, lnum, []) + if empty(existing_sign) || existing_sign[1] !~# '^neomake_'.a:type.'_' + call add(place_new, [lnum, sign_type]) + continue + endif + + let sign_id = existing_sign[0] + if existing_sign[1] == sign_type + let count_reused += 1 + " call neomake#log#debug(printf( + " \ 'Reusing sign: id=%d, type=%s, lnum=%d.', + " \ sign_id, existing_sign[1], lnum), log_context) + else + let cmd = printf('sign place %s name=%s buffer=%d', + \ sign_id, sign_type, a:bufnr) + call neomake#log#debug('Upgrading sign for lnum='.lnum.': '.cmd.'.', log_context) + exe cmd + endif + + " Keep this sign from being cleaned. + if exists('s:last_placed_signs[a:type][a:bufnr][sign_id]') + unlet s:last_placed_signs[a:type][a:bufnr][sign_id] + endif + endfor + if count_reused + call neomake#log#debug(printf('Reused %d signs.', count_reused), log_context) + endif + + for [lnum, sign_type] in place_new + if !exists('next_sign_id') + if !empty(placed_signs) + let next_sign_id = max(map(values(copy(placed_signs)), 'v:val[0]')) + 1 + else + let next_sign_id = s:base_sign_id + endif + else + let next_sign_id += 1 + endif + let cmd = 'sign place '.next_sign_id.' line='.lnum. + \ ' name='.sign_type. + \ ' buffer='.a:bufnr + call neomake#log#debug('Placing sign: '.cmd.'.', log_context) + let placed_signs[lnum] = [next_sign_id, sign_type] + exe cmd + endfor + + let s:placed_signs[a:type][a:bufnr] = {} + for [lnum, sign_info] in items(placed_signs) + let s:placed_signs[a:type][a:bufnr][sign_info[0]] = sign_info[1] + endfor +endfunction + +function! neomake#signs#CleanAllOldSigns(type) abort + call neomake#log#debug_obj('Removing signs', s:last_placed_signs) + for buf in keys(s:last_placed_signs[a:type]) + call neomake#signs#CleanOldSigns(buf, a:type) + endfor +endfunction + +" type may be either 'file' or 'project' +function! neomake#signs#CleanOldSigns(bufnr, type) abort + if !has_key(s:last_placed_signs[a:type], a:bufnr) + return + endif + let placed_signs = s:last_placed_signs[a:type][a:bufnr] + unlet s:last_placed_signs[a:type][a:bufnr] + if bufexists(+a:bufnr) + call neomake#log#debug(printf('Cleaning %d old signs.', len(placed_signs)), {'bufnr': a:bufnr}) + for sign_id in keys(placed_signs) + exe 'sign unplace '.sign_id.' buffer='.a:bufnr + if has_key(s:placed_signs[a:type], a:bufnr) + if has_key(s:placed_signs[a:type][a:bufnr], sign_id) + unlet s:placed_signs[a:type][a:bufnr][sign_id] + endif + endif + endfor + else + call neomake#log#debug_obj('Skipped cleaning of old signs in non-existing buffer '.a:bufnr, placed_signs) + endif +endfunction + +function! neomake#signs#RedefineSign(name, opts) abort + let sign_define = 'sign define '.a:name + for attr in keys(a:opts) + let sign_define .= ' '.attr.'='.a:opts[attr] + endfor + call neomake#log#debug(printf('Defining sign: %s.', sign_define)) + exe sign_define +endfunction + +function! neomake#signs#RedefineErrorSign(...) abort + let default_opts = {'text': '✖', 'texthl': 'NeomakeErrorSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_error_sign') + call extend(opts, g:neomake_error_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_err', opts) + call neomake#signs#RedefineSign('neomake_project_err', opts) +endfunction + +function! neomake#signs#RedefineWarningSign(...) abort + let default_opts = {'text': '‼', 'texthl': 'NeomakeWarningSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_warning_sign') + call extend(opts, g:neomake_warning_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_warn', opts) + call neomake#signs#RedefineSign('neomake_project_warn', opts) +endfunction + +function! neomake#signs#RedefineMessageSign(...) abort + let default_opts = {'text': '➤', 'texthl': 'NeomakeMessageSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_message_sign') + call extend(opts, g:neomake_message_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_msg', opts) + call neomake#signs#RedefineSign('neomake_project_msg', opts) +endfunction + +function! neomake#signs#RedefineInfoSign(...) abort + let default_opts = {'text': 'ℹ', 'texthl': 'NeomakeInfoSign'} + let opts = {} + if a:0 + call extend(opts, a:1) + elseif exists('g:neomake_info_sign') + call extend(opts, g:neomake_info_sign) + endif + call extend(opts, default_opts, 'keep') + call neomake#signs#RedefineSign('neomake_file_info', opts) + call neomake#signs#RedefineSign('neomake_project_info', opts) +endfunction + +function! neomake#signs#DefineHighlights() abort + " Use background from SignColumn. + let ctermbg = neomake#utils#GetHighlight('SignColumn', 'bg', 'Normal') + let guibg = neomake#utils#GetHighlight('SignColumn', 'bg#', 'Normal') + + " Define NeomakeErrorSign, NeomakeWarningSign etc. + call neomake#utils#define_derived_highlights('Neomake%sSign', [ctermbg, guibg]) +endfunction + +function! neomake#signs#DefineSigns() abort + call neomake#signs#RedefineErrorSign() + call neomake#signs#RedefineWarningSign() + call neomake#signs#RedefineInfoSign() + call neomake#signs#RedefineMessageSign() +endfunction + +function! s:wipe_signs(bufnr) abort + for type in ['file', 'project'] + if has_key(s:placed_signs[type], a:bufnr) + unlet s:placed_signs[type][a:bufnr] + endif + if has_key(s:last_placed_signs[type], a:bufnr) + unlet s:last_placed_signs[type][a:bufnr] + endif + endfor +endfunction +augroup neomake_signs + au! + autocmd BufWipeout * call s:wipe_signs(expand('<abuf>')) +augroup END + +call neomake#signs#DefineSigns() +call neomake#signs#DefineHighlights() diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/statusline.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/statusline.vim new file mode 100644 index 0000000..14fb543 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/statusline.vim @@ -0,0 +1,423 @@ +scriptencoding utf-8 + +unlockvar s:unknown_counts +let s:unknown_counts = {} +lockvar s:unknown_counts + +let s:counts = {} + +" Key: bufnr, Value: dict with cache keys. +let s:cache = {} + +" For debugging. +let g:neomake#statusline#_s = s: + +function! s:clear_cache(bufnr) abort + if has_key(s:cache, a:bufnr) + unlet s:cache[a:bufnr] + endif +endfunction + +function! neomake#statusline#clear_cache() abort + let s:cache = {} +endfunction + +function! s:incCount(counts, item, buf) abort + if !empty(a:item.type) && (!a:buf || a:item.bufnr ==# a:buf) + let type = toupper(a:item.type) + let a:counts[type] = get(a:counts, type, 0) + 1 + if a:buf + call s:clear_cache(a:buf) + else + let s:cache = {} + endif + return 1 + endif + return 0 +endfunction + +function! neomake#statusline#make_finished(make_info) abort + if a:make_info.options.file_mode + let bufnr = a:make_info.options.bufnr + if !empty(a:make_info.finished_jobs) && !has_key(s:counts, bufnr) + let s:counts[bufnr] = {} + endif + call s:clear_cache(bufnr) + else + let s:cache = {} + if !empty(a:make_info.finished_jobs) && !has_key(s:counts, 'project') + let s:counts['project'] = {} + endif + endif + + " Trigger redraw of all statuslines. + " TODO: only do this if some relevant formats are used?! + redrawstatus! +endfunction + +function! neomake#statusline#ResetCountsForBuf(...) abort + let bufnr = a:0 ? +a:1 : bufnr('%') + call s:clear_cache(bufnr) + if has_key(s:counts, bufnr) + let r = s:counts[bufnr] != {} + unlet s:counts[bufnr] + if r + call neomake#utils#hook('NeomakeCountsChanged', { + \ 'reset': 1, 'file_mode': 1, 'bufnr': bufnr}) + endif + return r + endif + return 0 +endfunction + +function! neomake#statusline#ResetCountsForProject(...) abort + let s:cache = {} + if !has_key(s:counts, 'project') + return 0 + endif + let r = s:counts['project'] != {} + let bufnr = bufnr('%') + unlet s:counts['project'] + if r + call neomake#utils#hook('NeomakeCountsChanged', { + \ 'reset': 1, 'file_mode': 0, 'bufnr': bufnr}) + endif + return r +endfunction + +function! neomake#statusline#ResetCounts() abort + let r = neomake#statusline#ResetCountsForProject() + for bufnr in keys(s:counts) + let r = neomake#statusline#ResetCountsForBuf(bufnr) || r + endfor + let s:counts = {} + return r +endfunction + +function! neomake#statusline#AddLoclistCount(buf, item) abort + let s:counts[a:buf] = get(s:counts, a:buf, {}) + return s:incCount(s:counts[a:buf], a:item, a:buf) +endfunction + +function! neomake#statusline#AddQflistCount(item) abort + let s:counts['project'] = get(s:counts, 'project', {}) + return s:incCount(s:counts['project'], a:item, 0) +endfunction + +function! neomake#statusline#LoclistCounts(...) abort + let buf = a:0 ? a:1 : bufnr('%') + if buf is# 'all' + return s:counts + endif + return get(s:counts, buf, {}) +endfunction + +function! neomake#statusline#QflistCounts() abort + return get(s:counts, 'project', s:unknown_counts) +endfunction + +function! s:showErrWarning(counts, prefix) abort + let w = get(a:counts, 'W', 0) + let e = get(a:counts, 'E', 0) + if w || e + let result = a:prefix + if e + let result .= 'E:'.e + endif + if w + if e + let result .= ',' + endif + let result .= 'W:'.w + endif + return result + else + return '' + endif +endfunction + +function! neomake#statusline#LoclistStatus(...) abort + return s:showErrWarning(neomake#statusline#LoclistCounts(), a:0 ? a:1 : '') +endfunction + +function! neomake#statusline#QflistStatus(...) abort + return s:showErrWarning(neomake#statusline#QflistCounts(), a:0 ? a:1 : '') +endfunction + +" Get counts for a bufnr or 'project'. +" Returns all counts when used without arguments. +function! neomake#statusline#get_counts(...) abort + if a:0 + return get(s:counts, a:1, s:unknown_counts) + endif + return s:counts +endfunction + + +let s:formatter = { + \ 'args': {}, + \ } +function! s:formatter.running_job_names() abort + let jobs = get(self.args, 'running_jobs', s:running_jobs(self.args.bufnr)) + let sep = get(self.args, 'running_jobs_separator', ', ') + let format_running_job_file = get(self.args, 'format_running_job_file', '%s') + let format_running_job_project = get(self.args, 'format_running_job_project', '%s!') + let formatted = [] + for job in jobs + if job.file_mode + call add(formatted, printf(format_running_job_file, job.name)) + else + call add(formatted, printf(format_running_job_project, job.name)) + endif + endfor + return join(formatted, sep) +endfunction + +function! s:formatter._substitute(m) abort + if has_key(self.args, a:m) + return self.args[a:m] + endif + if !has_key(self, a:m) + let self.errors += [printf('Unknown statusline format: {{%s}}.', a:m)] + return '{{'.a:m.'}}' + endif + try + return call(self[a:m], [], self) + catch + call neomake#log#error(printf( + \ 'Error while formatting statusline: %s.', v:exception)) + endtry +endfunction + +function! s:formatter.format(f, args) abort + if empty(a:f) + return a:f + endif + let self.args = a:args + let self.errors = [] + let r = substitute(a:f, '{{\(.\{-}\)}}', '\=self._substitute(submatch(1))', 'g') + if !empty(self.errors) + call neomake#log#error(printf( + \ 'Error%s when formatting %s: %s', + \ len(self.errors) > 1 ? 's' : '', + \ string(a:f), join(self.errors, ', '))) + endif + return r +endfunction + + +function! s:running_jobs(bufnr) abort + return filter(copy(neomake#GetJobs()), + \ "v:val.bufnr == a:bufnr && !get(v:val, 'canceled', 0)") +endfunction + +function! s:format_running(format_running, options, bufnr, running_jobs) abort + let args = {'bufnr': a:bufnr, 'running_jobs': a:running_jobs} + for opt in ['running_jobs_separator', 'format_running_job_project', 'format_running_job_file'] + if has_key(a:options, opt) + let args[opt] = a:options[opt] + endif + endfor + return s:formatter.format(a:format_running, args) +endfunction + +function! neomake#statusline#get_status(bufnr, options) abort + let filemode_jobs = [] + let project_jobs = [] + let format_running = get(a:options, 'format_running', '… ({{running_job_names}})') + if format_running isnot 0 + let running_jobs = s:running_jobs(a:bufnr) + if !empty(running_jobs) + for j in running_jobs + if j.file_mode + let filemode_jobs += [j] + else + let project_jobs += [j] + endif + endfor + endif + endif + + let r_loclist = '' + let r_quickfix = '' + + let use_highlights_with_defaults = get(a:options, 'use_highlights_with_defaults', 1) + + " Location list counts. + let loclist_counts = get(s:counts, a:bufnr, s:unknown_counts) + if !empty(filemode_jobs) + let r_loclist = s:format_running(format_running, a:options, a:bufnr, filemode_jobs) + elseif empty(loclist_counts) + if loclist_counts is s:unknown_counts + let format_unknown = get(a:options, 'format_loclist_unknown', '?') + let r_loclist = s:formatter.format(format_unknown, {'bufnr': a:bufnr}) + else + let format_ok = get(a:options, 'format_loclist_ok', use_highlights_with_defaults ? '%#NeomakeStatusGood#✓%#NeomakeStatReset#' : '✓') + let r_loclist = s:formatter.format(format_ok, {'bufnr': a:bufnr}) + endif + else + let format_loclist = get(a:options, 'format_loclist_issues', + \ use_highlights_with_defaults ? '%s%%#NeomakeStatReset#' : '%s') + if !empty(format_loclist) + let loclist = '' + for [type, c] in items(loclist_counts) + if has_key(a:options, 'format_loclist_type_'.type) + let format = a:options['format_loclist_type_'.type] + elseif has_key(a:options, 'format_loclist_type_default') + let format = a:options['format_loclist_type_default'] + else + let hl = '' + if use_highlights_with_defaults + if hlexists('NeomakeStatColorType'.type) + let hl = '%#NeomakeStatColorType{{type}}#' + elseif hlexists('NeomakeStatColorDefault') + let hl = '%#NeomakeStatColorDefault#' + endif + endif + let format = hl.' {{type}}:{{count}} ' + endif + let loclist .= s:formatter.format(format, { + \ 'bufnr': a:bufnr, + \ 'count': c, + \ 'type': type}) + endfor + let r_loclist = printf(format_loclist, loclist) + endif + endif + + " Quickfix counts. + let qflist_counts = get(s:counts, 'project', s:unknown_counts) + if !empty(project_jobs) + let r_quickfix = s:format_running(format_running, a:options, a:bufnr, project_jobs) + elseif empty(qflist_counts) + let format_ok = get(a:options, 'format_quickfix_ok', '') + if !empty(format_ok) + let r_quickfix = s:formatter.format(format_ok, {'bufnr': a:bufnr}) + endif + else + let format_quickfix = get(a:options, 'format_quickfix_issues', + \ use_highlights_with_defaults ? '%s%%#NeomakeStatReset#' : '%s') + if !empty(format_quickfix) + let quickfix = '' + for [type, c] in items(qflist_counts) + if has_key(a:options, 'format_quickfix_type_'.type) + let format = a:options['format_quickfix_type_'.type] + elseif has_key(a:options, 'format_quickfix_type_default') + let format = a:options['format_quickfix_type_default'] + else + let hl = '' + if use_highlights_with_defaults + if hlexists('NeomakeStatColorQuickfixType'.type) + let hl = '%#NeomakeStatColorQuickfixType{{type}}#' + elseif hlexists('NeomakeStatColorQuickfixDefault') + let hl = '%#NeomakeStatColorQuickfixDefault#' + endif + endif + let format = hl.' Q{{type}}:{{count}} ' + endif + if !empty(format) + let quickfix .= s:formatter.format(format, { + \ 'bufnr': a:bufnr, + \ 'count': c, + \ 'type': type}) + endif + endfor + let r_quickfix = printf(format_quickfix, quickfix) + endif + endif + + let format_lists = get(a:options, 'format_lists', '{{loclist}}{{lists_sep}}{{quickfix}}') + if empty(r_loclist) || empty(r_quickfix) + let lists_sep = '' + else + let lists_sep = get(a:options, 'lists_sep', ' ') + endif + return s:formatter.format(format_lists, {'loclist': r_loclist, 'quickfix': r_quickfix, 'lists_sep': lists_sep}) +endfunction + +function! neomake#statusline#get(bufnr, ...) abort + let options = a:0 ? a:1 : {} + let cache_key = string(options) + if !exists('s:cache[a:bufnr][cache_key]') + if !has_key(s:cache, a:bufnr) + let s:cache[a:bufnr] = {} + endif + let bufnr = +a:bufnr + + " TODO: needs to go into cache key then! + if getbufvar(bufnr, '&filetype') ==# 'qf' + let s:cache[bufnr][cache_key] = '' + else + let [disabled, src] = neomake#config#get_with_source('disabled', -1, {'bufnr': bufnr, 'log_source': 'statusline#get'}) + if src ==# 'default' + let disabled_scope = '' + else + let disabled_scope = src[0] + endif + if disabled != -1 && disabled + " Automake Disabled + let format_disabled_info = get(options, 'format_disabled_info', '{{disabled_scope}}-') + let disabled_info = s:formatter.format(format_disabled_info, + \ {'disabled_scope': disabled_scope}) + " Defaults to showing the disabled information (i.e. scope) + let format_disabled = get(options, 'format_status_disabled', '{{disabled_info}} %s') + let outer_format = s:formatter.format(format_disabled, {'disabled_info': disabled_info}) + else + " Automake Enabled + " Defaults to showing only the status + let format_enabled = get(options, 'format_status_enabled', '%s') + let outer_format = s:formatter.format(format_enabled, {}) + endif + let format_status = get(options, 'format_status', '%s') + let status = neomake#statusline#get_status(bufnr, options) + + let r = printf(outer_format, printf(format_status, status)) + + let s:cache[bufnr][cache_key] = r + endif + endif + return s:cache[a:bufnr][cache_key] +endfunction + +" XXX: TODO: cleanup/doc?! +function! neomake#statusline#DefineHighlights() abort + for suffix in ['', 'NC'] + let hl = 'StatusLine'.suffix + + " Highlight used for resetting color (used after counts). + exe 'hi default link NeomakeStatReset'.suffix.' StatusLine'.suffix + + " Uses "green" for NeomakeStatusGood, but the default with + " NeomakeStatusGoodNC (since it might be underlined there, and should + " not stand out in general there). + exe 'hi default NeomakeStatusGood'.suffix + \ . ' ctermfg=' . (suffix ? neomake#utils#GetHighlight(hl, 'fg') : 'green') + \ . ' guifg=' . (suffix ? neomake#utils#GetHighlight(hl, 'fg#') : 'green') + \ . ' ctermbg='.neomake#utils#GetHighlight(hl, 'bg') + \ . ' guifg='.neomake#utils#GetHighlight(hl, 'bg#') + \ . (neomake#utils#GetHighlight(hl, 'underline') ? ' cterm=underline' : '') + \ . (neomake#utils#GetHighlight(hl, 'underline#') ? ' gui=underline' : '') + \ . (neomake#utils#GetHighlight(hl, 'reverse') ? ' cterm=reverse' : '') + \ . (neomake#utils#GetHighlight(hl, 'reverse#') ? ' gui=reverse' : '') + endfor + + " Default highlight for type counts. + exe 'hi NeomakeStatColorDefault cterm=NONE ctermfg=white ctermbg=blue' + hi link NeomakeStatColorQuickfixDefault NeomakeStatColorDefault + + " Specific highlights for types. Only used if defined. + exe 'hi NeomakeStatColorTypeE cterm=NONE ctermfg=white ctermbg=red' + hi link NeomakeStatColorQuickfixTypeE NeomakeStatColorTypeE + + exe 'hi NeomakeStatColorTypeW cterm=NONE ctermfg=white ctermbg=yellow' + hi link NeomakeStatColorQuickfixTypeW NeomakeStatColorTypeW +endfunction + +" Global augroup, gets configured always currently when autoloaded. +augroup neomake_statusline + autocmd! + autocmd BufWipeout * call s:clear_cache(expand('<abuf>')) + autocmd ColorScheme * call neomake#statusline#DefineHighlights() +augroup END +call neomake#statusline#DefineHighlights() +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/utils.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/utils.vim new file mode 100644 index 0000000..860fe41 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/utils.vim @@ -0,0 +1,795 @@ +" vim: ts=4 sw=4 et +scriptencoding utf-8 + +" Get verbosity, optionally based on jobinfo's make_id (a:1). +function! neomake#utils#get_verbosity(...) abort + if a:0 && has_key(a:1, 'make_id') + return neomake#GetMakeOptions(a:1.make_id).verbosity + endif + return get(g:, 'neomake_verbose', 1) + &verbose +endfunction + +function! neomake#utils#Stringify(obj) abort + if type(a:obj) == type([]) + let ls = map(copy(a:obj), 'neomake#utils#Stringify(v:val)') + return '['.join(ls, ', ').']' + elseif type(a:obj) == type({}) + let ls = [] + for [k, l:V] in items(neomake#utils#fix_self_ref(a:obj)) + if type(V) == type(function('tr')) + let fname = substitute(string(V), ', {\zs.*\ze})', '…', '') + call add(ls, k.': '.fname) + else + call add(ls, k.': '.neomake#utils#Stringify(V)) + endif + unlet V " vim73 + endfor + return '{'.join(ls, ', ').'}' + elseif type(a:obj) == type(function('tr')) + return string(a:obj) + else + return a:obj + endif +endfunction + +function! neomake#utils#truncate_width(string, width) abort + let pos = a:width + while pos >= 0 + let s = matchstr(a:string, '.\{,'.pos.'}', 0, 1) + let w = strwidth(s) + if w <= a:width + return s + endif + let pos -= max([(w-a:width)/2, 1]) + endwhile + return '' +endfunction + +" This comes straight out of syntastic. +"print as much of a:msg as possible without "Press Enter" prompt appearing +function! neomake#utils#WideMessage(msg) abort " {{{2 + let old_ruler = &ruler + let old_showcmd = &showcmd + + " Replace newlines (typically in the msg) with a single space. This + " might happen with writegood. + let msg = substitute(a:msg, '\r\?\n', ' ', 'g') + + "convert tabs to spaces so that the tabs count towards the window + "width as the proper amount of characters + let chunks = split(msg, "\t", 1) + let msg = join(map(chunks[:-2], "v:val . repeat(' ', &tabstop - strwidth(v:val) % &tabstop)"), '') . chunks[-1] + let msg = neomake#utils#truncate_width(msg, &columns-1) + + set noruler noshowcmd + redraw + + call neomake#log#debug('WideMessage: echo '.msg.'.') + echo msg + + let &ruler = old_ruler + let &showcmd = old_showcmd +endfunction " }}}2 + +" This comes straight out of syntastic. +function! neomake#utils#IsRunningWindows() abort + return has('win32') || has('win64') +endfunction + +" Get directory/path separator. +function! neomake#utils#Slash() abort + return (!exists('+shellslash') || &shellslash) ? '/' : '\' +endfunction + +function! neomake#utils#Exists(exe) abort + " DEPRECATED: just use executable() directly. + return executable(a:exe) +endfunction + +" Object used with neomake#utils#MakerFromCommand. +let s:maker_from_command = extend(copy(g:neomake#core#command_maker_base), { + \ 'remove_invalid_entries': 0, + \ }) +function! s:maker_from_command._get_argv(jobinfo) abort dict + let fname = self._get_fname_for_args(a:jobinfo) + let args = neomake#utils#ExpandArgs(self.args, a:jobinfo) + if !empty(fname) + if self.__command_is_string + let fname = neomake#utils#shellescape(fname) + let args[-1] .= ' '.fname + else + call add(args, fname) + endif + endif + return neomake#compat#get_argv(self.exe, args, 1) +endfunction + +" Create a maker object for a given command. +" Args: command (string or list). Gets wrapped in a shell in case it is a +" string. +function! neomake#utils#MakerFromCommand(command) abort + let maker = copy(s:maker_from_command) + if type(a:command) == type('') + let argv = split(&shell) + split(&shellcmdflag) + let maker.exe = argv[0] + let maker.args = argv[1:] + [a:command] + let maker.__command_is_string = 1 + else + let maker.exe = a:command[0] + let maker.args = a:command[1:] + let maker.__command_is_string = 0 + endif + return maker +endfunction + +let s:super_ft_cache = {} +function! neomake#utils#GetSupersetOf(ft) abort + if !has_key(s:super_ft_cache, a:ft) + call neomake#utils#load_ft_makers(a:ft) + let l:SupersetOf = 'neomake#makers#ft#'.a:ft.'#SupersetOf' + if exists('*'.SupersetOf) + let s:super_ft_cache[a:ft] = call(SupersetOf, []) + else + let s:super_ft_cache[a:ft] = '' + endif + endif + return s:super_ft_cache[a:ft] +endfunction + +let s:loaded_ft_maker_runtime = [] +function! neomake#utils#load_ft_makers(ft) abort + " Load ft maker, but only once (for performance reasons and to allow for + " monkeypatching it in tests). + if index(s:loaded_ft_maker_runtime, a:ft) == -1 + if !exists('*neomake#makers#ft#'.a:ft.'#EnabledMakers') + silent exe 'runtime! autoload/neomake/makers/ft/'.a:ft.'.vim' + endif + call add(s:loaded_ft_maker_runtime, a:ft) + endif +endfunction + +let s:loaded_global_maker_runtime = 0 +function! neomake#utils#load_global_makers() abort + " Load global makers, but only once (for performance reasons and to allow + " for monkeypatching it in tests). + if !s:loaded_global_maker_runtime + exe 'runtime! autoload/neomake/makers/*.vim' + let s:loaded_global_maker_runtime = 1 + endif +endfunction + +function! neomake#utils#get_ft_confname(ft, ...) abort + return substitute(a:ft, '\W', a:0 ? a:1 : '_', 'g') +endfunction + +" Resolve filetype a:ft into a list of filetypes suitable for config vars +" (i.e. 'foo.bar' => ['foo_bar', 'foo', 'bar']). +function! neomake#utils#get_config_fts(ft, ...) abort + let delim = a:0 ? a:1 : '_' + let cache_key = a:ft . delim + if !has_key(s:cache_config_fts, cache_key) + let r = [] + let fts = split(a:ft, '\.') + for ft in fts + call add(r, ft) + let super_ft = neomake#utils#GetSupersetOf(ft) + while !empty(super_ft) + if index(fts, super_ft) == -1 + call add(r, super_ft) + endif + let super_ft = neomake#utils#GetSupersetOf(super_ft) + endwhile + endfor + if len(fts) > 1 + call insert(r, a:ft, 0) + endif + let s:cache_config_fts[cache_key] = map(r, 'neomake#utils#get_ft_confname(v:val, delim)') + endif + return s:cache_config_fts[cache_key] +endfunction +let s:cache_config_fts = {} + +let s:unset = {} " Sentinel. + +" Get a setting by key, based on filetypes, from the buffer or global +" namespace, defaulting to default. +" Use an empty bufnr ('') to ignore buffer-local settings. +function! neomake#utils#GetSetting(key, maker, default, ft, bufnr, ...) abort + let maker_only = a:0 ? a:1 : 0 + + " Check new-style config. + if exists('g:neomake') || !empty(getbufvar(a:bufnr, 'neomake')) + let context = {'ft': a:ft, 'maker': a:maker, 'bufnr': a:bufnr, 'maker_only': maker_only} + let [l:Ret, source] = neomake#config#get_with_source(a:key, g:neomake#config#undefined, context) + " Check old-style setting when source is the maker. + if source ==# 'maker' && !maker_only + let tmpmaker = {} + if has_key(a:maker, 'name') + let tmpmaker.name = a:maker.name + endif + let l:RetOld = s:get_oldstyle_setting(a:key, tmpmaker, s:unset, a:ft, a:bufnr, 1) + if RetOld isnot# s:unset + return RetOld + endif + endif + if Ret isnot g:neomake#config#undefined + return Ret + endif + endif + + return s:get_oldstyle_setting(a:key, a:maker, a:default, a:ft, a:bufnr, maker_only) +endfunction + +function! s:get_oldstyle_setting(key, maker, default, ft, bufnr, maker_only) abort + let maker_name = get(a:maker, 'name', '') + if a:maker_only && empty(maker_name) + if has_key(a:maker, a:key) + return get(a:maker, a:key) + endif + return a:default + endif + + if !empty(a:ft) + let fts = neomake#utils#get_config_fts(a:ft) + [''] + else + let fts = [''] + endif + for ft in fts + let part = join(filter([ft, maker_name], '!empty(v:val)'), '_') + if empty(part) + break + endif + let config_var = 'neomake_'.part.'_'.a:key + if a:bufnr isnot# '' + let l:Bufcfgvar = neomake#compat#getbufvar(a:bufnr, config_var, s:unset) + if Bufcfgvar isnot s:unset + return copy(Bufcfgvar) + endif + endif + if has_key(g:, config_var) + return copy(get(g:, config_var)) + endif + unlet! Bufcfgvar " vim73 + endfor + + if has_key(a:maker, a:key) + return get(a:maker, a:key) + endif + + let key = a:key + if a:maker_only + let key = maker_name.'_'.key + endif + let key = a:maker_only ? maker_name.'_'.a:key : a:key + " Look for 'neomake_'.key in the buffer and global namespace. + let bufvar = neomake#compat#getbufvar(a:bufnr, 'neomake_'.key, s:unset) + if bufvar isnot s:unset + return bufvar + endif + if a:key !=# 'enabled_makers' && has_key(g:, 'neomake_'.key) + return get(g:, 'neomake_'.key) + endif + return a:default +endfunction + +" Helper function to define default highlight for a:group (e.g. +" "Neomake%sSign"), using fg from another highlight, abd given background. +function! neomake#utils#define_derived_highlights(group_format, bg) abort + for [type, fg_from] in items({ + \ 'Error': ['Error', 'bg'], + \ 'Warning': ['Todo', 'fg'], + \ 'Info': ['Question', 'fg'], + \ 'Message': ['ModeMsg', 'fg'] + \ }) + let group = printf(a:group_format, type) + call s:define_derived_highlight_group(group, fg_from, a:bg) + endfo +endfunction + +function! s:define_derived_highlight_group(group, fg_from, bg) abort + let [fg_group, fg_attr] = a:fg_from + let [ctermbg, guibg] = a:bg + let bg = 'ctermbg='.ctermbg.' guibg='.guibg + + " NOTE: fg falls back to "Normal" always, not bg (for e.g. "SignColumn") + " inbetween. + let ctermfg = neomake#utils#GetHighlight(fg_group, fg_attr, 'Normal') + let guifg = neomake#utils#GetHighlight(fg_group, fg_attr.'#', 'Normal') + + " Ensure that we're not using bg as fg (as with gotham + " colorscheme, issue https://github.com/neomake/neomake/pull/659). + if ctermfg !=# 'NONE' && ctermfg ==# ctermbg + let ctermfg = neomake#utils#GetHighlight(fg_group, neomake#utils#ReverseSynIDattr(fg_attr)) + endif + if guifg !=# 'NONE' && guifg ==# guibg + let guifg = neomake#utils#GetHighlight(fg_group, neomake#utils#ReverseSynIDattr(fg_attr).'#') + endif + exe 'hi '.a:group.'Default ctermfg='.ctermfg.' guifg='.guifg.' '.bg + if !neomake#utils#highlight_is_defined(a:group) + exe 'hi link '.a:group.' '.a:group.'Default' + endif +endfunction + +" Get property from highlighting group. +function! neomake#utils#GetHighlight(group, what, ...) abort + let fallback = a:0 ? a:1 : '' + let mode = a:what[-1:] ==# '#' ? 'gui' : 'cterm' + let reverse = synIDattr(synIDtrans(hlID(a:group)), 'reverse', mode) + let what = a:what + if reverse + let what = neomake#utils#ReverseSynIDattr(what) + endif + if what[-1:] ==# '#' + let val = synIDattr(synIDtrans(hlID(a:group)), what, mode) + else + let val = synIDattr(synIDtrans(hlID(a:group)), what, mode) + endif + if empty(val) || val == -1 + if !empty(fallback) + " NOTE: this might still be NONE also for "Normal", with + " e.g. `vim -u NONE`. + return neomake#utils#GetHighlight(fallback, a:what) + endif + return 'NONE' + endif + return val +endfunction + +function! neomake#utils#ReverseSynIDattr(attr) abort + if a:attr ==# 'fg' + return 'bg' + elseif a:attr ==# 'bg' + return 'fg' + elseif a:attr ==# 'fg#' + return 'bg#' + elseif a:attr ==# 'bg#' + return 'fg#' + endif + return a:attr +endfunction + +" Deprecated: moved to neomake#postprocess#compress_whitespace. +function! neomake#utils#CompressWhitespace(entry) abort + call neomake#postprocess#compress_whitespace(a:entry) +endfunction + +function! neomake#utils#redir(cmd) abort + " @vimlint(EVL108, 1) + if exists('*execute') && has('nvim-0.2.0') + " @vimlint(EVL108, 0) + " NOTE: require Neovim, since Vim has at least an issue when using + " this in a :command-completion function. + " Ref: https://github.com/neomake/neomake/issues/650. + " Neovim 0.1.7 also parses 'highlight' wrongly. + return execute(a:cmd) + endif + if type(a:cmd) == type([]) + let r = '' + for cmd in a:cmd + let r .= neomake#utils#redir(cmd) + endfor + return r + endif + try + redir => neomake_redir + silent exe a:cmd + catch /^Vim(redir):E121:/ + throw printf('Neomake: neomake#utils#redir: called with outer :redir (error: %s).', + \ v:exception) + finally + redir END + endtry + return neomake_redir +endfunction + +function! neomake#utils#ExpandArgs(args, jobinfo) abort + if has_key(a:jobinfo, 'tempfile') + let fname = a:jobinfo.tempfile + else + let fname = bufname(a:jobinfo.bufnr) + if !empty(fname) + let fname = fnamemodify(fname, ':p') + endif + endif + let ret = map(copy(a:args), "substitute(v:val, '%t', fname, 'g')") + + " Expand % in args similar to when using :! + " \% is ignored + " \\% is expanded to \\file.ext + " %% becomes % + " % must be followed with an expansion keyword + let ret = map(ret, + \ 'substitute(v:val, ' + \ . '''\(\%(\\\@<!\\\)\@<!%\%(%\|<\|\%(:[phtreS8.~]\)\+\|\ze\w\@!\)\)'', ' + \ . '''\=(submatch(1) == "%%" ? "%" : expand(substitute(submatch(1), "^%", "#'.a:jobinfo.bufnr.'", "")))'', ' + \ . '''g'')') + let ret = map(ret, 'substitute(v:val, ''\v^\~\ze%(/|$)'', expand(''~''), ''g'')') + return ret +endfunction + +if has('patch-7.3.1058') + function! s:function(name) abort + return function(a:name) + endfunction +else + " Older Vim does not handle s: function references across files. + function! s:function(name) abort + return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_'),'')) + endfunction +endif + +function! s:handle_hook(jobinfo, event, context) abort + let context_str = string(map(copy(a:context), + \ "v:key ==# 'make_info' ? 'make_info #'.get(v:val, 'make_id')" + \ .": (v:key ==# 'options' && has_key(v:val, 'jobs') ? extend(copy(v:val), {'jobs': map(copy(v:val.jobs), 'v:val.maker.name')}, 'force')" + \ .": (v:key ==# 'jobinfo' ? v:val.as_string()" + \ .": (v:key ==# 'finished_jobs' ? map(copy(v:val), 'v:val.as_string()') : v:val)))")) + + if exists('g:neomake_hook_context') + call neomake#log#debug(printf('Queuing User autocmd %s for nested invocation (%s).', a:event, context_str), + \ a:jobinfo) + return neomake#action_queue#add( + \ ['Timer', 'BufEnter', 'WinEnter', 'InsertLeave', 'CursorHold', 'CursorHoldI'], + \ [s:function('s:handle_hook'), [a:jobinfo, a:event, a:context]]) + endif + + let log_args = [printf('Calling User autocmd %s with context: %s.', + \ a:event, context_str)] + if !empty(a:jobinfo) + let log_args += [a:jobinfo] + endif + call call('neomake#log#info', log_args) + + unlockvar g:neomake_hook_context + let g:neomake_hook_context = a:context + lockvar 1 g:neomake_hook_context + try + call neomake#compat#doautocmd('User '.a:event) + catch + let error = v:exception + if error[-1:] !=# '.' + let error .= '.' + endif + call neomake#log#exception(printf( + \ 'Error during User autocmd for %s: %s', + \ a:event, error), a:jobinfo) + finally + unlet g:neomake_hook_context + endtry + return g:neomake#action_queue#processed +endfunction + +function! neomake#utils#hook(event, context, ...) abort + if exists('#User#'.a:event) + let jobinfo = a:0 ? a:1 : ( + \ has_key(a:context, 'jobinfo') ? a:context.jobinfo : {}) + return s:handle_hook(jobinfo, a:event, a:context) + endif +endfunction + +function! neomake#utils#diff_dict(old, new) abort + let diff = {'removed': {}, 'added': {}, 'changed': {}} + + for k in keys(a:old) + if !has_key(a:new, k) + let diff['removed'][k] = a:old[k] + elseif type(a:old[k]) !=# type(a:new[k]) || a:old[k] !=# a:new[k] + let diff['changed'][k] = [a:old[k], a:new[k]] + endif + endfor + + for k in keys(a:new) + if !has_key(a:old, k) + let diff['added'][k] = a:new[k] + endif + endfor + + call filter(diff, '!empty(v:val)') + + return diff +endfunction + +" Sort quickfix/location list entries by distance to current cursor position's +" column, but preferring entries starting at or behind the cursor position. +function! neomake#utils#sort_by_col(a, b) abort + let col = getpos('.')[2] + if a:a.col > col + if a:b.col < col + return 1 + endif + elseif a:b.col > col + return -1 + endif + return abs(col - a:a.col) - abs(col - a:b.col) +endfunction + +function! neomake#utils#path_sep() abort + return neomake#utils#IsRunningWindows() ? ';' : ':' +endfunction + +" Find a file matching `a:glob` (using `globpath()`) by going up the +" directories from the start directory (a:1, defaults to `expand('%:p:h')`, +" i.e. the directory of the current buffer's file).) +function! neomake#utils#FindGlobFile(glob, ...) abort + let curDir = a:0 ? a:1 : expand('%:p:h') + let fileFound = [] + while 1 + let fileFound = neomake#compat#globpath_list(curDir, a:glob, 1) + if !empty(fileFound) + return fileFound[0] + endif + let lastFolder = curDir + let curDir = fnamemodify(curDir, ':h') + if curDir ==# lastFolder + break + endif + endwhile + return '' +endfunction + +function! neomake#utils#JSONdecode(json) abort + return neomake#compat#json_decode(a:json) +endfunction + +" Smarter shellescape, via vim-fugitive. +function! s:gsub(str,pat,rep) abort + return substitute(a:str,'\v\C'.a:pat,a:rep,'g') +endfunction + +function! neomake#utils#shellescape(arg) abort + if a:arg =~# '^[A-Za-z0-9_/.=-]\+$' + return a:arg + elseif &shell =~? 'cmd' || exists('+shellslash') && !&shellslash + return '"'.s:gsub(s:gsub(a:arg, '"', '""'), '\%', '"%"').'"' + endif + return shellescape(a:arg) +endfunction + +function! neomake#utils#get_buffer_lines(bufnr) abort + let buflines = getbufline(a:bufnr, 1, '$') + " Special case: empty buffer; do not write an empty line in this case. + if len(buflines) > 1 || buflines != [''] + if getbufvar(a:bufnr, '&endofline') + \ || (!getbufvar(a:bufnr, '&binary') + \ && (!exists('+fixendofline') || getbufvar(a:bufnr, '&fixendofline'))) + call add(buflines, '') + endif + endif + return buflines +endfunction + +function! neomake#utils#write_tempfile(bufnr, temp_file) abort + call writefile(neomake#utils#get_buffer_lines(a:bufnr), a:temp_file, 'b') + if exists('*setfperm') + let perms = getfperm(bufname(+a:bufnr)) + if empty(perms) + let perms = 'rw-------' + endif + call setfperm(a:temp_file, perms) + endif +endfunction + +" Wrapper around fnamemodify that handles special buffers (e.g. fugitive). +function! neomake#utils#fnamemodify(bufnr, modifier) abort + let bufnr = +a:bufnr + if empty(getbufvar(bufnr, 'fugitive_type')) + let path = bufname(bufnr) + else + if exists('*FugitivePath') + let path = FugitivePath(bufname(bufnr)) + else + let fug_buffer = fugitive#buffer(bufnr) + let path = fug_buffer.repo().translate(fug_buffer.path()) + endif + if empty(a:modifier) + let path = fnamemodify(path, ':.') + endif + endif + return empty(path) ? '' : fnamemodify(path, a:modifier) +endfunction + +function! neomake#utils#fix_self_ref(obj, ...) abort + if type(a:obj) != type({}) + if type(a:obj) == type([]) + return map(copy(a:obj), 'neomake#utils#fix_self_ref(v:val)') + endif + return a:obj + endif + let obj = copy(a:obj) + for k in keys(obj) + if a:0 + let self_ref = filter(copy(a:1), 'v:val[1][0] is obj[k]') + if !empty(self_ref) + let obj[k] = printf('<self-ref-%d: %s>', self_ref[0][0], self_ref[0][1][1]) + continue + endif + endif + if type(obj[k]) == type({}) + let obj[k] = neomake#utils#fix_self_ref(obj[k], a:0 ? a:1 + [[len(a:1)+1, [a:obj, k]]] : [[1, [a:obj, k]]]) + elseif has('nvim') + " Ensure that it can be used as a string. + " Ref: https://github.com/neovim/neovim/issues/7432 + try + call string(obj[k]) + catch /^Vim(call):E724:/ + let obj[k] = '<unrepresentable object, type='.type(obj).'>' + endtry + endif + endfor + return obj +endfunction + +function! neomake#utils#parse_highlight(group) abort + let output = neomake#utils#redir('highlight '.a:group) + return join(split(output)[2:]) +endfunction + +function! neomake#utils#highlight_is_defined(group) abort + if !hlexists(a:group) + return 0 + endif + return neomake#utils#parse_highlight(a:group) !=# 'cleared' +endfunction + +" Get the root directory of the current project. +" This is determined by looking for specific files (e.g. `.git` and +" `Makefile`), and `g:neomake#makers#ft#X#project_root_files` (if defined for +" filetype "X"). +" a:1 buffer number (defaults to current) +function! neomake#utils#get_project_root(...) abort + let bufnr = a:0 ? a:1 : bufnr('%') + let ft = getbufvar(bufnr, '&filetype') + call neomake#utils#load_ft_makers(ft) + + let project_root_files = ['.git', 'Makefile'] + + let ft_project_root_files = 'neomake#makers#ft#'.ft.'#project_root_files' + if has_key(g:, ft_project_root_files) + let project_root_files = get(g:, ft_project_root_files) + project_root_files + endif + + let buf_dir = expand('#'.bufnr.':p:h') + for fname in project_root_files + let project_root = neomake#utils#FindGlobFile(fname, buf_dir) + if !empty(project_root) + return fnamemodify(project_root, ':h') + endif + endfor + return '' +endfunction + +" Return the number of lines for a given buffer. +" This returns 0 for unloaded buffers. +if exists('*nvim_buf_line_count') + function! neomake#utils#get_buf_line_count(bufnr) abort + if !bufloaded(a:bufnr) + " https://github.com/neovim/neovim/issues/7688 + return 0 + endif + return nvim_buf_line_count(a:bufnr) + endfunction +else + function! neomake#utils#get_buf_line_count(bufnr) abort + if a:bufnr == bufnr('%') + return line('$') + endif + " TODO: this should get cached (based on b:changedtick), and cleaned + " in BufWipeOut. + return len(getbufline(a:bufnr, 1, '$')) + endfunction +endif + +" Returns: [error, cd_back_cmd] +function! neomake#utils#temp_cd(dir, ...) abort + if a:dir ==# '.' + return ['', ''] + endif + if a:0 + let cur_wd = a:1 + else + let cur_wd = getcwd() + if cur_wd ==# a:dir + " No need to change directory. + return ['', ''] + endif + endif + let cd = haslocaldir() ? 'lcd' : (exists(':tcd') == 2 && haslocaldir(-1, 0)) ? 'tcd' : 'cd' + try + exe cd.' '.fnameescape(a:dir) + catch + " Tests fail with E344, but in reality it is E472?! + " If uncaught, both are shown - let's just catch everything. + return [v:exception, ''] + endtry + return ['', cd.' '.fnameescape(cur_wd)] +endfunction + +if exists('*nvim_buf_get_lines') + function! neomake#utils#buf_get_lines(bufnr, start, end) abort + if a:start < 1 + throw 'neomake#utils#buf_get_lines: start is lower than 1' + endif + try + return nvim_buf_get_lines(a:bufnr, a:start-1, a:end-1, 1) + catch + throw 'neomake#utils#buf_get_lines: '.substitute(v:exception, '\v^[^:]+:', '', '') + endtry + endfunction +else + function! neomake#utils#buf_get_lines(bufnr, start, end) abort + if a:bufnr != bufnr('%') + throw 'Neomake: neomake#utils#buf_get_lines: used for non-current buffer' + endif + if a:start < 1 + throw 'neomake#utils#buf_get_lines: start is lower than 1' + endif + if a:end-1 > line('$') + throw 'neomake#utils#buf_get_lines: end is higher than number of lines' + endif + let r = [] + let i = a:start + while i < a:end + let r += [getline(i)] + let i += 1 + endwhile + return r + endfunction +endif + +if exists('*nvim_buf_set_lines') + function! neomake#utils#buf_set_lines(bufnr, start, end, replacement) abort + if a:start < 1 + return 'neomake#utils#buf_set_lines: start is lower than 1' + endif + try + call nvim_buf_set_lines(a:bufnr, a:start-1, a:end-1, 1, a:replacement) + catch + " call neomake#log#error('Fixing entry failed (out of bounds)') + return 'neomake#utils#buf_set_lines: '.substitute(v:exception, '\v^[^:]+:', '', '') + endtry + return '' + endfunction +else + function! neomake#utils#buf_set_lines(bufnr, start, end, replacement) abort + if a:bufnr != bufnr('%') + return 'neomake#utils#buf_set_lines: used for non-current buffer' + endif + + if a:start < 1 + return 'neomake#utils#buf_set_lines: start is lower than 1' + endif + if a:end > line('$')+1 + return 'neomake#utils#buf_set_lines: end is higher than number of lines' + endif + + if a:start == a:end + let lnum = a:start < 0 ? line('$') - a:start : a:start + if append(lnum-1, a:replacement) == 1 + call neomake#log#error(printf('Failed to append line(s): %d (%d).', a:start, lnum), {'bufnr': a:bufnr}) + endif + + else + let range = a:end - a:start + if range > len(a:replacement) + let end = min([a:end, line('$')]) + silent execute a:start.','.end.'d_' + call setline(a:start, a:replacement) + else + let i = 0 + let n = len(a:replacement) + while i < n + call setline(a:start + i, a:replacement[i]) + let i += 1 + endwhile + endif + endif + return '' + endfunction +endif + +function! neomake#utils#shorten_list_for_log(l, max) abort + if len(a:l) > a:max + return a:l[:a:max-1] + ['... ('.len(a:l).' total)'] + endif + return a:l +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/neomake/virtualtext.vim b/dotfiles/.local/share/nvim/site/autoload/neomake/virtualtext.vim new file mode 100644 index 0000000..b97f2d7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/neomake/virtualtext.vim @@ -0,0 +1,113 @@ +scriptencoding utf8 + +let s:highlight_types = { + \ 'E': 'NeomakeVirtualtextError', + \ 'W': 'NeomakeVirtualtextWarning', + \ 'I': 'NeomakeVirtualtextInfo', + \ 'M': 'NeomakeVirtualtextMessage' + \ } + +function! neomake#virtualtext#show(...) abort + let list = neomake#list#get() + if empty(list) + echom 'Neomake: no annotations to show (no list)' + return + endif + + let filter = a:0 ? a:1 : '' + if empty(filter) + let entries = list.entries + else + let entries = map(copy(list.entries), filter) + endif + + if empty(entries) + echom 'Neomake: no annotations to show (no errors)' + return + endif + + for entry in entries + let buf_info = getbufvar(entry.bufnr, '_neomake_info', {}) + + call neomake#virtualtext#add_entry(entry, s:all_ns) + + " Keep track of added entries, because stacking is not supported. + let set_buf_info = 0 + if !has_key(buf_info, 'virtual_text_entries') + let buf_info.virtual_text_entries = [] + endif + if index(buf_info.virtual_text_entries, entry.lnum) == -1 + " Do not add it, but define it still - could return here also later. + call add(buf_info.virtual_text_entries, entry.lnum) + let set_buf_info = 1 + endif + + if set_buf_info + call setbufvar(entry.bufnr, '_neomake_info', buf_info) + endif + endfor +endfunction + +function! neomake#virtualtext#add_entry(entry, src_id) abort + let hi = get(s:highlight_types, toupper(a:entry.type), 'NeomakeVirtualtextMessage') + let prefix = get(g:, 'neomake_virtualtext_prefix', '❯ ') + let text = prefix . a:entry.text + let used_src_id = nvim_buf_set_virtual_text(a:entry.bufnr, a:src_id, a:entry.lnum-1, [[text, hi]], {}) + return used_src_id +endfunction + +function! neomake#virtualtext#show_errors() abort + call neomake#virtualtext#show('v:val ==? "e"') +endfunction + +function! neomake#virtualtext#hide() abort + let bufnr = bufnr('%') + let buf_info = getbufvar(bufnr, '_neomake_info', {}) + call nvim_buf_clear_highlight(bufnr, s:all_ns, 0, -1) + if !empty(get(buf_info, 'virtual_text_entries', [])) + let buf_info.virtual_text_entries = [] + call setbufvar(bufnr, '_neomake_info', buf_info) + endif +endfunction + +if exists('*nvim_create_namespace') " Includes nvim_buf_set_virtual_text. + let s:current_ns = nvim_create_namespace('neomake-virtualtext-current') + let s:all_ns = nvim_create_namespace('neomake-virtualtext-all') + let s:cur_virtualtext = [] + + function! neomake#virtualtext#handle_current_error() abort + if !get(g:, 'neomake_virtualtext_current_error', 1) + return + endif + + if !empty(s:cur_virtualtext) + if bufexists(s:cur_virtualtext[0]) + call nvim_buf_clear_highlight(s:cur_virtualtext[0], s:cur_virtualtext[1], 0, -1) + endif + endif + let entry = neomake#get_nearest_error() + if empty(entry) + let s:cur_virtualtext = [] + else + " Only add it when there is none already (stacking is not + " supported). https://github.com/neovim/neovim/issues/9285 + let buf_info = getbufvar(entry.bufnr, '_neomake_info', {}) + if index(get(buf_info, 'virtual_text_entries', []), entry.lnum) == -1 + let src_id = neomake#virtualtext#add_entry(entry, s:current_ns) + let s:cur_virtualtext = [bufnr('%'), src_id] + endif + endif + endfunction +else + function! neomake#virtualtext#handle_current_error() abort + endfunction +endif + +function! neomake#virtualtext#DefineHighlights() abort + " NOTE: linking to SpellBad etc is bad/distracting (with undercurl). + call neomake#utils#define_derived_highlights('NeomakeVirtualtext%s', ['NONE', 'NONE']) +endfunction + +call neomake#virtualtext#DefineHighlights() + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/autoload/node.vim b/dotfiles/.local/share/nvim/site/autoload/node.vim new file mode 100644 index 0000000..3954e4c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/node.vim @@ -0,0 +1,110 @@ +" Vim by default sets the filetype to JavaScript for the following suffices. +" And, yes, it has .jsx there. +let node#suffixesadd = [".js", ".json", ".es", ".jsx"] + +function! node#initialize(root) + let b:node_root = a:root + + command! -bar -bang -nargs=1 -buffer -complete=customlist,s:complete Nedit + \ exe s:nedit(<q-args>, bufname("%"), "edit<bang>") + command! -bar -bang -nargs=1 -buffer -complete=customlist,s:complete Nopen + \ exe s:nopen(<q-args>, bufname("%"), "edit<bang>") + + nnoremap <buffer><silent> <Plug>NodeGotoFile + \ :call <SID>edit(expand("<cfile>"), bufname("%"))<CR> + nnoremap <buffer><silent> <Plug>NodeSplitGotoFile + \ :call <SID>edit(expand("<cfile>"), bufname("%"), "split")<CR> + nnoremap <buffer><silent> <Plug>NodeVSplitGotoFile + \ :call <SID>edit(expand("<cfile>"), bufname("%"), "vsplit")<CR> + nnoremap <buffer><silent> <Plug>NodeTabGotoFile + \ :call <SID>edit(expand("<cfile>"), bufname("%"), "tab split")<CR> + + silent doautocmd User Node +endfunction + +function! node#javascript() + " This might be called multiple times if multiple filetypes match. + if exists("b:node_javascript") && b:node_javascript | return | endif + let b:node_javascript = 1 + + setlocal path-=/usr/include + let &l:suffixesadd .= "," . join(g:node#suffixesadd, ",") + let &l:include = '\<require(\(["'']\)\zs[^\1]\+\ze\1' + let &l:includeexpr = "node#lib#find(v:fname, bufname('%'))" + + " @ is used for scopes, but isn't a default filename character on + " non-Windows sytems. + setlocal isfname+=@-@ + + if !hasmapto("<Plug>NodeGotoFile") + " Split gotofiles don't take a count for the new window's width, but for + " opening the nth file. Though Node.vim doesn't support counts atm. + nmap <buffer> gf <Plug>NodeGotoFile + nmap <buffer> <C-w>f <Plug>NodeSplitGotoFile + nmap <buffer> <C-w><C-f> <Plug>NodeSplitGotoFile + nmap <buffer> <C-w>gf <Plug>NodeTabGotoFile + endif +endfunction + +function! s:edit(name, from, ...) + if empty(a:name) | return | endif + let dir = isdirectory(a:from) ? a:from : fnamemodify(a:from, ":h") + let command = a:0 == 1 ? a:1 : "edit" + + " If just a plain filename with no directory part, check if it exists: + if a:name !~# '^\v(/|\./|\.\./)' && filereadable(dir . "/" . a:name) + let path = dir . "/" . a:name + else + let path = node#lib#find(a:name, dir) + end + + if empty(path) + return s:error("E447: Can't find file \"" . a:name . "\" in path") + endif + + exe command . " " . fnameescape(path) +endfunction + +function! s:nedit(name, from, ...) + let command = a:0 == 1 ? a:1 : "edit" + call s:edit(a:name, b:node_root, command) +endfunction + +function! s:nopen(name, from, ...) + let command = a:0 == 1 ? a:1 : "edit" + call s:nedit(a:name, a:from, command) + if exists("b:node_root") | exe "lcd " . fnameescape(b:node_root) | endif +endfunction + +function! s:complete(arg, cmd, cursor) + let matches = node#lib#glob(s:dirname(a:arg)) + + " Show private modules (_*) only if explicitly asked: + if a:arg[0] != "_" | call filter(matches, "v:val[0] != '_'") | endif + + let filter = "stridx(v:val, a:arg) == 0" + let ignorecase = 0 + let ignorecase = ignorecase || exists("&fileignorecase") && &fileignorecase + let ignorecase = ignorecase || exists("&wildignorecase") && &wildignorecase + if ignorecase | let filter = "stridx(tolower(v:val),tolower(a:arg)) == 0" | en + + return filter(matches, filter) +endfunction + +function! s:dirname(path) + let dirname = fnamemodify(a:path, ":h") + if dirname == "." | return "" | endif + + " To not change the amount of final consecutive slashes, using this + " dirname/basename trick: + let basename = fnamemodify(a:path, ":t") + return a:path[0 : 0 - len(basename) - 1] +endfunction + +" Using the built-in :echoerr prints a stacktrace, which isn't that nice. +function! s:error(msg) + echohl ErrorMsg + echomsg a:msg + echohl NONE + let v:errmsg = a:msg +endfunction diff --git a/dotfiles/.local/share/nvim/site/autoload/node/lib.vim b/dotfiles/.local/share/nvim/site/autoload/node/lib.vim new file mode 100644 index 0000000..1c7a8c1 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/autoload/node/lib.vim @@ -0,0 +1,153 @@ +let s:ABSPATH = '^/' +let s:RELPATH = '\v^\.\.?(/|$)' +let s:MODULE = '\v^(/|\.\.?(/|$))@!' + +" Damn Netrw can't handle HTTPS at all. It's 2013! Insecure bastard! +let s:CORE_URL_PREFIX = "https://rawgit.com/nodejs/node" +let s:CORE_MODULES = ["_debugger", "_http_agent", "_http_client", + \ "_http_common", "_http_incoming", "_http_outgoing", "_http_server", + \ "_linklist", "_stream_duplex", "_stream_passthrough", "_stream_readable", + \ "_stream_transform", "_stream_writable", "_tls_legacy", "_tls_wrap", + \ "assert", "buffer", "child_process", "cluster", "console", "constants", + \ "crypto", "dgram", "dns", "domain", "events", "freelist", "fs", "http", + \ "https", "module", "net", "node", "os", "path", "punycode", "querystring", + \ "readline", "repl", "smalloc", "stream", "string_decoder", "sys", + \ "timers", "tls", "tty", "url", "util", "vm", "zlib"] + +function! node#lib#find(name, from) + if index(s:CORE_MODULES, a:name) != -1 + let l:version = node#lib#version() + let l:version = empty(l:version) ? "master" : "v" . l:version + let l:dir = a:name == "node" ? "src" : "lib" + let l:url = get(g:, "node_repository_url", s:CORE_URL_PREFIX) + return l:url ."/". l:version ."/". l:dir ."/". a:name .".js" + endif + + let l:path = s:resolve(s:absolutize(a:name, a:from)) + if !empty(path) | return fnamemodify(resolve(path), ":.") | endif +endfunction + +function! node#lib#version() + if exists("b:node_version") | return b:node_version | endif + if !executable("node") | let b:node_version = "" | return | endif + let b:node_version = matchstr(system("node --version"), '^v\?\zs[0-9.]\+') + return b:node_version +endfunction + +function! s:absolutize(name, from) + if a:name =~# s:ABSPATH + return a:name + elseif a:name =~# s:RELPATH + let dir = isdirectory(a:from) ? a:from : fnamemodify(a:from, ":h") + return dir . "/" . a:name + else + return b:node_root . "/node_modules/" . a:name + endif +endfunction + +function! s:resolve(path) + " Node checks for files *before* directories, so see if the path does not + " end with a slash or dots and try to match it as a file. + if a:path !~# '\v/(\.\.?/?)?$' + let path_with_suffix = s:resolveSuffix(a:path) + if !empty(path_with_suffix) | return path_with_suffix | endif + endif + + if isdirectory(a:path) | return s:resolveFromDirectory(a:path) | endif +endfunction + +function! s:resolveFromDirectory(path) + " Node.js checks for package.json in every directory, not just the + " module's parent. According to: + " http://nodejs.org/api/modules.html#modules_all_together + if filereadable(a:path . "/package.json") + " Turns out, even though Node says it does not support directories in + " main, it does. + " NOTE: If package.json's main is empty or refers to a non-existent file, + " ./index.js is still tried. + let main = s:mainFromPackage(a:path . "/package.json") + + if !empty(main) && main != "" + let path = s:resolve(a:path . "/" . main) + if !empty(path) | return path | endif + endif + endif + + " We need to check for ./index.js's existence here rather than leave it to + " the caller, because otherwise we can't distinguish if this ./index was + " from the directory defaulting to ./index.js or it was the package.json + " which referred to ./index, which in itself could mean both ./index.js and + " ./index/index.js. + return s:resolveSuffix(a:path . "/index") +endfunction + +function! s:mainFromPackage(path) + for line in readfile(a:path) + if line !~# '"main"\s*:' | continue | endif + return matchstr(line, '"main"\s*:\s*"\zs[^"]\+\ze"') + endfor +endfunction + +function! s:resolveSuffix(path) + for suffix in s:uniq([""] + g:node#suffixesadd + split(&l:suffixesadd, ",")) + let path = a:path . suffix + if filereadable(path) | return path | endif + endfor +endfunction + +let s:GLOB_WILDIGNORE = 1 + +function! node#lib#glob(name) + let matches = [] + + if empty(a:name) + let matches += s:CORE_MODULES + endif + + if empty(a:name) || a:name =~# s:MODULE + let root = b:node_root . "/node_modules" + let matches += s:glob(empty(a:name) ? root : root . "/" . a:name, root) + endif + + if a:name =~# s:ABSPATH + let matches += s:glob(a:name, 0) + endif + + if empty(a:name) || a:name =~# s:RELPATH + let root = b:node_root + let relatives = s:glob(empty(a:name) ? root : root . "/" . a:name, root) + + "call map(relatives, "substitute(v:val, '^\./\./', './', '')") + if empty(a:name) | call map(relatives, "'./' . v:val") | endif + call filter(relatives, "v:val !~# '^\\.//*node_modules/$'") + + let matches += relatives + endif + + return matches +endfunction + +function! s:glob(path, stripPrefix) + " Remove a single trailing slash because we're adding one with the glob. + let path = substitute(a:path, '/$', "", "") + " Glob() got the ability to return a list only in Vim 7.3.465. Using split + " for compatibility. + let list = split(glob(fnameescape(path)."/*", s:GLOB_WILDIGNORE), "\n") + + " Add slashes to directories, like /bin/ls. + call map(list, "v:val . (isdirectory(v:val) ? '/' : '')") + + if !empty(a:stripPrefix) + " Counting and removing bytes intentionally as there's no substr function + " that takes character count, only bytes. + let prefix_length = len(a:stripPrefix) + 1 + return map(list, "strpart(v:val, prefix_length)") + endif + + return list +endfunction + +function! s:uniq(list) + let list = reverse(copy(a:list)) + return reverse(filter(list, "index(list, v:val, v:key + 1) == -1")) +endfunction diff --git a/dotfiles/.local/share/nvim/site/colors/gruvbox.vim b/dotfiles/.local/share/nvim/site/colors/gruvbox.vim new file mode 100644 index 0000000..ab9a629 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/colors/gruvbox.vim @@ -0,0 +1,1393 @@ +" ----------------------------------------------------------------------------- +" File: gruvbox.vim +" Description: Retro groove color scheme for Vim +" Author: morhetz <morhetz@gmail.com> +" Source: https://github.com/morhetz/gruvbox +" Last Modified: 12 Aug 2017 +" ----------------------------------------------------------------------------- + +" Supporting code ------------------------------------------------------------- +" Initialisation: {{{ + +if version > 580 + hi clear + if exists("syntax_on") + syntax reset + endif +endif + +let g:colors_name='gruvbox' + +if !(has('termguicolors') && &termguicolors) && !has('gui_running') && &t_Co != 256 + finish +endif + +" }}} +" Global Settings: {{{ + +if !exists('g:gruvbox_bold') + let g:gruvbox_bold=1 +endif +if !exists('g:gruvbox_italic') + if has('gui_running') || $TERM_ITALICS == 'true' + let g:gruvbox_italic=1 + else + let g:gruvbox_italic=0 + endif +endif +if !exists('g:gruvbox_undercurl') + let g:gruvbox_undercurl=1 +endif +if !exists('g:gruvbox_underline') + let g:gruvbox_underline=1 +endif +if !exists('g:gruvbox_inverse') + let g:gruvbox_inverse=1 +endif + +if !exists('g:gruvbox_guisp_fallback') || index(['fg', 'bg'], g:gruvbox_guisp_fallback) == -1 + let g:gruvbox_guisp_fallback='NONE' +endif + +if !exists('g:gruvbox_improved_strings') + let g:gruvbox_improved_strings=0 +endif + +if !exists('g:gruvbox_improved_warnings') + let g:gruvbox_improved_warnings=0 +endif + +if !exists('g:gruvbox_termcolors') + let g:gruvbox_termcolors=256 +endif + +if !exists('g:gruvbox_invert_indent_guides') + let g:gruvbox_invert_indent_guides=0 +endif + +if exists('g:gruvbox_contrast') + echo 'g:gruvbox_contrast is deprecated; use g:gruvbox_contrast_light and g:gruvbox_contrast_dark instead' +endif + +if !exists('g:gruvbox_contrast_dark') + let g:gruvbox_contrast_dark='medium' +endif + +if !exists('g:gruvbox_contrast_light') + let g:gruvbox_contrast_light='medium' +endif + +let s:is_dark=(&background == 'dark') + +" }}} +" Palette: {{{ + +" setup palette dictionary +let s:gb = {} + +" fill it with absolute colors +let s:gb.dark0_hard = ['#1d2021', 234] " 29-32-33 +let s:gb.dark0 = ['#282828', 235] " 40-40-40 +let s:gb.dark0_soft = ['#32302f', 236] " 50-48-47 +let s:gb.dark1 = ['#3c3836', 237] " 60-56-54 +let s:gb.dark2 = ['#504945', 239] " 80-73-69 +let s:gb.dark3 = ['#665c54', 241] " 102-92-84 +let s:gb.dark4 = ['#7c6f64', 243] " 124-111-100 +let s:gb.dark4_256 = ['#7c6f64', 243] " 124-111-100 + +let s:gb.gray_245 = ['#928374', 245] " 146-131-116 +let s:gb.gray_244 = ['#928374', 244] " 146-131-116 + +let s:gb.light0_hard = ['#f9f5d7', 230] " 249-245-215 +let s:gb.light0 = ['#fbf1c7', 229] " 253-244-193 +let s:gb.light0_soft = ['#f2e5bc', 228] " 242-229-188 +let s:gb.light1 = ['#ebdbb2', 223] " 235-219-178 +let s:gb.light2 = ['#d5c4a1', 250] " 213-196-161 +let s:gb.light3 = ['#bdae93', 248] " 189-174-147 +let s:gb.light4 = ['#a89984', 246] " 168-153-132 +let s:gb.light4_256 = ['#a89984', 246] " 168-153-132 + +let s:gb.bright_red = ['#fb4934', 167] " 251-73-52 +let s:gb.bright_green = ['#b8bb26', 142] " 184-187-38 +let s:gb.bright_yellow = ['#fabd2f', 214] " 250-189-47 +let s:gb.bright_blue = ['#83a598', 109] " 131-165-152 +let s:gb.bright_purple = ['#d3869b', 175] " 211-134-155 +let s:gb.bright_aqua = ['#8ec07c', 108] " 142-192-124 +let s:gb.bright_orange = ['#fe8019', 208] " 254-128-25 + +let s:gb.neutral_red = ['#cc241d', 124] " 204-36-29 +let s:gb.neutral_green = ['#98971a', 106] " 152-151-26 +let s:gb.neutral_yellow = ['#d79921', 172] " 215-153-33 +let s:gb.neutral_blue = ['#458588', 66] " 69-133-136 +let s:gb.neutral_purple = ['#b16286', 132] " 177-98-134 +let s:gb.neutral_aqua = ['#689d6a', 72] " 104-157-106 +let s:gb.neutral_orange = ['#d65d0e', 166] " 214-93-14 + +let s:gb.faded_red = ['#9d0006', 88] " 157-0-6 +let s:gb.faded_green = ['#79740e', 100] " 121-116-14 +let s:gb.faded_yellow = ['#b57614', 136] " 181-118-20 +let s:gb.faded_blue = ['#076678', 24] " 7-102-120 +let s:gb.faded_purple = ['#8f3f71', 96] " 143-63-113 +let s:gb.faded_aqua = ['#427b58', 66] " 66-123-88 +let s:gb.faded_orange = ['#af3a03', 130] " 175-58-3 + +" }}} +" Setup Emphasis: {{{ + +let s:bold = 'bold,' +if g:gruvbox_bold == 0 + let s:bold = '' +endif + +let s:italic = 'italic,' +if g:gruvbox_italic == 0 + let s:italic = '' +endif + +let s:underline = 'underline,' +if g:gruvbox_underline == 0 + let s:underline = '' +endif + +let s:undercurl = 'undercurl,' +if g:gruvbox_undercurl == 0 + let s:undercurl = '' +endif + +let s:inverse = 'inverse,' +if g:gruvbox_inverse == 0 + let s:inverse = '' +endif + +" }}} +" Setup Colors: {{{ + +let s:vim_bg = ['bg', 'bg'] +let s:vim_fg = ['fg', 'fg'] +let s:none = ['NONE', 'NONE'] + +" determine relative colors +if s:is_dark + let s:bg0 = s:gb.dark0 + if g:gruvbox_contrast_dark == 'soft' + let s:bg0 = s:gb.dark0_soft + elseif g:gruvbox_contrast_dark == 'hard' + let s:bg0 = s:gb.dark0_hard + endif + + let s:bg1 = s:gb.dark1 + let s:bg2 = s:gb.dark2 + let s:bg3 = s:gb.dark3 + let s:bg4 = s:gb.dark4 + + let s:gray = s:gb.gray_245 + + let s:fg0 = s:gb.light0 + let s:fg1 = s:gb.light1 + let s:fg2 = s:gb.light2 + let s:fg3 = s:gb.light3 + let s:fg4 = s:gb.light4 + + let s:fg4_256 = s:gb.light4_256 + + let s:red = s:gb.bright_red + let s:green = s:gb.bright_green + let s:yellow = s:gb.bright_yellow + let s:blue = s:gb.bright_blue + let s:purple = s:gb.bright_purple + let s:aqua = s:gb.bright_aqua + let s:orange = s:gb.bright_orange +else + let s:bg0 = s:gb.light0 + if g:gruvbox_contrast_light == 'soft' + let s:bg0 = s:gb.light0_soft + elseif g:gruvbox_contrast_light == 'hard' + let s:bg0 = s:gb.light0_hard + endif + + let s:bg1 = s:gb.light1 + let s:bg2 = s:gb.light2 + let s:bg3 = s:gb.light3 + let s:bg4 = s:gb.light4 + + let s:gray = s:gb.gray_244 + + let s:fg0 = s:gb.dark0 + let s:fg1 = s:gb.dark1 + let s:fg2 = s:gb.dark2 + let s:fg3 = s:gb.dark3 + let s:fg4 = s:gb.dark4 + + let s:fg4_256 = s:gb.dark4_256 + + let s:red = s:gb.faded_red + let s:green = s:gb.faded_green + let s:yellow = s:gb.faded_yellow + let s:blue = s:gb.faded_blue + let s:purple = s:gb.faded_purple + let s:aqua = s:gb.faded_aqua + let s:orange = s:gb.faded_orange +endif + +" reset to 16 colors fallback +if g:gruvbox_termcolors == 16 + let s:bg0[1] = 0 + let s:fg4[1] = 7 + let s:gray[1] = 8 + let s:red[1] = 9 + let s:green[1] = 10 + let s:yellow[1] = 11 + let s:blue[1] = 12 + let s:purple[1] = 13 + let s:aqua[1] = 14 + let s:fg1[1] = 15 +endif + +" save current relative colors back to palette dictionary +let s:gb.bg0 = s:bg0 +let s:gb.bg1 = s:bg1 +let s:gb.bg2 = s:bg2 +let s:gb.bg3 = s:bg3 +let s:gb.bg4 = s:bg4 + +let s:gb.gray = s:gray + +let s:gb.fg0 = s:fg0 +let s:gb.fg1 = s:fg1 +let s:gb.fg2 = s:fg2 +let s:gb.fg3 = s:fg3 +let s:gb.fg4 = s:fg4 + +let s:gb.fg4_256 = s:fg4_256 + +let s:gb.red = s:red +let s:gb.green = s:green +let s:gb.yellow = s:yellow +let s:gb.blue = s:blue +let s:gb.purple = s:purple +let s:gb.aqua = s:aqua +let s:gb.orange = s:orange + +" }}} +" Setup Terminal Colors For Neovim: {{{ + +if has('nvim') + let g:terminal_color_0 = s:bg0[0] + let g:terminal_color_8 = s:gray[0] + + let g:terminal_color_1 = s:gb.neutral_red[0] + let g:terminal_color_9 = s:red[0] + + let g:terminal_color_2 = s:gb.neutral_green[0] + let g:terminal_color_10 = s:green[0] + + let g:terminal_color_3 = s:gb.neutral_yellow[0] + let g:terminal_color_11 = s:yellow[0] + + let g:terminal_color_4 = s:gb.neutral_blue[0] + let g:terminal_color_12 = s:blue[0] + + let g:terminal_color_5 = s:gb.neutral_purple[0] + let g:terminal_color_13 = s:purple[0] + + let g:terminal_color_6 = s:gb.neutral_aqua[0] + let g:terminal_color_14 = s:aqua[0] + + let g:terminal_color_7 = s:fg4[0] + let g:terminal_color_15 = s:fg1[0] +endif + +" }}} +" Overload Setting: {{{ + +let s:hls_cursor = s:orange +if exists('g:gruvbox_hls_cursor') + let s:hls_cursor = get(s:gb, g:gruvbox_hls_cursor) +endif + +let s:number_column = s:none +if exists('g:gruvbox_number_column') + let s:number_column = get(s:gb, g:gruvbox_number_column) +endif + +let s:sign_column = s:bg1 + +if exists('g:gitgutter_override_sign_column_highlight') && + \ g:gitgutter_override_sign_column_highlight == 1 + let s:sign_column = s:number_column +else + let g:gitgutter_override_sign_column_highlight = 0 + + if exists('g:gruvbox_sign_column') + let s:sign_column = get(s:gb, g:gruvbox_sign_column) + endif +endif + +let s:color_column = s:bg1 +if exists('g:gruvbox_color_column') + let s:color_column = get(s:gb, g:gruvbox_color_column) +endif + +let s:vert_split = s:bg0 +if exists('g:gruvbox_vert_split') + let s:vert_split = get(s:gb, g:gruvbox_vert_split) +endif + +let s:invert_signs = '' +if exists('g:gruvbox_invert_signs') + if g:gruvbox_invert_signs == 1 + let s:invert_signs = s:inverse + endif +endif + +let s:invert_selection = s:inverse +if exists('g:gruvbox_invert_selection') + if g:gruvbox_invert_selection == 0 + let s:invert_selection = '' + endif +endif + +let s:invert_tabline = '' +if exists('g:gruvbox_invert_tabline') + if g:gruvbox_invert_tabline == 1 + let s:invert_tabline = s:inverse + endif +endif + +let s:italicize_comments = s:italic +if exists('g:gruvbox_italicize_comments') + if g:gruvbox_italicize_comments == 0 + let s:italicize_comments = '' + endif +endif + +let s:italicize_strings = '' +if exists('g:gruvbox_italicize_strings') + if g:gruvbox_italicize_strings == 1 + let s:italicize_strings = s:italic + endif +endif + +" }}} +" Highlighting Function: {{{ + +function! s:HL(group, fg, ...) + " Arguments: group, guifg, guibg, gui, guisp + + " foreground + let fg = a:fg + + " background + if a:0 >= 1 + let bg = a:1 + else + let bg = s:none + endif + + " emphasis + if a:0 >= 2 && strlen(a:2) + let emstr = a:2 + else + let emstr = 'NONE,' + endif + + " special fallback + if a:0 >= 3 + if g:gruvbox_guisp_fallback != 'NONE' + let fg = a:3 + endif + + " bg fallback mode should invert higlighting + if g:gruvbox_guisp_fallback == 'bg' + let emstr .= 'inverse,' + endif + endif + + let histring = [ 'hi', a:group, + \ 'guifg=' . fg[0], 'ctermfg=' . fg[1], + \ 'guibg=none', 'ctermbg=' . bg[1], + \ 'gui=' . emstr[:-2], 'cterm=' . emstr[:-2] + \ ] + + " special + if a:0 >= 3 + call add(histring, 'guisp=' . a:3[0]) + endif + + execute join(histring, ' ') +endfunction + +" }}} +" Gruvbox Hi Groups: {{{ + +" memoize common hi groups +call s:HL('GruvboxFg0', s:fg0) +call s:HL('GruvboxFg1', s:fg1) +call s:HL('GruvboxFg2', s:fg2) +call s:HL('GruvboxFg3', s:fg3) +call s:HL('GruvboxFg4', s:fg4) +call s:HL('GruvboxGray', s:gray) +call s:HL('GruvboxBg0', s:bg0) +call s:HL('GruvboxBg1', s:bg1) +call s:HL('GruvboxBg2', s:bg2) +call s:HL('GruvboxBg3', s:bg3) +call s:HL('GruvboxBg4', s:bg4) + +call s:HL('GruvboxRed', s:red) +call s:HL('GruvboxRedBold', s:red, s:none, s:bold) +call s:HL('GruvboxGreen', s:green) +call s:HL('GruvboxGreenBold', s:green, s:none, s:bold) +call s:HL('GruvboxYellow', s:yellow) +call s:HL('GruvboxYellowBold', s:yellow, s:none, s:bold) +call s:HL('GruvboxBlue', s:blue) +call s:HL('GruvboxBlueBold', s:blue, s:none, s:bold) +call s:HL('GruvboxPurple', s:purple) +call s:HL('GruvboxPurpleBold', s:purple, s:none, s:bold) +call s:HL('GruvboxAqua', s:aqua) +call s:HL('GruvboxAquaBold', s:aqua, s:none, s:bold) +call s:HL('GruvboxOrange', s:orange) +call s:HL('GruvboxOrangeBold', s:orange, s:none, s:bold) + +call s:HL('GruvboxRedSign', s:red, s:sign_column, s:invert_signs) +call s:HL('GruvboxGreenSign', s:green, s:sign_column, s:invert_signs) +call s:HL('GruvboxYellowSign', s:yellow, s:sign_column, s:invert_signs) +call s:HL('GruvboxBlueSign', s:blue, s:sign_column, s:invert_signs) +call s:HL('GruvboxPurpleSign', s:purple, s:sign_column, s:invert_signs) +call s:HL('GruvboxAquaSign', s:aqua, s:sign_column, s:invert_signs) + +" }}} + +" Vanilla colorscheme --------------------------------------------------------- +" General UI: {{{ + +" Normal text +call s:HL('Normal', s:fg1, s:bg0) + +" Correct background (see issue #7): +" --- Problem with changing between dark and light on 256 color terminal +" --- https://github.com/morhetz/gruvbox/issues/7 +if s:is_dark + set background=dark +else + set background=light +endif + +if version >= 700 + " Screen line that the cursor is + call s:HL('CursorLine', s:none, s:bg1) + " Screen column that the cursor is + hi! link CursorColumn CursorLine + + " Tab pages line filler + call s:HL('TabLineFill', s:bg4, s:bg1, s:invert_tabline) + " Active tab page label + call s:HL('TabLineSel', s:green, s:bg1, s:invert_tabline) + " Not active tab page label + hi! link TabLine TabLineFill + + " Match paired bracket under the cursor + call s:HL('MatchParen', s:none, s:bg3, s:bold) +endif + +if version >= 703 + " Highlighted screen columns + call s:HL('ColorColumn', s:none, s:color_column) + + " Concealed element: \lambda → λ + call s:HL('Conceal', s:blue, s:none) + + " Line number of CursorLine + call s:HL('CursorLineNr', s:yellow, s:bg1) +endif + +hi! link NonText GruvboxBg2 +hi! link SpecialKey GruvboxBg2 + +call s:HL('Visual', s:none, s:bg3, s:invert_selection) +hi! link VisualNOS Visual + +call s:HL('Search', s:yellow, s:bg0, s:inverse) +call s:HL('IncSearch', s:hls_cursor, s:bg0, s:inverse) + +call s:HL('Underlined', s:blue, s:none, s:underline) + +call s:HL('StatusLine', s:bg2, s:fg1, s:inverse) +call s:HL('StatusLineNC', s:bg1, s:fg4, s:inverse) + +" The column separating vertically split windows +call s:HL('VertSplit', s:bg3, s:vert_split) + +" Current match in wildmenu completion +call s:HL('WildMenu', s:blue, s:bg2, s:bold) + +" Directory names, special names in listing +hi! link Directory GruvboxGreenBold + +" Titles for output from :set all, :autocmd, etc. +hi! link Title GruvboxGreenBold + +" Error messages on the command line +call s:HL('ErrorMsg', s:bg0, s:red, s:bold) +" More prompt: -- More -- +hi! link MoreMsg GruvboxYellowBold +" Current mode message: -- INSERT -- +hi! link ModeMsg GruvboxYellowBold +" 'Press enter' prompt and yes/no questions +hi! link Question GruvboxOrangeBold +" Warning messages +hi! link WarningMsg GruvboxRedBold + +" }}} +" Gutter: {{{ + +" Line number for :number and :# commands +call s:HL('LineNr', s:bg4, s:number_column) + +" Column where signs are displayed +call s:HL('SignColumn', s:none, s:sign_column) + +" Line used for closed folds +call s:HL('Folded', s:gray, s:bg1, s:italic) +" Column where folds are displayed +call s:HL('FoldColumn', s:gray, s:bg1) + +" }}} +" Cursor: {{{ + +" Character under cursor +call s:HL('Cursor', s:none, s:none, s:inverse) +" Visual mode cursor, selection +hi! link vCursor Cursor +" Input moder cursor +hi! link iCursor Cursor +" Language mapping cursor +hi! link lCursor Cursor + +" }}} +" Syntax Highlighting: {{{ + +if g:gruvbox_improved_strings == 0 + hi! link Special GruvboxOrange +else + call s:HL('Special', s:orange, s:bg1, s:italicize_strings) +endif + +call s:HL('Comment', s:gray, s:none, s:italicize_comments) +call s:HL('Todo', s:vim_fg, s:vim_bg, s:bold . s:italic) +call s:HL('Error', s:red, s:vim_bg, s:bold . s:inverse) + +" Generic statement +hi! link Statement GruvboxRed +" if, then, else, endif, swicth, etc. +hi! link Conditional GruvboxRed +" for, do, while, etc. +hi! link Repeat GruvboxRed +" case, default, etc. +hi! link Label GruvboxRed +" try, catch, throw +hi! link Exception GruvboxRed +" sizeof, "+", "*", etc. +hi! link Operator Normal +" Any other keyword +hi! link Keyword GruvboxRed + +" Variable name +hi! link Identifier GruvboxBlue +" Function name +hi! link Function GruvboxGreenBold + +" Generic preprocessor +hi! link PreProc GruvboxAqua +" Preprocessor #include +hi! link Include GruvboxAqua +" Preprocessor #define +hi! link Define GruvboxAqua +" Same as Define +hi! link Macro GruvboxAqua +" Preprocessor #if, #else, #endif, etc. +hi! link PreCondit GruvboxAqua + +" Generic constant +hi! link Constant GruvboxPurple +" Character constant: 'c', '/n' +hi! link Character GruvboxPurple +" String constant: "this is a string" +if g:gruvbox_improved_strings == 0 + call s:HL('String', s:green, s:none, s:italicize_strings) +else + call s:HL('String', s:fg1, s:bg1, s:italicize_strings) +endif +" Boolean constant: TRUE, false +hi! link Boolean GruvboxPurple +" Number constant: 234, 0xff +hi! link Number GruvboxPurple +" Floating point constant: 2.3e10 +hi! link Float GruvboxPurple + +" Generic type +hi! link Type GruvboxYellow +" static, register, volatile, etc +hi! link StorageClass GruvboxOrange +" struct, union, enum, etc. +hi! link Structure GruvboxAqua +" typedef +hi! link Typedef GruvboxYellow + +" }}} +" Completion Menu: {{{ + +if version >= 700 + " Popup menu: normal item + call s:HL('Pmenu', s:fg1, s:bg2) + " Popup menu: selected item + call s:HL('PmenuSel', s:bg2, s:blue, s:bold) + " Popup menu: scrollbar + call s:HL('PmenuSbar', s:none, s:bg2) + " Popup menu: scrollbar thumb + call s:HL('PmenuThumb', s:none, s:bg4) +endif + +" }}} +" Diffs: {{{ + +call s:HL('DiffDelete', s:red, s:bg0, s:inverse) +call s:HL('DiffAdd', s:green, s:bg0, s:inverse) +"call s:HL('DiffChange', s:bg0, s:blue) +"call s:HL('DiffText', s:bg0, s:yellow) + +" Alternative setting +call s:HL('DiffChange', s:aqua, s:bg0, s:inverse) +call s:HL('DiffText', s:yellow, s:bg0, s:inverse) + +" }}} +" Spelling: {{{ + +if has("spell") + " Not capitalised word, or compile warnings + if g:gruvbox_improved_warnings == 0 + call s:HL('SpellCap', s:none, s:none, s:undercurl, s:red) + else + call s:HL('SpellCap', s:green, s:none, s:bold . s:italic) + endif + " Not recognized word + call s:HL('SpellBad', s:none, s:none, s:undercurl, s:blue) + " Wrong spelling for selected region + call s:HL('SpellLocal', s:none, s:none, s:undercurl, s:aqua) + " Rare word + call s:HL('SpellRare', s:none, s:none, s:undercurl, s:purple) +endif + +" }}} + +" Plugin specific ------------------------------------------------------------- +" EasyMotion: {{{ + +hi! link EasyMotionTarget Search +hi! link EasyMotionShade Comment + +" }}} +" Sneak: {{{ + +hi! link Sneak Search +hi! link SneakLabel Search + +" }}} +" Indent Guides: {{{ + +if !exists('g:indent_guides_auto_colors') + let g:indent_guides_auto_colors = 0 +endif + +if g:indent_guides_auto_colors == 0 + if g:gruvbox_invert_indent_guides == 0 + call s:HL('IndentGuidesOdd', s:vim_bg, s:bg2) + call s:HL('IndentGuidesEven', s:vim_bg, s:bg1) + else + call s:HL('IndentGuidesOdd', s:vim_bg, s:bg2, s:inverse) + call s:HL('IndentGuidesEven', s:vim_bg, s:bg3, s:inverse) + endif +endif + +" }}} +" IndentLine: {{{ + +if !exists('g:indentLine_color_term') + let g:indentLine_color_term = s:bg2[1] +endif +if !exists('g:indentLine_color_gui') + let g:indentLine_color_gui = s:bg2[0] +endif + +" }}} +" Rainbow Parentheses: {{{ + +if !exists('g:rbpt_colorpairs') + let g:rbpt_colorpairs = + \ [ + \ ['blue', '#458588'], ['magenta', '#b16286'], + \ ['red', '#cc241d'], ['166', '#d65d0e'] + \ ] +endif + +let g:rainbow_guifgs = [ '#d65d0e', '#cc241d', '#b16286', '#458588' ] +let g:rainbow_ctermfgs = [ '166', 'red', 'magenta', 'blue' ] + +if !exists('g:rainbow_conf') + let g:rainbow_conf = {} +endif +if !has_key(g:rainbow_conf, 'guifgs') + let g:rainbow_conf['guifgs'] = g:rainbow_guifgs +endif +if !has_key(g:rainbow_conf, 'ctermfgs') + let g:rainbow_conf['ctermfgs'] = g:rainbow_ctermfgs +endif + +let g:niji_dark_colours = g:rbpt_colorpairs +let g:niji_light_colours = g:rbpt_colorpairs + +"}}} +" GitGutter: {{{ + +hi! link GitGutterAdd GruvboxGreenSign +hi! link GitGutterChange GruvboxAquaSign +hi! link GitGutterDelete GruvboxRedSign +hi! link GitGutterChangeDelete GruvboxAquaSign + +" }}} +" GitCommit: "{{{ + +hi! link gitcommitSelectedFile GruvboxGreen +hi! link gitcommitDiscardedFile GruvboxRed + +" }}} +" Signify: {{{ + +hi! link SignifySignAdd GruvboxGreenSign +hi! link SignifySignChange GruvboxAquaSign +hi! link SignifySignDelete GruvboxRedSign + +" }}} +" Syntastic: {{{ + +call s:HL('SyntasticError', s:none, s:none, s:undercurl, s:red) +call s:HL('SyntasticWarning', s:none, s:none, s:undercurl, s:yellow) + +hi! link SyntasticErrorSign GruvboxRedSign +hi! link SyntasticWarningSign GruvboxYellowSign + +" }}} +" Signature: {{{ +hi! link SignatureMarkText GruvboxBlueSign +hi! link SignatureMarkerText GruvboxPurpleSign + +" }}} +" ShowMarks: {{{ + +hi! link ShowMarksHLl GruvboxBlueSign +hi! link ShowMarksHLu GruvboxBlueSign +hi! link ShowMarksHLo GruvboxBlueSign +hi! link ShowMarksHLm GruvboxBlueSign + +" }}} +" CtrlP: {{{ + +hi! link CtrlPMatch GruvboxYellow +hi! link CtrlPNoEntries GruvboxRed +hi! link CtrlPPrtBase GruvboxBg2 +hi! link CtrlPPrtCursor GruvboxBlue +hi! link CtrlPLinePre GruvboxBg2 + +call s:HL('CtrlPMode1', s:blue, s:bg2, s:bold) +call s:HL('CtrlPMode2', s:bg0, s:blue, s:bold) +call s:HL('CtrlPStats', s:fg4, s:bg2, s:bold) + +" }}} +" Startify: {{{ + +hi! link StartifyBracket GruvboxFg3 +hi! link StartifyFile GruvboxFg1 +hi! link StartifyNumber GruvboxBlue +hi! link StartifyPath GruvboxGray +hi! link StartifySlash GruvboxGray +hi! link StartifySection GruvboxYellow +hi! link StartifySpecial GruvboxBg2 +hi! link StartifyHeader GruvboxOrange +hi! link StartifyFooter GruvboxBg2 + +" }}} +" Vimshell: {{{ + +let g:vimshell_escape_colors = [ + \ s:bg4[0], s:red[0], s:green[0], s:yellow[0], + \ s:blue[0], s:purple[0], s:aqua[0], s:fg4[0], + \ s:bg0[0], s:red[0], s:green[0], s:orange[0], + \ s:blue[0], s:purple[0], s:aqua[0], s:fg0[0] + \ ] + +" }}} +" BufTabLine: {{{ + +call s:HL('BufTabLineCurrent', s:bg0, s:fg4) +call s:HL('BufTabLineActive', s:fg4, s:bg2) +call s:HL('BufTabLineHidden', s:bg4, s:bg1) +call s:HL('BufTabLineFill', s:bg0, s:bg0) + +" }}} +" Asynchronous Lint Engine: {{{ + +call s:HL('ALEError', s:none, s:none, s:undercurl, s:red) +call s:HL('ALEWarning', s:none, s:none, s:undercurl, s:yellow) +call s:HL('ALEInfo', s:none, s:none, s:undercurl, s:blue) + +hi! link ALEErrorSign GruvboxRedSign +hi! link ALEWarningSign GruvboxYellowSign +hi! link ALEInfoSign GruvboxBlueSign + +" }}} +" Dirvish: {{{ + +hi! link DirvishPathTail GruvboxAqua +hi! link DirvishArg GruvboxYellow + +" }}} +" Netrw: {{{ + +hi! link netrwDir GruvboxAqua +hi! link netrwClassify GruvboxAqua +hi! link netrwLink GruvboxGray +hi! link netrwSymLink GruvboxFg1 +hi! link netrwExe GruvboxYellow +hi! link netrwComment GruvboxGray +hi! link netrwList GruvboxBlue +hi! link netrwHelpCmd GruvboxAqua +hi! link netrwCmdSep GruvboxFg3 +hi! link netrwVersion GruvboxGreen + +" }}} +" NERDTree: {{{ + +hi! link NERDTreeDir GruvboxAqua +hi! link NERDTreeDirSlash GruvboxAqua + +hi! link NERDTreeOpenable GruvboxOrange +hi! link NERDTreeClosable GruvboxOrange + +hi! link NERDTreeFile GruvboxFg1 +hi! link NERDTreeExecFile GruvboxYellow + +hi! link NERDTreeUp GruvboxGray +hi! link NERDTreeCWD GruvboxGreen +hi! link NERDTreeHelp GruvboxFg1 + +hi! link NERDTreeToggleOn GruvboxGreen +hi! link NERDTreeToggleOff GruvboxRed + +" }}} +" Vim Multiple Cursors: {{{ + +call s:HL('multiple_cursors_cursor', s:none, s:none, s:inverse) +call s:HL('multiple_cursors_visual', s:none, s:bg2) + +" }}} + +" Filetype specific ----------------------------------------------------------- +" Diff: {{{ + +hi! link diffAdded GruvboxGreen +hi! link diffRemoved GruvboxRed +hi! link diffChanged GruvboxAqua + +hi! link diffFile GruvboxOrange +hi! link diffNewFile GruvboxYellow + +hi! link diffLine GruvboxBlue + +" }}} +" Html: {{{ + +hi! link htmlTag GruvboxBlue +hi! link htmlEndTag GruvboxBlue + +hi! link htmlTagName GruvboxAquaBold +hi! link htmlArg GruvboxAqua + +hi! link htmlScriptTag GruvboxPurple +hi! link htmlTagN GruvboxFg1 +hi! link htmlSpecialTagName GruvboxAquaBold + +call s:HL('htmlLink', s:fg4, s:none, s:underline) + +hi! link htmlSpecialChar GruvboxOrange + +call s:HL('htmlBold', s:vim_fg, s:vim_bg, s:bold) +call s:HL('htmlBoldUnderline', s:vim_fg, s:vim_bg, s:bold . s:underline) +call s:HL('htmlBoldItalic', s:vim_fg, s:vim_bg, s:bold . s:italic) +call s:HL('htmlBoldUnderlineItalic', s:vim_fg, s:vim_bg, s:bold . s:underline . s:italic) + +call s:HL('htmlUnderline', s:vim_fg, s:vim_bg, s:underline) +call s:HL('htmlUnderlineItalic', s:vim_fg, s:vim_bg, s:underline . s:italic) +call s:HL('htmlItalic', s:vim_fg, s:vim_bg, s:italic) + +" }}} +" Xml: {{{ + +hi! link xmlTag GruvboxBlue +hi! link xmlEndTag GruvboxBlue +hi! link xmlTagName GruvboxBlue +hi! link xmlEqual GruvboxBlue +hi! link docbkKeyword GruvboxAquaBold + +hi! link xmlDocTypeDecl GruvboxGray +hi! link xmlDocTypeKeyword GruvboxPurple +hi! link xmlCdataStart GruvboxGray +hi! link xmlCdataCdata GruvboxPurple +hi! link dtdFunction GruvboxGray +hi! link dtdTagName GruvboxPurple + +hi! link xmlAttrib GruvboxAqua +hi! link xmlProcessingDelim GruvboxGray +hi! link dtdParamEntityPunct GruvboxGray +hi! link dtdParamEntityDPunct GruvboxGray +hi! link xmlAttribPunct GruvboxGray + +hi! link xmlEntity GruvboxOrange +hi! link xmlEntityPunct GruvboxOrange +" }}} +" Vim: {{{ + +call s:HL('vimCommentTitle', s:fg4_256, s:none, s:bold . s:italicize_comments) + +hi! link vimNotation GruvboxOrange +hi! link vimBracket GruvboxOrange +hi! link vimMapModKey GruvboxOrange +hi! link vimFuncSID GruvboxFg3 +hi! link vimSetSep GruvboxFg3 +hi! link vimSep GruvboxFg3 +hi! link vimContinue GruvboxFg3 + +" }}} +" Clojure: {{{ + +hi! link clojureKeyword GruvboxBlue +hi! link clojureCond GruvboxOrange +hi! link clojureSpecial GruvboxOrange +hi! link clojureDefine GruvboxOrange + +hi! link clojureFunc GruvboxYellow +hi! link clojureRepeat GruvboxYellow +hi! link clojureCharacter GruvboxAqua +hi! link clojureStringEscape GruvboxAqua +hi! link clojureException GruvboxRed + +hi! link clojureRegexp GruvboxAqua +hi! link clojureRegexpEscape GruvboxAqua +call s:HL('clojureRegexpCharClass', s:fg3, s:none, s:bold) +hi! link clojureRegexpMod clojureRegexpCharClass +hi! link clojureRegexpQuantifier clojureRegexpCharClass + +hi! link clojureParen GruvboxFg3 +hi! link clojureAnonArg GruvboxYellow +hi! link clojureVariable GruvboxBlue +hi! link clojureMacro GruvboxOrange + +hi! link clojureMeta GruvboxYellow +hi! link clojureDeref GruvboxYellow +hi! link clojureQuote GruvboxYellow +hi! link clojureUnquote GruvboxYellow + +" }}} +" C: {{{ + +hi! link cOperator GruvboxPurple +hi! link cStructure GruvboxOrange + +" }}} +" Python: {{{ + +hi! link pythonBuiltin GruvboxOrange +hi! link pythonBuiltinObj GruvboxOrange +hi! link pythonBuiltinFunc GruvboxOrange +hi! link pythonFunction GruvboxAqua +hi! link pythonDecorator GruvboxRed +hi! link pythonInclude GruvboxBlue +hi! link pythonImport GruvboxBlue +hi! link pythonRun GruvboxBlue +hi! link pythonCoding GruvboxBlue +hi! link pythonOperator GruvboxRed +hi! link pythonException GruvboxRed +hi! link pythonExceptions GruvboxPurple +hi! link pythonBoolean GruvboxPurple +hi! link pythonDot GruvboxFg3 +hi! link pythonConditional GruvboxRed +hi! link pythonRepeat GruvboxRed +hi! link pythonDottedName GruvboxGreenBold + +" }}} +" CSS: {{{ + +hi! link cssBraces GruvboxBlue +hi! link cssFunctionName GruvboxYellow +hi! link cssIdentifier GruvboxOrange +hi! link cssClassName GruvboxGreen +hi! link cssColor GruvboxBlue +hi! link cssSelectorOp GruvboxBlue +hi! link cssSelectorOp2 GruvboxBlue +hi! link cssImportant GruvboxGreen +hi! link cssVendor GruvboxFg1 + +hi! link cssTextProp GruvboxAqua +hi! link cssAnimationProp GruvboxAqua +hi! link cssUIProp GruvboxYellow +hi! link cssTransformProp GruvboxAqua +hi! link cssTransitionProp GruvboxAqua +hi! link cssPrintProp GruvboxAqua +hi! link cssPositioningProp GruvboxYellow +hi! link cssBoxProp GruvboxAqua +hi! link cssFontDescriptorProp GruvboxAqua +hi! link cssFlexibleBoxProp GruvboxAqua +hi! link cssBorderOutlineProp GruvboxAqua +hi! link cssBackgroundProp GruvboxAqua +hi! link cssMarginProp GruvboxAqua +hi! link cssListProp GruvboxAqua +hi! link cssTableProp GruvboxAqua +hi! link cssFontProp GruvboxAqua +hi! link cssPaddingProp GruvboxAqua +hi! link cssDimensionProp GruvboxAqua +hi! link cssRenderProp GruvboxAqua +hi! link cssColorProp GruvboxAqua +hi! link cssGeneratedContentProp GruvboxAqua + +" }}} +" JavaScript: {{{ + +hi! link javaScriptBraces GruvboxFg1 +hi! link javaScriptFunction GruvboxAqua +hi! link javaScriptIdentifier GruvboxRed +hi! link javaScriptMember GruvboxBlue +hi! link javaScriptNumber GruvboxPurple +hi! link javaScriptNull GruvboxPurple +hi! link javaScriptParens GruvboxFg3 + +" }}} +" YAJS: {{{ + +hi! link javascriptImport GruvboxAqua +hi! link javascriptExport GruvboxAqua +hi! link javascriptClassKeyword GruvboxAqua +hi! link javascriptClassExtends GruvboxAqua +hi! link javascriptDefault GruvboxAqua + +hi! link javascriptClassName GruvboxYellow +hi! link javascriptClassSuperName GruvboxYellow +hi! link javascriptGlobal GruvboxYellow + +hi! link javascriptEndColons GruvboxFg1 +hi! link javascriptFuncArg GruvboxFg1 +hi! link javascriptGlobalMethod GruvboxFg1 +hi! link javascriptNodeGlobal GruvboxFg1 +hi! link javascriptBOMWindowProp GruvboxFg1 +hi! link javascriptArrayMethod GruvboxFg1 +hi! link javascriptArrayStaticMethod GruvboxFg1 +hi! link javascriptCacheMethod GruvboxFg1 +hi! link javascriptDateMethod GruvboxFg1 +hi! link javascriptMathStaticMethod GruvboxFg1 + +" hi! link javascriptProp GruvboxFg1 +hi! link javascriptURLUtilsProp GruvboxFg1 +hi! link javascriptBOMNavigatorProp GruvboxFg1 +hi! link javascriptDOMDocMethod GruvboxFg1 +hi! link javascriptDOMDocProp GruvboxFg1 +hi! link javascriptBOMLocationMethod GruvboxFg1 +hi! link javascriptBOMWindowMethod GruvboxFg1 +hi! link javascriptStringMethod GruvboxFg1 + +hi! link javascriptVariable GruvboxOrange +" hi! link javascriptVariable GruvboxRed +" hi! link javascriptIdentifier GruvboxOrange +" hi! link javascriptClassSuper GruvboxOrange +hi! link javascriptIdentifier GruvboxOrange +hi! link javascriptClassSuper GruvboxOrange + +" hi! link javascriptFuncKeyword GruvboxOrange +" hi! link javascriptAsyncFunc GruvboxOrange +hi! link javascriptFuncKeyword GruvboxAqua +hi! link javascriptAsyncFunc GruvboxAqua +hi! link javascriptClassStatic GruvboxOrange + +hi! link javascriptOperator GruvboxRed +hi! link javascriptForOperator GruvboxRed +hi! link javascriptYield GruvboxRed +hi! link javascriptExceptions GruvboxRed +hi! link javascriptMessage GruvboxRed + +hi! link javascriptTemplateSB GruvboxAqua +hi! link javascriptTemplateSubstitution GruvboxFg1 + +" hi! link javascriptLabel GruvboxBlue +" hi! link javascriptObjectLabel GruvboxBlue +" hi! link javascriptPropertyName GruvboxBlue +hi! link javascriptLabel GruvboxFg1 +hi! link javascriptObjectLabel GruvboxFg1 +hi! link javascriptPropertyName GruvboxFg1 + +hi! link javascriptLogicSymbols GruvboxFg1 +hi! link javascriptArrowFunc GruvboxYellow + +hi! link javascriptDocParamName GruvboxFg4 +hi! link javascriptDocTags GruvboxFg4 +hi! link javascriptDocNotation GruvboxFg4 +hi! link javascriptDocParamType GruvboxFg4 +hi! link javascriptDocNamedParamType GruvboxFg4 + +hi! link javascriptBrackets GruvboxFg1 +hi! link javascriptDOMElemAttrs GruvboxFg1 +hi! link javascriptDOMEventMethod GruvboxFg1 +hi! link javascriptDOMNodeMethod GruvboxFg1 +hi! link javascriptDOMStorageMethod GruvboxFg1 +hi! link javascriptHeadersMethod GruvboxFg1 + +hi! link javascriptAsyncFuncKeyword GruvboxRed +hi! link javascriptAwaitFuncKeyword GruvboxRed + +" }}} +" PanglossJS: {{{ + +hi! link jsClassKeyword GruvboxAqua +hi! link jsExtendsKeyword GruvboxAqua +hi! link jsExportDefault GruvboxAqua +hi! link jsTemplateBraces GruvboxAqua +hi! link jsGlobalNodeObjects GruvboxFg1 +hi! link jsGlobalObjects GruvboxFg1 +hi! link jsFunction GruvboxAqua +hi! link jsFuncParens GruvboxFg3 +hi! link jsParens GruvboxFg3 +hi! link jsNull GruvboxPurple +hi! link jsUndefined GruvboxPurple +hi! link jsClassDefinition GruvboxYellow + +" }}} +" TypeScript: {{{ + +hi! link typeScriptReserved GruvboxAqua +hi! link typeScriptLabel GruvboxAqua +hi! link typeScriptFuncKeyword GruvboxAqua +hi! link typeScriptIdentifier GruvboxOrange +hi! link typeScriptBraces GruvboxFg1 +hi! link typeScriptEndColons GruvboxFg1 +hi! link typeScriptDOMObjects GruvboxFg1 +hi! link typeScriptAjaxMethods GruvboxFg1 +hi! link typeScriptLogicSymbols GruvboxFg1 +hi! link typeScriptDocSeeTag Comment +hi! link typeScriptDocParam Comment +hi! link typeScriptDocTags vimCommentTitle +hi! link typeScriptGlobalObjects GruvboxFg1 +hi! link typeScriptParens GruvboxFg3 +hi! link typeScriptOpSymbols GruvboxFg3 +hi! link typeScriptHtmlElemProperties GruvboxFg1 +hi! link typeScriptNull GruvboxPurple +hi! link typeScriptInterpolationDelimiter GruvboxAqua + +" }}} +" PureScript: {{{ + +hi! link purescriptModuleKeyword GruvboxAqua +hi! link purescriptModuleName GruvboxFg1 +hi! link purescriptWhere GruvboxAqua +hi! link purescriptDelimiter GruvboxFg4 +hi! link purescriptType GruvboxFg1 +hi! link purescriptImportKeyword GruvboxAqua +hi! link purescriptHidingKeyword GruvboxAqua +hi! link purescriptAsKeyword GruvboxAqua +hi! link purescriptStructure GruvboxAqua +hi! link purescriptOperator GruvboxBlue + +hi! link purescriptTypeVar GruvboxFg1 +hi! link purescriptConstructor GruvboxFg1 +hi! link purescriptFunction GruvboxFg1 +hi! link purescriptConditional GruvboxOrange +hi! link purescriptBacktick GruvboxOrange + +" }}} +" CoffeeScript: {{{ + +hi! link coffeeExtendedOp GruvboxFg3 +hi! link coffeeSpecialOp GruvboxFg3 +hi! link coffeeCurly GruvboxOrange +hi! link coffeeParen GruvboxFg3 +hi! link coffeeBracket GruvboxOrange + +" }}} +" Ruby: {{{ + +hi! link rubyStringDelimiter GruvboxGreen +hi! link rubyInterpolationDelimiter GruvboxAqua + +" }}} +" ObjectiveC: {{{ + +hi! link objcTypeModifier GruvboxRed +hi! link objcDirective GruvboxBlue + +" }}} +" Go: {{{ + +hi! link goDirective GruvboxAqua +hi! link goConstants GruvboxPurple +hi! link goDeclaration GruvboxRed +hi! link goDeclType GruvboxBlue +hi! link goBuiltins GruvboxOrange + +" }}} +" Lua: {{{ + +hi! link luaIn GruvboxRed +hi! link luaFunction GruvboxAqua +hi! link luaTable GruvboxOrange + +" }}} +" MoonScript: {{{ + +hi! link moonSpecialOp GruvboxFg3 +hi! link moonExtendedOp GruvboxFg3 +hi! link moonFunction GruvboxFg3 +hi! link moonObject GruvboxYellow + +" }}} +" Java: {{{ + +hi! link javaAnnotation GruvboxBlue +hi! link javaDocTags GruvboxAqua +hi! link javaCommentTitle vimCommentTitle +hi! link javaParen GruvboxFg3 +hi! link javaParen1 GruvboxFg3 +hi! link javaParen2 GruvboxFg3 +hi! link javaParen3 GruvboxFg3 +hi! link javaParen4 GruvboxFg3 +hi! link javaParen5 GruvboxFg3 +hi! link javaOperator GruvboxOrange + +hi! link javaVarArg GruvboxGreen + +" }}} +" Elixir: {{{ + +hi! link elixirDocString Comment + +hi! link elixirStringDelimiter GruvboxGreen +hi! link elixirInterpolationDelimiter GruvboxAqua + +hi! link elixirModuleDeclaration GruvboxYellow + +" }}} +" Scala: {{{ + +" NB: scala vim syntax file is kinda horrible +hi! link scalaNameDefinition GruvboxFg1 +hi! link scalaCaseFollowing GruvboxFg1 +hi! link scalaCapitalWord GruvboxFg1 +hi! link scalaTypeExtension GruvboxFg1 + +hi! link scalaKeyword GruvboxRed +hi! link scalaKeywordModifier GruvboxRed + +hi! link scalaSpecial GruvboxAqua +hi! link scalaOperator GruvboxFg1 + +hi! link scalaTypeDeclaration GruvboxYellow +hi! link scalaTypeTypePostDeclaration GruvboxYellow + +hi! link scalaInstanceDeclaration GruvboxFg1 +hi! link scalaInterpolation GruvboxAqua + +" }}} +" Markdown: {{{ + +call s:HL('markdownItalic', s:fg3, s:none, s:italic) + +hi! link markdownH1 GruvboxGreenBold +hi! link markdownH2 GruvboxGreenBold +hi! link markdownH3 GruvboxYellowBold +hi! link markdownH4 GruvboxYellowBold +hi! link markdownH5 GruvboxYellow +hi! link markdownH6 GruvboxYellow + +hi! link markdownCode GruvboxAqua +hi! link markdownCodeBlock GruvboxAqua +hi! link markdownCodeDelimiter GruvboxAqua + +hi! link markdownBlockquote GruvboxGray +hi! link markdownListMarker GruvboxGray +hi! link markdownOrderedListMarker GruvboxGray +hi! link markdownRule GruvboxGray +hi! link markdownHeadingRule GruvboxGray + +hi! link markdownUrlDelimiter GruvboxFg3 +hi! link markdownLinkDelimiter GruvboxFg3 +hi! link markdownLinkTextDelimiter GruvboxFg3 + +hi! link markdownHeadingDelimiter GruvboxOrange +hi! link markdownUrl GruvboxPurple +hi! link markdownUrlTitleDelimiter GruvboxGreen + +call s:HL('markdownLinkText', s:gray, s:none, s:underline) +hi! link markdownIdDeclaration markdownLinkText + +" }}} +" Haskell: {{{ + +" hi! link haskellType GruvboxYellow +" hi! link haskellOperators GruvboxOrange +" hi! link haskellConditional GruvboxAqua +" hi! link haskellLet GruvboxOrange +" +hi! link haskellType GruvboxFg1 +hi! link haskellIdentifier GruvboxFg1 +hi! link haskellSeparator GruvboxFg1 +hi! link haskellDelimiter GruvboxFg4 +hi! link haskellOperators GruvboxBlue +" +hi! link haskellBacktick GruvboxOrange +hi! link haskellStatement GruvboxOrange +hi! link haskellConditional GruvboxOrange + +hi! link haskellLet GruvboxAqua +hi! link haskellDefault GruvboxAqua +hi! link haskellWhere GruvboxAqua +hi! link haskellBottom GruvboxAqua +hi! link haskellBlockKeywords GruvboxAqua +hi! link haskellImportKeywords GruvboxAqua +hi! link haskellDeclKeyword GruvboxAqua +hi! link haskellDeriving GruvboxAqua +hi! link haskellAssocType GruvboxAqua + +hi! link haskellNumber GruvboxPurple +hi! link haskellPragma GruvboxPurple + +hi! link haskellString GruvboxGreen +hi! link haskellChar GruvboxGreen + +" }}} +" Json: {{{ + +hi! link jsonKeyword GruvboxGreen +hi! link jsonQuote GruvboxGreen +hi! link jsonBraces GruvboxFg1 +hi! link jsonString GruvboxFg1 + +" }}} + + +" Functions ------------------------------------------------------------------- +" Search Highlighting Cursor {{{ + +function! GruvboxHlsShowCursor() + call s:HL('Cursor', s:bg0, s:hls_cursor) +endfunction + +function! GruvboxHlsHideCursor() + call s:HL('Cursor', s:none, s:none, s:inverse) +endfunction + +" }}} + +" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker: diff --git a/dotfiles/.local/share/nvim/site/colors/solarized.vim b/dotfiles/.local/share/nvim/site/colors/solarized.vim new file mode 100644 index 0000000..70f5223 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/colors/solarized.vim @@ -0,0 +1,1117 @@ +" Name: Solarized vim colorscheme +" Author: Ethan Schoonover <es@ethanschoonover.com> +" URL: http://ethanschoonover.com/solarized +" (see this url for latest release & screenshots) +" License: OSI approved MIT license (see end of this file) +" Created: In the middle of the night +" Modified: 2011 May 05 +" +" Usage "{{{ +" +" --------------------------------------------------------------------- +" ABOUT: +" --------------------------------------------------------------------- +" Solarized is a carefully designed selective contrast colorscheme with dual +" light and dark modes that runs in both GUI, 256 and 16 color modes. +" +" See the homepage above for screenshots and details. +" +" --------------------------------------------------------------------- +" OPTIONS: +" --------------------------------------------------------------------- +" See the "solarized.txt" help file included with this colorscheme (in the +" "doc" subdirectory) for information on options, usage, the Toggle Background +" function and more. If you have already installed Solarized, this is available +" from the Solarized menu and command line as ":help solarized" +" +" --------------------------------------------------------------------- +" INSTALLATION: +" --------------------------------------------------------------------- +" Two options for installation: manual or pathogen +" +" MANUAL INSTALLATION OPTION: +" --------------------------------------------------------------------- +" +" 1. Download the solarized distribution (available on the homepage above) +" and unarchive the file. +" 2. Move `solarized.vim` to your `.vim/colors` directory. +" 3. Move each of the files in each subdirectories to the corresponding .vim +" subdirectory (e.g. autoload/togglebg.vim goes into your .vim/autoload +" directory as .vim/autoload/togglebg.vim). +" +" RECOMMENDED PATHOGEN INSTALLATION OPTION: +" --------------------------------------------------------------------- +" +" 1. Download and install Tim Pope's Pathogen from: +" https://github.com/tpope/vim-pathogen +" +" 2. Next, move or clone the `vim-colors-solarized` directory so that it is +" a subdirectory of the `.vim/bundle` directory. +" +" a. **clone with git:** +" +" $ cd ~/.vim/bundle +" $ git clone git://github.com/altercation/vim-colors-solarized.git +" +" b. **or move manually into the pathogen bundle directory:** +" In the parent directory of vim-colors-solarized: +" +" $ mv vim-colors-solarized ~/.vim/bundle/ +" +" MODIFY VIMRC: +" +" After either Option 1 or Option 2 above, put the following two lines in your +" .vimrc: +" +" syntax enable +" set background=dark +" colorscheme solarized +" +" or, for the light background mode of Solarized: +" +" syntax enable +" set background=light +" colorscheme solarized +" +" I like to have a different background in GUI and terminal modes, so I can use +" the following if-then. However, I find vim's background autodetection to be +" pretty good and, at least with MacVim, I can leave this background value +" assignment out entirely and get the same results. +" +" if has('gui_running') +" set background=light +" else +" set background=dark +" endif +" +" See the Solarized homepage at http://ethanschoonover.com/solarized for +" screenshots which will help you select either the light or dark background. +" +" --------------------------------------------------------------------- +" COLOR VALUES +" --------------------------------------------------------------------- +" Download palettes and files from: http://ethanschoonover.com/solarized +" +" L\*a\*b values are canonical (White D65, Reference D50), other values are +" matched in sRGB space. +" +" SOLARIZED HEX 16/8 TERMCOL XTERM/HEX L*A*B sRGB HSB +" --------- ------- ---- ------- ----------- ---------- ----------- ----------- +" base03 #002b36 8/4 brblack 234 #1c1c1c 15 -12 -12 0 43 54 193 100 21 +" base02 #073642 0/4 black 235 #262626 20 -12 -12 7 54 66 192 90 26 +" base01 #586e75 10/7 brgreen 240 #4e4e4e 45 -07 -07 88 110 117 194 25 46 +" base00 #657b83 11/7 bryellow 241 #585858 50 -07 -07 101 123 131 195 23 51 +" base0 #839496 12/6 brblue 244 #808080 60 -06 -03 131 148 150 186 13 59 +" base1 #93a1a1 14/4 brcyan 245 #8a8a8a 65 -05 -02 147 161 161 180 9 63 +" base2 #eee8d5 7/7 white 254 #d7d7af 92 -00 10 238 232 213 44 11 93 +" base3 #fdf6e3 15/7 brwhite 230 #ffffd7 97 00 10 253 246 227 44 10 99 +" yellow #b58900 3/3 yellow 136 #af8700 60 10 65 181 137 0 45 100 71 +" orange #cb4b16 9/3 brred 166 #d75f00 50 50 55 203 75 22 18 89 80 +" red #dc322f 1/1 red 160 #d70000 50 65 45 220 50 47 1 79 86 +" magenta #d33682 5/5 magenta 125 #af005f 50 65 -05 211 54 130 331 74 83 +" violet #6c71c4 13/5 brmagenta 61 #5f5faf 50 15 -45 108 113 196 237 45 77 +" blue #268bd2 4/4 blue 33 #0087ff 55 -10 -45 38 139 210 205 82 82 +" cyan #2aa198 6/6 cyan 37 #00afaf 60 -35 -05 42 161 152 175 74 63 +" green #859900 2/2 green 64 #5f8700 60 -20 65 133 153 0 68 100 60 +" +" --------------------------------------------------------------------- +" COLORSCHEME HACKING +" --------------------------------------------------------------------- +" +" Useful commands for testing colorschemes: +" :source $VIMRUNTIME/syntax/hitest.vim +" :help highlight-groups +" :help cterm-colors +" :help group-name +" +" Useful links for developing colorschemes: +" http://www.vim.org/scripts/script.php?script_id=2937 +" http://vimcasts.org/episodes/creating-colorschemes-for-vim/ +" http://www.frexx.de/xterm-256-notes/" +" +" }}} +" Environment Specific Overrides "{{{ +" Allow or disallow certain features based on current terminal emulator or +" environment. + +" Terminals that support italics +let s:terms_italic=[ + \"rxvt", + \"gnome-terminal" + \] +" For reference only, terminals are known to be incomptible. +" Terminals that are in neither list need to be tested. +let s:terms_noitalic=[ + \"iTerm.app", + \"Apple_Terminal" + \] +if has("gui_running") + let s:terminal_italic=1 " TODO: could refactor to not require this at all +else + let s:terminal_italic=0 " terminals will be guilty until proven compatible + for term in s:terms_italic + if $TERM_PROGRAM =~ term + let s:terminal_italic=1 + endif + endfor +endif + +" }}} +" Default option values"{{{ +" --------------------------------------------------------------------- +" s:options_list is used to autogenerate a list of all non-default options +" using "call SolarizedOptions()" or with the "Generate .vimrc commands" +" Solarized menu option. See the "Menus" section below for the function itself. +let s:options_list=[ + \'" this block of commands has been autogenerated by solarized.vim and', + \'" includes the current, non-default Solarized option values.', + \'" To use, place these commands in your .vimrc file (replacing any', + \'" existing colorscheme commands). See also ":help solarized"', + \'', + \'" ------------------------------------------------------------------', + \'" Solarized Colorscheme Config', + \'" ------------------------------------------------------------------', + \] +let s:colorscheme_list=[ + \'syntax enable', + \'set background='.&background, + \'colorscheme solarized', + \] +let s:defaults_list=[ + \'" ------------------------------------------------------------------', + \'', + \'" The following items are available options, but do not need to be', + \'" included in your .vimrc as they are currently set to their defaults.', + \'' + \] +let s:lazycat_list=[ + \'" lazy method of appending this onto your .vimrc ":w! >> ~/.vimrc"', + \'" ------------------------------------------------------------------', + \] + +function! s:SetOption(name,default) + if type(a:default) == type(0) + let l:wrap='' + let l:ewrap='' + else + let l:wrap='"' + let l:ewrap='\"' + endif + if !exists("g:solarized_".a:name) || g:solarized_{a:name}==a:default + exe 'let g:solarized_'.a:name.'='.l:wrap.a:default.l:wrap.'"' + exe 'call add(s:defaults_list, "\" let g:solarized_'.a:name.'='.l:ewrap.g:solarized_{a:name}.l:ewrap.'")' + else + exe 'call add(s:options_list, "let g:solarized_'.a:name.'='.l:ewrap.g:solarized_{a:name}.l:ewrap.' \"default value is '.a:default.'")' + endif +endfunction + +if ($TERM_PROGRAM ==? "apple_terminal" && &t_Co < 256) + let s:solarized_termtrans_default = 1 +else + let s:solarized_termtrans_default = 0 +endif +call s:SetOption("termtrans",s:solarized_termtrans_default) +call s:SetOption("degrade",0) +call s:SetOption("bold",1) +call s:SetOption("underline",1) +call s:SetOption("italic",1) " note that we need to override this later if the terminal doesn't support +call s:SetOption("termcolors",16) +call s:SetOption("contrast","normal") +call s:SetOption("visibility","normal") +call s:SetOption("diffmode","normal") +call s:SetOption("hitrail",0) +call s:SetOption("menu",1) + +"}}} +" Colorscheme initialization "{{{ +" --------------------------------------------------------------------- +hi clear +if exists("syntax_on") + syntax reset +endif +let colors_name = "solarized" + +"}}} +" GUI & CSApprox hexadecimal palettes"{{{ +" --------------------------------------------------------------------- +" +" Set both gui and terminal color values in separate conditional statements +" Due to possibility that CSApprox is running (though I suppose we could just +" leave the hex values out entirely in that case and include only cterm colors) +" We also check to see if user has set solarized (force use of the +" neutral gray monotone palette component) +if (has("gui_running") && g:solarized_degrade == 0) + let s:vmode = "gui" + let s:base03 = "#002b36" + let s:base02 = "#073642" + let s:base01 = "#586e75" + let s:base00 = "#657b83" + let s:base0 = "#839496" + let s:base1 = "#93a1a1" + let s:base2 = "#eee8d5" + let s:base3 = "#fdf6e3" + let s:yellow = "#b58900" + let s:orange = "#cb4b16" + let s:red = "#dc322f" + let s:magenta = "#d33682" + let s:violet = "#6c71c4" + let s:blue = "#268bd2" + let s:cyan = "#2aa198" + "let s:green = "#859900" "original + let s:green = "#719e07" "experimental +elseif (has("gui_running") && g:solarized_degrade == 1) + " These colors are identical to the 256 color mode. They may be viewed + " while in gui mode via "let g:solarized_degrade=1", though this is not + " recommened and is for testing only. + let s:vmode = "gui" + let s:base03 = "#1c1c1c" + let s:base02 = "#262626" + let s:base01 = "#4e4e4e" + let s:base00 = "#585858" + let s:base0 = "#808080" + let s:base1 = "#8a8a8a" + let s:base2 = "#d7d7af" + let s:base3 = "#ffffd7" + let s:yellow = "#af8700" + let s:orange = "#d75f00" + let s:red = "#af0000" + let s:magenta = "#af005f" + let s:violet = "#5f5faf" + let s:blue = "#0087ff" + let s:cyan = "#00afaf" + let s:green = "#5f8700" +elseif g:solarized_termcolors != 256 && &t_Co >= 16 + let s:vmode = "cterm" + let s:base03 = "8" + let s:base02 = "0" + let s:base01 = "10" + let s:base00 = "11" + let s:base0 = "12" + let s:base1 = "14" + let s:base2 = "7" + let s:base3 = "15" + let s:yellow = "3" + let s:orange = "9" + let s:red = "1" + let s:magenta = "5" + let s:violet = "13" + let s:blue = "4" + let s:cyan = "6" + let s:green = "2" +elseif g:solarized_termcolors == 256 + let s:vmode = "cterm" + let s:base03 = "234" + let s:base02 = "235" + let s:base01 = "239" + let s:base00 = "240" + let s:base0 = "244" + let s:base1 = "245" + let s:base2 = "187" + let s:base3 = "230" + let s:yellow = "136" + let s:orange = "166" + let s:red = "124" + let s:magenta = "125" + let s:violet = "61" + let s:blue = "33" + let s:cyan = "37" + let s:green = "64" +else + let s:vmode = "cterm" + let s:bright = "* term=bold cterm=bold" +" let s:base03 = "0".s:bright +" let s:base02 = "0" +" let s:base01 = "2".s:bright +" let s:base00 = "3".s:bright +" let s:base0 = "4".s:bright +" let s:base1 = "6".s:bright +" let s:base2 = "7" +" let s:base3 = "7".s:bright +" let s:yellow = "3" +" let s:orange = "1".s:bright +" let s:red = "1" +" let s:magenta = "5" +" let s:violet = "5".s:bright +" let s:blue = "4" +" let s:cyan = "6" +" let s:green = "2" + let s:base03 = "DarkGray" " 0* + let s:base02 = "Black" " 0 + let s:base01 = "LightGreen" " 2* + let s:base00 = "LightYellow" " 3* + let s:base0 = "LightBlue" " 4* + let s:base1 = "LightCyan" " 6* + let s:base2 = "LightGray" " 7 + let s:base3 = "White" " 7* + let s:yellow = "DarkYellow" " 3 + let s:orange = "LightRed" " 1* + let s:red = "DarkRed" " 1 + let s:magenta = "DarkMagenta" " 5 + let s:violet = "LightMagenta" " 5* + let s:blue = "DarkBlue" " 4 + let s:cyan = "DarkCyan" " 6 + let s:green = "DarkGreen" " 2 + +endif +"}}} +" Formatting options and null values for passthrough effect "{{{ +" --------------------------------------------------------------------- + let s:none = "NONE" + let s:none = "NONE" + let s:t_none = "NONE" + let s:n = "NONE" + let s:c = ",undercurl" + let s:r = ",reverse" + let s:s = ",standout" + let s:ou = "" + let s:ob = "" +"}}} +" Background value based on termtrans setting "{{{ +" --------------------------------------------------------------------- +if (has("gui_running") || g:solarized_termtrans == 0) + let s:back = s:base03 +else + let s:back = "NONE" +endif +"}}} +" Alternate light scheme "{{{ +" --------------------------------------------------------------------- +if &background == "light" + let s:temp03 = s:base03 + let s:temp02 = s:base02 + let s:temp01 = s:base01 + let s:temp00 = s:base00 + let s:base03 = s:base3 + let s:base02 = s:base2 + let s:base01 = s:base1 + let s:base00 = s:base0 + let s:base0 = s:temp00 + let s:base1 = s:temp01 + let s:base2 = s:temp02 + let s:base3 = s:temp03 + if (s:back != "NONE") + let s:back = s:base03 + endif +endif +"}}} +" Optional contrast schemes "{{{ +" --------------------------------------------------------------------- +if g:solarized_contrast == "high" + let s:base01 = s:base00 + let s:base00 = s:base0 + let s:base0 = s:base1 + let s:base1 = s:base2 + let s:base2 = s:base3 + let s:back = s:back +endif +if g:solarized_contrast == "low" + let s:back = s:base02 + let s:ou = ",underline" +endif +"}}} +" Overrides dependent on user specified values and environment "{{{ +" --------------------------------------------------------------------- +if (g:solarized_bold == 0 || &t_Co == 8 ) + let s:b = "" + let s:bb = ",bold" +else + let s:b = ",bold" + let s:bb = "" +endif + +if g:solarized_underline == 0 + let s:u = "" +else + let s:u = ",underline" +endif + +if g:solarized_italic == 0 || s:terminal_italic == 0 + let s:i = "" +else + let s:i = ",italic" +endif +"}}} +" Highlighting primitives"{{{ +" --------------------------------------------------------------------- + +exe "let s:bg_none = ' ".s:vmode."bg=".s:none ."'" +exe "let s:bg_back = ' ".s:vmode."bg=".s:back ."'" +exe "let s:bg_base03 = ' ".s:vmode."bg=".s:base03 ."'" +exe "let s:bg_base02 = ' ".s:vmode."bg=".s:base02 ."'" +exe "let s:bg_base01 = ' ".s:vmode."bg=".s:base01 ."'" +exe "let s:bg_base00 = ' ".s:vmode."bg=".s:base00 ."'" +exe "let s:bg_base0 = ' ".s:vmode."bg=".s:base0 ."'" +exe "let s:bg_base1 = ' ".s:vmode."bg=".s:base1 ."'" +exe "let s:bg_base2 = ' ".s:vmode."bg=".s:base2 ."'" +exe "let s:bg_base3 = ' ".s:vmode."bg=".s:base3 ."'" +exe "let s:bg_green = ' ".s:vmode."bg=".s:green ."'" +exe "let s:bg_yellow = ' ".s:vmode."bg=".s:yellow ."'" +exe "let s:bg_orange = ' ".s:vmode."bg=".s:orange ."'" +exe "let s:bg_red = ' ".s:vmode."bg=".s:red ."'" +exe "let s:bg_magenta = ' ".s:vmode."bg=".s:magenta."'" +exe "let s:bg_violet = ' ".s:vmode."bg=".s:violet ."'" +exe "let s:bg_blue = ' ".s:vmode."bg=".s:blue ."'" +exe "let s:bg_cyan = ' ".s:vmode."bg=".s:cyan ."'" + +exe "let s:fg_none = ' ".s:vmode."fg=".s:none ."'" +exe "let s:fg_back = ' ".s:vmode."fg=".s:back ."'" +exe "let s:fg_base03 = ' ".s:vmode."fg=".s:base03 ."'" +exe "let s:fg_base02 = ' ".s:vmode."fg=".s:base02 ."'" +exe "let s:fg_base01 = ' ".s:vmode."fg=".s:base01 ."'" +exe "let s:fg_base00 = ' ".s:vmode."fg=".s:base00 ."'" +exe "let s:fg_base0 = ' ".s:vmode."fg=".s:base0 ."'" +exe "let s:fg_base1 = ' ".s:vmode."fg=".s:base1 ."'" +exe "let s:fg_base2 = ' ".s:vmode."fg=".s:base2 ."'" +exe "let s:fg_base3 = ' ".s:vmode."fg=".s:base3 ."'" +exe "let s:fg_green = ' ".s:vmode."fg=".s:green ."'" +exe "let s:fg_yellow = ' ".s:vmode."fg=".s:yellow ."'" +exe "let s:fg_orange = ' ".s:vmode."fg=".s:orange ."'" +exe "let s:fg_red = ' ".s:vmode."fg=".s:red ."'" +exe "let s:fg_magenta = ' ".s:vmode."fg=".s:magenta."'" +exe "let s:fg_violet = ' ".s:vmode."fg=".s:violet ."'" +exe "let s:fg_blue = ' ".s:vmode."fg=".s:blue ."'" +exe "let s:fg_cyan = ' ".s:vmode."fg=".s:cyan ."'" + +exe "let s:fmt_none = ' ".s:vmode."=NONE". " term=NONE". "'" +exe "let s:fmt_bold = ' ".s:vmode."=NONE".s:b. " term=NONE".s:b."'" +exe "let s:fmt_bldi = ' ".s:vmode."=NONE".s:b. " term=NONE".s:b."'" +exe "let s:fmt_undr = ' ".s:vmode."=NONE".s:u. " term=NONE".s:u."'" +exe "let s:fmt_undb = ' ".s:vmode."=NONE".s:u.s:b. " term=NONE".s:u.s:b."'" +exe "let s:fmt_undi = ' ".s:vmode."=NONE".s:u. " term=NONE".s:u."'" +exe "let s:fmt_uopt = ' ".s:vmode."=NONE".s:ou. " term=NONE".s:ou."'" +exe "let s:fmt_curl = ' ".s:vmode."=NONE".s:c. " term=NONE".s:c."'" +exe "let s:fmt_ital = ' ".s:vmode."=NONE".s:i. " term=NONE".s:i."'" +exe "let s:fmt_stnd = ' ".s:vmode."=NONE".s:s. " term=NONE".s:s."'" +exe "let s:fmt_revr = ' ".s:vmode."=NONE".s:r. " term=NONE".s:r."'" +exe "let s:fmt_revb = ' ".s:vmode."=NONE".s:r.s:b. " term=NONE".s:r.s:b."'" +" revbb (reverse bold for bright colors) is only set to actual bold in low +" color terminals (t_co=8, such as OS X Terminal.app) and should only be used +" with colors 8-15. +exe "let s:fmt_revbb = ' ".s:vmode."=NONE".s:r.s:bb. " term=NONE".s:r.s:bb."'" +exe "let s:fmt_revbbu = ' ".s:vmode."=NONE".s:r.s:bb.s:u." term=NONE".s:r.s:bb.s:u."'" + +if has("gui_running") + exe "let s:sp_none = ' guisp=".s:none ."'" + exe "let s:sp_back = ' guisp=".s:back ."'" + exe "let s:sp_base03 = ' guisp=".s:base03 ."'" + exe "let s:sp_base02 = ' guisp=".s:base02 ."'" + exe "let s:sp_base01 = ' guisp=".s:base01 ."'" + exe "let s:sp_base00 = ' guisp=".s:base00 ."'" + exe "let s:sp_base0 = ' guisp=".s:base0 ."'" + exe "let s:sp_base1 = ' guisp=".s:base1 ."'" + exe "let s:sp_base2 = ' guisp=".s:base2 ."'" + exe "let s:sp_base3 = ' guisp=".s:base3 ."'" + exe "let s:sp_green = ' guisp=".s:green ."'" + exe "let s:sp_yellow = ' guisp=".s:yellow ."'" + exe "let s:sp_orange = ' guisp=".s:orange ."'" + exe "let s:sp_red = ' guisp=".s:red ."'" + exe "let s:sp_magenta = ' guisp=".s:magenta."'" + exe "let s:sp_violet = ' guisp=".s:violet ."'" + exe "let s:sp_blue = ' guisp=".s:blue ."'" + exe "let s:sp_cyan = ' guisp=".s:cyan ."'" +else + let s:sp_none = "" + let s:sp_back = "" + let s:sp_base03 = "" + let s:sp_base02 = "" + let s:sp_base01 = "" + let s:sp_base00 = "" + let s:sp_base0 = "" + let s:sp_base1 = "" + let s:sp_base2 = "" + let s:sp_base3 = "" + let s:sp_green = "" + let s:sp_yellow = "" + let s:sp_orange = "" + let s:sp_red = "" + let s:sp_magenta = "" + let s:sp_violet = "" + let s:sp_blue = "" + let s:sp_cyan = "" +endif + +"}}} +" Basic highlighting"{{{ +" --------------------------------------------------------------------- +" note that link syntax to avoid duplicate configuration doesn't work with the +" exe compiled formats + +exe "hi! Normal" .s:fmt_none .s:fg_base0 .s:bg_back + +exe "hi! Comment" .s:fmt_ital .s:fg_base01 .s:bg_none +" *Comment any comment + +exe "hi! Constant" .s:fmt_none .s:fg_cyan .s:bg_none +" *Constant any constant +" String a string constant: "this is a string" +" Character a character constant: 'c', '\n' +" Number a number constant: 234, 0xff +" Boolean a boolean constant: TRUE, false +" Float a floating point constant: 2.3e10 + +exe "hi! Identifier" .s:fmt_none .s:fg_blue .s:bg_none +" *Identifier any variable name +" Function function name (also: methods for classes) +" +exe "hi! Statement" .s:fmt_none .s:fg_green .s:bg_none +" *Statement any statement +" Conditional if, then, else, endif, switch, etc. +" Repeat for, do, while, etc. +" Label case, default, etc. +" Operator "sizeof", "+", "*", etc. +" Keyword any other keyword +" Exception try, catch, throw + +exe "hi! PreProc" .s:fmt_none .s:fg_orange .s:bg_none +" *PreProc generic Preprocessor +" Include preprocessor #include +" Define preprocessor #define +" Macro same as Define +" PreCondit preprocessor #if, #else, #endif, etc. + +exe "hi! Type" .s:fmt_none .s:fg_yellow .s:bg_none +" *Type int, long, char, etc. +" StorageClass static, register, volatile, etc. +" Structure struct, union, enum, etc. +" Typedef A typedef + +exe "hi! Special" .s:fmt_none .s:fg_red .s:bg_none +" *Special any special symbol +" SpecialChar special character in a constant +" Tag you can use CTRL-] on this +" Delimiter character that needs attention +" SpecialComment special things inside a comment +" Debug debugging statements + +exe "hi! Underlined" .s:fmt_none .s:fg_violet .s:bg_none +" *Underlined text that stands out, HTML links + +exe "hi! Ignore" .s:fmt_none .s:fg_none .s:bg_none +" *Ignore left blank, hidden |hl-Ignore| + +exe "hi! Error" .s:fmt_bold .s:fg_red .s:bg_none +" *Error any erroneous construct + +exe "hi! Todo" .s:fmt_bold .s:fg_magenta.s:bg_none +" *Todo anything that needs extra attention; mostly the +" keywords TODO FIXME and XXX +" +"}}} +" Extended highlighting "{{{ +" --------------------------------------------------------------------- +if (g:solarized_visibility=="high") + exe "hi! SpecialKey" .s:fmt_revr .s:fg_red .s:bg_none + exe "hi! NonText" .s:fmt_bold .s:fg_red .s:bg_none +elseif (g:solarized_visibility=="low") + exe "hi! SpecialKey" .s:fmt_bold .s:fg_base02 .s:bg_none + exe "hi! NonText" .s:fmt_bold .s:fg_base02 .s:bg_none +else + exe "hi! SpecialKey" .s:fmt_bold .s:fg_base00 .s:bg_base02 + exe "hi! NonText" .s:fmt_bold .s:fg_base00 .s:bg_none +endif +exe "hi! StatusLine" .s:fmt_none .s:fg_base1 .s:bg_base02 .s:fmt_revbb +exe "hi! StatusLineNC" .s:fmt_none .s:fg_base00 .s:bg_base02 .s:fmt_revbb +exe "hi! Visual" .s:fmt_none .s:fg_base01 .s:bg_base03 .s:fmt_revbb +exe "hi! Directory" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! ErrorMsg" .s:fmt_revr .s:fg_red .s:bg_none +exe "hi! IncSearch" .s:fmt_stnd .s:fg_orange .s:bg_none +exe "hi! Search" .s:fmt_revr .s:fg_yellow .s:bg_none +exe "hi! MoreMsg" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! ModeMsg" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! LineNr" .s:fmt_none .s:fg_base01 .s:bg_base02 +exe "hi! Question" .s:fmt_bold .s:fg_cyan .s:bg_none +if ( has("gui_running") || &t_Co > 8 ) + exe "hi! VertSplit" .s:fmt_none .s:fg_base00 .s:bg_base00 +else + exe "hi! VertSplit" .s:fmt_revbb .s:fg_base00 .s:bg_base02 +endif +exe "hi! Title" .s:fmt_bold .s:fg_orange .s:bg_none +exe "hi! VisualNOS" .s:fmt_stnd .s:fg_none .s:bg_base02 .s:fmt_revbb +exe "hi! WarningMsg" .s:fmt_bold .s:fg_red .s:bg_none +exe "hi! WildMenu" .s:fmt_none .s:fg_base2 .s:bg_base02 .s:fmt_revbb +exe "hi! Folded" .s:fmt_undb .s:fg_base0 .s:bg_base02 .s:sp_base03 +exe "hi! FoldColumn" .s:fmt_none .s:fg_base0 .s:bg_base02 +if (g:solarized_diffmode=="high") +exe "hi! DiffAdd" .s:fmt_revr .s:fg_green .s:bg_none +exe "hi! DiffChange" .s:fmt_revr .s:fg_yellow .s:bg_none +exe "hi! DiffDelete" .s:fmt_revr .s:fg_red .s:bg_none +exe "hi! DiffText" .s:fmt_revr .s:fg_blue .s:bg_none +elseif (g:solarized_diffmode=="low") +exe "hi! DiffAdd" .s:fmt_undr .s:fg_green .s:bg_none .s:sp_green +exe "hi! DiffChange" .s:fmt_undr .s:fg_yellow .s:bg_none .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_bold .s:fg_red .s:bg_none +exe "hi! DiffText" .s:fmt_undr .s:fg_blue .s:bg_none .s:sp_blue +else " normal + if has("gui_running") +exe "hi! DiffAdd" .s:fmt_bold .s:fg_green .s:bg_base02 .s:sp_green +exe "hi! DiffChange" .s:fmt_bold .s:fg_yellow .s:bg_base02 .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_bold .s:fg_red .s:bg_base02 +exe "hi! DiffText" .s:fmt_bold .s:fg_blue .s:bg_base02 .s:sp_blue + else +exe "hi! DiffAdd" .s:fmt_none .s:fg_green .s:bg_base02 .s:sp_green +exe "hi! DiffChange" .s:fmt_none .s:fg_yellow .s:bg_base02 .s:sp_yellow +exe "hi! DiffDelete" .s:fmt_none .s:fg_red .s:bg_base02 +exe "hi! DiffText" .s:fmt_none .s:fg_blue .s:bg_base02 .s:sp_blue + endif +endif +exe "hi! SignColumn" .s:fmt_none .s:fg_base0 +exe "hi! Conceal" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! SpellBad" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_red +exe "hi! SpellCap" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_violet +exe "hi! SpellRare" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_cyan +exe "hi! SpellLocal" .s:fmt_curl .s:fg_none .s:bg_none .s:sp_yellow +exe "hi! Pmenu" .s:fmt_none .s:fg_base0 .s:bg_base02 .s:fmt_revbb +exe "hi! PmenuSel" .s:fmt_none .s:fg_base01 .s:bg_base2 .s:fmt_revbb +exe "hi! PmenuSbar" .s:fmt_none .s:fg_base2 .s:bg_base0 .s:fmt_revbb +exe "hi! PmenuThumb" .s:fmt_none .s:fg_base0 .s:bg_base03 .s:fmt_revbb +exe "hi! TabLine" .s:fmt_undr .s:fg_base0 .s:bg_base02 .s:sp_base0 +exe "hi! TabLineFill" .s:fmt_undr .s:fg_base0 .s:bg_base02 .s:sp_base0 +exe "hi! TabLineSel" .s:fmt_undr .s:fg_base01 .s:bg_base2 .s:sp_base0 .s:fmt_revbbu +exe "hi! CursorColumn" .s:fmt_none .s:fg_none .s:bg_base02 +exe "hi! CursorLine" .s:fmt_uopt .s:fg_none .s:bg_base02 .s:sp_base1 +exe "hi! ColorColumn" .s:fmt_none .s:fg_none .s:bg_base02 +exe "hi! Cursor" .s:fmt_none .s:fg_base03 .s:bg_base0 +hi! link lCursor Cursor +exe "hi! MatchParen" .s:fmt_bold .s:fg_red .s:bg_base01 + +"}}} +" vim syntax highlighting "{{{ +" --------------------------------------------------------------------- +"exe "hi! vimLineComment" . s:fg_base01 .s:bg_none .s:fmt_ital +"hi! link vimComment Comment +"hi! link vimLineComment Comment +hi! link vimVar Identifier +hi! link vimFunc Function +hi! link vimUserFunc Function +hi! link helpSpecial Special +hi! link vimSet Normal +hi! link vimSetEqual Normal +exe "hi! vimCommentString" .s:fmt_none .s:fg_violet .s:bg_none +exe "hi! vimCommand" .s:fmt_none .s:fg_yellow .s:bg_none +exe "hi! vimCmdSep" .s:fmt_bold .s:fg_blue .s:bg_none +exe "hi! helpExample" .s:fmt_none .s:fg_base1 .s:bg_none +exe "hi! helpOption" .s:fmt_none .s:fg_cyan .s:bg_none +exe "hi! helpNote" .s:fmt_none .s:fg_magenta.s:bg_none +exe "hi! helpVim" .s:fmt_none .s:fg_magenta.s:bg_none +exe "hi! helpHyperTextJump" .s:fmt_undr .s:fg_blue .s:bg_none +exe "hi! helpHyperTextEntry".s:fmt_none .s:fg_green .s:bg_none +exe "hi! vimIsCommand" .s:fmt_none .s:fg_base00 .s:bg_none +exe "hi! vimSynMtchOpt" .s:fmt_none .s:fg_yellow .s:bg_none +exe "hi! vimSynType" .s:fmt_none .s:fg_cyan .s:bg_none +exe "hi! vimHiLink" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! vimHiGroup" .s:fmt_none .s:fg_blue .s:bg_none +exe "hi! vimGroup" .s:fmt_undb .s:fg_blue .s:bg_none +"}}} +" diff highlighting "{{{ +" --------------------------------------------------------------------- +hi! link diffAdded Statement +hi! link diffLine Identifier +"}}} +" git & gitcommit highlighting "{{{ +"git +"exe "hi! gitDateHeader" +"exe "hi! gitIdentityHeader" +"exe "hi! gitIdentityKeyword" +"exe "hi! gitNotesHeader" +"exe "hi! gitReflogHeader" +"exe "hi! gitKeyword" +"exe "hi! gitIdentity" +"exe "hi! gitEmailDelimiter" +"exe "hi! gitEmail" +"exe "hi! gitDate" +"exe "hi! gitMode" +"exe "hi! gitHashAbbrev" +"exe "hi! gitHash" +"exe "hi! gitReflogMiddle" +"exe "hi! gitReference" +"exe "hi! gitStage" +"exe "hi! gitType" +"exe "hi! gitDiffAdded" +"exe "hi! gitDiffRemoved" +"gitcommit +"exe "hi! gitcommitSummary" +exe "hi! gitcommitComment" .s:fmt_ital .s:fg_base01 .s:bg_none +hi! link gitcommitUntracked gitcommitComment +hi! link gitcommitDiscarded gitcommitComment +hi! link gitcommitSelected gitcommitComment +exe "hi! gitcommitUnmerged" .s:fmt_bold .s:fg_green .s:bg_none +exe "hi! gitcommitOnBranch" .s:fmt_bold .s:fg_base01 .s:bg_none +exe "hi! gitcommitBranch" .s:fmt_bold .s:fg_magenta .s:bg_none +hi! link gitcommitNoBranch gitcommitBranch +exe "hi! gitcommitDiscardedType".s:fmt_none .s:fg_red .s:bg_none +exe "hi! gitcommitSelectedType" .s:fmt_none .s:fg_green .s:bg_none +"exe "hi! gitcommitUnmergedType" +"exe "hi! gitcommitType" +"exe "hi! gitcommitNoChanges" +"exe "hi! gitcommitHeader" +exe "hi! gitcommitHeader" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! gitcommitUntrackedFile".s:fmt_bold .s:fg_cyan .s:bg_none +exe "hi! gitcommitDiscardedFile".s:fmt_bold .s:fg_red .s:bg_none +exe "hi! gitcommitSelectedFile" .s:fmt_bold .s:fg_green .s:bg_none +exe "hi! gitcommitUnmergedFile" .s:fmt_bold .s:fg_yellow .s:bg_none +exe "hi! gitcommitFile" .s:fmt_bold .s:fg_base0 .s:bg_none +hi! link gitcommitDiscardedArrow gitcommitDiscardedFile +hi! link gitcommitSelectedArrow gitcommitSelectedFile +hi! link gitcommitUnmergedArrow gitcommitUnmergedFile +"exe "hi! gitcommitArrow" +"exe "hi! gitcommitOverflow" +"exe "hi! gitcommitBlank" +" }}} +" html highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! htmlTag" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! htmlEndTag" .s:fmt_none .s:fg_base01 .s:bg_none +exe "hi! htmlTagN" .s:fmt_bold .s:fg_base1 .s:bg_none +exe "hi! htmlTagName" .s:fmt_bold .s:fg_blue .s:bg_none +exe "hi! htmlSpecialTagName".s:fmt_ital .s:fg_blue .s:bg_none +exe "hi! htmlArg" .s:fmt_none .s:fg_base00 .s:bg_none +exe "hi! javaScript" .s:fmt_none .s:fg_yellow .s:bg_none +"}}} +" perl highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! perlHereDoc" . s:fg_base1 .s:bg_back .s:fmt_none +exe "hi! perlVarPlain" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! perlStatementFileDesc". s:fg_cyan.s:bg_back.s:fmt_none + +"}}} +" tex highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! texStatement" . s:fg_cyan .s:bg_back .s:fmt_none +exe "hi! texMathZoneX" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texMathMatcher" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texMathMatcher" . s:fg_yellow .s:bg_back .s:fmt_none +exe "hi! texRefLabel" . s:fg_yellow .s:bg_back .s:fmt_none +"}}} +" ruby highlighting "{{{ +" --------------------------------------------------------------------- +exe "hi! rubyDefine" . s:fg_base1 .s:bg_back .s:fmt_bold +"rubyInclude +"rubySharpBang +"rubyAccess +"rubyPredefinedVariable +"rubyBoolean +"rubyClassVariable +"rubyBeginEnd +"rubyRepeatModifier +"hi! link rubyArrayDelimiter Special " [ , , ] +"rubyCurlyBlock { , , } + +"hi! link rubyClass Keyword +"hi! link rubyModule Keyword +"hi! link rubyKeyword Keyword +"hi! link rubyOperator Operator +"hi! link rubyIdentifier Identifier +"hi! link rubyInstanceVariable Identifier +"hi! link rubyGlobalVariable Identifier +"hi! link rubyClassVariable Identifier +"hi! link rubyConstant Type +"}}} +" haskell syntax highlighting"{{{ +" --------------------------------------------------------------------- +" For use with syntax/haskell.vim : Haskell Syntax File +" http://www.vim.org/scripts/script.php?script_id=3034 +" See also Steffen Siering's github repository: +" http://github.com/urso/dotrc/blob/master/vim/syntax/haskell.vim +" --------------------------------------------------------------------- +" +" Treat True and False specially, see the plugin referenced above +let hs_highlight_boolean=1 +" highlight delims, see the plugin referenced above +let hs_highlight_delimiters=1 + +exe "hi! cPreCondit". s:fg_orange.s:bg_none .s:fmt_none + +exe "hi! VarId" . s:fg_blue .s:bg_none .s:fmt_none +exe "hi! ConId" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hsImport" . s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! hsString" . s:fg_base00 .s:bg_none .s:fmt_none + +exe "hi! hsStructure" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hs_hlFunctionName" . s:fg_blue .s:bg_none +exe "hi! hsStatement" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsImportLabel" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hs_OpFunctionName" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hs_DeclareFunction" . s:fg_orange .s:bg_none .s:fmt_none +exe "hi! hsVarSym" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsType" . s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! hsTypedef" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsModuleName" . s:fg_green .s:bg_none .s:fmt_undr +exe "hi! hsModuleStartLabel" . s:fg_magenta.s:bg_none .s:fmt_none +hi! link hsImportParams Delimiter +hi! link hsDelimTypeExport Delimiter +hi! link hsModuleStartLabel hsStructure +hi! link hsModuleWhereLabel hsModuleStartLabel + +" following is for the haskell-conceal plugin +" the first two items don't have an impact, but better safe +exe "hi! hsNiceOperator" . s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! hsniceoperator" . s:fg_cyan .s:bg_none .s:fmt_none + +"}}} +" pandoc markdown syntax highlighting "{{{ +" --------------------------------------------------------------------- + +"PandocHiLink pandocNormalBlock +exe "hi! pandocTitleBlock" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocTitleBlockTitle" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocTitleComment" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocComment" .s:fg_base01 .s:bg_none .s:fmt_ital +exe "hi! pandocVerbatimBlock" .s:fg_yellow .s:bg_none .s:fmt_none +hi! link pandocVerbatimBlockDeep pandocVerbatimBlock +hi! link pandocCodeBlock pandocVerbatimBlock +hi! link pandocCodeBlockDelim pandocVerbatimBlock +exe "hi! pandocBlockQuote" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader1" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader2" .s:fg_cyan .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader3" .s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader4" .s:fg_red .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader5" .s:fg_base0 .s:bg_none .s:fmt_none +exe "hi! pandocBlockQuoteLeader6" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocListMarker" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocListReference" .s:fg_magenta.s:bg_none .s:fmt_undr + +" Definitions +" --------------------------------------------------------------------- +let s:fg_pdef = s:fg_violet +exe "hi! pandocDefinitionBlock" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocDefinitionTerm" .s:fg_pdef .s:bg_none .s:fmt_stnd +exe "hi! pandocDefinitionIndctr" .s:fg_pdef .s:bg_none .s:fmt_bold +exe "hi! pandocEmphasisDefinition" .s:fg_pdef .s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNestedDefinition" .s:fg_pdef .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisDefinition" .s:fg_pdef .s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNestedDefinition" .s:fg_pdef.s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisDefinition" .s:fg_pdef.s:bg_none.s:fmt_bldi +exe "hi! pandocStrikeoutDefinition" .s:fg_pdef .s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInlineDefinition" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocSuperscriptDefinition" .s:fg_pdef .s:bg_none .s:fmt_none +exe "hi! pandocSubscriptDefinition" .s:fg_pdef .s:bg_none .s:fmt_none + +" Tables +" --------------------------------------------------------------------- +let s:fg_ptable = s:fg_blue +exe "hi! pandocTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocTableStructure" .s:fg_ptable.s:bg_none .s:fmt_none +hi! link pandocTableStructureTop pandocTableStructre +hi! link pandocTableStructureEnd pandocTableStructre +exe "hi! pandocTableZebraLight" .s:fg_ptable.s:bg_base03.s:fmt_none +exe "hi! pandocTableZebraDark" .s:fg_ptable.s:bg_base02.s:fmt_none +exe "hi! pandocEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNestedTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNestedTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisTable" .s:fg_ptable.s:bg_none .s:fmt_bldi +exe "hi! pandocStrikeoutTable" .s:fg_ptable.s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInlineTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocSuperscriptTable" .s:fg_ptable.s:bg_none .s:fmt_none +exe "hi! pandocSubscriptTable" .s:fg_ptable.s:bg_none .s:fmt_none + +" Headings +" --------------------------------------------------------------------- +let s:fg_phead = s:fg_orange +exe "hi! pandocHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocHeadingMarker" .s:fg_yellow.s:bg_none.s:fmt_bold +exe "hi! pandocEmphasisHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocEmphasisNestedHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocStrongEmphasisNestedHeading" .s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasisHeading".s:fg_phead .s:bg_none.s:fmt_bldi +exe "hi! pandocStrikeoutHeading" .s:fg_phead .s:bg_none.s:fmt_revr +exe "hi! pandocVerbatimInlineHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocSuperscriptHeading" .s:fg_phead .s:bg_none.s:fmt_bold +exe "hi! pandocSubscriptHeading" .s:fg_phead .s:bg_none.s:fmt_bold + +" Links +" --------------------------------------------------------------------- +exe "hi! pandocLinkDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocLinkLabel" .s:fg_blue .s:bg_none .s:fmt_undr +exe "hi! pandocLinkText" .s:fg_blue .s:bg_none .s:fmt_undb +exe "hi! pandocLinkURL" .s:fg_base00 .s:bg_none .s:fmt_undr +exe "hi! pandocLinkTitle" .s:fg_base00 .s:bg_none .s:fmt_undi +exe "hi! pandocLinkTitleDelim" .s:fg_base01 .s:bg_none .s:fmt_undi .s:sp_base00 +exe "hi! pandocLinkDefinition" .s:fg_cyan .s:bg_none .s:fmt_undr .s:sp_base00 +exe "hi! pandocLinkDefinitionID" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocImageCaption" .s:fg_violet .s:bg_none .s:fmt_undb +exe "hi! pandocFootnoteLink" .s:fg_green .s:bg_none .s:fmt_undr +exe "hi! pandocFootnoteDefLink" .s:fg_green .s:bg_none .s:fmt_bold +exe "hi! pandocFootnoteInline" .s:fg_green .s:bg_none .s:fmt_undb +exe "hi! pandocFootnote" .s:fg_green .s:bg_none .s:fmt_none +exe "hi! pandocCitationDelim" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocCitation" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocCitationID" .s:fg_magenta.s:bg_none .s:fmt_undr +exe "hi! pandocCitationRef" .s:fg_magenta.s:bg_none .s:fmt_none + +" Main Styles +" --------------------------------------------------------------------- +exe "hi! pandocStyleDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocEmphasis" .s:fg_base0 .s:bg_none .s:fmt_ital +exe "hi! pandocEmphasisNested" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasis" .s:fg_base0 .s:bg_none .s:fmt_bold +exe "hi! pandocStrongEmphasisNested" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrongEmphasisEmphasis" .s:fg_base0 .s:bg_none .s:fmt_bldi +exe "hi! pandocStrikeout" .s:fg_base01 .s:bg_none .s:fmt_revr +exe "hi! pandocVerbatimInline" .s:fg_yellow .s:bg_none .s:fmt_none +exe "hi! pandocSuperscript" .s:fg_violet .s:bg_none .s:fmt_none +exe "hi! pandocSubscript" .s:fg_violet .s:bg_none .s:fmt_none + +exe "hi! pandocRule" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocRuleLine" .s:fg_blue .s:bg_none .s:fmt_bold +exe "hi! pandocEscapePair" .s:fg_red .s:bg_none .s:fmt_bold +exe "hi! pandocCitationRef" .s:fg_magenta.s:bg_none .s:fmt_none +exe "hi! pandocNonBreakingSpace" . s:fg_red .s:bg_none .s:fmt_revr +hi! link pandocEscapedCharacter pandocEscapePair +hi! link pandocLineBreak pandocEscapePair + +" Embedded Code +" --------------------------------------------------------------------- +exe "hi! pandocMetadataDelim" .s:fg_base01 .s:bg_none .s:fmt_none +exe "hi! pandocMetadata" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocMetadataKey" .s:fg_blue .s:bg_none .s:fmt_none +exe "hi! pandocMetadata" .s:fg_blue .s:bg_none .s:fmt_bold +hi! link pandocMetadataTitle pandocMetadata + +"}}} +" Utility autocommand "{{{ +" --------------------------------------------------------------------- +" In cases where Solarized is initialized inside a terminal vim session and +" then transferred to a gui session via the command `:gui`, the gui vim process +" does not re-read the colorscheme (or .vimrc for that matter) so any `has_gui` +" related code that sets gui specific values isn't executed. +" +" Currently, Solarized sets only the cterm or gui values for the colorscheme +" depending on gui or terminal mode. It's possible that, if the following +" autocommand method is deemed excessively poor form, that approach will be +" used again and the autocommand below will be dropped. +" +" However it seems relatively benign in this case to include the autocommand +" here. It fires only in cases where vim is transferring from terminal to gui +" mode (detected with the script scope s:vmode variable). It also allows for +" other potential terminal customizations that might make gui mode suboptimal. +" +autocmd GUIEnter * if (s:vmode != "gui") | exe "colorscheme " . g:colors_name | endif +"}}} +" Highlight Trailing Space {{{ +" Experimental: Different highlight when on cursorline +function! s:SolarizedHiTrail() + if g:solarized_hitrail==0 + hi! clear solarizedTrailingSpace + else + syn match solarizedTrailingSpace "\s*$" + exe "hi! solarizedTrailingSpace " .s:fmt_undr .s:fg_red .s:bg_none .s:sp_red + endif +endfunction +augroup SolarizedHiTrail + autocmd! + if g:solarized_hitrail==1 + autocmd! Syntax * call s:SolarizedHiTrail() + autocmd! ColorScheme * if g:colors_name == "solarized" | call s:SolarizedHiTrail() | else | augroup! s:SolarizedHiTrail | endif + endif +augroup END +" }}} +" Menus "{{{ +" --------------------------------------------------------------------- +" Turn off Solarized menu by including the following assignment in your .vimrc: +" +" let g:solarized_menu=0 + +function! s:SolarizedOptions() + new "new buffer + setf vim "vim filetype + let failed = append(0, s:defaults_list) + let failed = append(0, s:colorscheme_list) + let failed = append(0, s:options_list) + let failed = append(0, s:lazycat_list) + 0 "jump back to the top +endfunction +if !exists(":SolarizedOptions") + command SolarizedOptions :call s:SolarizedOptions() +endif + +function! SolarizedMenu() + if exists("g:loaded_solarized_menu") + try + silent! aunmenu Solarized + endtry + endif + let g:loaded_solarized_menu = 1 + + if g:colors_name == "solarized" && g:solarized_menu != 0 + + amenu &Solarized.&Contrast.&Low\ Contrast :let g:solarized_contrast="low" \| colorscheme solarized<CR> + amenu &Solarized.&Contrast.&Normal\ Contrast :let g:solarized_contrast="normal" \| colorscheme solarized<CR> + amenu &Solarized.&Contrast.&High\ Contrast :let g:solarized_contrast="high" \| colorscheme solarized<CR> + an &Solarized.&Contrast.-sep- <Nop> + amenu &Solarized.&Contrast.&Help:\ Contrast :help 'solarized_contrast'<CR> + + amenu &Solarized.&Visibility.&Low\ Visibility :let g:solarized_visibility="low" \| colorscheme solarized<CR> + amenu &Solarized.&Visibility.&Normal\ Visibility :let g:solarized_visibility="normal" \| colorscheme solarized<CR> + amenu &Solarized.&Visibility.&High\ Visibility :let g:solarized_visibility="high" \| colorscheme solarized<CR> + an &Solarized.&Visibility.-sep- <Nop> + amenu &Solarized.&Visibility.&Help:\ Visibility :help 'solarized_visibility'<CR> + + amenu &Solarized.&Background.&Toggle\ Background :ToggleBG<CR> + amenu &Solarized.&Background.&Dark\ Background :set background=dark \| colorscheme solarized<CR> + amenu &Solarized.&Background.&Light\ Background :set background=light \| colorscheme solarized<CR> + an &Solarized.&Background.-sep- <Nop> + amenu &Solarized.&Background.&Help:\ ToggleBG :help togglebg<CR> + + if g:solarized_bold==0 | let l:boldswitch="On" | else | let l:boldswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Bold\\ ".l:boldswitch." :let g:solarized_bold=(abs(g:solarized_bold-1)) \\| colorscheme solarized<CR>" + if g:solarized_italic==0 | let l:italicswitch="On" | else | let l:italicswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Italic\\ ".l:italicswitch." :let g:solarized_italic=(abs(g:solarized_italic-1)) \\| colorscheme solarized<CR>" + if g:solarized_underline==0 | let l:underlineswitch="On" | else | let l:underlineswitch="Off" | endif + exe "amenu &Solarized.&Styling.&Turn\\ Underline\\ ".l:underlineswitch." :let g:solarized_underline=(abs(g:solarized_underline-1)) \\| colorscheme solarized<CR>" + + amenu &Solarized.&Diff\ Mode.&Low\ Diff\ Mode :let g:solarized_diffmode="low" \| colorscheme solarized<CR> + amenu &Solarized.&Diff\ Mode.&Normal\ Diff\ Mode :let g:solarized_diffmode="normal" \| colorscheme solarized<CR> + amenu &Solarized.&Diff\ Mode.&High\ Diff\ Mode :let g:solarized_diffmode="high" \| colorscheme solarized<CR> + + if g:solarized_hitrail==0 | let l:hitrailswitch="On" | else | let l:hitrailswitch="Off" | endif + exe "amenu &Solarized.&Experimental.&Turn\\ Highlight\\ Trailing\\ Spaces\\ ".l:hitrailswitch." :let g:solarized_hitrail=(abs(g:solarized_hitrail-1)) \\| colorscheme solarized<CR>" + an &Solarized.&Experimental.-sep- <Nop> + amenu &Solarized.&Experimental.&Help:\ HiTrail :help 'solarized_hitrail'<CR> + + an &Solarized.-sep1- <Nop> + + amenu &Solarized.&Autogenerate\ options :SolarizedOptions<CR> + + an &Solarized.-sep2- <Nop> + + amenu &Solarized.&Help.&Solarized\ Help :help solarized<CR> + amenu &Solarized.&Help.&Toggle\ Background\ Help :help togglebg<CR> + amenu &Solarized.&Help.&Removing\ This\ Menu :help solarized-menu<CR> + + an 9999.77 &Help.&Solarized\ Colorscheme :help solarized<CR> + an 9999.78 &Help.&Toggle\ Background :help togglebg<CR> + an 9999.79 &Help.-sep3- <Nop> + + endif +endfunction + +autocmd ColorScheme * if g:colors_name != "solarized" | silent! aunmenu Solarized | else | call SolarizedMenu() | endif + +"}}} +" License "{{{ +" --------------------------------------------------------------------- +" +" Copyright (c) 2011 Ethan Schoonover +" +" Permission is hereby granted, free of charge, to any person obtaining a copy +" of this software and associated documentation files (the "Software"), to deal +" in the Software without restriction, including without limitation the rights +" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +" copies of the Software, and to permit persons to whom the Software is +" furnished to do so, subject to the following conditions: +" +" The above copyright notice and this permission notice shall be included in +" all copies or substantial portions of the Software. +" +" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +" THE SOFTWARE. +" +" vim:foldmethod=marker:foldlevel=0 +"}}} diff --git a/dotfiles/.local/share/nvim/site/colors/ultramar.vim b/dotfiles/.local/share/nvim/site/colors/ultramar.vim new file mode 100644 index 0000000..7dd6673 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/colors/ultramar.vim @@ -0,0 +1,1393 @@ +" ----------------------------------------------------------------------------- +" File: ultramar.vim +" Description: Ultramar color scheme for vim +" Author: Yaroslav de la Peña Smirnov <contact@yaroslavps.com> +" Source: https://github.com/Yaroslav-95/ultramar +" Last Modified: 14 Nov 2019 +" ----------------------------------------------------------------------------- + +" Supporting code ------------------------------------------------------------- +" Initialisation: {{{ + +if version > 580 + hi clear + if exists("syntax_on") + syntax reset + endif +endif + +let g:colors_name='ultramar' + +if !(has('termguicolors') && &termguicolors) && !has('gui_running') && &t_Co != 256 + finish +endif + +" }}} +" Global Settings: {{{ + +if !exists('g:ultramar_bold') + let g:ultramar_bold=1 +endif +if !exists('g:ultramar_italic') + if has('gui_running') || $TERM_ITALICS == 'true' + let g:ultramar_italic=1 + else + let g:ultramar_italic=0 + endif +endif +if !exists('g:ultramar_undercurl') + let g:ultramar_undercurl=1 +endif +if !exists('g:ultramar_underline') + let g:ultramar_underline=1 +endif +if !exists('g:ultramar_inverse') + let g:ultramar_inverse=1 +endif + +if !exists('g:ultramar_guisp_fallback') || index(['fg', 'bg'], g:ultramar_guisp_fallback) == -1 + let g:ultramar_guisp_fallback='NONE' +endif + +if !exists('g:ultramar_improved_strings') + let g:ultramar_improved_strings=0 +endif + +if !exists('g:ultramar_improved_warnings') + let g:ultramar_improved_warnings=0 +endif + +if !exists('g:ultramar_termcolors') + let g:ultramar_termcolors=256 +endif + +if !exists('g:ultramar_invert_indent_guides') + let g:ultramar_invert_indent_guides=0 +endif + +if exists('g:ultramar_contrast') + echo 'g:ultramar_contrast is deprecated; use g:ultramar_contrast_light and g:ultramar_contrast_dark instead' +endif + +if !exists('g:ultramar_contrast_dark') + let g:ultramar_contrast_dark='medium' +endif + +if !exists('g:ultramar_contrast_light') + let g:ultramar_contrast_light='medium' +endif + +let s:is_dark=(&background == 'dark') + +" }}} +" Palette: {{{ + +" setup palette dictionary +let s:palette = {} + +" fill it with absolute colors +let s:palette.dark0_hard = ['#1d2021', 234] " 29-32-33 +let s:palette.dark0 = ['#1b1e25', 235] " 40-40-40 +let s:palette.dark0_soft = ['#3b4252', 236] " 50-48-47 +let s:palette.dark1 = ['#3b4252', 237] " 60-56-54 +let s:palette.dark2 = ['#434c5e', 239] " 80-73-69 +let s:palette.dark3 = ['#434c5e', 241] " 102-92-84 +let s:palette.dark4 = ['#697792', 243] " 124-111-100 +let s:palette.dark4_256 = ['#697792', 243] " 124-111-100 + +let s:palette.gray_245 = ['#9197a5', 245] " 146-131-116 +let s:palette.gray_244 = ['#9197a5', 244] " 146-131-116 + +let s:palette.light0_hard = ['#fbf1c7', 230] " 249-245-215 +let s:palette.light0 = ['#fbf1c7', 229] " 253-244-193 +let s:palette.light0_soft = ['#f9f5d7', 228] " 242-229-188 +let s:palette.light1 = ['#e5e9f0', 223] " 235-219-178 +let s:palette.light2 = ['#e5e9f0', 250] " 213-196-161 +let s:palette.light3 = ['#d8dee9', 248] " 189-174-147 +let s:palette.light4 = ['#d8dee9', 246] " 168-153-132 +let s:palette.light4_256 = ['#d8dee9', 246] " 168-153-132 + +let s:palette.bright_red = ['#c45c5c', 167] " 251-73-52 +let s:palette.bright_green = ['#9eba86', 142] " 184-187-38 +let s:palette.bright_yellow = ['#e2b55a', 214] " 250-189-47 +let s:palette.bright_blue = ['#81acc1', 109] " 131-165-152 +let s:palette.bright_purple = ['#b48ead', 175] " 211-134-155 +let s:palette.bright_aqua = ['#89b6a0', 108] " 142-192-124 +let s:palette.bright_orange = ['#d08770', 208] " 254-128-25 + +let s:palette.neutral_red = ['#b73030', 124] " 204-36-29 +let s:palette.neutral_green = ['#7ea95a', 106] " 152-151-26 +let s:palette.neutral_yellow = ['#b2872f', 172] " 215-153-33 +let s:palette.neutral_blue = ['#3f6e90', 66] " 69-133-136 +let s:palette.neutral_purple = ['#9c6992', 132] " 177-98-134 +let s:palette.neutral_aqua = ['#5b8277', 72] " 104-157-106 +let s:palette.neutral_orange = ['#af5539', 166] " 214-93-14 + +let s:palette.faded_red = ['#b73030', 88] " 157-0-6 +let s:palette.faded_green = ['#7ea95a', 100] " 121-116-14 +let s:palette.faded_yellow = ['#b2872f', 136] " 181-118-20 +let s:palette.faded_blue = ['#3f6e90', 24] " 7-102-120 +let s:palette.faded_purple = ['#9c6992', 96] " 143-63-113 +let s:palette.faded_aqua = ['#5b8277', 66] " 66-123-88 +let s:palette.faded_orange = ['#af5539', 130] " 175-58-3 + +" }}} +" Setup Emphasis: {{{ + +let s:bold = 'bold,' +if g:ultramar_bold == 0 + let s:bold = '' +endif + +let s:italic = 'italic,' +if g:ultramar_italic == 0 + let s:italic = '' +endif + +let s:underline = 'underline,' +if g:ultramar_underline == 0 + let s:underline = '' +endif + +let s:undercurl = 'undercurl,' +if g:ultramar_undercurl == 0 + let s:undercurl = '' +endif + +let s:inverse = 'inverse,' +if g:ultramar_inverse == 0 + let s:inverse = '' +endif + +" }}} +" Setup Colors: {{{ + +let s:vim_bg = ['bg', 'bg'] +let s:vim_fg = ['fg', 'fg'] +let s:none = ['NONE', 'NONE'] + +" determine relative colors +if s:is_dark + let s:bg0 = s:palette.dark0 + if g:ultramar_contrast_dark == 'soft' + let s:bg0 = s:palette.dark0_soft + elseif g:ultramar_contrast_dark == 'hard' + let s:bg0 = s:palette.dark0_hard + endif + + let s:bg1 = s:palette.dark1 + let s:bg2 = s:palette.dark2 + let s:bg3 = s:palette.dark3 + let s:bg4 = s:palette.dark4 + + let s:gray = s:palette.gray_245 + + let s:fg0 = s:palette.light0 + let s:fg1 = s:palette.light1 + let s:fg2 = s:palette.light2 + let s:fg3 = s:palette.light3 + let s:fg4 = s:palette.light4 + + let s:fg4_256 = s:palette.light4_256 + + let s:red = s:palette.bright_red + let s:green = s:palette.bright_green + let s:yellow = s:palette.bright_yellow + let s:blue = s:palette.bright_blue + let s:purple = s:palette.bright_purple + let s:aqua = s:palette.bright_aqua + let s:orange = s:palette.bright_orange +else + let s:bg0 = s:palette.light0 + if g:ultramar_contrast_light == 'soft' + let s:bg0 = s:palette.light0_soft + elseif g:ultramar_contrast_light == 'hard' + let s:bg0 = s:palette.light0_hard + endif + + let s:bg1 = s:palette.light1 + let s:bg2 = s:palette.light2 + let s:bg3 = s:palette.light3 + let s:bg4 = s:palette.light4 + + let s:gray = s:palette.gray_244 + + let s:fg0 = s:palette.dark0 + let s:fg1 = s:palette.dark1 + let s:fg2 = s:palette.dark2 + let s:fg3 = s:palette.dark3 + let s:fg4 = s:palette.dark4 + + let s:fg4_256 = s:palette.dark4_256 + + let s:red = s:palette.faded_red + let s:green = s:palette.faded_green + let s:yellow = s:palette.faded_yellow + let s:blue = s:palette.faded_blue + let s:purple = s:palette.faded_purple + let s:aqua = s:palette.faded_aqua + let s:orange = s:palette.faded_orange +endif + +" reset to 16 colors fallback +if g:ultramar_termcolors == 16 + let s:bg0[1] = 0 + let s:fg4[1] = 7 + let s:gray[1] = 8 + let s:red[1] = 9 + let s:green[1] = 10 + let s:yellow[1] = 11 + let s:blue[1] = 12 + let s:purple[1] = 13 + let s:aqua[1] = 14 + let s:fg1[1] = 15 +endif + +" save current relative colors back to palette dictionary +let s:palette.bg0 = s:bg0 +let s:palette.bg1 = s:bg1 +let s:palette.bg2 = s:bg2 +let s:palette.bg3 = s:bg3 +let s:palette.bg4 = s:bg4 + +let s:palette.gray = s:gray + +let s:palette.fg0 = s:fg0 +let s:palette.fg1 = s:fg1 +let s:palette.fg2 = s:fg2 +let s:palette.fg3 = s:fg3 +let s:palette.fg4 = s:fg4 + +let s:palette.fg4_256 = s:fg4_256 + +let s:palette.red = s:red +let s:palette.green = s:green +let s:palette.yellow = s:yellow +let s:palette.blue = s:blue +let s:palette.purple = s:purple +let s:palette.aqua = s:aqua +let s:palette.orange = s:orange + +" }}} +" Setup Terminal Colors For Neovim: {{{ + +if has('nvim') + let g:terminal_color_0 = s:bg0[0] + let g:terminal_color_8 = s:gray[0] + + let g:terminal_color_1 = s:palette.neutral_red[0] + let g:terminal_color_9 = s:red[0] + + let g:terminal_color_2 = s:palette.neutral_green[0] + let g:terminal_color_10 = s:green[0] + + let g:terminal_color_3 = s:palette.neutral_yellow[0] + let g:terminal_color_11 = s:yellow[0] + + let g:terminal_color_4 = s:palette.neutral_blue[0] + let g:terminal_color_12 = s:blue[0] + + let g:terminal_color_5 = s:palette.neutral_purple[0] + let g:terminal_color_13 = s:purple[0] + + let g:terminal_color_6 = s:palette.neutral_aqua[0] + let g:terminal_color_14 = s:aqua[0] + + let g:terminal_color_7 = s:fg4[0] + let g:terminal_color_15 = s:fg1[0] +endif + +" }}} +" Overload Setting: {{{ + +let s:hls_cursor = s:orange +if exists('g:ultramar_hls_cursor') + let s:hls_cursor = get(s:palette, g:ultramar_hls_cursor) +endif + +let s:number_column = s:none +if exists('g:ultramar_number_column') + let s:number_column = get(s:palette, g:ultramar_number_column) +endif + +let s:sign_column = s:bg1 + +if exists('g:gitgutter_override_sign_column_highlight') && + \ g:gitgutter_override_sign_column_highlight == 1 + let s:sign_column = s:number_column +else + let g:gitgutter_override_sign_column_highlight = 0 + + if exists('g:ultramar_sign_column') + let s:sign_column = get(s:palette, g:ultramar_sign_column) + endif +endif + +let s:color_column = s:bg1 +if exists('g:ultramar_color_column') + let s:color_column = get(s:palette, g:ultramar_color_column) +endif + +let s:vert_split = s:bg0 +if exists('g:ultramar_vert_split') + let s:vert_split = get(s:palette, g:ultramar_vert_split) +endif + +let s:invert_signs = '' +if exists('g:ultramar_invert_signs') + if g:ultramar_invert_signs == 1 + let s:invert_signs = s:inverse + endif +endif + +let s:invert_selection = s:inverse +if exists('g:ultramar_invert_selection') + if g:ultramar_invert_selection == 0 + let s:invert_selection = '' + endif +endif + +let s:invert_tabline = '' +if exists('g:ultramar_invert_tabline') + if g:ultramar_invert_tabline == 1 + let s:invert_tabline = s:inverse + endif +endif + +let s:italicize_comments = s:italic +if exists('g:ultramar_italicize_comments') + if g:ultramar_italicize_comments == 0 + let s:italicize_comments = '' + endif +endif + +let s:italicize_strings = '' +if exists('g:ultramar_italicize_strings') + if g:ultramar_italicize_strings == 1 + let s:italicize_strings = s:italic + endif +endif + +" }}} +" Highlighting Function: {{{ + +function! s:HL(group, fg, ...) + " Arguments: group, guifg, guibg, gui, guisp + + " foreground + let fg = a:fg + + " background + if a:0 >= 1 + let bg = a:1 + else + let bg = s:none + endif + + " emphasis + if a:0 >= 2 && strlen(a:2) + let emstr = a:2 + else + let emstr = 'NONE,' + endif + + " special fallback + if a:0 >= 3 + if g:ultramar_guisp_fallback != 'NONE' + let fg = a:3 + endif + + " bg fallback mode should invert higlighting + if g:ultramar_guisp_fallback == 'bg' + let emstr .= 'inverse,' + endif + endif + + let histring = [ 'hi', a:group, + \ 'guifg=' . fg[0], 'ctermfg=' . fg[1], + \ 'guibg=none', 'ctermbg=' . bg[1], + \ 'gui=' . emstr[:-2], 'cterm=' . emstr[:-2] + \ ] + + " special + if a:0 >= 3 + call add(histring, 'guisp=' . a:3[0]) + endif + + execute join(histring, ' ') +endfunction + +" }}} +" Gruvbox Hi Groups: {{{ + +" memoize common hi groups +call s:HL('GruvboxFg0', s:fg0) +call s:HL('GruvboxFg1', s:fg1) +call s:HL('GruvboxFg2', s:fg2) +call s:HL('GruvboxFg3', s:fg3) +call s:HL('GruvboxFg4', s:fg4) +call s:HL('GruvboxGray', s:gray) +call s:HL('GruvboxBg0', s:bg0) +call s:HL('GruvboxBg1', s:bg1) +call s:HL('GruvboxBg2', s:bg2) +call s:HL('GruvboxBg3', s:bg3) +call s:HL('GruvboxBg4', s:bg4) + +call s:HL('GruvboxRed', s:red) +call s:HL('GruvboxRedBold', s:red, s:none, s:bold) +call s:HL('GruvboxGreen', s:green) +call s:HL('GruvboxGreenBold', s:green, s:none, s:bold) +call s:HL('GruvboxYellow', s:yellow) +call s:HL('GruvboxYellowBold', s:yellow, s:none, s:bold) +call s:HL('GruvboxBlue', s:blue) +call s:HL('GruvboxBlueBold', s:blue, s:none, s:bold) +call s:HL('GruvboxPurple', s:purple) +call s:HL('GruvboxPurpleBold', s:purple, s:none, s:bold) +call s:HL('GruvboxAqua', s:aqua) +call s:HL('GruvboxAquaBold', s:aqua, s:none, s:bold) +call s:HL('GruvboxOrange', s:orange) +call s:HL('GruvboxOrangeBold', s:orange, s:none, s:bold) + +call s:HL('GruvboxRedSign', s:red, s:sign_column, s:invert_signs) +call s:HL('GruvboxGreenSign', s:green, s:sign_column, s:invert_signs) +call s:HL('GruvboxYellowSign', s:yellow, s:sign_column, s:invert_signs) +call s:HL('GruvboxBlueSign', s:blue, s:sign_column, s:invert_signs) +call s:HL('GruvboxPurpleSign', s:purple, s:sign_column, s:invert_signs) +call s:HL('GruvboxAquaSign', s:aqua, s:sign_column, s:invert_signs) + +" }}} + +" Vanilla colorscheme --------------------------------------------------------- +" General UI: {{{ + +" Normal text +call s:HL('Normal', s:fg1, s:bg0) + +" Correct background (see issue #7): +" --- Problem with changing between dark and light on 256 color terminal +" --- https://github.com/morhetz/ultramar/issues/7 +if s:is_dark + set background=dark +else + set background=light +endif + +if version >= 700 + " Screen line that the cursor is + call s:HL('CursorLine', s:none, s:bg1) + " Screen column that the cursor is + hi! link CursorColumn CursorLine + + " Tab pages line filler + call s:HL('TabLineFill', s:bg4, s:bg1, s:invert_tabline) + " Active tab page label + call s:HL('TabLineSel', s:green, s:bg1, s:invert_tabline) + " Not active tab page label + hi! link TabLine TabLineFill + + " Match paired bracket under the cursor + call s:HL('MatchParen', s:none, s:bg3, s:bold) +endif + +if version >= 703 + " Highlighted screen columns + call s:HL('ColorColumn', s:none, s:color_column) + + " Concealed element: \lambda → λ + call s:HL('Conceal', s:blue, s:none) + + " Line number of CursorLine + call s:HL('CursorLineNr', s:yellow, s:bg1) +endif + +hi! link NonText GruvboxBg2 +hi! link SpecialKey GruvboxBg2 + +call s:HL('Visual', s:none, s:bg3, s:invert_selection) +hi! link VisualNOS Visual + +call s:HL('Search', s:yellow, s:bg0, s:inverse) +call s:HL('IncSearch', s:hls_cursor, s:bg0, s:inverse) + +call s:HL('Underlined', s:blue, s:none, s:underline) + +call s:HL('StatusLine', s:bg2, s:fg1, s:inverse) +call s:HL('StatusLineNC', s:bg1, s:fg4, s:inverse) + +" The column separating vertically split windows +call s:HL('VertSplit', s:bg3, s:vert_split) + +" Current match in wildmenu completion +call s:HL('WildMenu', s:blue, s:bg2, s:bold) + +" Directory names, special names in listing +hi! link Directory GruvboxGreenBold + +" Titles for output from :set all, :autocmd, etc. +hi! link Title GruvboxGreenBold + +" Error messages on the command line +call s:HL('ErrorMsg', s:bg0, s:red, s:bold) +" More prompt: -- More -- +hi! link MoreMsg GruvboxYellowBold +" Current mode message: -- INSERT -- +hi! link ModeMsg GruvboxYellowBold +" 'Press enter' prompt and yes/no questions +hi! link Question GruvboxOrangeBold +" Warning messages +hi! link WarningMsg GruvboxRedBold + +" }}} +" Gutter: {{{ + +" Line number for :number and :# commands +call s:HL('LineNr', s:bg4, s:number_column) + +" Column where signs are displayed +call s:HL('SignColumn', s:none, s:sign_column) + +" Line used for closed folds +call s:HL('Folded', s:gray, s:bg1, s:italic) +" Column where folds are displayed +call s:HL('FoldColumn', s:gray, s:bg1) + +" }}} +" Cursor: {{{ + +" Character under cursor +call s:HL('Cursor', s:none, s:none, s:inverse) +" Visual mode cursor, selection +hi! link vCursor Cursor +" Input moder cursor +hi! link iCursor Cursor +" Language mapping cursor +hi! link lCursor Cursor + +" }}} +" Syntax Highlighting: {{{ + +if g:ultramar_improved_strings == 0 + hi! link Special GruvboxOrange +else + call s:HL('Special', s:orange, s:bg1, s:italicize_strings) +endif + +call s:HL('Comment', s:gray, s:none, s:italicize_comments) +call s:HL('Todo', s:vim_fg, s:vim_bg, s:bold . s:italic) +call s:HL('Error', s:red, s:vim_bg, s:bold . s:inverse) + +" Generic statement +hi! link Statement GruvboxRed +" if, then, else, endif, swicth, etc. +hi! link Conditional GruvboxRed +" for, do, while, etc. +hi! link Repeat GruvboxRed +" case, default, etc. +hi! link Label GruvboxRed +" try, catch, throw +hi! link Exception GruvboxRed +" sizeof, "+", "*", etc. +hi! link Operator Normal +" Any other keyword +hi! link Keyword GruvboxRed + +" Variable name +hi! link Identifier GruvboxBlue +" Function name +hi! link Function GruvboxGreenBold + +" Generic preprocessor +hi! link PreProc GruvboxAqua +" Preprocessor #include +hi! link Include GruvboxAqua +" Preprocessor #define +hi! link Define GruvboxAqua +" Same as Define +hi! link Macro GruvboxAqua +" Preprocessor #if, #else, #endif, etc. +hi! link PreCondit GruvboxAqua + +" Generic constant +hi! link Constant GruvboxPurple +" Character constant: 'c', '/n' +hi! link Character GruvboxPurple +" String constant: "this is a string" +if g:ultramar_improved_strings == 0 + call s:HL('String', s:green, s:none, s:italicize_strings) +else + call s:HL('String', s:fg1, s:bg1, s:italicize_strings) +endif +" Boolean constant: TRUE, false +hi! link Boolean GruvboxPurple +" Number constant: 234, 0xff +hi! link Number GruvboxPurple +" Floating point constant: 2.3e10 +hi! link Float GruvboxPurple + +" Generic type +hi! link Type GruvboxYellow +" static, register, volatile, etc +hi! link StorageClass GruvboxOrange +" struct, union, enum, etc. +hi! link Structure GruvboxAqua +" typedef +hi! link Typedef GruvboxYellow + +" }}} +" Completion Menu: {{{ + +if version >= 700 + " Popup menu: normal item + call s:HL('Pmenu', s:fg1, s:bg2) + " Popup menu: selected item + call s:HL('PmenuSel', s:bg2, s:blue, s:bold) + " Popup menu: scrollbar + call s:HL('PmenuSbar', s:none, s:bg2) + " Popup menu: scrollbar thumb + call s:HL('PmenuThumb', s:none, s:bg4) +endif + +" }}} +" Diffs: {{{ + +call s:HL('DiffDelete', s:red, s:bg0, s:inverse) +call s:HL('DiffAdd', s:green, s:bg0, s:inverse) +"call s:HL('DiffChange', s:bg0, s:blue) +"call s:HL('DiffText', s:bg0, s:yellow) + +" Alternative setting +call s:HL('DiffChange', s:aqua, s:bg0, s:inverse) +call s:HL('DiffText', s:yellow, s:bg0, s:inverse) + +" }}} +" Spelling: {{{ + +if has("spell") + " Not capitalised word, or compile warnings + if g:ultramar_improved_warnings == 0 + call s:HL('SpellCap', s:none, s:none, s:undercurl, s:red) + else + call s:HL('SpellCap', s:green, s:none, s:bold . s:italic) + endif + " Not recognized word + call s:HL('SpellBad', s:none, s:none, s:undercurl, s:blue) + " Wrong spelling for selected region + call s:HL('SpellLocal', s:none, s:none, s:undercurl, s:aqua) + " Rare word + call s:HL('SpellRare', s:none, s:none, s:undercurl, s:purple) +endif + +" }}} + +" Plugin specific ------------------------------------------------------------- +" EasyMotion: {{{ + +hi! link EasyMotionTarget Search +hi! link EasyMotionShade Comment + +" }}} +" Sneak: {{{ + +hi! link Sneak Search +hi! link SneakLabel Search + +" }}} +" Indent Guides: {{{ + +if !exists('g:indent_guides_auto_colors') + let g:indent_guides_auto_colors = 0 +endif + +if g:indent_guides_auto_colors == 0 + if g:ultramar_invert_indent_guides == 0 + call s:HL('IndentGuidesOdd', s:vim_bg, s:bg2) + call s:HL('IndentGuidesEven', s:vim_bg, s:bg1) + else + call s:HL('IndentGuidesOdd', s:vim_bg, s:bg2, s:inverse) + call s:HL('IndentGuidesEven', s:vim_bg, s:bg3, s:inverse) + endif +endif + +" }}} +" IndentLine: {{{ + +if !exists('g:indentLine_color_term') + let g:indentLine_color_term = s:bg2[1] +endif +if !exists('g:indentLine_color_gui') + let g:indentLine_color_gui = s:bg2[0] +endif + +" }}} +" Rainbow Parentheses: {{{ + +if !exists('g:rbpt_colorpairs') + let g:rbpt_colorpairs = + \ [ + \ ['blue', '#458588'], ['magenta', '#b16286'], + \ ['red', '#cc241d'], ['166', '#d65d0e'] + \ ] +endif + +let g:rainbow_guifgs = [ '#d65d0e', '#cc241d', '#b16286', '#458588' ] +let g:rainbow_ctermfgs = [ '166', 'red', 'magenta', 'blue' ] + +if !exists('g:rainbow_conf') + let g:rainbow_conf = {} +endif +if !has_key(g:rainbow_conf, 'guifgs') + let g:rainbow_conf['guifgs'] = g:rainbow_guifgs +endif +if !has_key(g:rainbow_conf, 'ctermfgs') + let g:rainbow_conf['ctermfgs'] = g:rainbow_ctermfgs +endif + +let g:niji_dark_colours = g:rbpt_colorpairs +let g:niji_light_colours = g:rbpt_colorpairs + +"}}} +" GitGutter: {{{ + +hi! link GitGutterAdd GruvboxGreenSign +hi! link GitGutterChange GruvboxAquaSign +hi! link GitGutterDelete GruvboxRedSign +hi! link GitGutterChangeDelete GruvboxAquaSign + +" }}} +" GitCommit: "{{{ + +hi! link gitcommitSelectedFile GruvboxGreen +hi! link gitcommitDiscardedFile GruvboxRed + +" }}} +" Signify: {{{ + +hi! link SignifySignAdd GruvboxGreenSign +hi! link SignifySignChange GruvboxAquaSign +hi! link SignifySignDelete GruvboxRedSign + +" }}} +" Syntastic: {{{ + +call s:HL('SyntasticError', s:none, s:none, s:undercurl, s:red) +call s:HL('SyntasticWarning', s:none, s:none, s:undercurl, s:yellow) + +hi! link SyntasticErrorSign GruvboxRedSign +hi! link SyntasticWarningSign GruvboxYellowSign + +" }}} +" Signature: {{{ +hi! link SignatureMarkText GruvboxBlueSign +hi! link SignatureMarkerText GruvboxPurpleSign + +" }}} +" ShowMarks: {{{ + +hi! link ShowMarksHLl GruvboxBlueSign +hi! link ShowMarksHLu GruvboxBlueSign +hi! link ShowMarksHLo GruvboxBlueSign +hi! link ShowMarksHLm GruvboxBlueSign + +" }}} +" CtrlP: {{{ + +hi! link CtrlPMatch GruvboxYellow +hi! link CtrlPNoEntries GruvboxRed +hi! link CtrlPPrtBase GruvboxBg2 +hi! link CtrlPPrtCursor GruvboxBlue +hi! link CtrlPLinePre GruvboxBg2 + +call s:HL('CtrlPMode1', s:blue, s:bg2, s:bold) +call s:HL('CtrlPMode2', s:bg0, s:blue, s:bold) +call s:HL('CtrlPStats', s:fg4, s:bg2, s:bold) + +" }}} +" Startify: {{{ + +hi! link StartifyBracket GruvboxFg3 +hi! link StartifyFile GruvboxFg1 +hi! link StartifyNumber GruvboxBlue +hi! link StartifyPath GruvboxGray +hi! link StartifySlash GruvboxGray +hi! link StartifySection GruvboxYellow +hi! link StartifySpecial GruvboxBg2 +hi! link StartifyHeader GruvboxOrange +hi! link StartifyFooter GruvboxBg2 + +" }}} +" Vimshell: {{{ + +let g:vimshell_escape_colors = [ + \ s:bg4[0], s:red[0], s:green[0], s:yellow[0], + \ s:blue[0], s:purple[0], s:aqua[0], s:fg4[0], + \ s:bg0[0], s:red[0], s:green[0], s:orange[0], + \ s:blue[0], s:purple[0], s:aqua[0], s:fg0[0] + \ ] + +" }}} +" BufTabLine: {{{ + +call s:HL('BufTabLineCurrent', s:bg0, s:fg4) +call s:HL('BufTabLineActive', s:fg4, s:bg2) +call s:HL('BufTabLineHidden', s:bg4, s:bg1) +call s:HL('BufTabLineFill', s:bg0, s:bg0) + +" }}} +" Asynchronous Lint Engine: {{{ + +call s:HL('ALEError', s:none, s:none, s:undercurl, s:red) +call s:HL('ALEWarning', s:none, s:none, s:undercurl, s:yellow) +call s:HL('ALEInfo', s:none, s:none, s:undercurl, s:blue) + +hi! link ALEErrorSign GruvboxRedSign +hi! link ALEWarningSign GruvboxYellowSign +hi! link ALEInfoSign GruvboxBlueSign + +" }}} +" Dirvish: {{{ + +hi! link DirvishPathTail GruvboxAqua +hi! link DirvishArg GruvboxYellow + +" }}} +" Netrw: {{{ + +hi! link netrwDir GruvboxAqua +hi! link netrwClassify GruvboxAqua +hi! link netrwLink GruvboxGray +hi! link netrwSymLink GruvboxFg1 +hi! link netrwExe GruvboxYellow +hi! link netrwComment GruvboxGray +hi! link netrwList GruvboxBlue +hi! link netrwHelpCmd GruvboxAqua +hi! link netrwCmdSep GruvboxFg3 +hi! link netrwVersion GruvboxGreen + +" }}} +" NERDTree: {{{ + +hi! link NERDTreeDir GruvboxAqua +hi! link NERDTreeDirSlash GruvboxAqua + +hi! link NERDTreeOpenable GruvboxOrange +hi! link NERDTreeClosable GruvboxOrange + +hi! link NERDTreeFile GruvboxFg1 +hi! link NERDTreeExecFile GruvboxYellow + +hi! link NERDTreeUp GruvboxGray +hi! link NERDTreeCWD GruvboxGreen +hi! link NERDTreeHelp GruvboxFg1 + +hi! link NERDTreeToggleOn GruvboxGreen +hi! link NERDTreeToggleOff GruvboxRed + +" }}} +" Vim Multiple Cursors: {{{ + +call s:HL('multiple_cursors_cursor', s:none, s:none, s:inverse) +call s:HL('multiple_cursors_visual', s:none, s:bg2) + +" }}} + +" Filetype specific ----------------------------------------------------------- +" Diff: {{{ + +hi! link diffAdded GruvboxGreen +hi! link diffRemoved GruvboxRed +hi! link diffChanged GruvboxAqua + +hi! link diffFile GruvboxOrange +hi! link diffNewFile GruvboxYellow + +hi! link diffLine GruvboxBlue + +" }}} +" Html: {{{ + +hi! link htmlTag GruvboxBlue +hi! link htmlEndTag GruvboxBlue + +hi! link htmlTagName GruvboxAquaBold +hi! link htmlArg GruvboxAqua + +hi! link htmlScriptTag GruvboxPurple +hi! link htmlTagN GruvboxFg1 +hi! link htmlSpecialTagName GruvboxAquaBold + +call s:HL('htmlLink', s:fg4, s:none, s:underline) + +hi! link htmlSpecialChar GruvboxOrange + +call s:HL('htmlBold', s:vim_fg, s:vim_bg, s:bold) +call s:HL('htmlBoldUnderline', s:vim_fg, s:vim_bg, s:bold . s:underline) +call s:HL('htmlBoldItalic', s:vim_fg, s:vim_bg, s:bold . s:italic) +call s:HL('htmlBoldUnderlineItalic', s:vim_fg, s:vim_bg, s:bold . s:underline . s:italic) + +call s:HL('htmlUnderline', s:vim_fg, s:vim_bg, s:underline) +call s:HL('htmlUnderlineItalic', s:vim_fg, s:vim_bg, s:underline . s:italic) +call s:HL('htmlItalic', s:vim_fg, s:vim_bg, s:italic) + +" }}} +" Xml: {{{ + +hi! link xmlTag GruvboxBlue +hi! link xmlEndTag GruvboxBlue +hi! link xmlTagName GruvboxBlue +hi! link xmlEqual GruvboxBlue +hi! link docbkKeyword GruvboxAquaBold + +hi! link xmlDocTypeDecl GruvboxGray +hi! link xmlDocTypeKeyword GruvboxPurple +hi! link xmlCdataStart GruvboxGray +hi! link xmlCdataCdata GruvboxPurple +hi! link dtdFunction GruvboxGray +hi! link dtdTagName GruvboxPurple + +hi! link xmlAttrib GruvboxAqua +hi! link xmlProcessingDelim GruvboxGray +hi! link dtdParamEntityPunct GruvboxGray +hi! link dtdParamEntityDPunct GruvboxGray +hi! link xmlAttribPunct GruvboxGray + +hi! link xmlEntity GruvboxOrange +hi! link xmlEntityPunct GruvboxOrange +" }}} +" Vim: {{{ + +call s:HL('vimCommentTitle', s:fg4_256, s:none, s:bold . s:italicize_comments) + +hi! link vimNotation GruvboxOrange +hi! link vimBracket GruvboxOrange +hi! link vimMapModKey GruvboxOrange +hi! link vimFuncSID GruvboxFg3 +hi! link vimSetSep GruvboxFg3 +hi! link vimSep GruvboxFg3 +hi! link vimContinue GruvboxFg3 + +" }}} +" Clojure: {{{ + +hi! link clojureKeyword GruvboxBlue +hi! link clojureCond GruvboxOrange +hi! link clojureSpecial GruvboxOrange +hi! link clojureDefine GruvboxOrange + +hi! link clojureFunc GruvboxYellow +hi! link clojureRepeat GruvboxYellow +hi! link clojureCharacter GruvboxAqua +hi! link clojureStringEscape GruvboxAqua +hi! link clojureException GruvboxRed + +hi! link clojureRegexp GruvboxAqua +hi! link clojureRegexpEscape GruvboxAqua +call s:HL('clojureRegexpCharClass', s:fg3, s:none, s:bold) +hi! link clojureRegexpMod clojureRegexpCharClass +hi! link clojureRegexpQuantifier clojureRegexpCharClass + +hi! link clojureParen GruvboxFg3 +hi! link clojureAnonArg GruvboxYellow +hi! link clojureVariable GruvboxBlue +hi! link clojureMacro GruvboxOrange + +hi! link clojureMeta GruvboxYellow +hi! link clojureDeref GruvboxYellow +hi! link clojureQuote GruvboxYellow +hi! link clojureUnquote GruvboxYellow + +" }}} +" C: {{{ + +hi! link cOperator GruvboxPurple +hi! link cStructure GruvboxOrange + +" }}} +" Python: {{{ + +hi! link pythonBuiltin GruvboxOrange +hi! link pythonBuiltinObj GruvboxOrange +hi! link pythonBuiltinFunc GruvboxOrange +hi! link pythonFunction GruvboxAqua +hi! link pythonDecorator GruvboxRed +hi! link pythonInclude GruvboxBlue +hi! link pythonImport GruvboxBlue +hi! link pythonRun GruvboxBlue +hi! link pythonCoding GruvboxBlue +hi! link pythonOperator GruvboxRed +hi! link pythonException GruvboxRed +hi! link pythonExceptions GruvboxPurple +hi! link pythonBoolean GruvboxPurple +hi! link pythonDot GruvboxFg3 +hi! link pythonConditional GruvboxRed +hi! link pythonRepeat GruvboxRed +hi! link pythonDottedName GruvboxGreenBold + +" }}} +" CSS: {{{ + +hi! link cssBraces GruvboxBlue +hi! link cssFunctionName GruvboxYellow +hi! link cssIdentifier GruvboxOrange +hi! link cssClassName GruvboxGreen +hi! link cssColor GruvboxBlue +hi! link cssSelectorOp GruvboxBlue +hi! link cssSelectorOp2 GruvboxBlue +hi! link cssImportant GruvboxGreen +hi! link cssVendor GruvboxFg1 + +hi! link cssTextProp GruvboxAqua +hi! link cssAnimationProp GruvboxAqua +hi! link cssUIProp GruvboxYellow +hi! link cssTransformProp GruvboxAqua +hi! link cssTransitionProp GruvboxAqua +hi! link cssPrintProp GruvboxAqua +hi! link cssPositioningProp GruvboxYellow +hi! link cssBoxProp GruvboxAqua +hi! link cssFontDescriptorProp GruvboxAqua +hi! link cssFlexibleBoxProp GruvboxAqua +hi! link cssBorderOutlineProp GruvboxAqua +hi! link cssBackgroundProp GruvboxAqua +hi! link cssMarginProp GruvboxAqua +hi! link cssListProp GruvboxAqua +hi! link cssTableProp GruvboxAqua +hi! link cssFontProp GruvboxAqua +hi! link cssPaddingProp GruvboxAqua +hi! link cssDimensionProp GruvboxAqua +hi! link cssRenderProp GruvboxAqua +hi! link cssColorProp GruvboxAqua +hi! link cssGeneratedContentProp GruvboxAqua + +" }}} +" JavaScript: {{{ + +hi! link javaScriptBraces GruvboxFg1 +hi! link javaScriptFunction GruvboxAqua +hi! link javaScriptIdentifier GruvboxRed +hi! link javaScriptMember GruvboxBlue +hi! link javaScriptNumber GruvboxPurple +hi! link javaScriptNull GruvboxPurple +hi! link javaScriptParens GruvboxFg3 + +" }}} +" YAJS: {{{ + +hi! link javascriptImport GruvboxAqua +hi! link javascriptExport GruvboxAqua +hi! link javascriptClassKeyword GruvboxAqua +hi! link javascriptClassExtends GruvboxAqua +hi! link javascriptDefault GruvboxAqua + +hi! link javascriptClassName GruvboxYellow +hi! link javascriptClassSuperName GruvboxYellow +hi! link javascriptGlobal GruvboxYellow + +hi! link javascriptEndColons GruvboxFg1 +hi! link javascriptFuncArg GruvboxFg1 +hi! link javascriptGlobalMethod GruvboxFg1 +hi! link javascriptNodeGlobal GruvboxFg1 +hi! link javascriptBOMWindowProp GruvboxFg1 +hi! link javascriptArrayMethod GruvboxFg1 +hi! link javascriptArrayStaticMethod GruvboxFg1 +hi! link javascriptCacheMethod GruvboxFg1 +hi! link javascriptDateMethod GruvboxFg1 +hi! link javascriptMathStaticMethod GruvboxFg1 + +" hi! link javascriptProp GruvboxFg1 +hi! link javascriptURLUtilsProp GruvboxFg1 +hi! link javascriptBOMNavigatorProp GruvboxFg1 +hi! link javascriptDOMDocMethod GruvboxFg1 +hi! link javascriptDOMDocProp GruvboxFg1 +hi! link javascriptBOMLocationMethod GruvboxFg1 +hi! link javascriptBOMWindowMethod GruvboxFg1 +hi! link javascriptStringMethod GruvboxFg1 + +hi! link javascriptVariable GruvboxOrange +" hi! link javascriptVariable GruvboxRed +" hi! link javascriptIdentifier GruvboxOrange +" hi! link javascriptClassSuper GruvboxOrange +hi! link javascriptIdentifier GruvboxOrange +hi! link javascriptClassSuper GruvboxOrange + +" hi! link javascriptFuncKeyword GruvboxOrange +" hi! link javascriptAsyncFunc GruvboxOrange +hi! link javascriptFuncKeyword GruvboxAqua +hi! link javascriptAsyncFunc GruvboxAqua +hi! link javascriptClassStatic GruvboxOrange + +hi! link javascriptOperator GruvboxRed +hi! link javascriptForOperator GruvboxRed +hi! link javascriptYield GruvboxRed +hi! link javascriptExceptions GruvboxRed +hi! link javascriptMessage GruvboxRed + +hi! link javascriptTemplateSB GruvboxAqua +hi! link javascriptTemplateSubstitution GruvboxFg1 + +" hi! link javascriptLabel GruvboxBlue +" hi! link javascriptObjectLabel GruvboxBlue +" hi! link javascriptPropertyName GruvboxBlue +hi! link javascriptLabel GruvboxFg1 +hi! link javascriptObjectLabel GruvboxFg1 +hi! link javascriptPropertyName GruvboxFg1 + +hi! link javascriptLogicSymbols GruvboxFg1 +hi! link javascriptArrowFunc GruvboxYellow + +hi! link javascriptDocParamName GruvboxFg4 +hi! link javascriptDocTags GruvboxFg4 +hi! link javascriptDocNotation GruvboxFg4 +hi! link javascriptDocParamType GruvboxFg4 +hi! link javascriptDocNamedParamType GruvboxFg4 + +hi! link javascriptBrackets GruvboxFg1 +hi! link javascriptDOMElemAttrs GruvboxFg1 +hi! link javascriptDOMEventMethod GruvboxFg1 +hi! link javascriptDOMNodeMethod GruvboxFg1 +hi! link javascriptDOMStorageMethod GruvboxFg1 +hi! link javascriptHeadersMethod GruvboxFg1 + +hi! link javascriptAsyncFuncKeyword GruvboxRed +hi! link javascriptAwaitFuncKeyword GruvboxRed + +" }}} +" PanglossJS: {{{ + +hi! link jsClassKeyword GruvboxAqua +hi! link jsExtendsKeyword GruvboxAqua +hi! link jsExportDefault GruvboxAqua +hi! link jsTemplateBraces GruvboxAqua +hi! link jsGlobalNodeObjects GruvboxFg1 +hi! link jsGlobalObjects GruvboxFg1 +hi! link jsFunction GruvboxAqua +hi! link jsFuncParens GruvboxFg3 +hi! link jsParens GruvboxFg3 +hi! link jsNull GruvboxPurple +hi! link jsUndefined GruvboxPurple +hi! link jsClassDefinition GruvboxYellow + +" }}} +" TypeScript: {{{ + +hi! link typeScriptReserved GruvboxAqua +hi! link typeScriptLabel GruvboxAqua +hi! link typeScriptFuncKeyword GruvboxAqua +hi! link typeScriptIdentifier GruvboxOrange +hi! link typeScriptBraces GruvboxFg1 +hi! link typeScriptEndColons GruvboxFg1 +hi! link typeScriptDOMObjects GruvboxFg1 +hi! link typeScriptAjaxMethods GruvboxFg1 +hi! link typeScriptLogicSymbols GruvboxFg1 +hi! link typeScriptDocSeeTag Comment +hi! link typeScriptDocParam Comment +hi! link typeScriptDocTags vimCommentTitle +hi! link typeScriptGlobalObjects GruvboxFg1 +hi! link typeScriptParens GruvboxFg3 +hi! link typeScriptOpSymbols GruvboxFg3 +hi! link typeScriptHtmlElemProperties GruvboxFg1 +hi! link typeScriptNull GruvboxPurple +hi! link typeScriptInterpolationDelimiter GruvboxAqua + +" }}} +" PureScript: {{{ + +hi! link purescriptModuleKeyword GruvboxAqua +hi! link purescriptModuleName GruvboxFg1 +hi! link purescriptWhere GruvboxAqua +hi! link purescriptDelimiter GruvboxFg4 +hi! link purescriptType GruvboxFg1 +hi! link purescriptImportKeyword GruvboxAqua +hi! link purescriptHidingKeyword GruvboxAqua +hi! link purescriptAsKeyword GruvboxAqua +hi! link purescriptStructure GruvboxAqua +hi! link purescriptOperator GruvboxBlue + +hi! link purescriptTypeVar GruvboxFg1 +hi! link purescriptConstructor GruvboxFg1 +hi! link purescriptFunction GruvboxFg1 +hi! link purescriptConditional GruvboxOrange +hi! link purescriptBacktick GruvboxOrange + +" }}} +" CoffeeScript: {{{ + +hi! link coffeeExtendedOp GruvboxFg3 +hi! link coffeeSpecialOp GruvboxFg3 +hi! link coffeeCurly GruvboxOrange +hi! link coffeeParen GruvboxFg3 +hi! link coffeeBracket GruvboxOrange + +" }}} +" Ruby: {{{ + +hi! link rubyStringDelimiter GruvboxGreen +hi! link rubyInterpolationDelimiter GruvboxAqua + +" }}} +" ObjectiveC: {{{ + +hi! link objcTypeModifier GruvboxRed +hi! link objcDirective GruvboxBlue + +" }}} +" Go: {{{ + +hi! link goDirective GruvboxAqua +hi! link goConstants GruvboxPurple +hi! link goDeclaration GruvboxRed +hi! link goDeclType GruvboxBlue +hi! link goBuiltins GruvboxOrange + +" }}} +" Lua: {{{ + +hi! link luaIn GruvboxRed +hi! link luaFunction GruvboxAqua +hi! link luaTable GruvboxOrange + +" }}} +" MoonScript: {{{ + +hi! link moonSpecialOp GruvboxFg3 +hi! link moonExtendedOp GruvboxFg3 +hi! link moonFunction GruvboxFg3 +hi! link moonObject GruvboxYellow + +" }}} +" Java: {{{ + +hi! link javaAnnotation GruvboxBlue +hi! link javaDocTags GruvboxAqua +hi! link javaCommentTitle vimCommentTitle +hi! link javaParen GruvboxFg3 +hi! link javaParen1 GruvboxFg3 +hi! link javaParen2 GruvboxFg3 +hi! link javaParen3 GruvboxFg3 +hi! link javaParen4 GruvboxFg3 +hi! link javaParen5 GruvboxFg3 +hi! link javaOperator GruvboxOrange + +hi! link javaVarArg GruvboxGreen + +" }}} +" Elixir: {{{ + +hi! link elixirDocString Comment + +hi! link elixirStringDelimiter GruvboxGreen +hi! link elixirInterpolationDelimiter GruvboxAqua + +hi! link elixirModuleDeclaration GruvboxYellow + +" }}} +" Scala: {{{ + +" NB: scala vim syntax file is kinda horrible +hi! link scalaNameDefinition GruvboxFg1 +hi! link scalaCaseFollowing GruvboxFg1 +hi! link scalaCapitalWord GruvboxFg1 +hi! link scalaTypeExtension GruvboxFg1 + +hi! link scalaKeyword GruvboxRed +hi! link scalaKeywordModifier GruvboxRed + +hi! link scalaSpecial GruvboxAqua +hi! link scalaOperator GruvboxFg1 + +hi! link scalaTypeDeclaration GruvboxYellow +hi! link scalaTypeTypePostDeclaration GruvboxYellow + +hi! link scalaInstanceDeclaration GruvboxFg1 +hi! link scalaInterpolation GruvboxAqua + +" }}} +" Markdown: {{{ + +call s:HL('markdownItalic', s:fg3, s:none, s:italic) + +hi! link markdownH1 GruvboxGreenBold +hi! link markdownH2 GruvboxGreenBold +hi! link markdownH3 GruvboxYellowBold +hi! link markdownH4 GruvboxYellowBold +hi! link markdownH5 GruvboxYellow +hi! link markdownH6 GruvboxYellow + +hi! link markdownCode GruvboxAqua +hi! link markdownCodeBlock GruvboxAqua +hi! link markdownCodeDelimiter GruvboxAqua + +hi! link markdownBlockquote GruvboxGray +hi! link markdownListMarker GruvboxGray +hi! link markdownOrderedListMarker GruvboxGray +hi! link markdownRule GruvboxGray +hi! link markdownHeadingRule GruvboxGray + +hi! link markdownUrlDelimiter GruvboxFg3 +hi! link markdownLinkDelimiter GruvboxFg3 +hi! link markdownLinkTextDelimiter GruvboxFg3 + +hi! link markdownHeadingDelimiter GruvboxOrange +hi! link markdownUrl GruvboxPurple +hi! link markdownUrlTitleDelimiter GruvboxGreen + +call s:HL('markdownLinkText', s:gray, s:none, s:underline) +hi! link markdownIdDeclaration markdownLinkText + +" }}} +" Haskell: {{{ + +" hi! link haskellType GruvboxYellow +" hi! link haskellOperators GruvboxOrange +" hi! link haskellConditional GruvboxAqua +" hi! link haskellLet GruvboxOrange +" +hi! link haskellType GruvboxFg1 +hi! link haskellIdentifier GruvboxFg1 +hi! link haskellSeparator GruvboxFg1 +hi! link haskellDelimiter GruvboxFg4 +hi! link haskellOperators GruvboxBlue +" +hi! link haskellBacktick GruvboxOrange +hi! link haskellStatement GruvboxOrange +hi! link haskellConditional GruvboxOrange + +hi! link haskellLet GruvboxAqua +hi! link haskellDefault GruvboxAqua +hi! link haskellWhere GruvboxAqua +hi! link haskellBottom GruvboxAqua +hi! link haskellBlockKeywords GruvboxAqua +hi! link haskellImportKeywords GruvboxAqua +hi! link haskellDeclKeyword GruvboxAqua +hi! link haskellDeriving GruvboxAqua +hi! link haskellAssocType GruvboxAqua + +hi! link haskellNumber GruvboxPurple +hi! link haskellPragma GruvboxPurple + +hi! link haskellString GruvboxGreen +hi! link haskellChar GruvboxGreen + +" }}} +" Json: {{{ + +hi! link jsonKeyword GruvboxGreen +hi! link jsonQuote GruvboxGreen +hi! link jsonBraces GruvboxFg1 +hi! link jsonString GruvboxFg1 + +" }}} + + +" Functions ------------------------------------------------------------------- +" Search Highlighting Cursor {{{ + +function! GruvboxHlsShowCursor() + call s:HL('Cursor', s:bg0, s:hls_cursor) +endfunction + +function! GruvboxHlsHideCursor() + call s:HL('Cursor', s:none, s:none, s:inverse) +endfunction + +" }}} + +" vim: set sw=2 ts=2 sts=2 et tw=80 ft=vim fdm=marker: diff --git a/dotfiles/.local/share/nvim/site/colors/wal.vim b/dotfiles/.local/share/nvim/site/colors/wal.vim new file mode 100755 index 0000000..53390be --- /dev/null +++ b/dotfiles/.local/share/nvim/site/colors/wal.vim @@ -0,0 +1,195 @@ +" wal.vim -- Vim color scheme. +" Author: Dylan Araps +" Webpage: https://github.com/dylanaraps/wal +" Description: A colorscheme that uses your terminal colors, made to work with 'wal'. + +hi clear +set background=dark + +if exists('syntax_on') + syntax reset +endif + +" Colorscheme name +let g:colors_name = 'wal' + +" highlight groups {{{ + +" set t_Co=16 +hi Normal ctermbg=NONE ctermfg=7 +hi NonText ctermbg=NONE ctermfg=0 +hi Comment ctermbg=NONE ctermfg=8 +hi Constant ctermbg=NONE ctermfg=3 +hi Error ctermbg=1 ctermfg=7 +hi Identifier ctermbg=NONE ctermfg=1 cterm=BOLD +hi Ignore ctermbg=8 ctermfg=0 +hi PreProc ctermbg=NONE ctermfg=3 +hi Special ctermbg=NONE ctermfg=6 +hi Statement ctermbg=NONE ctermfg=1 +hi String ctermbg=NONE ctermfg=2 +hi Number ctermbg=NONE ctermfg=3 +hi Todo ctermbg=2 ctermfg=0 +hi Type ctermbg=NONE ctermfg=3 +hi Underlined ctermbg=NONE ctermfg=1 cterm=underline +hi StatusLine ctermbg=7 ctermfg=0 +hi StatusLineNC ctermbg=NONE ctermfg=NONE +hi TabLine ctermbg=NONE ctermfg=8 +hi TabLineFill ctermbg=NONE ctermfg=8 +hi TabLineSel ctermbg=4 ctermfg=0 +hi TermCursorNC ctermbg=3 ctermfg=0 +hi VertSplit ctermbg=NONE ctermfg=NONE +hi Title ctermbg=NONE ctermfg=4 +hi CursorLine ctermbg=8 ctermfg=0 +hi LineNr ctermbg=NONE ctermfg=8 +hi CursorLineNr ctermbg=NONE ctermfg=8 +hi helpLeadBlank ctermbg=NONE ctermfg=7 +hi helpNormal ctermbg=NONE ctermfg=7 +hi Visual ctermbg=0 ctermfg=15 cterm=reverse term=reverse +hi VisualNOS ctermbg=NONE ctermfg=1 +hi Pmenu ctermbg=8 ctermfg=7 +hi PmenuSbar ctermbg=6 ctermfg=7 +hi PmenuSel ctermbg=4 ctermfg=0 +hi PmenuThumb ctermbg=8 ctermfg=8 +hi FoldColumn ctermbg=NONE ctermfg=7 +hi Folded ctermbg=NONE ctermfg=8 +hi WildMenu ctermbg=2 ctermfg=0 +hi SpecialKey ctermbg=NONE ctermfg=8 +hi DiffAdd ctermbg=NONE ctermfg=2 +hi DiffChange ctermbg=NONE ctermfg=8 +hi DiffDelete ctermbg=NONE ctermfg=1 +hi DiffText ctermbg=NONE ctermfg=4 +hi IncSearch ctermbg=3 ctermfg=0 +hi Search ctermbg=3 ctermfg=0 +hi Directory ctermbg=NONE ctermfg=4 +hi MatchParen ctermbg=8 ctermfg=0 +hi ColorColumn ctermbg=4 ctermfg=0 +hi signColumn ctermbg=NONE ctermfg=4 +hi ErrorMsg ctermbg=NONE ctermfg=8 +hi ModeMsg ctermbg=NONE ctermfg=2 +hi MoreMsg ctermbg=NONE ctermfg=2 +hi Question ctermbg=NONE ctermfg=4 +hi WarningMsg ctermbg=1 ctermfg=0 +hi Cursor ctermbg=NONE ctermfg=8 +hi Structure ctermbg=NONE ctermfg=5 +hi CursorColumn ctermbg=8 ctermfg=7 +hi ModeMsg ctermbg=NONE ctermfg=7 +hi SpellBad ctermbg=NONE ctermfg=1 cterm=underline +hi SpellCap ctermbg=NONE ctermfg=4 cterm=underline +hi SpellLocal ctermbg=NONE ctermfg=5 cterm=underline +hi SpellRare ctermbg=NONE ctermfg=6 cterm=underline +hi Boolean ctermbg=NONE ctermfg=5 +hi Character ctermbg=NONE ctermfg=1 +hi Conditional ctermbg=NONE ctermfg=5 +hi Define ctermbg=NONE ctermfg=5 +hi Delimiter ctermbg=NONE ctermfg=5 +hi Float ctermbg=NONE ctermfg=5 +hi Include ctermbg=NONE ctermfg=4 +hi Keyword ctermbg=NONE ctermfg=5 +hi Label ctermbg=NONE ctermfg=3 +hi Operator ctermbg=NONE ctermfg=7 +hi Repeat ctermbg=NONE ctermfg=3 +hi SpecialChar ctermbg=NONE ctermfg=5 +hi Tag ctermbg=NONE ctermfg=3 +hi Typedef ctermbg=NONE ctermfg=3 +hi vimUserCommand ctermbg=NONE ctermfg=1 cterm=BOLD + hi link vimMap vimUserCommand + hi link vimLet vimUserCommand + hi link vimCommand vimUserCommand + hi link vimFTCmd vimUserCommand + hi link vimAutoCmd vimUserCommand + hi link vimNotFunc vimUserCommand +hi vimNotation ctermbg=NONE ctermfg=4 +hi vimMapModKey ctermbg=NONE ctermfg=4 +hi vimBracket ctermbg=NONE ctermfg=7 +hi vimCommentString ctermbg=NONE ctermfg=8 +hi htmlLink ctermbg=NONE ctermfg=1 cterm=underline +hi htmlBold ctermbg=NONE ctermfg=3 cterm=BOLD +hi htmlItalic ctermbg=NONE ctermfg=5 +hi htmlEndTag ctermbg=NONE ctermfg=7 +hi htmlTag ctermbg=NONE ctermfg=7 +hi htmlTagName ctermbg=NONE ctermfg=1 cterm=BOLD +hi htmlH1 ctermbg=NONE ctermfg=7 + hi link htmlH2 htmlH1 + hi link htmlH3 htmlH1 + hi link htmlH4 htmlH1 + hi link htmlH5 htmlH1 + hi link htmlH6 htmlH1 +hi cssMultiColumnAttr ctermbg=NONE ctermfg=2 + hi link cssFontAttr cssMultiColumnAttr + hi link cssFlexibleBoxAttr cssMultiColumnAttr +hi cssBraces ctermbg=NONE ctermfg=7 + hi link cssAttrComma cssBraces +hi cssValueLength ctermbg=NONE ctermfg=7 +hi cssUnitDecorators ctermbg=NONE ctermfg=7 +hi cssValueNumber ctermbg=NONE ctermfg=7 + hi link cssValueLength cssValueNumber +hi cssNoise ctermbg=NONE ctermfg=8 +hi cssTagName ctermbg=NONE ctermfg=1 +hi cssFunctionName ctermbg=NONE ctermfg=4 +hi scssSelectorChar ctermbg=NONE ctermfg=7 +hi scssAttribute ctermbg=NONE ctermfg=7 + hi link scssDefinition cssNoise +hi sassidChar ctermbg=NONE ctermfg=1 +hi sassClassChar ctermbg=NONE ctermfg=5 +hi sassInclude ctermbg=NONE ctermfg=5 +hi sassMixing ctermbg=NONE ctermfg=5 +hi sassMixinName ctermbg=NONE ctermfg=4 +hi javaScript ctermbg=NONE ctermfg=7 +hi javaScriptBraces ctermbg=NONE ctermfg=7 +hi javaScriptNumber ctermbg=NONE ctermfg=5 +hi markdownH1 ctermbg=NONE ctermfg=7 + hi link markdownH2 markdownH1 + hi link markdownH3 markdownH1 + hi link markdownH4 markdownH1 + hi link markdownH5 markdownH1 + hi link markdownH6 markdownH1 +hi markdownAutomaticLink ctermbg=NONE ctermfg=2 cterm=underline + hi link markdownUrl markdownAutomaticLink +hi markdownError ctermbg=NONE ctermfg=7 +hi markdownCode ctermbg=NONE ctermfg=3 +hi markdownCodeBlock ctermbg=NONE ctermfg=3 +hi markdownCodeDelimiter ctermbg=NONE ctermfg=5 +hi markdownItalic cterm=Italic +hi markdownBold cterm=Bold +hi xdefaultsValue ctermbg=NONE ctermfg=7 +hi rubyInclude ctermbg=NONE ctermfg=4 +hi rubyDefine ctermbg=NONE ctermfg=5 +hi rubyFunction ctermbg=NONE ctermfg=4 +hi rubyStringDelimiter ctermbg=NONE ctermfg=2 +hi rubyInteger ctermbg=NONE ctermfg=3 +hi rubyAttribute ctermbg=NONE ctermfg=4 +hi rubyConstant ctermbg=NONE ctermfg=3 +hi rubyInterpolation ctermbg=NONE ctermfg=2 +hi rubyInterpolationDelimiter ctermbg=NONE ctermfg=3 +hi rubyRegexp ctermbg=NONE ctermfg=6 +hi rubySymbol ctermbg=NONE ctermfg=2 +hi rubyTodo ctermbg=NONE ctermfg=8 +hi rubyRegexpAnchor ctermbg=NONE ctermfg=7 + hi link rubyRegexpQuantifier rubyRegexpAnchor +hi pythonOperator ctermbg=NONE ctermfg=5 +hi pythonFunction ctermbg=NONE ctermfg=4 +hi pythonRepeat ctermbg=NONE ctermfg=5 +hi pythonStatement ctermbg=NONE ctermfg=1 cterm=Bold +hi pythonBuiltIn ctermbg=NONE ctermfg=4 +hi phpMemberSelector ctermbg=NONE ctermfg=7 +hi phpComparison ctermbg=NONE ctermfg=7 +hi phpParent ctermbg=NONE ctermfg=7 +hi cOperator ctermbg=NONE ctermfg=6 +hi cPreCondit ctermbg=NONE ctermfg=5 +hi SignifySignAdd ctermbg=NONE ctermfg=2 +hi SignifySignChange ctermbg=NONE ctermfg=4 +hi SignifySignDelete ctermbg=NONE ctermfg=1 +hi NERDTreeDirSlash ctermbg=NONE ctermfg=4 +hi NERDTreeExecFile ctermbg=NONE ctermfg=7 +hi ALEErrorSign ctermbg=NONE ctermfg=1 +hi ALEWarningSign ctermbg=NONE ctermfg=3 +hi ALEError ctermbg=NONE ctermfg=1 +hi ALEWarning ctermbg=NONE ctermfg=3 + +" }}} + +" Plugin options {{{ + +let g:limelight_conceal_ctermfg = 8 + +" }}} diff --git a/dotfiles/.local/share/nvim/site/contrib/highlight-log b/dotfiles/.local/share/nvim/site/contrib/highlight-log new file mode 100755 index 0000000..c4697fd --- /dev/null +++ b/dotfiles/.local/share/nvim/site/contrib/highlight-log @@ -0,0 +1,144 @@ +#!/usr/bin/env bash + +# This script adds color highlighting to the output from Neomake's Vader tests +# (when called with "vader"), or to the file that gets written into according +# to `neomake_logfile`. +# +# You can use the following to watch colored logs in a terminal window, after +# having used `let g:neomake_logfile = '/tmp/neomake.log'` in Neovim/Vim: +# +# tail -f /tmp/neomake.log | /path/to/neomake/contrib/highlight-log + +bold="[1m" # $(tput bold) +bold_off="[22m" +debug_color="[2m" # $(tput dim), does not work in urxvt (although in infocmp/terminfo). +debug_color_off="[22m" +color_off="[39m" +log_color="[33;1m" +log_color_off="$bold_off$color_off" +error_color="[31;1m" +error_color_off="$bold_off$color_off" + +# compact: display test headers, but not inner output for successful ones. +compact=0 + +while [ $# -ne 0 ]; do + case $1 in + --compact) compact=1; shift ;; + --) shift; break ;; + -?*) echo "Unknown option: $1" 1>&2; exit 64 ;; + *) break ;; + esac +done + +if [ "$1" = vader ]; then + # Match non-log lines (i.e. keep output from :Log, which should cause + # all messages from a case to be visible). + # This should also ignore empty lines and lines starting with a character + # (e.g. via NVIM_LOG_FILE:=/dev/stderr, and from :echom). + re_log_line='^(.*( )? )(> .*)$' + re_ignore_log_line='^.*( )? > \[(debug |verbose|warning|error )|((D|V|W|E) +\+[.0-9]+)\]' + + colorize() { + # Only colorize if stdout is connected to a tty (not with :!make). + if ! [ -t 1 ]; then + cat - + return + fi + + # sed: add coloring to Vader's output: + # 1. failures (includes pending) in red "(X)" + # 2. test case header in bold "(2/2)" + # 3. Neomake's error log messages + # 4. Neomake's debug log messages + # 5. non-Neomake log lines (e.g. from :Log) + sed -E -e 's/^(([^ ].*)? +)\([ [:digit:]]+\/[[:digit:]]+\) \[[ [:alpha:]]+\] \(X\).*/'"$error_color"'\0'"$error_color_off"'/' \ + -e 's/^(([^ ].*)? +)(\([ [:digit:]]+\/[[:digit:]]+\))/\1'"$bold"'\3'"$bold_off"'/' \ + -e 's/^ +> \[(error |E +[.[:digit:]]+)\]: .*/'"$bold"'\0'"$bold_off"'/' \ + -e 's/^ +> \[(debug |D +[.[:digit:]]+)\]: .*/'"$debug_color"'\0'"$debug_color_off"'/' \ + -e '/'"$re_ignore_log_line"'/! s/'"$re_log_line"'/\1'"$log_color"'\3'"$log_color_off"'/' + } + + if ((compact)); then + # Do not display output for successful tests (i.e. the log statements). + last_start_match= + # Match Vader header ("( 1/33) [EXECUTE] …"), but also if there is output + # from Vim, e.g. with ":colder". + re_vader_header='^([^ ].*)?\ +(\(\ *[0-9]+/[0-9]+\))' + filtering=0 + finished_reading=0 + stopped_filtering=0 + while [ "$finished_reading" = 0 ]; do + if ! read -r; then + if [ -z "$REPLY" ]; then + break + finished_reading=1 + fi + fi + if [[ "$REPLY" == *'Vader error:'* ]] || [[ "$REPLY" == 'Error'* ]] || [[ "$REPLY" == 'Traceback'* ]]; then + printf "\r" >&2 + printf "[31m[1m%s[0m\n" "$REPLY" + continue + fi + if (( stopped_filtering )); then + echo "$REPLY" + continue + fi + if [[ "$REPLY" == *'Starting Vader:'* ]]; then + echo "$REPLY" + elif [[ "$REPLY" == ' Duration: '* ]]; then + echo "$REPLY" + elif [[ "$REPLY" == *'(X)'* ]]; then + # Should also match "(1/1) [EXECUTE] (X) Error: Vim(function):E126: Missing :endfunction" already. + if [[ -n "$filtered" ]]; then + echo "$filtered" + fi + echo "$REPLY" + filtered= + filtering=0 + elif [[ "$REPLY" =~ $re_vader_header ]]; then + filtering=1 + if [[ ${BASH_REMATCH[2]} == "$last_start_match" ]]; then + filtered="$filtered"$'\n'"$REPLY" + else + echo "$REPLY" + filtered= + fi + last_start_match="${BASH_REMATCH[2]}" + elif [[ "$REPLY" == *'Success/Total: '* || "$REPLY" == ' Slowest tests:' ]]; then + echo "$REPLY" + filtering=0 + filtered= + stopped_filtering=1 + elif ! ((filtering)); then + echo "$REPLY" + elif [[ "$REPLY" =~ $re_log_line && ! "$REPLY" =~ $re_ignore_log_line ]]; then + if [[ "$REPLY" =~ '> SKIP:' ]]; then + echo "$REPLY" + continue + fi + if [[ -n "$filtered" ]]; then + echo "$filtered" + fi + echo "$REPLY" + filtered= + filtering=0 + elif [[ -n "$filtered" ]]; then + filtered="$filtered"$'\n'"$REPLY" + else + filtered="$REPLY" + fi + done + else + cat - + fi | colorize + +else + # Output from neomake_logfile. + error='^[:[:digit:]]\+ \[E .*' + warn='^[:[:digit:]]\+ \[W .*' + debug='^[:[:digit:]]\+ \[D .*' + sed -e "s/$error/[31m[1m\0[0m/" \ + -e "s/$warn/w:[33m\0[0m/" \ + -e "s/$debug/$debug_color\\0$debug_color_off/" +fi diff --git a/dotfiles/.local/share/nvim/site/contrib/run-tests-watch b/dotfiles/.local/share/nvim/site/contrib/run-tests-watch new file mode 100755 index 0000000..11edbdf --- /dev/null +++ b/dotfiles/.local/share/nvim/site/contrib/run-tests-watch @@ -0,0 +1,127 @@ +#!/bin/sh -x +# +# Wrapper around inotifywait to run tests on file changes. +# If a test file changes, only this file is run (first), while the whole test +# suite is run afterwards (and initially). +# +# The recommended way to run it is via `make testwatch`, or `make testwatchx` +# (to exit on first failure). +# +# # Internal documentation: +# The default run command is "make %s" (where %s gets replaced with the test +# file(s)), and can be given as first argument. +# +# You can specify VADER_OPTIONS=-x to exit on the first test failure: +# VADER_OPTIONS=-x contrib/run-tests-watch +# or use the following: +# contrib/run-tests-watch 'make %s VADER_OPTIONS=-x' +# +# VADER_ARGS gets used to focus on a specific test file initially, until +# another test file gets changed. + +watch="autoload plugin tests" +echo "Watching: $watch" + +if [ -n "$1" ]; then + cmdpattern="$1" +else + cmdpattern="make %s VADER_OPTIONS='$VADER_OPTIONS'" +fi + +title() { + printf '\e]1;%s\a' "$*" + printf '\e]2;%s\a' "$*" +} + +status_file=$(mktemp) +handle_cmd_result() { + if [ "$1" = 0 ]; then + last_test_succeeded=1 + title "✔ $2" + if [ "${2#*${alltestsfile}*}" != "$2" ]; then + alltests_succeeded=1 + fi + else + last_test_succeeded=0 + title "✘ $2" + if [ "${2#*${alltestsfile}*}" != "$2" ]; then + alltests_succeeded=0 + fi + fi + echo "$last_test_succeeded $alltests_succeeded" > "$status_file" +} + +# Recursively kill childs - required to get out of a running pdb. +kill_with_childs() { + for p in $(pgrep -P "$1"); do + kill_with_childs "$p" + done + if kill -0 "$1" 2>/dev/null; then + kill "$1" || true + fi +} + +alltestsfile='tests/all.vader' +alltests_succeeded=0 +pid= +changed_files= +set -e +last_changed_testsfile="${VADER_ARGS:-$alltestsfile}" + +while true; do + testfiles="$last_changed_testsfile" + if [ -n "$changed_files" ]; then + # There was a previous run + echo "=================================================================" + echo "changed file: $changed_files" + + read -r last_test_succeeded alltests_succeeded < "$status_file" || alltests_succeeded=0 + + if [ "${changed_files#tests/}" != "$changed_files" ] \ + && [ "${changed_files#tests/include/}" = "$changed_files" ]; then + # A test file was changed (but not an include file). + last_changed_testsfile="$changed_files" + testfiles="$last_changed_testsfile" + + # Run full tests afterwards (if not successful before). + if [ "$testfiles" != "$alltestsfile" ] && [ "$alltests_succeeded" = 0 ]; then + testfiles="$testfiles $alltestsfile" + fi + + elif [ "$last_test_succeeded" = 1 ]; then + # Run all tests. + alltests_succeeded=0 + testfiles="$alltestsfile" + + if [ "${VADER_OPTIONS#*-x*}" != "$VADER_OPTIONS" ]; then + # Run tests matching the changed file first, e.g. tests/config.vader for + # autoload/neomake/config.vim. + test_file_for_changed_file="tests/${changed_files#autoload/neomake/}" + test_file_for_changed_file="${test_file_for_changed_file%.vim}.vader" + declare -p test_file_for_changed_file + if [ -f "$test_file_for_changed_file" ]; then + testfiles="$test_file_for_changed_file $testfiles" + fi + fi + fi + + if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then + echo 'Killing previous run…' + kill_with_childs "$pid" + fi + fi + + # shellcheck disable=SC2059 + cmd="$(printf "$cmdpattern" "$testfiles")" + echo "Running $cmd" + title "… $testfiles" + # shellcheck disable=SC2015 + (set +e; eval "$cmd"; handle_cmd_result "$?" "$testfiles") </dev/tty & + pid=$! + + sleep 1 + # shellcheck disable=SC2086 + changed_files="$(inotifywait -q -r -e close_write \ + --exclude '/(__pycache__/|\.)|.*\@neomake_.*' \ + --format '%w%f' $watch)" +done diff --git a/dotfiles/.local/share/nvim/site/contrib/vim-checks b/dotfiles/.local/share/nvim/site/contrib/vim-checks new file mode 100755 index 0000000..c4791d7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/contrib/vim-checks @@ -0,0 +1,123 @@ +#!/usr/bin/env bash + +set -eu + +# This Bash script implements custom sanity checks for scripts beyond what +# Vint covers, which are easy to check with regex. +# +# Adopted from ALE (https://github.com/w0rp/ale/blob/10679b29/custom-checks) +# +# Copyright (c) 2016, w0rp <devw0rp@gmail.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +RETURN_CODE=0 + +function print_help() { + echo "Usage: ./custom-checks FILE|DIRECTORY…" 1>&2 + echo 1>&2 + echo " -h, --help Print this help text" 1>&2 + exit 1 +} + +while [ $# -ne 0 ]; do + case $1 in + -h) ;& --help) + print_help + ;; + --) + shift + break + ;; + -?*) + echo "Invalid argument: $1" 1>&2 + exit 1 + ;; + *) + break + ;; + esac +done + +if [ $# -eq 0 ] || [ -z "$1" ]; then + print_help +fi + +shopt -s globstar + +args=("$@") + +expand_arg() { + if [[ -d $arg ]]; then + expanded_arg=("$arg"/**/*.vim) + else + expanded_arg=("$arg") + fi +} + +check_errors() { + regex="$1"; shift + message="$1"; shift + + for arg in "${args[@]}"; do + expand_arg "$arg" + # Ensure that errors from grep are not ignored, i.e. busybox's grep + # does not have "--with-filename". + set +e + output="$(grep "$@" --with-filename -n "$regex" "${expanded_arg[@]}" 2>&1)" + ret=$? + set -e + if (( ret > 1 )); then + echo "$output" + RETURN_CODE=2 + continue + fi + if [[ -z "$output" ]]; then + continue + fi + + while IFS= read -r match; do + RETURN_CODE=1 + echo "$match $message" + done < <(echo "$output" \ + | grep -o '^[^:]\+\(:[0-9]\+\)\?:' \ + | sed 's:^\./::') + done +} + +check_errors \ + '^\s*function.*) *$' \ + 'Function without abort keyword (See :help except-compat)' +check_errors ' \+$' 'Trailing whitespace' +check_errors '^ * end\?i\? *$' 'Write endif, not en, end, or endi' +check_errors '^(( )*([^ ]|$)|\s+\\)' 'Use four spaces for indentation' -v -E +check_errors $'\t' 'Do not use tabs for indentation' +check_errors '^\s*[^" ].*[^&]l:[a-z]' 'Do not use l: prefix for local variables' +for arg in "${args[@]}"; do + expand_arg "$arg" + grep --files-without-match '^"[ ]vim: ts=4 sw=4 et' "${expanded_arg[@]}" \ + | while read -r f; do + echo "$f:$(( $(wc -l "$f" | cut -f1 -d\ ) + 1)): Missing modeline" + done +done + +exit $RETURN_CODE diff --git a/dotfiles/.local/share/nvim/site/contrib/vimhelplint b/dotfiles/.local/share/nvim/site/contrib/vimhelplint new file mode 100755 index 0000000..3a87e2c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/contrib/vimhelplint @@ -0,0 +1,46 @@ +#!/bin/sh +# A wrapper around vim-vimhelp (https://github.com/machakann/vim-vimhelplint). +# +# This file is automatically used by autoload/neomake/makers/ft/help.vim, if +# vimhelplint is installed in Neomake's build dir (and `vimhelplint` is not +# found as an executable). +# +# You can run `make build/vimhelplint` (from Neomake's root) to +# download/install it into Neomake's build dir, and Neomake will use this for +# help files then. + +if [ -z "$VIMHELPLINT_DIR" ]; then + # Change to parent dir (not POSIXly, but resolving symlinks). + CDPATH='' cd -P -- "$(dirname -- "$(readlink -f -- "$0" 2>/dev/null || echo "$0")")/.." || exit + VIMHELPLINT_DIR=$PWD/build/vimhelplint + cd - >/dev/null || exit +fi +vimhelplint=${VIMHELPLINT_DIR}/ftplugin/help_lint.vim + +if ! [ -f "$vimhelplint" ]; then + echo "$vimhelplint not found." >&2 + echo "Run 'make build/vimhelplint' Neomake's root directory to install it." >&2 + exit 64 +fi + +file="$1" +if [ -z "$file" ]; then + echo 'No input file specified.' >&2 + exit 64 +fi +if ! [ -e "$file" ]; then + echo "File $file is not readable." >&2 + exit 1 +fi + +out=$(${VIMHELPLINT_VIM:-vim} -esN -u NONE -i NONE \ + -c "silent edit $1" \ + -c 'set ft=help' \ + -c "source $vimhelplint" \ + -c 'verb VimhelpLintEcho' \ + -c 'qall!' 2>&1) +if [ -z "$out" ]; then + exit 0 +fi +echo "$out" +exit 1 diff --git a/dotfiles/.local/share/nvim/site/doc/airline.txt b/dotfiles/.local/share/nvim/site/doc/airline.txt new file mode 100644 index 0000000..5ef18d3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/doc/airline.txt @@ -0,0 +1,1554 @@ +*airline.txt* Lean and mean status/tabline that's light as air +*airline* *vim-airline* + _ _ _ _ ~ + __ _(_)_ __ ___ __ _(_)_ __| (_)_ __ ___ ~ + \ \ / / | '_ ` _ \ _____ / _` | | '__| | | '_ \ / _ \ ~ + \ V /| | | | | | |_____| (_| | | | | | | | | | __/ ~ + \_/ |_|_| |_| |_| \__,_|_|_| |_|_|_| |_|\___| ~ + ~ +============================================================================== +CONTENTS *airline-contents* + + 01. Intro ............................................... |airline-intro| + 02. Features ......................................... |airline-features| + 03. Name ................................................. |airline-name| + 04. Configuration ............................... |airline-configuration| + 05. Commands ......................................... |airline-commands| + 06. Autocommands ................................. |airline-autocommands| + 07. Customization ............................... |airline-customization| + 08. Extensions ..................................... |airline-extensions| + 09. Advanced Customization ............. |airline-advanced-customization| + 10. Funcrefs ......................................... |airline-funcrefs| + 11. Pipeline ......................................... |airline-pipeline| + 12. Writing Extensions ..................... |airline-writing-extensions| + 13. Writing Themes ..................................... |airline-themes| + 14. Troubleshooting ........................... |airline-troubleshooting| + 15. Contributions ............................... |airline-contributions| + 16. License ........................................... |airline-license| + +============================================================================== +INTRODUCTION *airline-intro* + +vim-airline is a fast and lightweight alternative to powerline, written +in 100% vimscript with no outside dependencies. + +When the plugin is correctly loaded, Vim will draw a nice statusline at the +bottom of each window. + +That line consists of several sections, each one displaying some piece of +information. By default (without configuration) this line will look like this: > + ++-----------------------------------------------------------------------------+ +|~ | +|~ | +|~ VIM - Vi IMproved | +|~ | +|~ version 8.0 | +|~ by Bram Moolenaar et al. | +|~ Vim is open source and freely distributable | +|~ | +|~ type :h :q<Enter> to exit | +|~ type :help<Enter> or <F1> for on-line help | +|~ type :help version8<Enter> for version info | +|~ | +|~ | ++-----------------------------------------------------------------------------+ +| A | B | C X | Y | Z | [...] | ++-----------------------------------------------------------------------------+ + +The statusline is the colored line at the bottom, which contains the sections +(possibly in different colors): + +section meaning (example)~ +-------------------------- + A displays the mode + additional flags like crypt/spell/paste (INSERT) + B VCS information (branch, hunk summary) (master) + C filename + read-only flag (~/.vim/vimrc RO) + X filetype (vim) + Y file encoding[fileformat] (utf-8[unix]) + Z current position in the file + percentage % ☰ current line/number of lines ln : column + So this: 10% ☰ 10/100 ln : 20 means: > + 10% - 10 percent + ☰ 10 - current line 10 + /100 ln - of 100 lines + : 20 - current column 20 +< + [...] additional sections (warning/errors/statistics) + from external plugins (e.g. YCM/syntastic/...) + +For a better look, those sections can be colored differently, depending on the mode and +whether the current file is 'modified' + +Additionally, several extensions exists, that can provide additional feature (e.g. the +tabline extension provides an extra statusline on the top of the Vim window and can +display loaded buffers and tabs in the current Vim session). + +Most of this is customizable and the default sections can be configured using the vim +variables g:airline_section_<name> (see |airline-default-sections|) + +============================================================================== +FEATURES *airline-features* + +* tiny core written with extensibility in mind. +* integrates with many popular plugins. +* looks good with regular fonts, and provides configuration points so you + can use unicode or powerline symbols. +* optimized for speed; it loads in under a millisecond. +* fully customizable; if you know a little 'statusline' syntax you can + tweak it to your needs. +* extremely easy to write themes. + +============================================================================== +NAME *airline-name* + +Where did the name come from? + +I wrote this on an airplane, and since it's light as air it turned out to be a +good name :-) + +============================================================================== +CONFIGURATION *airline-configuration* + +There are a couple configuration values available (shown with their default +values): + +* the separator used on the left side > + let g:airline_left_sep='>' +< +* the separator used on the right side > + let g:airline_right_sep='<' +< +* enable modified detection > + let g:airline_detect_modified=1 + +* enable paste detection > + let g:airline_detect_paste=1 +< +* enable crypt detection > + let g:airline_detect_crypt=1 + +* enable spell detection > + let g:airline_detect_spell=1 + +* display spelling language when spell detection is enabled + (if enough space is available) > + let g:airline_detect_spelllang=1 +< +* enable iminsert detection > + let g:airline_detect_iminsert=0 +< +* determine whether inactive windows should have the left section collapsed to + only the filename of that buffer. > + let g:airline_inactive_collapse=1 +< +* Use alternative seperators for the statusline of inactive windows > + let g:airline_inactive_alt_sep=1 +< +* themes are automatically selected based on the matching colorscheme. this + can be overridden by defining a value. > + let g:airline_theme='dark' +< + Note: Only the dark theme is distributed with vim-airline. For more themes, + checkout the vim-airline-themes repository + (github.com/vim-airline/vim-airline-themes) + +* if you want to patch the airline theme before it gets applied, you can + supply the name of a function where you can modify the palette. > + let g:airline_theme_patch_func = 'AirlineThemePatch' + function! AirlineThemePatch(palette) + if g:airline_theme == 'badwolf' + for colors in values(a:palette.inactive) + let colors[3] = 245 + endfor + endif + endfunction +< +* By default, airline will use unicode symbols if your encoding matches + utf-8. If you want the powerline symbols set this variable: > + let g:airline_powerline_fonts = 1 +< + If you want to use plain ascii symbols, set this variable: > + let g:airline_symbols_ascii = 1 +< +* define the set of text to display for each mode. > + let g:airline_mode_map = {} " see source for the defaults + + " or copy paste the following into your vimrc for shortform text + let g:airline_mode_map = { + \ '__' : '-', + \ 'c' : 'C', + \ 'i' : 'I', + \ 'ic' : 'I', + \ 'ix' : 'I', + \ 'n' : 'N', + \ 'ni' : 'N', + \ 'no' : 'N', + \ 'R' : 'R', + \ 'Rv' : 'R', + \ 's' : 'S', + \ 'S' : 'S', + \ '' : 'S', + \ 't' : 'T', + \ 'v' : 'V', + \ 'V' : 'V', + \ '' : 'V', + \ } +< +* define the set of filename match queries which excludes a window from having + its statusline modified > + let g:airline_exclude_filenames = [] " see source for current list +< +* define the set of filetypes which are excluded from having its window + statusline modified > + let g:airline_exclude_filetypes = [] " see source for current list +< +* defines whether the preview window should be excluded from have its window + statusline modified (may help with plugins which use the preview window + heavily) > + let g:airline_exclude_preview = 0 +< +* disable the Airline customization for selective windows (this is a + window-local variable so you can disable it per-window) > + let w:airline_disabled = 1 + +* Do not draw separators for empty sections (only for the active window) > + let g:airline_skip_empty_sections = 1 +< + This variable can be overriden by setting a window-local variable with + the same name (in the correct window): > + let w:airline_skip_empty_sections = 0 +< +* Caches the changes to the highlighting groups, should therefore be faster. + Set this to one, if you experience a sluggish Vim: > + let g:airline_highlighting_cache = 0 +< +* disable airline on FocusLost autocommand (e.g. when Vim loses focus): > + let g:airline_focuslost_inactive = 1 +< +* configure the fileformat output + By default, it will display something like 'utf-8[unix]', however, you can + skip displaying it, if the output matches a configured string. To do so, + set > + let g:airline#parts#ffenc#skip_expected_string='utf-8[unix]' +< +============================================================================== +COMMANDS *airline-commands* + +:AirlineTheme {theme-name} *:AirlineTheme* + Displays or changes the current theme. + +:AirlineToggleWhitespace *:AirlineToggleWhitespace* + Toggles whitespace detection. + +:AirlineToggle *:AirlineToggle* + Toggles between the standard 'statusline' and airline. + +:AirlineRefresh *:AirlineRefresh* + Refreshes all highlight groups and redraws the statusline. + +:AirlineExtensions *:AirlineExtensions* + Shows the status of all available airline extensions. + +============================================================================== +AUTOCOMMANDS *airline-autocommands* + +Airline comes with some user-defined autocommands. + +|AirlineAfterInit| after plugin is initialized, but before the statusline + is replaced +|AirlineAfterTheme| after theme of the statusline has been changed +|AirlineToggledOn| after airline is activated and replaced the statusline +|AirlineToggledOff| after airline is deactivated and the statusline is + restored to the original +|AirlineModeChanged| The mode in Vim changed. + +============================================================================== +CUSTOMIZATION *airline-customization* + +The following are some unicode symbols for customizing the left/right +separators, as well as the powerline font glyphs. + +Note: You must define the dictionary first before setting values. Also, it's a +good idea to check whether it exists as to avoid accidentally overwriting +its contents. > + if !exists('g:airline_symbols') + let g:airline_symbols = {} + endif + + " unicode symbols + let g:airline_left_sep = '»' + let g:airline_left_sep = '▶' + let g:airline_right_sep = '«' + let g:airline_right_sep = '◀' + let g:airline_symbols.crypt = '🔒' + let g:airline_symbols.linenr = '☰' + let g:airline_symbols.linenr = '␊' + let g:airline_symbols.linenr = '' + let g:airline_symbols.linenr = '¶' + let g:airline_symbols.maxlinenr = '' + let g:airline_symbols.maxlinenr = '㏑' + let g:airline_symbols.branch = '⎇' + let g:airline_symbols.paste = 'ρ' + let g:airline_symbols.paste = 'Þ' + let g:airline_symbols.paste = '∥' + let g:airline_symbols.spell = 'Ꞩ' + let g:airline_symbols.notexists = 'Ɇ' + let g:airline_symbols.whitespace = 'Ξ' + + " powerline symbols + let g:airline_left_sep = '' + let g:airline_left_alt_sep = '' + let g:airline_right_sep = '' + let g:airline_right_alt_sep = '' + let g:airline_symbols.branch = '' + let g:airline_symbols.readonly = '' + let g:airline_symbols.linenr = '☰' + let g:airline_symbols.maxlinenr = '' + + " old vim-powerline symbols + let g:airline_left_sep = '⮀' + let g:airline_left_alt_sep = '⮁' + let g:airline_right_sep = '⮂' + let g:airline_right_alt_sep = '⮃' + let g:airline_symbols.branch = '⭠' + let g:airline_symbols.readonly = '⭤' + let g:airline_symbols.linenr = '⭡' +< + +For more intricate customizations, you can replace the predefined sections +with the usual statusline syntax. + +Note: If you define any section variables it will replace the default values +entirely. If you want to disable only certain parts of a section you can try +using variables defined in the |airline-configuration| or |airline-extensions| +section. + |airline-default-sections| +> + variable names default contents + ---------------------------------------------------------------------------- + let g:airline_section_a (mode, crypt, paste, spell, iminsert) + let g:airline_section_b (hunks, branch)[*] + let g:airline_section_c (bufferline or filename) + let g:airline_section_gutter (readonly, csv) + let g:airline_section_x (tagbar, filetype, virtualenv) + let g:airline_section_y (fileencoding, fileformat) + let g:airline_section_z (percentage, line number, column number) + let g:airline_section_error (ycm_error_count, syntastic-err, eclim, + languageclient_error_count) + let g:airline_section_warning (ycm_warning_count, syntastic-warn, + languageclient_warning_count, whitespace) + + " [*] This section needs at least the fugitive extension or else + " it will remain empty + " + " here is an example of how you could replace the branch indicator with + " the current working directory (limited to 10 characters), + " followed by the filename. + let g:airline_section_b = '%-0.10{getcwd()}' + let g:airline_section_c = '%t' +< + *airline#ignore_bufadd_pat* +Determines a pattern to ignore a buffer name for various things (e.g. the +tabline extension) or the read-only check. Default is +`g:airline#extensions#tabline#ignore_bufadd_pat` (see below) or +`'gundo|undotree|vimfiler|tagbar|nerd_tree|startify|!'` if it is unset. + +The "!" prevents terminal buffers to appear in the tabline. + + *airline#extensions#tabline#exclude_buffers* +Buffer numbers to be excluded from showing in the tabline (similar to +|airline#ignore_bufadd_pat|. + +============================================================================== +EXTENSIONS *airline-extensions* + +Most extensions are enabled by default and lazily loaded when the +corresponding plugin (if any) is detected. + +By default, airline will attempt to load any extension it can find in the +'runtimepath'. On some systems this can result in an undesirable startup +cost. You can disable the check with the following flag. > + let g:airline#extensions#disable_rtp_load = 1 +< + Note: Third party plugins that rely on this behavior will be affected. You + will need to manually load them. + +Alternatively, if you want a minimalistic setup and would rather opt-in which +extensions get loaded instead of disabling each individually, you can declare +the following list variable: > + " an empty list disables all extensions + let g:airline_extensions = [] + + " or only load what you want + let g:airline_extensions = ['branch', 'tabline'] +< +In addition, each extension can be configured individually. Following are the +options for each extension (in alphabetical order, after the default extension) + +Usually, each extension will only be loaded if the required Vim plugin is +installed as well, otherwise it will remain disabled. See the output of the +|:AirlineExtensions| command. + +------------------------------------- *airline-ale* +ale <https://github.com/w0rp/ale> + +* enable/disable ale integration > + let g:airline#extensions#ale#enabled = 1 + +* ale error_symbol > + let airline#extensions#ale#error_symbol = 'E:' +< +* ale warning > + let airline#extensions#ale#warning_symbol = 'W:' + +* ale show_line_numbers > + let airline#extensions#ale#show_line_numbers = 1 +< +* ale open_lnum_symbol > + let airline#extensions#ale#open_lnum_symbol = '(L' +< +* ale close_lnum_symbol > + let airline#extensions#ale#close_lnum_symbol = ')' +< +------------------------------------- *airline-branch* +vim-airline will display the branch-indicator together with the branch name in +the statusline, if one of the following plugins is installed: + +fugitive.vim <https://github.com/tpope/vim-fugitive> +lawrencium <https://bitbucket.org/ludovicchabant/vim-lawrencium> +vcscommand <http://www.vim.org/scripts/script.php?script_id=90> + +If a file is edited, that is not yet in the repository, the +notexists symbol will be displayed after the branch name. + +* enable/disable fugitive/lawrencium integration > + let g:airline#extensions#branch#enabled = 1 +< +* change the text for when no branch is detected > + let g:airline#extensions#branch#empty_message = '' +< +* define the order in which the branches of different vcs systems will be + displayed on the statusline (currently only for fugitive and lawrencium) > + let g:airline#extensions#branch#vcs_priority = ["git", "mercurial"] +< +* use vcscommand.vim if available > + let g:airline#extensions#branch#use_vcscommand = 0 +< +* truncate long branch names to a fixed length > + let g:airline#extensions#branch#displayed_head_limit = 10 +< +* customize formatting of branch name > + " default value leaves the name unmodifed + let g:airline#extensions#branch#format = 0 + + " to only show the tail, e.g. a branch 'feature/foo' becomes 'foo', use + let g:airline#extensions#branch#format = 1 + + " to truncate all path sections but the last one, e.g. a branch + " 'foo/bar/baz' becomes 'f/b/baz', use + let g:airline#extensions#branch#format = 2 + + " if a string is provided, it should be the name of a function that + " takes a string and returns the desired value + let g:airline#extensions#branch#format = 'CustomBranchName' + function! CustomBranchName(name) + return '[' . a:name . ']' + endfunction +< +* truncate sha1 commits at this number of characters > + let g:airline#extensions#branch#sha1_len = 10 + +* customize branch name retrieval for any version control system > + let g:airline#extensions#branch#custom_head = 'GetScmBranch' + function! GetScmBranch() + if !exists('b:perforce_client') + let b:perforce_client = system('p4 client -o | grep Client') + " Invalidate cache to prevent stale data when switching clients. Use a + " buffer-unique group name to prevent clearing autocmds for other + " buffers. + exec 'augroup perforce_client-'. bufnr("%") + au! + autocmd BufWinLeave <buffer> silent! unlet! b:perforce_client + augroup END + endif + return b:perforce_client + endfunction +< +------------------------------------- *airline-bufferline* +vim-bufferline <https://github.com/bling/vim-bufferline> + +* enable/disable bufferline integration > + let g:airline#extensions#bufferline#enabled = 1 +< +* determine whether bufferline will overwrite customization variables > + let g:airline#extensions#bufferline#overwrite_variables = 1 +< +------------------------------------- *airline-capslock* +vim-capslock <https://github.com/tpope/vim-capslock> + +* enable/disable vim-capslock integration > + let g:airline#extensions#capslock#enabled = 1 + +------------------------------------- *airline-csv* +csv.vim <https://github.com/chrisbra/csv.vim> + +* enable/disable csv integration for displaying the current column. > + let g:airline#extensions#csv#enabled = 1 +< +* change how columns are displayed. > + let g:airline#extensions#csv#column_display = 'Number' (default) + let g:airline#extensions#csv#column_display = 'Name' +< +------------------------------------- *airline-ctrlp* +ctrlp <https://github.com/ctrlpvim/ctrlp.vim> + +* configure which mode colors should ctrlp window use (takes effect + only if the active airline theme doesn't define ctrlp colors) > + let g:airline#extensions#ctrlp#color_template = 'insert' (default) + let g:airline#extensions#ctrlp#color_template = 'normal' + let g:airline#extensions#ctrlp#color_template = 'visual' + let g:airline#extensions#ctrlp#color_template = 'replace' +< +* configure whether to show the previous and next modes (mru, buffer, etc...) +> + let g:airline#extensions#ctrlp#show_adjacent_modes = 1 +< +------------------------------------- *airline-ctrlspace* +vim-ctrlspace <https://github.com/szw/vim-ctrlspace> + +* enable/disable vim-ctrlspace integration > + let g:airline#extensions#ctrlspace#enabled = 1 +< + To make the vim-ctrlspace integration work you will need to make the + ctrlspace statusline function call the correct airline function. Therefore + add the following line into your .vimrc: > + + let g:CtrlSpaceStatuslineFunction = "airline#extensions#ctrlspace#statusline()" +< +------------------------------------- *airline-cursormode* +cursormode <https://github.com/vheon/vim-cursormode> + +Built-in extension to displays cursor in different colors depending on the +current mode (only works in terminals iTerm, AppleTerm and xterm) + +* enable cursormode integration > + let g:airline#extensions#cursormode#enabled = 1 + +* mode function. Return value is used as key for the color mapping. Default is + |mode()| + `let g:cursormode_mode_func = 'mode'` + +* color mapping. Keys come from `g:cursormode_mode_func` (background value can + be appended) + `let g:cursormode_color_map = {` + `\ "nlight": '#000000',` + `\ "ndark": '#BBBBBB',` + `\ "i": g:airline#themes#{g:airline_theme}#palette.insert.airline_a[1],` + `\ "R": g:airline#themes#{g:airline_theme}#palette.replace.airline_a[1],` + `\ "v": g:airline#themes#{g:airline_theme}#palette.visual.airline_a[1],` + `\ "V": g:airline#themes#{g:airline_theme}#palette.visual.airline_a[1],` + `\ "\<C-V>": g:airline#themes#{g:airline_theme}#palette.visual.airline_a[1],` + `\ }` + +------------------------------------- *airline-default* +The default extensions is an internal extension that is needed for handling +all other extensions, takes care of how all sections will be combined into a +'statusline' specific item and when to truncate each section. + +It understands all of the `g:` variables in the |airline-configuration| +section, however it also has some more fine-tuned configuration values that +you can use. + +* control which sections get truncated and at what width. > + let g:airline#extensions#default#section_truncate_width = { + \ 'b': 79, + \ 'x': 60, + \ 'y': 88, + \ 'z': 45, + \ 'warning': 80, + \ 'error': 80, + \ } + + " Note: set to an empty dictionary to disable truncation. + let g:airline#extensions#default#section_truncate_width = {} +< +* configure the layout of the sections by specifying an array of two arrays + (first array is the left side, second array is the right side). > + let g:airline#extensions#default#layout = [ + \ [ 'a', 'b', 'c' ], + \ [ 'x', 'y', 'z', 'error', 'warning' ] + \ ] +< +* configure the layout to not use %(%) grouping items in the statusline. + Try setting this to zero, if you notice bleeding color artifacts > + let airline#extensions#default#section_use_groupitems = 1 +< +------------------------------------- *airline-eclim* +eclim <https://eclim.org> + +* enable/disable eclim integration, which works well with the + |airline-syntastic| extension. > + let g:airline#extensions#eclim#enabled = 1 + +------------------------------------- *airline-fugitiveline* +This extension hides the fugitive://**// part of the buffer names, to only +show the file name as if it were in the current working tree. +It is deactivated by default if |airline-bufferline| is activated. + +* enable/disable bufferline integration > + let g:airline#extensions#fugitiveline#enabled = 1 +< +------------------------------------- *airline-grepper* +vim-grepper <https://github.com/mhinz/vim-grepper> + +* enable/disable vim-grepper integration > + let g:airline#extensions#grepper#enabled = 1 + +------------------------------------- *airline-gutentags* +vim-gutentags <https://github.com/ludovicchabant/vim-gutentags> + +* enable/disable vim-gutentags integration > + let g:airline#extensions#gutentags#enabled = 1 + +------------------------------------- *airline-hunks* +vim-gitgutter <https://github.com/airblade/vim-gitgutter> +vim-signify <https://github.com/mhinz/vim-signify> +changesPlugin <https://github.com/chrisbra/changesPlugin> +quickfixsigns <https://github.com/tomtom/quickfixsigns_vim> + +* enable/disable showing a summary of changed hunks under source control. > + let g:airline#extensions#hunks#enabled = 1 +< +* enable/disable showing only non-zero hunks. > + let g:airline#extensions#hunks#non_zero_only = 0 +< +* set hunk count symbols. > + let g:airline#extensions#hunks#hunk_symbols = ['+', '~', '-'] +< +------------------------------------- *airline-keymap* +vim-keymap + +This extension displays the current 'keymap' in use. + +* enable/disable vim-keymap extension > + let g:airline#extensions#keymap#enabled = 1 + +------------------------------------- *airline-languageclient* +LanguageClient <https://github.com/autozimu/LanguageClient-neovim> +(despite its name, it can be used for Vim and Neovim). + +* enable/disable LanguageClient integration > + let g:airline#extensions#languageclient#enabled = 1 + +* languageclient error_symbol > + let airline#extensions#languageclient#error_symbol = 'E:' +< +* languageclient warning_symbol > + let airline#extensions#languageclient#warning_symbol = 'W:' + +* languageclient show_line_numbers > + let airline#extensions#languageclient#show_line_numbers = 1 +< +* languageclient open_lnum_symbol > + let airline#extensions#languageclient#open_lnum_symbol = '(L' +< +* languageclient close_lnum_symbol > + let airline#extensions#languageclient#close_lnum_symbol = ')' + +------------------------------------- *airline-localsearch* +localsearch <https://github.com/mox-mox/localsearch> + +* enable/disable localsearch indicator integration > + let g:airline#extensions#localsearch#enabled = 1 + +------------------------------------- *airline-neomake* +neomake <https://github.com/neomake/neomake> + +* enable/disable neomake integration > + let g:airline#extensions#neomake#enabled = 1 + +* neomake error_symbol > + let airline#extensions#neomake#error_symbol = 'E:' +< +* neomake warning > + let airline#extensions#neomake#warning_symbol = 'W:' +< +------------------------------------- *airline-nerdtree* +NerdTree <https://github.com/scrooloose/nerdtree.git> + +Airline displays the Nerdtree specific statusline (which can be configured using +the |'NerdTreeStatusline'| variable (for details, see the help of NerdTree) + +------------------------------------- *airline-nrrwrgn* +NrrwRgn <https://github.com/chrisbra/NrrwRgn> + +* enable/disable NrrwRgn integration > + let g:airline#extensions#nrrwrgn#enabled = 1 + +------------------------------------- *airline-obsession* +vim-obsession <https://github.com/tpope/vim-obsession> + +* enable/disable vim-obsession integration > + let g:airline#extensions#obsession#enabled = 1 + +* set marked window indicator string > + let g:airline#extensions#obsession#indicator_text = '$' +< +------------------------------------- *airline-po* +This extension will display the currently translated, untranslated and fuzzy +messages when editing translations (po files). Related plugin (not necessary +for this extension is po.vim from +<http://www.vim.org/scripts/script.php?script_id=2530> + +It will be enabled if the `msgfmt` executable is available and one is editing +files with the 'filetype' "po". + +* enable/disable po integration > + let g:airline#extensions#po#enabled = 1 +< +* truncate width names to a fixed length > + let g:airline#extensions#po#displayed_limit = 0 + +------------------------------------- *airline-promptline* +promptline <https://github.com/edkolev/promptline.vim> + +* configure the path to the snapshot .sh file. Mandatory option. The created + file should be sourced by the shell on login > + " in .vimrc + airline#extensions#promptline#snapshot_file = "~/.shell_prompt.sh" + + " in .bashrc/.zshrc + [ -f ~/.shell_prompt.sh ] && source ~/.shell_prompt.sh +< +* enable/disable promptline integration > + let g:airline#extensions#promptline#enabled = 0 +< +* configure which mode colors should be used in prompt > + let airline#extensions#promptline#color_template = 'normal' (default) + let airline#extensions#promptline#color_template = 'insert' + let airline#extensions#promptline#color_template = 'visual' + let airline#extensions#promptline#color_template = 'replace' +< +------------------------------------- *airline-quickfix* +The quickfix extension is a simple built-in extension which determines +whether the buffer is a quickfix or location list buffer, and adjusts the +title accordingly. + +* configure the title text for quickfix buffers > + let g:airline#extensions#quickfix#quickfix_text = 'Quickfix' +< +* configure the title text for location list buffers > + let g:airline#extensions#quickfix#location_text = 'Location' +< +------------------------------------- *airline-syntastic* +syntastic <https://github.com/vim-syntastic/syntastic> + +* enable/disable syntastic integration > + let g:airline#extensions#syntastic#enabled = 1 + + Note: The recommendation from syntastic to modify the statusline directly + does not apply, if you use vim-airline, since it will take care for you of + adjusting the statusline. + +* syntastic error_symbol > + let airline#extensions#syntastic#error_symbol = 'E:' +< +* syntastic statusline error format (see |syntastic_stl_format|) > + let airline#extensions#syntastic#stl_format_err = '%E{[%e(#%fe)]}' + +* syntastic warning > + let airline#extensions#syntastic#warning_symbol = 'W:' +< +* syntastic statusline warning format (see |syntastic_stl_format|) > + let airline#extensions#syntastic#stl_format_warn = '%W{[%w(#%fw)]}' +< +------------------------------------- *airline-tabline* +Note: If you're using the ctrlspace tabline only the option marked with (c) +are supported! + +* enable/disable enhanced tabline. (c) > + let g:airline#extensions#tabline#enabled = 0 + +* enable/disable displaying open splits per tab (only when tabs are opened). > + let g:airline#extensions#tabline#show_splits = 1 + +* switch position of buffers and tabs on splited tabline (c) + (only supported for ctrlspace plugin). > + let g:airline#extensions#tabline#switch_buffers_and_tabs = 0 +< +* enable/disable displaying buffers with a single tab. (c) > + let g:airline#extensions#tabline#show_buffers = 1 + +Note: If you are using neovim (has('tablineat') = 1), then you can click +on the tabline with the left mouse button to switch to that buffer, and +with the middle mouse button to delete that buffer. + +* if you want to show the current active buffer like this: + ---------------------- + buffer <buffer> buffer ` +> + let g:airline#extensions#tabline#alt_sep = 1 +< Only makes sense, if g:airline_right_sep is not empty. + default: 0 + +* enable/disable displaying tabs, regardless of number. (c) > + let g:airline#extensions#tabline#show_tabs = 1 +< +* configure filename match rules to exclude from the tabline. > + let g:airline#extensions#tabline#excludes = [] + +* enable/disable display preview window buffer in the tabline. > + let g:airline#extensions#tabline#exclude_preview = 1 + +* configure how numbers are displayed in tab mode. > + let g:airline#extensions#tabline#tab_nr_type = 0 " # of splits (default) + let g:airline#extensions#tabline#tab_nr_type = 1 " tab number + let g:airline#extensions#tabline#tab_nr_type = 2 " splits and tab number + let g:airline#extensions#tabline#tabnr_formatter = 'tabnr' + + Note: last option can be used to specify a different formatter for + displaying the numbers. By default tabline/formatter/tabnr.vim is used +< +* enable/disable displaying tab number in tabs mode. > + let g:airline#extensions#tabline#show_tab_nr = 1 + +* enable/disable displaying tab number in tabs mode for ctrlspace. (c) > + let g:airline#extensions#tabline#ctrlspace_show_tab_nr = 0 + +* enable/disable displaying tab type (e.g. [buffers]/[tabs]) > + let g:airline#extensions#tabline#show_tab_type = 1 + +* show buffer label at first position: > + let g:airline#extensions#tabline#buf_label_first = 1 + +* rename label for buffers (default: 'buffers') (c) > + let g:airline#extensions#tabline#buffers_label = 'b' + +* rename label for tabs (default: 'tabs') (c) > + let g:airline#extensions#tabline#tabs_label = 't' + +* change the symbol for skipped tabs/buffers (default '...') > + let g:airline#extensions#tabline#overflow_marker = '…' + +* always show current tabpage/buffer first > + let airline#extensions#tabline#current_first = 1 +< default: 0 + +* enable/disable displaying index of the buffer. + + When enabled, numbers will be displayed in the tabline and mappings will be + exposed to allow you to select a buffer directly. Up to 11 mappings will be + exposed. > + + let g:airline#extensions#tabline#buffer_idx_mode = 1 + nmap <leader>1 <Plug>AirlineSelectTab1 + nmap <leader>2 <Plug>AirlineSelectTab2 + nmap <leader>3 <Plug>AirlineSelectTab3 + nmap <leader>4 <Plug>AirlineSelectTab4 + nmap <leader>5 <Plug>AirlineSelectTab5 + nmap <leader>6 <Plug>AirlineSelectTab6 + nmap <leader>7 <Plug>AirlineSelectTab7 + nmap <leader>8 <Plug>AirlineSelectTab8 + nmap <leader>9 <Plug>AirlineSelectTab9 + nmap <leader>- <Plug>AirlineSelectPrevTab + nmap <leader>+ <Plug>AirlineSelectNextTab +< + The <Plug>AirlineSelect<Prev/Next>Tab mapping handles counts as well, + so one can handle arbirtrarily number of buffers/tabs. + + Note: Mappings will be ignored within "g:airline#extensions#tabline#keymap_ignored_filetypes". + + Note: In buffer_idx_mode these mappings won't change the + current tab, but switch to the buffer visible in that tab. + Use |gt| for switching tabs. + In tabmode, those mappings will switch to the specified tab. + +* define the set of filetypes which are ignored selectTab keymappings > + let g:airline#extensions#tabline#keymap_ignored_filetypes = ['vimfiler', 'nerdtree'] + +* change the display format of the buffer index > + let g:airline#extensions#tabline#buffer_idx_format = { + \ '0': '0 ', + \ '1': '1 ', + \ '2': '2 ', + \ '3': '3 ', + \ '4': '4 ', + \ '5': '5 ', + \ '6': '6 ', + \ '7': '7 ', + \ '8': '8 ', + \ '9': '9 ' + \} +< +* defines the name of a formatter for how buffer names are displayed. (c) > + let g:airline#extensions#tabline#formatter = 'default' + + " here is how you can define a 'foo' formatter: + " create a file in the dir autoload/airline/extensions/tabline/formatters/ + " called foo.vim > + function! airline#extensions#tabline#formatters#foo#format(bufnr, buffers) + return fnamemodify(bufname(a:bufnr), ':t') + endfunction + let g:airline#extensions#tabline#formatter = 'foo' +< + + Note: the following variables are used by the 'default' formatter. + When no disambiguation is needed, both 'unique_tail_improved' and + 'unique_tail' delegate formatting to 'default', so these variables also + control rendering of unique filenames when using these formatters. + + * configure whether buffer numbers should be shown. > + let g:airline#extensions#tabline#buffer_nr_show = 0 +< + * configure how buffer numbers should be formatted with |printf()|. > + let g:airline#extensions#tabline#buffer_nr_format = '%s: ' +< + * configure the formatting of filenames (see |filename-modifiers|). > + let g:airline#extensions#tabline#fnamemod = ':p:.' +< + * configure collapsing parent directories in buffer name. > + let g:airline#extensions#tabline#fnamecollapse = 1 +< + * configure truncating non-active buffer names to specified length. > + let g:airline#extensions#tabline#fnametruncate = 0 + + " The `unique_tail` algorithm will display the tail of the filename, unless + " there is another file of the same name, in which it will display it along + " with the containing parent directory. + let g:airline#extensions#tabline#formatter = 'unique_tail' + + " The following variables are also used by `unique_tail` formatter. + " the meanings are the same as the ones in default formatter. + + let g:airline#extensions#tabline#fnamemod = ':p:.' + let g:airline#extensions#tabline#fnamecollapse = 1 + + " The `unique_tail_improved` - another algorithm, that will smartly uniquify + " buffers names with similar filename, suppressing common parts of paths. + let g:airline#extensions#tabline#formatter = 'unique_tail_improved' +< +* configure the minimum number of buffers needed to show the tabline. > + let g:airline#extensions#tabline#buffer_min_count = 0 +< + Note: this setting only applies to a single tab and when `show_buffers` is + true. + +* configure the minimum number of tabs needed to show the tabline. > + let g:airline#extensions#tabline#tab_min_count = 0 +< + Note: this setting only applies when `show_buffers` is false. + +* configure separators for the tabline only. > + let g:airline#extensions#tabline#left_sep = '' + let g:airline#extensions#tabline#left_alt_sep = '' + let g:airline#extensions#tabline#right_sep = '' + let g:airline#extensions#tabline#right_alt_sep = '' + +* configure whether close button should be shown: > + let g:airline#extensions#tabline#show_close_button = 1 + +* configure symbol used to represent close button > + let g:airline#extensions#tabline#close_symbol = 'X' + +* configure pattern to be ignored on BufAdd autocommand > + " fixes unnecessary redraw, when e.g. opening Gundo window + let airline#extensions#tabline#ignore_bufadd_pat = + \ '\c\vgundo|undotree|vimfiler|tagbar|nerd_tree' + +Note: Enabling this extension will modify 'showtabline' and 'guioptions'. + +* enable Refresh of tabline buffers on |BufAdd| autocommands + (set this to one, if you note 'AirlineTablineRefresh', however, this + won't update airline on |:badd| commands) > + let airline#extensions#tabline#disable_refresh = 0 + +* preserve windows when closing a buffer from the bufferline (neovim specific, + only works with buffers and not real tabs, default: 0) > + let airline#extensions#tabline#middle_click_preserves_windows = 1 +< +------------------------------------- *airline-taboo* +taboo.vim <https://github.com/gcmt/taboo.vim> + +* enable/disable taboo.vim integration > + let g:airline#extensions#taboo#enabled = 1 +< +------------------------------------- *airline-tagbar* +tagbar <https://github.com/majutsushi/tagbar> + +* enable/disable tagbar integration > + let g:airline#extensions#tagbar#enabled = 1 +< +* change how tags are displayed (:help tagbar-statusline) > + let g:airline#extensions#tagbar#flags = '' (default) + let g:airline#extensions#tagbar#flags = 'f' + let g:airline#extensions#tagbar#flags = 's' + let g:airline#extensions#tagbar#flags = 'p' +< +------------------------------------- *airline-tmuxline* +tmuxline <https://github.com/edkolev/tmuxline.vim> + +* enable/disable tmuxline integration > + let g:airline#extensions#tmuxline#enabled = 0 +< +* configure which mode colors should be used in tmux statusline > + let airline#extensions#tmuxline#color_template = 'normal' (default) + let airline#extensions#tmuxline#color_template = 'insert' + let airline#extensions#tmuxline#color_template = 'visual' + let airline#extensions#tmuxline#color_template = 'replace' +< +* if specified, setting this option will trigger writing to the file whenever the + airline theme is applied, i.e. when :AirlineTheme is executed and on vim + startup > + airline#extensions#tmuxline#snapshot_file = "~/.tmux-statusline-colors.conf" +< +------------------------------------- *airline-vimagit* +vimagit <https://github.com/jreybert/vimagit> + +* enable/disable vimagit integration > + let g:airline#extensions#vimagit#enabled = 1 +< +------------------------------------- *airline-vimtex* +vimtex <https://github.com/lervag/vimtex> + +Shows the current file's vimtex related info. + +* enable/disable vimtex integration > + let g:airline#extensions#vimtex#enabled = 1 +< +* left and right delimiters (shown only when status string is not empty) > + let g:airline#extensions#vimtex#left = "{" + let g:airline#extensions#vimtex#right = "}" + +State indicators: + +* the current tex file is the main project file (nothing is shown by default) > + let g:airline#extensions#vimtex#main = "" + +* the current tex file is a subfile of the project + and the compilation is set for the main file > + let g:airline#extensions#vimtex#sub_main = "m" + +* the current tex file is a subfile of the project + and the compilation is set for this subfile > + let g:airline#extensions#vimtex#sub_local = "l" + +* single compilation is running > + let g:airline#extensions#vimtex#compiled = "c₁" + +* continuous compilation is running > + let g:airline#extensions#vimtex#continuous = "c" + +* viewer is opened > + let g:airline#extensions#vimtex#viewer = "v" + +------------------------------------- *airline-virtualenv* +virtualenv <https://github.com/jmcantrell/vim-virtualenv> + +* enable/disable virtualenv integration > + let g:airline#extensions#virtualenv#enabled = 1 +< +------------------------------------- *airline-whitespace* +* enable/disable detection of whitespace errors. > + let g:airline#extensions#whitespace#enabled = 1 +< +* disable detection of whitespace errors. > + " useful to call for particular file types (e.g., in "ftplugin/*") + silent! call airline#extensions#whitespace#disable() +< +* customize the type of mixed indent checking to perform. > + " must be all spaces or all tabs before the first non-whitespace character + let g:airline#extensions#whitespace#mixed_indent_algo = 0 (default) + + " certain number of spaces are allowed after tabs, but not in between + " this algorithm works well for /** */ style comments in a tab-indented file + let g:airline#extensions#whitespace#mixed_indent_algo = 1 + + " spaces are allowed after tabs, but not in between + " this algorithm works well with programming styles that use tabs for + " indentation and spaces for alignment + let g:airline#extensions#whitespace#mixed_indent_algo = 2 +< +* customize the whitespace symbol. > + let g:airline#extensions#whitespace#symbol = '!' +< +* configure which whitespace checks to enable. > + " indent: mixed indent within a line + " long: overlong lines + " trailing: trailing whitespace + " mixed-indent-file: different indentation in different lines + let g:airline#extensions#whitespace#checks = [ 'indent', 'trailing', 'long', 'mixed-indent-file' ] + + " this can also be configured for an individual buffer + let b:airline_whitespace_checks = [ 'indent', 'trailing', 'long', 'mixed-indent-file' ] +< +* configure the maximum number of lines where whitespace checking is enabled. > + let g:airline#extensions#whitespace#max_lines = 20000 +< +* configure whether a message should be displayed. > + let g:airline#extensions#whitespace#show_message = 1 +< +* configure the formatting of the warning messages. > + let g:airline#extensions#whitespace#trailing_format = 'trailing[%s]' + let g:airline#extensions#whitespace#mixed_indent_format = 'mixed-indent[%s]' + let g:airline#extensions#whitespace#long_format = 'long[%s]' + let g:airline#extensions#whitespace#mixed_indent_file_format = 'mix-indent-file[%s]' + +* configure custom trailing whitespace regexp rule > + let g:airline#extensions#whitespace#trailing_regexp = '\s$' + +* configure, which filetypes have special treatment of /* */ comments, + matters for mix-indent-file algorithm: > + let airline#extensions#c_like_langs = ['arduino', 'c', 'cpp', 'cuda', 'go', 'javascript', 'ld', 'php'] +< +* disable whitespace checking for an individual buffer > + " Checking is enabled by default because b:airline_whitespace_disabled + " is by default not defined: + unlet b:airline_whitespace_disabled + + " If b:airline_whitespace_disabled is defined and is non-zero for a buffer, + " then whitespace checking will be disabled for that buffer; for example: + " let b:airline_whitespace_disabled = 1 +< +* disable specific whitespace checks for individual filetypes > + " The global variable g:airline#extensions#whitespace#skip_indent_check_ft + " defines what whitespaces checks to skip per filetype. + " the list can contain any of the available checks, + " (see above at g:airline#extensions#whitespace#checks) + " To disable mixed-indent-file for go files use: + let g:airline#extensions#whitespace#skip_indent_check_ft = {'go': ['mixed-indent-file']} +< +------------------------------------- *airline-windowswap* +vim-windowswap <https://github.com/wesQ3/vim-windowswap> + +* enable/disable vim-windowswap integration > + let g:airline#extensions#windowswap#enabled = 1 + +* set marked window indicator string > + let g:airline#extensions#windowswap#indicator_text = 'WS' +< +------------------------------------- *airline-wordcount* +* enable/disable word counting of the document/visual selection > + let g:airline#extensions#wordcount#enabled = 1 +< +* set list of filetypes for which word counting is enabled: > + " The default value matches filetypes typically used for documentation + " such as markdown and help files. + let g:airline#extensions#wordcount#filetypes = + \ ['help', 'markdown', 'rst', 'org', 'text', 'asciidoc', 'tex', 'mail'] + " Use ['all'] to enable for all filetypes. + +* defines the name of a formatter for word count will be displayed: > + " The default will try to guess LC_NUMERIC and format number accordingly + " e.g. 1,042 in English and 1.042 in German locale + let g:airline#extensions#wordcount#formatter = 'default' + + " here is how you can define a 'foo' formatter: + " create a file in autoload/airline/extensions/wordcount/formatters/ + " called foo.vim, which defines the following function signature: + function! airline#extensions#wordcount#formatters#foo#to_string(wordcount) + return a:wordcount == 0 ? 'NONE' : + \ a:wordcount > 100 ? 'okay' : 'not enough') + endfunction + let g:airline#extensions#wordline#formatter = 'foo' + " The function is passed the word count of the document or visual selection + +* defines how to display the wordcount statistics for the default formatter: > + " Defaults are below. If fmt_short isn't defined, fmt is used. + " '%s' will be substituted by the word count + " fmt_short is displayed when window width is less than 80 + let g:airline#extensions#wordcount#formatter#default#fmt = '%s words' + let g:airline#extensions#wordcount#formatter#default#fmt_short = '%sW' +< +------------------------------------- *airline-xkblayout* + +The vim-xkblayout extension will only be enabled, if the global variable +`g:XkbSwitchLib` is set. It should be set to a C library that will be called +using |libcall()| with the function name `Xkb_Switch_getXkbLayout`. For +details on how to use it, see e.g. <https://github.com/ierton/xkb-switch> + +* enable/disable vim-xkblayout extension > + let g:airline#extensions#xkblayout#enabled = 1 + +* redefine keyboard layout short codes to shown in status > + let g:airline#extensions#xkblayout#short_codes = {'Russian-Phonetic': 'RU', 'ABC': 'EN'} +< + 'RU' instead of system 'Russian-Phonetic', + 'EN' instead of system 'ABC'. + + Default: > + let g:airline#extensions#xkblayout#short_codes = {'2SetKorean': 'KR', 'Chinese': 'CN', 'Japanese': 'JP'} + +* define path to the backend switcher library + Linux (Install https://github.com/ierton/xkb-switch): > + let g:XkbSwitchLib = '/usr/local/lib/libxkbswitch.so' +< + macOS (Install https://github.com/vovkasm/input-source-switcher): > + let g:XkbSwitchLib = '/usr/local/lib/libInputSourceSwitcher.dylib' + +------------------------------------- *airline-xtabline* +xtabline <https://github.com/mg979/vim-xtabline> + +This is a simplified and stand-alone version of the original extension. +The bigger version adds fzf commands, session management, tab bookmarks, and +features that you may not need. They both require |vim-airline| anyway. + +Main features and default mappings of this extension are: + +* tab cwd persistance, also across sessions if vim-obsession is being used. + +* buffer filtering in the tabline: only buffers whose path is within the tab + cwd will be shown in the tabline. + +* toggle tabs/buffer view on the tabline, toggle buffer filtering: +> + nmap <F5> <Plug>XTablineToggleTabs + nmap <leader><F5> <Plug>XTablineToggleFiltering + +* reopen last closed tab, restoring its cwd and buffers: +> + nmap <leader>tr <Plug>XTablineReopen <SID>ReopenLastTab + +* switch among filtered buffers (accepts count): +> + nmap ]l <Plug>XTablineNextBuffer + nmap [l <Plug>XTablinePrevBuffer + +* go to N buffer (a count must be provided): +> + nmap <BS> <Plug>XTablineSelectBuffer + +* alternative command if count is not provided: +> + let g:xtabline_alt_action = "buffer #" + +Note: Make sure to also enable > + :let g:airline_extensions#tabline#show_buffers = 1 +otherwise the tabline might not actually be displayed correctly (see +|airline-tabline|) + +* exclude fugitive logs and files that share part of the real buffer path: +> + let g:xtabline_include_previews = 0 (default 1) + +* activate fast cwd selection mappings: +> + let g:xtabline_cd_commands = 1 (default 0) + +* default mappings for them are: +> + map <leader>cdc <Plug>XTablineCdCurrent + map <leader>cdd <Plug>XTablineCdDown1 + map <leader>cd2 <Plug>XTablineCdDown2 + map <leader>cd3 <Plug>XTablineCdDown3 + map <leader>cdh <Plug>XTablineCdHome + +Note: if you don't use these mappings and change the cwd, the tabline won't +be updated automatically. Either re-enter the tab or press <F5> two times. + +* here are some easier mappings to change tab buffer: +> + nnoremap <silent> <expr> <Right> v:count? + \ airline#extensions#tabline#xtabline#next_buffer(v:count) : "\<Right>" + nnoremap <silent> <expr> <Left> v:count? + \ airline#extensions#tabline#xtabline#prev_buffer(v:count) : "\<Left>" + +------------------------------------- *airline-ycm* +YouCompleteMe <https://github.com/Valloric/YouCompleteMe> + +Shows number of errors and warnings in the current file detected by YCM. + +* enable/disable YCM integration > + let g:airline#extensions#ycm#enabled = 1 + +* set error count prefix > + let g:airline#extensions#ycm#error_symbol = 'E:' + +* set warning count prefix > + let g:airline#extensions#ycm#warning_symbol = 'W:' +< +============================================================================== +ADVANCED CUSTOMIZATION *airline-advanced-customization* + +The defaults will accommodate the mass majority of users with minimal +configuration. However, if you want to reposition sections or contents you can +do so with built-in helper functions, which makes it possible to create +sections in a more declarative style. + +------------------------------------- *airline-parts* +A part is something that contains metadata that eventually gets rendered into +the statusline. You can define parts that contain constant strings or +functions. Defining parts is needed if you want to use features like automatic +insertion of separators or hiding based on window width. + +For example, this is how you would define a part function: > + call airline#parts#define_function('foo', 'GetFooText') +< +Here is how you would define a part that is visible only if the window width +greater than a minimum width. > + call airline#parts#define_minwidth('foo', 50) +< +Parts can be configured to be visible conditionally. > + call airline#parts#define_condition('foo', 'getcwd() =~ "work_dir"') +< +Now add part "foo" to section section airline_section_y: > + let g:airline_section_y = airline#section#create_right(['ffenc','foo']) +< +Note: Part definitions are combinative; e.g. the two examples above modify the +same `foo` part. + +Note: Look at the source code and tests for the full API. + +------------------------------------- *airline-predefined-parts* +Before is a list of parts that are predefined by vim-airline. + +* `mode` displays the current mode +* `iminsert` displays the current insert method +* `paste` displays the paste indicator +* `crypt` displays the crypted indicator +* `spell` displays the spell indicator +* `filetype` displays the file type +* `readonly` displays the read only indicator +* `file` displays the filename and modified indicator +* `path` displays the filename (absolute path) and modifier indicator +* `linenr` displays the current line number +* `maxlinenr` displays the number of lines in the buffer +* `ffenc` displays the file format and encoding + +And the following are defined for their respective extensions: + +`ale_error_count` `ale_warning_count` `branch` `eclim` `hunks` +`languageclient_error_count` `languageclient_warning_count` +`neomake_error_count` `neomake_warning_count` `obsession` `syntastic-warn` +`syntastic-err` `tagbar` `whitespace` `windowswap` `ycm_error_count` +`ycm_warning_count` + +------------------------------------- *airline-accents* +Accents can be defined on any part, like so: > + call airline#parts#define_accent('foo', 'red') +< +This will override the colors of that part by using what is defined in that +particular accent. In the above example, the `red` accent is used, which means +regardless of which section the part is used in, it will have red foreground +colors instead of the section's default foreground color. + +The following accents are defined by default. Themes can define their variants +of the colors, but defaults will be provided if missing. > + bold, italic, red, green, blue, yellow, orange, purple, none +< +The defaults configure the mode and line number parts to be bold, and the +readonly part to be red. + +"none" is special. This can be used, to remove a bold accent from an existing +theme. For example, usually the mode part of the statusline is usually defined +to be bold. However, it can be hard to remove an existing bold accent from the +default configuration. Therefore, you can use the none accent to remove +existing accents, so if you put > + call airline#parts#define_accent('mode', 'none') +the mode section will be set to non-bold font style. + +------------------------------------- *airline-sections* +Once a part is defined, you can use helper functions to generate the +statuslines for each section. For example, to use the part above, we could +define a section like this: > + function! AirlineInit() + let g:airline_section_a = airline#section#create(['mode', ' ', 'foo']) + let g:airline_section_b = airline#section#create_left(['ffenc','file']) + let g:airline_section_c = airline#section#create(['%{getcwd()}']) + endfunction + autocmd User AirlineAfterInit call AirlineInit() +< +This will create a section with the `mode`, followed by a space, and our `foo` +part in section `a`. Section `b` will have two parts with a left-side +separator. And section `c` will contain the current path. You may notice that +the space and cwd are not defined parts. For convenience, if a part of that +key does not exist, it will be inserted as is. The unit tests will be a good +resource for possibilities. + +Note: The use of |User| is important, because most extensions are lazily +loaded, so we must give them a chance to define their parts before we can use +them. Also this autocommand is only triggered, after the airline functions are +actually available on startup. + +Note: The `airline#section#create` function and friends will do its best to +create a section with the appropriate separators, but it only works for +function and text parts. Special 'statusline' items like %f or raw/undefined +parts will not work as it is not possible to inspect their widths/contents +before rendering to the statusline. + +============================================================================== +FUNCREFS *airline-funcrefs* + +vim-airline internally uses funcrefs to integrate with third party plugins, +and you can tap into this functionality to extend it for you needs. This is +the most powerful way to customize the statusline, and sometimes it may be +easier to go this route than the above methods. + +Every section can have two values. The default value is the global `g:` +variable which is used in the absence of a `w:` value. This makes it very easy +to override only certain parts of the statusline by only defining window-local +variables for a subset of all sections. + +------------------------------------- *add_statusline_func* + *add_inactive_statusline_func* +The following is an example of how you can extend vim-airline to support a +new plugin. > + function! MyPlugin(...) + if &filetype == 'MyPluginFileType' + let w:airline_section_a = 'MyPlugin' + let w:airline_section_b = '%f' + let w:airline_section_c = '%{MyPlugin#function()}' + let g:airline_variable_referenced_in_statusline = 'foo' + endif + endfunction + call airline#add_statusline_func('MyPlugin') +< +Notice that only the left side of the statusline is overwritten. This means +the right side (the line/column numbers, etc) will be intact. + +To have the function act only on statuslines of inactive functions, use +`airline#add_inactive_statusline_func('MyPlugin')` + +------------------------------------- *remove_statusline_func* +You can also remove a function as well, which is useful for when you want a +temporary override. > + call airline#remove_statusline_func('MyPlugin') +< +============================================================================== +PIPELINE *airline-pipeline* + +Sometimes you want to do more than just use overrides. The statusline funcref +is invoked and passed two arguments. The first of these arguments is the +statusline builder. You can use this to build completely custom statuslines +to your liking. Here is an example: > +> + function! MyPlugin(...) + " first variable is the statusline builder + let builder = a:1 + + " WARNING: the API for the builder is not finalized and may change + call builder.add_section('Normal', '%f') + call builder.add_section('WarningMsg', '%{getcwd()}') + call builder.split() + call builder.add_section('airline_z', '%p%%') + + " tell the core to use the contents of the builder + return 1 + endfunction +< +The above example uses various example highlight groups to demonstrate +that you can use any combination from the loaded colorscheme. However, if +you want colors to change between modes, you should use one of the section +highlight groups, e.g. `airline_a` and `airline_b`. + +The second variable is the context, which is a dictionary containing various +values such as whether the statusline is active or not, and the window number. +> + context = { + 'winnr': 'the window number for the statusline', + 'active': 'whether the window is active or not', + 'bufnr': 'the current buffer for this window', + } +< +------------------------------------- *airline-pipeline-return-codes* +The pipeline accepts various return codes and can be used to determine the +next action. The following are the supported codes: > + 0 the default, continue on with the next funcref + -1 do not modify the statusline + 1 modify the statusline with the current contents of the builder +< +Note: Any value other than 0 will halt the pipeline and prevent the next +funcref from executing. + +============================================================================== +WRITING EXTENSIONS *airline-writing-extensions* + +For contributions into the plugin, here are the following guidelines: + +1. For simple 'filetype' checks, they can be added directly into the +`extensions.vim` file. + +2. Pretty much everything else should live as a separate file under the +`extensions/` directory. + + a. Inside `extensions.vim`, add a check for some variable or command that + is always available (these must be defined in `plugin/`, and _not_ + `autoload/` of the other plugin). If it exists, then initialize the + extension. This ensures that the extension is loaded if and only if the + user has the other plugin installed. Also, a check to + `airline#extensions#foo_plugin#enabled` should be performed to allow the + user to disable it. + + b. Configuration variables for the extension should reside in the + extension, e.g. `g:airline#extensions#foo_plugin#bar_variable`. + +See the source of |example.vim| for documented code of how to write one. +Looking at the other extensions is also a good resource. + +============================================================================== +WRITING THEMES *airline-themes* + +Themes are written "close to the metal" -- you will need to know some basic +VimL syntax to write a theme, but if you've written in any programming +language before it will be easy to pick up. + +The |dark.vim| theme fully documents this procedure and will guide you through +the process. + +For other examples, you can visit the official themes repository at +<https://github.com/vim-airline/vim-airline-themes>. It also includes +examples such as |jellybeans.vim| which define colors by extracting highlight +groups from the underlying colorscheme. + +============================================================================== +TROUBLESHOOTING *airline-troubleshooting* + +Q. There are no colors. +A. You need to set up your terminal correctly. For more details, see + <http://vim.wikia.com/wiki/256_colors_in_vim>. Alternatively, if you want + to bypass the automatic detection of terminal colors, you can force Vim + into 256 color mode with this: > + set t_Co=256 +< + Also if you enable true color mode in your terminal, make sure it will work + correctly with your terminal. Check if it makes a difference without it: > + set notermguicolors + +Q. Powerline symbols are not showing up. +A. First, you must install patched powerline fonts. Second, you must enable + unicode in vim. > + set encoding=utf-8 +< +Q. There is a pause when leaving insert mode. +A. Add the following to your vimrc. > + set ttimeoutlen=50 +< +Q. The colors look a little off for some themes. +A. Certain themes are derived from the active colorscheme by extracting colors + from predefined highlight groups. These airline themes will look good for + their intended matching colorschemes, but will be hit or miss when loaded + with other colorschemes. + +Q. Themes are missing +A. Themes have been extracted into the vim-airlines-themes repository. Simply + clone https://github.com/vim-airline/vim-airline-themes and everything + should work again. + +Q. Performance is bad +A. Check the question at the wiki: + https://github.com/vim-airline/vim-airline/wiki/FAQ#i-have-a-performance-problem + +Solutions to other common problems can be found in the Wiki: +<https://github.com/vim-airline/vim-airline/wiki/FAQ> + +============================================================================== +CONTRIBUTIONS *airline-contributions* + +Contributions and pull requests are welcome. + +============================================================================== +LICENSE *airline-license* + +MIT License. Copyright © 2013-2018 Bailey Ling, Christian Brabandt et al. + + vim:tw=78:ts=8:ft=help:norl: diff --git a/dotfiles/.local/share/nvim/site/doc/neomake.txt b/dotfiles/.local/share/nvim/site/doc/neomake.txt new file mode 100644 index 0000000..77622a3 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/doc/neomake.txt @@ -0,0 +1,1052 @@ +*neomake.txt* - asynchronous make for Vim version 7.4+ and Neovim + + ███╗ ██╗███████╗ ██████╗ ███╗ ███╗ █████╗ ██╗ ██╗███████╗ + ████╗ ██║██╔════╝██╔═══██╗████╗ ████║██╔══██╗██║ ██╔╝██╔════╝ + ██╔██╗ ██║█████╗ ██║ ██║██╔████╔██║███████║█████╔╝ █████╗ + ██║╚██╗██║██╔══╝ ██║ ██║██║╚██╔╝██║██╔══██║██╔═██╗ ██╔══╝ + ██║ ╚████║███████╗╚██████╔╝██║ ╚═╝ ██║██║ ██║██║ ██╗███████╗ + ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ + + Run make tasks (such as linters and build tools) asynchronously. + +============================================================================== +CONTENTS *neomake* + + 1. Introduction ............................... |neomake-introduction| + 2. Commands ....................................... |neomake-commands| + 3. Configuration ............................. |neomake-configuration| + 3.1. Automake ..................................... |neomake-automake| + 4. Functions ..................................... |neomake-functions| + 5. Autocommands/Hooks ............................. |neomake-autocmds| + 6. Frequently Asked Questions (FAQ) .................... |neomake-faq| + +============================================================================== +1. Introduction *neomake-introduction* + +Neomake leverages Neovim's or Vim's |job-control| feature where available to +run programs like syntax checkers asynchronously. Where job control is not +available, it resorts to a synchronous |system()| call, making it possible to +run this plugin in both older Vims and Neovim. +This plugin is heavily inspired by Vim plugins such as Syntastic and +dispatch. + +============================================================================== +2. Commands *neomake-commands* + + *:Neomake* + *:NeomakeFile* +:Neomake [makers] Run a make command with the current file as input. If + no makers are specified, the default makers for the + current |filetype| are used. See + |neomake-configuration| for more on makers. + + *:Neomake!* + *:NeomakeProject* +:Neomake! [makers] Run a make command with no file as input. If no makers + are specified, the default top-level makers will be + used. If no default top-level makers exist, + |'makeprg'| will be used. + + *:NeomakeSh* +:NeomakeSh {command} Run {command} in a shell (according to 'shell'). The + command output will be loaded into the quickfix list + when the job is complete. Example: > + :NeomakeSh find . -name '*.pyc' +< + *:NeomakeSh!* +:NeomakeSh! {command} Same as |:NeomakeSh|, but does not buffer the output. + Example: > + :NeomakeSh! while true; do date; sleep 1; done +< + *:NeomakeInfo* +:NeomakeInfo Display information, meant for debugging and inclusion + in bug reports / help requests. + + *:NeomakeListJobs* +:NeomakeListJobs List all running jobs in the format: > + job_id job_name +< + *:NeomakeCancelJob* +:NeomakeCancelJob {job_id} + Terminate a job identified by its job_id. + + *:NeomakeCancelJobs* +:NeomakeCancelJobs + Terminate all jobs. + + *:NeomakeClean* + *:NeomakeClean!* +:NeomakeClean[!] + Clean signs, highlights etc. for file-mode, or + project-mode (with bang). + +============================================================================== +2.1. Toggle commands *neomake-toggle* + +The following commands enable, disable or toggle Neomake globally, per tab or +per buffer by changing the `disabled` setting, which gets checked when Neomake +gets called via autocommands, e.g. with |neomake-automake| or custom +autocommands. You can still call e.g. |:Neomake| manually, and it will run. +In verbose mode (e.g. when called with |:verbose| (`:verb Neomake`)) the new +status gets displayed. + +*:NeomakeToggle* toggles Neomake globally. +*:NeomakeToggleBuffer* toggles Neomake for the current buffer. +*:NeomakeToggleTab* toggles Neomake for the current tab. + *neomake-disable* +*:NeomakeDisable* disables Neomake globally. +*:NeomakeDisableBuffer* disables Neomake for the current buffer. +*:NeomakeDisableTab* disables Neomake for the current tab. + *neomake-enable* +*:NeomakeEnable* enables Neomake globally. +*:NeomakeEnableBuffer* enables Neomake for the current buffer. +*:NeomakeEnableTab* enables Neomake for the current tab. + +*:NeomakeStatus* displays the current status. + +============================================================================== +3. Configuration *neomake-configuration* + +If you just want an easy way to run |:make| asynchronously, you're all set. +Just set your |'makeprg'| and |'errorformat'| as usual, and run |:Neomake!|. +If you want more, read on. + +3.1 Automaking *neomake-automake* + +To configure Neomake to automatically run on certain events you can use +`neomake#configure#automake()`. + +The first argument can either be a dictionary (mapping autocommand event +names to config dicts for fine grained control), or a string (as a shortcut to +configure certain modes). The 2nd argument is the default delay to use. + +String usage (simple setup):~ + + n: normal mode~ + This uses the |TextChanged| (falling back to |CursorHold|) and |InsertLeave| + events. + + i: insert mode~ + This uses the |TextChangedI| event (falling back to |CursorHoldI|). + + r: "read" mode - when a buffer gets read/open~ + This will hook into the |BufWinEnter|, |FileType| and |FileChangedShellPost| + events. + + w: "write" mode - when a buffer gets written~ + This uses the |BufWritePost| event, with an explicit timeout of 0. + +Examples: > + + " When writing a buffer. + call neomake#configure#automake('w') + " When writing a buffer, and on normal mode changes (after 750ms). + call neomake#configure#automake('nw', 750) + " When reading a buffer (after 1s), and when writing. + call neomake#configure#automake('rw', 1000) + +Dictionary usage (advanced setup):~ +> + call neomake#configure#automake({ + \ 'TextChanged': {}, + \ 'InsertLeave': {}, + \ 'BufWritePost': {'delay': 0}, + \ 'BufWinEnter': {}, + \ }, 500) +< +This will trigger Neomake on |TextChanged|, |InsertLeave|, |BufWritePost| and +|BufWinEnter|, with a delay of 500ms by default, but 0 for |BufWritePost|. + +You could do some advanced setup, based on if your laptop is running on +battery: > + function! MyOnBattery() + return readfile('/sys/class/power_supply/AC/online') == ['0'] + endfunction + if MyOnBattery() + call neomake#configure#automake('w') + else + call neomake#configure#automake('nrw', 1000) + endif +< + *neomake-automake-dynamic-delay* +The automake delay gets adjusted dynamically when timers or make runs get +aborted. This is meant to support the use case where you are doing multiple +changes in succession (e.g. |undo|). +This can be controlled with the experimental `automake.cancelation_delay` +setting, which has to be a list: > + call neomake#configure('automake.cancelation_delay', [0.2, 0.5, 3000]) +> +The first value gets multiplied with the number of restarted timers (before a +make was triggered). +The second value gets multiplied with canceled/restarted make runs. +The sum of those values plus 1 gets multiplied with the original/configured +delay. The third value is used as a maximum. +With the default settings from above this means that given a default delay of +500ms, 7 restarted timer, and 1 restarted make run, it would use a delay of +`(7*0.2 + 1*0.5 + 1) * 500 = 1450`. +The counts for restarted timers and make runs gets reset once a make run +finishes. + +Makers *neomake-makers* +A maker is an object that tells Neomake how to run a job for you. + + *neomake-makers-get_list_entries* +If a maker has a `get_list_entries` function, this gets used to retrieve +entries for the location or quickfix list directly. +The function gets passed a jobinfo (|neomake-object-jobinfo|) object, and +should return a list of entries that will be used to fill the +location/quickfix list: > + let maker = {'name': 'My maker'} + function! maker.get_list_entries(jobinfo) abort + return [ + \ {'text': 'Some error', 'lnum': 1, 'bufnr': a:jobinfo.bufnr}, + \ {'text': 'Some warning', 'type': 'W', 'lnum': 2, 'col': 1, + \ 'length': 5, 'filename': '/path/to/file'}, + \ ] + endfunction +< +The required keys for entries are `text` and `lnum`, and you should set one of +`bufnr` or `filename` (otherwise the entry will not be valid). +The `length` entry in the example is internal to Neomake, and sets the length +for an highlight (see |neomake-highlight|). + + *neomake-job-makers* +Otherwise a maker gets run as a job with a file as input ("file mode", good +for linting), or with no file as input ("project mode", good for building and +project-level tasks). + +Here is a sample maker definition: > + let g:neomake_make_maker = { + \ 'exe': 'make', + \ 'args': ['--build'], + \ 'errorformat': '%f:%l:%c: %m', + \ } + " Use the maker like this: + :Neomake! make +< + *neomake-makers-InitForJob* +You can configure a maker dynamically through a `InitForJob` function, which +gets the jobinfo (|neomake-object-jobinfo|) as its argument. + +This can also be configured as setting: > + function! CustomExe(jobinfo) abort + let self.args = [self.exe] + self.args + let self.exe = 'some_custom_wrapper' + endfunction + call neomake#config#set('ft.python.InitForJob', function('CustomExe')) +< + *neomake-makers-exe* + *neomake-makers-args* +`exe` has to be a string, while `args` can be a list or a string. +If `args` is a list, entries like '%' and '%:p' will be |expand()|ed, and +quoting/escaping is applied automatically. If you want to handle escaping +yourself, `args` should be a string. + +In the above example, the exe argument isn't strictly necessary, since Neomake +uses the name of the maker as the default value for it. If you want it to be +usable on an individual file, you should also include the filetype in the +name: > + let g:neomake_c_lint_maker = { + \ 'exe': 'lint', + \ 'args': ['--option', 'x'], + \ 'errorformat': '%f:%l:%c: %m', + \ } + + " Run this maker for the open file (runs "lint --option x myfile.c"): + :Neomake lint + + " Or run it on the whole project, executing the command from Vim's current + " working directory (runs "lint --option x"): + :Neomake! c_lint +< + *neomake-args-file* +When running a maker on a file with |:Neomake|, you may want to control where +in the `args` list the file's path will appear. To do this, insert '%t' in +the `args` list and use `append_file=0`: > + let g:neomake_c_lint_maker = { + \ 'exe': 'lint', + \ 'args': ['%t', '--option', 'x'], + \ 'append_file': 0, + \ 'errorformat': '%f:%l:%c: %m', + \ } +< +This will cause "lint /path/to/file.c --option x" to be run instead of +"lint --option x /path/to/file.c". + +`%t` gets replaced with the absolute path to the file (handling any temporary +file). + + *neomake-makers-processing* +A job maker's output gets processed in two ways: +1. through a maker's `process_output` function, or +2. via its `errorformat` (together with `mapexpr` and `postprocess`). + + *neomake-makers-process_output* +If a maker has a `process_output` function, this gets used to retrieve +entries for the location or quickfix list for the job's output directly. + +The function gets called with a `context` dictionary, with the following +entries: + - `output`: a list of lines + - `source`: the source of the output (`stderr`, `stdout`) + - `jobinfo`: the jobinfo object, see |neomake-object-jobinfo| +It should return a list of entries (dictionaries), where `text` and `lnum` +are required. `bufnr` defaults to the jobs's buffer. + +Using this method skips the processing based on `errorformat` (including +`mapexpr` and `postprocess`). + +See |neomake-makers-process_json| below for handling JSON output. + + *neomake-makers-process_json* +A maker's `process_json` function gets a |dict| with parsed JSON directly, +handling the JSON parsing and any errors before. + +The function gets called with a `context` dictionary, containing the following +entries: + - `json`: a dictionary with the parsed JSON + - `source`: the source of the output (`stderr`, `stdout`) + - `jobinfo`: the jobinfo object, see |neomake-object-jobinfo| +It should return a list of entries (dictionaries), where `text` and `lnum` +are required. `bufnr` defaults to the jobs's buffer. + +Using this method skips the processing based on `errorformat` (including +`mapexpr` and `postprocess`). + + *neomake-makers-filter_output* +A maker's `filter_output` function can filter any output before it gets +processed further. + +The function gets called with two arguments: the list of lines (to be modified +in place) and a context dictionary with the following entries: + - `source`: the source of the output (`stderr`, `stdout`) + - `jobinfo`: the jobinfo object, see |neomake-object-jobinfo| + + *neomake-makers-mapexpr* +You can define two optional properties on a maker object to process its +output: `mapexpr` is applied to the maker's output before any processing, and +`postprocess` is applied to each of the quickfix or location list entries. + +The `mapexpr` property gets passed directly into |map()| as the `expr` +argument: > + call map(lines, maker.mapexpr) +<where `lines` contains the maker output. + +The following variables are available in the `mapexpr`: + + - `neomake_output_source`: either "stderr" or "stdout", depending on + where the output is coming from. This will be "stdout" always for + non-async Vim. + - `neomake_bufname` and `neomake_bufdir`: the buffer's absolute path + (|bufname()|) and directory, respectively. + +The `mapexpr` itself gets evaluated in the context of the affected buffer in +file mode, and in the context of the buffer that is current when the maker +finished otherwise. + +The following `mapexpr` could be used to prefix the output type: > + "printf('[%s] %s', neomake_output_source, v:val)" +< + *neomake-makers-postprocess* +The `postprocess` property is a function (or list of functions) that get(s) +called for each entry in the location or quickfix list. +It allows to change entries there or remove them by setting the `valid` entry +to `-1`. + +Example: make all entries a warning where `nr` is in the range of 100-199: > + function PostprocessLintMaker(entry) + if a:entry.nr >= 100 && a:entry.nr < 200 + let a:entry.type = 'W' + endif + endfunction + let g:neomake_ft_lint_maker = { + \ 'exe': 'lint', + \ 'args': ['--option', 'x'], + \ 'errorformat': '%f:%l:%c:%n: %m', + \ 'postprocess': function('PostprocessLintMaker') + \ } +< +Example: remove some entry for a specific maker (using |expr-lambda|): > + let g:neomake_asciidoc_asciidoc_postprocess = { + \ entry -> entry.text =~# 'illegal system attribute name: font-style' + \ ? extend(entry, {'valid': -1}) + \ : entry} +< + +Builtin postprocessors are `neomake#postprocess#compress_whitespace`, which +fixes whitespace issues (which is useful with multiline error messages), +and `neomake#postprocess#generic_length`, which adds a length property (used +for highlights |neomake-highlight|) for entries, when the message refers to an +identifier at the entry's column. +See `neomake#makers#ft#text#PostprocessWritegood` for an example. + +Entries can be selectively removed in post-processing by setting its "valid" +property to `-1`. This removal will happen even if `remove_invalid_entries` +is disabled. This feature is meant for conditional removals and a simpler way +for end users to filter list entries. Makers should handle removals through +|errorformat| using '%-G' to remove items that should never appear in the +error list. + + *neomake-makers-buffer_output* +Default: 1 +By default Neomake will only process the output from makers when either the +output type changes (from stderr to stdout or vice versa), or at the end of +the job. + +If you have a maker that is expected to run longer, and you want to get +feedback as early as possible, you can set this to `0`. + +You can override this for a maker using e.g.: > + let g:neomake_ft_test_maker_buffer_output = 0 +< +Your results will appear earlier, but if the |'errorformat'| is meant to parse +multiline output this will likely cause issues (depending on how the maker +flushes its output). + +To change the default for all makers use: > + call neomake#config#set('maker_defaults.buffer_output', 0) +< + *neomake-makers-remove_invalid_entries* +Default: 0 +This option filters invalid entries from makers from the location/quickfix +list (i.e. entries that do not match the |'errorformat'|, and that would show +up with a `||` prefix in the location/quickfix list): > + let g:neomake_ft_maker_remove_invalid_entries = 1 +< +NOTE: the default for this is 0, because unhandled/unexpected output might be +useful, e.g. when the program displays some error. +Makers should handle this properly through |errorformat|, e.g. by using '%-G' +(see |efm-ignore| and |neomake-faq-errorformat|). + +To change the default for all makers use: > + call neomake#config#set('maker_defaults.remove_invalid_entries, 1) +< + *neomake-makers-cwd* +The working directory of a maker defaults to the current working directory +of the make run (|getcwd()|). +The `cwd` property overrides this, and gets expanded in the context of the +current buffer. Special buffers (like fugitive blobs) get handled for values +starting with `%:` (typically used in this context), falling back to +|expand()|. See |filename-modifiers|. + > +Example: change to the buffer's directory: > + let g:neomake_my_example_maker = { + \ 'exe': 'pwd', + \ 'cwd': '%:p:h' + \ } +< + *neomake-makers-tempfile_enabled* +Default: 1 +This will pass a temporary file with the buffer's contents to the maker, in +case the buffer is not readable, modified, or has no filename. +A maker can specify the temporary file's name through the `tempfile_name` +property, and you can set it through the |neomake-makers-InitForJob| callback +(for advanced usage). +Otherwise it gets generated based on the original filename/filetype, and +falls back to using |tempname()|. + +You can configure this per buffer or maker as usual, e.g.: > + let g:neomake_<ft>_<name>_tempfile_enabled = 0 +< + *neomake-makers-tempfile_dir* +Default: unset +You can configure the directory to use for temporary files (see +|neomake-makers-tempfile_enabled|). + +The default behavior is to use the same directory as the original file, so +that any config files (e.g. `setup.cfg` for Python tools) take effect. + +You can configure this per buffer or maker as usual, e.g.: > + let g:neomake_<ft>_<name>_tempfile_dir = '/tmp/custom' +< +The value gets expanded (via `neomake#utils#ExpandArgs`), which allows for +the following to use the original file's directory structure (`%:p:h`): > + let g:neomake_tempfile_dir = '/tmp/custom%:p:h' +< + *neomake-makers-output_stream* +Default: "both" ("stdout", "stderr", "both") +The `output_stream` setting specifies what stream gets used for output from +the maker. +Any output on a stream not configured here gets reported as unexpected output. + + *neomake-makers-supports_stdin* +Default: 0 +With `supports_stdin = 1` a maker indicates that it can use stdin instead of a +temporary file. By default "-" is then used for the filename. + +`supports_stdin` can be a dict function on the maker, which will get the +current jobinfo as its argument, and should return 1 or 0. +This function can change `self.args`, which is useful to append options like +e.g. "['--stdin-display-name', '%:p']". +You can also change `self.tempfile_name` therein. +It can be useful to change the current working directory for the maker here, +e.g. when it does not use its `--stdin-display-name` (or similar) option +to look for its config. Use the jobinfo's `cd` method for this: > + function! maker.supports_stdin(jobinfo) abort + let self.args += ['--stdin-display-name', '%:.'] + call a:jobinfo.cd('%:h') + return 1 + endfunction +< + *neomake-makers-uses_stdin* +Default: 0 +`uses_stdin = 1` can be used to always use stdin for file arguments, +regardless of if a temporary file / stdin is required to be used. +It uses "-" as the default for "tempfile_name". + +Global Options *neomake-options* + +*g:neomake_<name>_maker* +*g:neomake_<ft>_<name>_maker* +Define a new filetype or project-level maker. See |neomake-makers|. + + *neomake-makers-properties* +*g:neomake_<name>_<property>* +*g:neomake_<ft>_<name>_<property>* +*b:neomake_<name>_<property>* +*b:neomake_<ft>_<name>_<property>* +Configure properties for a maker where <property> is one of `exe`, `args`, +`errorformat`, `buffer_output`, `remove_invalid_entries`, `append_file`, +or `supports_stdin`. + +This can also be set per buffer, e.g.: > + let g:neomake_javascript_jshint_exe = './myjshint' + let b:neomake_javascript_jshint_exe = './myotherjshint' +< + +The global defaults can be configured using `g:neomake_<property>`, i.e. +*g:neomake_remove_invalid_entries* to remove invalid entries from the quickfix +/ location list (|neomake-makers-remove_invalid_entries|), unless explicitly +provided by the maker or overridden by your global/buffer setting. + +The internal defaults are: > + let defaults = { + \ 'exe': maker.name, + \ 'args': [], + \ 'errorformat': &errorformat, + \ 'buffer_output': 0, + \ 'remove_invalid_entries': 0 + \ } +< + +*g:neomake_<ft>_enabled_makers* +*b:neomake_<ft>_enabled_makers* +This setting will tell Neomake which makers to use by default for the given +filetype `<ft>` (when called without a maker as an argument, i.e. |:Neomake|). + +The default for this setting is the return value of the function +`neomake#makers#ft#<ft>#EnabledMakers`. For Python this is defined in +`./autoload/neomake/makers/ft/python.vim`, and might return: > + ['python', 'frosted', 'pylama'] +< +This setting can also be defined per buffer, so the following snippet can be +used to configure a custom set of makers from your vimrc: > + let g:neomake_python_enabled_makers = ['pep8', 'pylint'] + augroup my_custom_maker + au! + au Filetype custom.py let b:neomake_python_enabled_makers = ['flake8'] + augroup END +< +Please refer to |autocmd-patterns| for help on defining the pattern +(`custom.py`) in this case. + +*g:neomake_enabled_makers* +*b:neomake_enabled_makers* +This setting will tell Neomake which makers to use by default when not +operating on a single file, or when no makers are defined for the filetype of +the current buffer. This effectively defaults to: > + let g:neomake_enabled_makers = ['makeprg'] +< +*g:neomake_open_list* +*b:neomake_open_list* +This setting will open the |location-list| or |quickfix| list (depending on +whether it is operating on a file) when adding entries. A value of 2 will +preserve the cursor position when the |location-list| or |quickfix| window is +opened. Defaults to 0. + +*g:neomake_list_height* +*b:neomake_list_height* +The maximum height of the |location-list| or |quickfix| list window opened by +Neomake. If there are fewer entries it will use that instead. +Defaults to 10. + +*g:neomake_echo_current_error* +This setting will |:echo| the error for the line your cursor is on, if any. +It uses a timer (if |timers| are available), and |CursorHold|/|CursorHoldI| +otherwise. +Defaults to 1. + +*g:neomake_virtualtext_current_error* +Use Neovim's virtualtext API to display the error for the current line next +to the text. This is experimental, and uses the same mechanism (timer) +as |g:neomake_echo_current_error|. +Defaults to 1 (only available on Neovim 0.3.2+). + +*g:neomake_virtualtext_prefix* +The prefix used with |g:neomake_virtualtext_current_error|. +Defaults to "❯ ". + +*g:neomake_cursormoved_delay* +Delay (in ms) for the timer used to echo the current error with +|g:neomake_echo_current_error|. +Defaults to 100. + +*g:neomake_serialize* +Setting this to 1 tells Neomake to run each enabled maker one after the other. +This is a good way to ensure messages don't get mixed up. This setting is +implied with non-async Vim versions. + +*g:neomake_serialize_abort_on_error* +Setting this to 1 tells Neomake to abort after the first error status is +encountered. This setting only works when |g:neomake_serialize| is on. + +*g:neomake_verbose* +Controls how verbose Neomake should be. Neomake log levels are as follows: + 0 - Errors only + 1 - Quiet message + 2 - Loud message (may log multiple messages at once, making the screen + shift momentarily) + 3 - Debug information (all messages). + This will also add time information to messages. +Each log level includes all the levels before it. + +Defaults to 1. + +|'verbose'| gets added to this setting, so you can use |:verbose| to increase +the verbosity temporarily: > + :3verb Neomake +< +*g:neomake_logfile* +Setting this to a file path will write all messages (regardless of the level +configured through |g:neomake_verbose|) into it. +This is useful for debugging/hacking, and when reporting issues. +It requires Vim 7.4.503+ (or Neovim) to work properly, otherwise it will not +append, but overwrite the file with each message. + + *neomake-signs* +*g:neomake_place_signs* +This setting enables the placement of signs next to items from the location +and quickfix list (i.e. errors/warnings etc recognized from the +|'errorformat'|). Defaults to 1. + +*g:neomake_error_sign* +*g:neomake_warning_sign* +*g:neomake_info_sign* +*g:neomake_message_sign* +These options allow you to control the appearance of the signs that are +placed into the |signs| column next to lines with messages. +These are dictionaries that represent the parameters provided by +|:sign-define|. Here is an example definition: > + let g:neomake_error_sign = { + \ 'text': 'E>', + \ 'texthl': 'ErrorMsg', + \ } +< +See the |:highlight| command to list the highlight groups available to you or +create new ones. + +Neomake uses the following defaults: > + + let g:neomake_error_sign = { + \ 'text': '✖', + \ 'texthl': 'NeomakeErrorSign', + \ } + let g:neomake_warning_sign = { + \ 'text': '‼', + \ 'texthl': 'NeomakeWarningSign', + \ } + let g:neomake_message_sign = { + \ 'text': '➤', + \ 'texthl': 'NeomakeMessageSign', + \ } + let g:neomake_info_sign = { + \ 'text': 'ℹ', + \ 'texthl': 'NeomakeInfoSign' + \ } +< + +Default |highlight-groups| are created with those names, but only if they do +not exist already, which allows you to customize them. This should typically +be done through the |ColorScheme| autoevent, which applies it after any color +scheme: > + + augroup my_neomake_signs + au! + autocmd ColorScheme * + \ hi NeomakeErrorSign ctermfg=white | + \ hi NeomakeWarningSign ctermfg=yellow + augroup END +< +You can use `neomake#utils#GetHighlight` to get e.g. the "bg" from +"SignColumn". See `neomake#signs#DefineHighlights` where this is used. + + *neomake-highlight* +*g:neomake_highlight_columns* +This setting enables highlighting of columns for items from the location and +quickfix list. Defaults to 1. + +*g:neomake_highlight_lines* +This setting enables highlighting of lines for items from the location and +quickfix list. Defaults to 0. + +If both |g:neomake_highlight_columns| and |g:neomake_highlight_lines| are +enabled, items with column information are highlighted using the column. + +The following highlighting groups are used: + - NeomakeError: links to "SpellBad" (|hl-SpellBad|) + - NeomakeWarning: links to "SpellCap" (|hl-SpellCap|) + - NeomakeInfo: links to "NeomakeWarning" + - NeomakeMessage: links to "NeomakeWarning" + +You can define them yourself: > + + augroup my_neomake_highlights + au! + autocmd ColorScheme * + \ highlight NeomakeError … | + \ highlight NeomakeWarning … + guisp=White + augroup END +> + +*g:airline#extensions#neomake#enabled* +Shows warning and error counts returned by |neomake#statusline#LoclistCounts| +in the warning and error sections of the vim-airline |'statusline'|. Defaults +to 1. + +============================================================================== +4. Functions *neomake-functions* + +This list is non-exhaustive at the moment, but you may find some of these +functions useful. + +*neomake#Make* (options) +This is the main entrypoint to Neomake, used by the |:Neomake| (and +|:Neomake!|) command. + +`options` is a dictionary, and might include: +- `file_mode`: 1 if the makers should get run against a single file (typically + used for linting). Default: 1. +- `enabled_makers`: the makers to use (list). Default: uses configuration. + +Returns: a list of jobinfo objects (|neomake-object-jobinfo|). + +Deprecated interface (with different return value)~ +The old and deprecated API will accept the following arguments instead of the +`options` dict: filemode, enabled_makers[, exit_callback]. +The `exit_callback` (which should get replaced by using the +|NeomakeJobFinished| or |NeomakeFinished| hooks) gets the following dictionary +as its sole argument: > + { 'status': <exit status of maker>, + \ 'name': <maker name>, + \ 'has_next': <1 if another maker follows, 0 otherwise> } +Returns: a list of job ids. + +*neomake#Sh* (command[, callback]) +This function is called by the |:NeomakeSh| command. It runs the specified +shell `command` according to 'shell'. |neomake#Sh| returns the single job id +that was created (-1 on Vim without asynchronous support); you can potentially +cancel this job with |neomake#CancelJob|. + +It also accepts a second, optional callback argument that is called when +the command exits. The callback is given the following dictionary as its +sole argument: > + { 'status': <exit status of command>, + \ 'name': 'sh: <command>', + \ 'has_next': 0 } +< +The callback will receive a `jobinfo` object dict as `self` +(|dict-functions|). + +*neomake#ListJobs* +Invoked via |:NeomakeListJobs|. Echoes a list of running jobs in the format +(job_id, job_name). + +*neomake#CancelJob* +Invoked via |:NeomakeCancelJob|. Terminate a job identified by its job_id. +Example: > + let job_id = neomake#Sh("bash -c 'while true; do sleep 1; done'") + call neomake#CancelJob(job_id) + +*neomake#signs#RedefineErrorSign* +*neomake#signs#RedefineWarningSign* +These functions define the error sign and the warning sign respectively. They +optionally take a dictionary in the same format as |g:neomake_error_sign|. If +no such dictionary is provided, the default values will be used. These +functions may be useful if somehow |:Neomake| is being invoked before you +define |g:neomake_error_sign|. > + let g:neomake_error_sign = {'text': 'D:'} + call neomake#signs#RedefineErrorSign() +< + *neomake-statusline* +The main function for statusline integration is `neomake#statusline#get()`, +which caches the information retrieved from `neomake#statusline#get_status()`. + +*neomake#statusline#get()* <bufnr> [options] +The function requires the buffer number as first argument, and an optional +dictionary. You might want to use |g:actual_curbuf| for bufnr, if calling +`neomake#status#get()` from a statusline expression, but then highlights are +not evaluated, and you typically want to use this in a statusline function +(`'set statusline=%!MyStatusLine()'`) instead. + +Returns a string for a 'statusline'. + +The optional argument is a dictionary of options (see below). + +The following example creates a custom 'statusline' function, where `a:active` +may reflect if the window is the current one (implementation not provided): > + let neomake_status_str = neomake#statusline#get(bufnr, { + \ 'format_running': '… ({{running_job_names}})', + \ 'format_loclist_ok': + \ (a:active ? '%#NeomakeStatusGood#' : '%*').'✓', + \ 'format_quickfix_ok': '', + \ 'format_quickfix_issues': (a:active ? '%s' : ''), + \ 'format_status': '%%(%s' + \ .(a:active ? '%%#StatColorHi2#' : '%%*') + \ .'%%)', + \ }) +< +A simpler example: > + let neomake_status_str = neomake#statusline#get(bufnr, { + \ 'format_running': '… ({{running_job_names}})', + \ 'format_loclist_ok': '✓', + \ 'format_quickfix_ok': '', + \ 'format_quickfix_issues': '%s', + \ }) +< +You can use the following options: + +For location list items:~ + - format_loclist_unknown: format for when the status for location list + issues is unknown, i.e. Neomake was not run on the current buffer. + Default: `'?'` + - format_loclist_ok: format for when there are no location list issues. + Default: `'%#NeomakeStatusGood#✓%#NeomakeStatReset#'` (a checkmark using + the NeomakeStatusGood highlight group). + - format_loclist_type_X: format for location list issues of type X + (E, W, I, …). + Default: looks up "format_loclist_type_default" first, and then uses + `' {{type}}:{{count}} '`, with an existing highlight group as prefix + ("NeomakeStatColorTypeX" or "NeomakeStatColorDefault"), e.g. + - format_loclist_type_default: default format for location list issues if + "format_loclist_type_X" is not defined. + - format_loclist_issues: format for wrapping all location list issues. + Default: `'%s%%#NeomakeStatReset'` (used with |printf()|). + +For quickfix list items:~ + - format_quickfix_ok: format for no quickfix issues. + Default: `''` + - format_quickfix_type_X: format for quickfix list issues of type X + (E, W, I, …). + Default: `' {{type}}:{{count}} '` + Default: looks up "format_quickfix_type_default" first, and then uses + `' Q{{type}}:{{count}} '`, with an existing highlight group as prefix + ("NeomakeStatColorQuickfixTypeX" or "NeomakeStatColorQuickfixDefault"). + - format_quickfix_issues: format for wrapping all quickfix list issues. + You can use an empty string to skip displaying quickfix issues, which can + be useful for non-current windows. + Default: `'%s%%#NeomakeStatReset'` (used with |printf()|). + +Status related:~ + - format_status: used to wrap the whole status. + This is a |printf()| format string, where `%s` gets replaced with the + whole status (and any literal/non-printf `%` needs to be escaped as `%%`). + Default: not used / `'%s'` + - format_status_disabled: used to wrap the whole status when disabled. + This is a |printf()| format string, where `%s` gets replaced with the + whole status (and any literal/non-printf `%` needs to be escaped as `%%`). + Default: `'{{disabled_info}} %s'` + - format_disabled_info: The `disabled_info` placeholder from the + "format_status_disabled" argument. There `disabled_scope` placeholder is + available here. Default: `'{{disabled_scope}}-'` + - format_status_enabled: used to wrap the whole status when enabled. + This is a |printf()| format string, where `%s` gets replaced with the + whole status (and any literal/non-printf `%` needs to be escaped as `%%`). + Default: not used / `'%s'` + +General:~ + - format_lists: used to format the overall location list and quickfix list + sections (before format_status). + `{{lists_sep}}` is empty ("") with only a single list section, + and defaults to " " if both are not empty. + Default: `'{{loclist}}{{lists_sep}}{{quickfix}}'` + +Running jobs:~ + If any jobs are currently running in file or project mode, those get + displayed by default in the loclist or quickfix section. The following + options control its appearance: + + - format_running: used in case there are jobs running. Use 0 (as a number) + to disable this, but fall through to the last known status. + Default: `… ({{running_job_names}})` + - format_running_job_file: Wrap the running job name for file-level makers. + Default: not used / `'%s'` + - format_running_job_project: Wrap the running job name for project makers. + Default: `'%s!'`. + - running_jobs_separator: Separator for formatted running job names. + Default: `', '`. + +Advanced options:~ + + - use_highlights_with_defaults: include highlight attributes with default + options (e.g. "%#NeomakeStatusGood#" with "format_loclist_ok"). + Default: 1 + +You can use the following format placeholders: + - `{{running_job_names}}}`: comma-separated list of running jobs (typically + their maker names). + This gets built using `format_running_job_file`, + `format_running_job_project`, and `running_jobs_separator`. + - `{{disabled_scope}}`: When manually overriden, the scope of the disabling. + One of "b", "t", "g". + +*neomake#statusline#LoclistStatus* +*neomake#statusline#QflistStatus* +These functions return text for your |'statusline'|. They each take an +optional first argument, which is the prefix text that will be shown if errors +or warnings exist. Example usage: > + set statusline+=\ %#ErrorMsg#%{neomake#statusline#QflistStatus('qf:\ ')} +< +The result of this will be something like 'qf: E:1, W:2' if there are errors +or warnings and the empty string otherwise. + +*neomake#statusline#LoclistCounts* +*neomake#statusline#QflistCounts* +These functions get the counts of errors by error type for the |location-list| +and the |quickfix| respectively. The return value is something like this: > + {'E': 2, 'W': 1, 'x': 5} +<Where 'E', 'W' and 'x' are error types. Empty error types are ignored for +now. + +By default, `LoclistCounts` returns the counts for the current buffer (i.e. +`bufnr("%")`), but you can pass an optional argument: passing a buffer number +will retrieve the counts for a particular buffer, while passing the string +"`all`" will return a dictionary of counts for all buffers. + +============================================================================== +5. Autocommands/Hooks *neomake-autocmds* + *neomake-hooks* +Neomake will trigger |User| autocommands on certain events. +With all these events a dictionary `g:neomake_hook_context` is available, +with key/value pairs depending on the autocommand/hook. + +Example: display a message for every maker that exits non-zero: > + function! MyOnNeomakeJobFinished() abort + let context = g:neomake_hook_context + if context.jobinfo.exit_code != 0 + echom printf('The job for maker %s exited non-zero: %s', + \ context.jobinfo.maker.name, context.jobinfo.exit_code) + endif + endfunction + augroup my_neomake_hooks + au! + autocmd User NeomakeJobFinished call MyOnNeomakeJobFinished() + augroup END +< +Note: you might want to use |autocmd-nested| (in particular when handling +opening of the location/quickfix window yourself, so that other autocommands +get triggered, e.g. |WinEnter| for the qf window that gets opened/created): > + augroup my_neomake_hooks + au! + autocmd User NeomakeFinished nested call MyOnNeomakeFinished() + augroup END +< + *NeomakeJobInit* +The NeomakeJobInit autocommand gets triggered before a job gets started. +You can use this to change the command (`jobinfo.argv`). +Context: + - `g:neomake_hook_context.jobinfo`: see |neomake-object-jobinfo|. + The `argv` entry contains the command to run (executable and arguments). + This can be a list or a string, depending on the maker and the job backend. + + *NeomakeJobStarted* +The NeomakeJobStarted autocommand gets triggered after a job started. +Context: + - `g:neomake_hook_context.jobinfo`: see |neomake-object-jobinfo|. + + *NeomakeCountsChanged* +The NeomakeCountsChanged user autocommand gets triggered after counts for the +location/quickfix list have changed, either because the list got reset or new +entries got added. +You can use this to e.g. update the statusline. +Context: + - `g:neomake_hook_context.reset`: 1 if the list got reset, 0 otherwise. + - `g:neomake_hook_context.jobinfo`: when the list is not reset; see + |neomake-object-jobinfo|. + + *NeomakeFinished* +The NeomakeFinished user autocommand gets triggered after all jobs of a build +have finished. +You can use this to e.g. close an empty location or quickfix window. +Context: + - `g:neomake_hook_context`: a dictionary with the following keys: + - `make_info`: make info, which contains all of the entries from below, + plus some more. (The object itself is not documented yet) + - `make_id`: the numeric ID of the make run. + - `options`: a dictionary (related to |neomake-object-jobinfo|): + - `file_mode` + - `bufnr` + - `ft` + - `finished_jobs`: a list of job infos (|neomake-object-jobinfo|) for the + finished jobs. + + *NeomakeJobFinished* +The NeomakeJobFinished autocommand gets triggered after a single job has +finished. +Context: + - `g:neomake_hook_context.jobinfo`: see |neomake-object-jobinfo|; `exit_code` + is available there. + +============================================================================== +5. Objects *neomake-objects* + + *neomake-object-jobinfo* +The `jobinfo` dictionary contains information about a job. +(this is experimental, so not everything is documented) + - `maker`: a dictionary containing information about the maker that ran + this job. See |neomake-object-maker|. + - `file_mode`: 1 for file mode, 0 for project/directory mode. + - `make_id`: the ID of the make run + - `get_pid()`: get the process ID (PID) of the job (-1 if not running + anymore). + + - Relevant for file mode: + - `bufnr`: the number of the buffer. + - `ft`: the filetype. + *neomake-object-maker* +The `maker` dictionary contains the following keys: +(this is experimental, so not everything is documented) + - `name`: name of the maker. + - `exe`: executable of the maker. + +============================================================================== +6. Frequently Asked Questions (FAQ) *neomake-faq* + +6.1 Other plugins overwrite the signs placed by Neomake~ + +When using quickfixsigns (https://github.com/tomtom/quickfixsigns_vim/) it +will also place signs for errors and warnings in the quickfix/location list, +and conflicts therefore with Neomake's own signs (see +|g:neomake_place_signs|). You can make quickfixsigns respect Neomake's signs +using this option: > + + let g:quickfixsigns_protect_sign_rx = '^neomake_' +< +6.2 How to configure the makers to be used?~ + +See |g:neomake_<ft>_enabled_makers| (press `<C-]>` on the link to go there). + + *neomake-faq-errorformat* +6.3 How to develop/debug the errorformat setting?~ + +Here are some tips to develop the 'errorformat' setting for makers: + +1. Get the output from the linter into a buffer (see also |:read!|). +2. Set the errorformat, e.g. `:let &efm = '%E%f:%l:%c\,%n: %m,%Z%m`. + See |errorformat| for documentation of the format itself. +3. Load the buffer into the quickfix list: `:cgetbuffer`. +4. Use |:copen| to open the quickfix window, and/or `:echo getqflist()` to + display the raw data. +5. Pay attention to the "`valid`" property of entries. + +vim: ft=help tw=78 isk+=<,>,\:,-,' diff --git a/dotfiles/.local/share/nvim/site/doc/tags b/dotfiles/.local/share/nvim/site/doc/tags new file mode 100644 index 0000000..e649efc --- /dev/null +++ b/dotfiles/.local/share/nvim/site/doc/tags @@ -0,0 +1,262 @@ +:AirlineExtensions airline.txt /*:AirlineExtensions* +:AirlineRefresh airline.txt /*:AirlineRefresh* +:AirlineTheme airline.txt /*:AirlineTheme* +:AirlineToggle airline.txt /*:AirlineToggle* +:AirlineToggleWhitespace airline.txt /*:AirlineToggleWhitespace* +:Neomake neomake.txt /*:Neomake* +:Neomake! neomake.txt /*:Neomake!* +:NeomakeCancelJob neomake.txt /*:NeomakeCancelJob* +:NeomakeCancelJobs neomake.txt /*:NeomakeCancelJobs* +:NeomakeClean neomake.txt /*:NeomakeClean* +:NeomakeClean! neomake.txt /*:NeomakeClean!* +:NeomakeDisable neomake.txt /*:NeomakeDisable* +:NeomakeDisableBuffer neomake.txt /*:NeomakeDisableBuffer* +:NeomakeDisableTab neomake.txt /*:NeomakeDisableTab* +:NeomakeEnable neomake.txt /*:NeomakeEnable* +:NeomakeEnableBuffer neomake.txt /*:NeomakeEnableBuffer* +:NeomakeEnableTab neomake.txt /*:NeomakeEnableTab* +:NeomakeFile neomake.txt /*:NeomakeFile* +:NeomakeInfo neomake.txt /*:NeomakeInfo* +:NeomakeListJobs neomake.txt /*:NeomakeListJobs* +:NeomakeProject neomake.txt /*:NeomakeProject* +:NeomakeSh neomake.txt /*:NeomakeSh* +:NeomakeSh! neomake.txt /*:NeomakeSh!* +:NeomakeStatus neomake.txt /*:NeomakeStatus* +:NeomakeToggle neomake.txt /*:NeomakeToggle* +:NeomakeToggleBuffer neomake.txt /*:NeomakeToggleBuffer* +:NeomakeToggleTab neomake.txt /*:NeomakeToggleTab* +:VdebugEval! Vdebug.txt /*:VdebugEval!* +NeomakeCountsChanged neomake.txt /*NeomakeCountsChanged* +NeomakeFinished neomake.txt /*NeomakeFinished* +NeomakeJobFinished neomake.txt /*NeomakeJobFinished* +NeomakeJobInit neomake.txt /*NeomakeJobInit* +NeomakeJobStarted neomake.txt /*NeomakeJobStarted* +Vdebug Vdebug.txt /*Vdebug* +Vdebug-contents Vdebug.txt /*Vdebug-contents* +VdebugAcknowledgements Vdebug.txt /*VdebugAcknowledgements* +VdebugBreakpointWindow Vdebug.txt /*VdebugBreakpointWindow* +VdebugBreakpoints Vdebug.txt /*VdebugBreakpoints* +VdebugCommandDetach Vdebug.txt /*VdebugCommandDetach* +VdebugCommandRun Vdebug.txt /*VdebugCommandRun* +VdebugCommandRunToCursor Vdebug.txt /*VdebugCommandRunToCursor* +VdebugCommandStepIn Vdebug.txt /*VdebugCommandStepIn* +VdebugCommandStepOut Vdebug.txt /*VdebugCommandStepOut* +VdebugCommandStepOver Vdebug.txt /*VdebugCommandStepOver* +VdebugCommandStop Vdebug.txt /*VdebugCommandStop* +VdebugCommands Vdebug.txt /*VdebugCommands* +VdebugEval Vdebug.txt /*VdebugEval* +VdebugEvalExpression Vdebug.txt /*VdebugEvalExpression* +VdebugEvalHighlighted Vdebug.txt /*VdebugEvalHighlighted* +VdebugEvalUnderCursor Vdebug.txt /*VdebugEvalUnderCursor* +VdebugFeatures Vdebug.txt /*VdebugFeatures* +VdebugIDEKey Vdebug.txt /*VdebugIDEKey* +VdebugInstallation Vdebug.txt /*VdebugInstallation* +VdebugIntro Vdebug.txt /*VdebugIntro* +VdebugIntroDBGP Vdebug.txt /*VdebugIntroDBGP* +VdebugIntroDebugging Vdebug.txt /*VdebugIntroDebugging* +VdebugIntroLanguages Vdebug.txt /*VdebugIntroLanguages* +VdebugKeys Vdebug.txt /*VdebugKeys* +VdebugLogWindow Vdebug.txt /*VdebugLogWindow* +VdebugOpt Vdebug.txt /*VdebugOpt* +VdebugOptionList Vdebug.txt /*VdebugOptionList* +VdebugOptions Vdebug.txt /*VdebugOptions* +VdebugOptions-break_on_open Vdebug.txt /*VdebugOptions-break_on_open* +VdebugOptions-continuous_mode Vdebug.txt /*VdebugOptions-continuous_mode* +VdebugOptions-debug_file Vdebug.txt /*VdebugOptions-debug_file* +VdebugOptions-debug_file_level Vdebug.txt /*VdebugOptions-debug_file_level* +VdebugOptions-debug_window_level Vdebug.txt /*VdebugOptions-debug_window_level* +VdebugOptions-ide_key Vdebug.txt /*VdebugOptions-ide_key* +VdebugOptions-marker_closed_tree Vdebug.txt /*VdebugOptions-marker_closed_tree* +VdebugOptions-marker_default Vdebug.txt /*VdebugOptions-marker_default* +VdebugOptions-marker_open_tree Vdebug.txt /*VdebugOptions-marker_open_tree* +VdebugOptions-on_close Vdebug.txt /*VdebugOptions-on_close* +VdebugOptions-path_maps Vdebug.txt /*VdebugOptions-path_maps* +VdebugOptions-port Vdebug.txt /*VdebugOptions-port* +VdebugOptions-server Vdebug.txt /*VdebugOptions-server* +VdebugOptions-sign_breakpoint Vdebug.txt /*VdebugOptions-sign_breakpoint* +VdebugOptions-sign_current Vdebug.txt /*VdebugOptions-sign_current* +VdebugOptions-timeout Vdebug.txt /*VdebugOptions-timeout* +VdebugOptions-watch_window_style Vdebug.txt /*VdebugOptions-watch_window_style* +VdebugRemote Vdebug.txt /*VdebugRemote* +VdebugRemoteConnection Vdebug.txt /*VdebugRemoteConnection* +VdebugRemoteFilePaths Vdebug.txt /*VdebugRemoteFilePaths* +VdebugRemoveBreakpoints Vdebug.txt /*VdebugRemoveBreakpoints* +VdebugSetBreakpoints Vdebug.txt /*VdebugSetBreakpoints* +VdebugSetBreakpoints-call Vdebug.txt /*VdebugSetBreakpoints-call* +VdebugSetBreakpoints-conditional Vdebug.txt /*VdebugSetBreakpoints-conditional* +VdebugSetBreakpoints-exception Vdebug.txt /*VdebugSetBreakpoints-exception* +VdebugSetBreakpoints-return Vdebug.txt /*VdebugSetBreakpoints-return* +VdebugSetBreakpoints-watch Vdebug.txt /*VdebugSetBreakpoints-watch* +VdebugSetLineBreakpoint Vdebug.txt /*VdebugSetLineBreakpoint* +VdebugSetUp Vdebug.txt /*VdebugSetUp* +VdebugSetUpNodejs Vdebug.txt /*VdebugSetUpNodejs* +VdebugSetUpPHP Vdebug.txt /*VdebugSetUpPHP* +VdebugSetUpPerl Vdebug.txt /*VdebugSetUpPerl* +VdebugSetUpPython Vdebug.txt /*VdebugSetUpPython* +VdebugSetUpRuby Vdebug.txt /*VdebugSetUpRuby* +VdebugSetUpTcl Vdebug.txt /*VdebugSetUpTcl* +VdebugSourceWindow Vdebug.txt /*VdebugSourceWindow* +VdebugStackWindow Vdebug.txt /*VdebugStackWindow* +VdebugStart Vdebug.txt /*VdebugStart* +VdebugStatusWindow Vdebug.txt /*VdebugStatusWindow* +VdebugTrace Vdebug.txt /*VdebugTrace* +VdebugTraceWindow Vdebug.txt /*VdebugTraceWindow* +VdebugTroubleshooting Vdebug.txt /*VdebugTroubleshooting* +VdebugUI Vdebug.txt /*VdebugUI* +VdebugUsage Vdebug.txt /*VdebugUsage* +VdebugViewBreakpoints Vdebug.txt /*VdebugViewBreakpoints* +VdebugWatchWindow Vdebug.txt /*VdebugWatchWindow* +add_inactive_statusline_func airline.txt /*add_inactive_statusline_func* +add_statusline_func airline.txt /*add_statusline_func* +airline airline.txt /*airline* +airline#extensions#tabline#exclude_buffers airline.txt /*airline#extensions#tabline#exclude_buffers* +airline#ignore_bufadd_pat airline.txt /*airline#ignore_bufadd_pat* +airline-accents airline.txt /*airline-accents* +airline-advanced-customization airline.txt /*airline-advanced-customization* +airline-ale airline.txt /*airline-ale* +airline-autocommands airline.txt /*airline-autocommands* +airline-branch airline.txt /*airline-branch* +airline-bufferline airline.txt /*airline-bufferline* +airline-capslock airline.txt /*airline-capslock* +airline-commands airline.txt /*airline-commands* +airline-configuration airline.txt /*airline-configuration* +airline-contents airline.txt /*airline-contents* +airline-contributions airline.txt /*airline-contributions* +airline-csv airline.txt /*airline-csv* +airline-ctrlp airline.txt /*airline-ctrlp* +airline-ctrlspace airline.txt /*airline-ctrlspace* +airline-cursormode airline.txt /*airline-cursormode* +airline-customization airline.txt /*airline-customization* +airline-default airline.txt /*airline-default* +airline-eclim airline.txt /*airline-eclim* +airline-extensions airline.txt /*airline-extensions* +airline-features airline.txt /*airline-features* +airline-fugitiveline airline.txt /*airline-fugitiveline* +airline-funcrefs airline.txt /*airline-funcrefs* +airline-grepper airline.txt /*airline-grepper* +airline-gutentags airline.txt /*airline-gutentags* +airline-hunks airline.txt /*airline-hunks* +airline-intro airline.txt /*airline-intro* +airline-keymap airline.txt /*airline-keymap* +airline-languageclient airline.txt /*airline-languageclient* +airline-license airline.txt /*airline-license* +airline-localsearch airline.txt /*airline-localsearch* +airline-name airline.txt /*airline-name* +airline-neomake airline.txt /*airline-neomake* +airline-nerdtree airline.txt /*airline-nerdtree* +airline-nrrwrgn airline.txt /*airline-nrrwrgn* +airline-obsession airline.txt /*airline-obsession* +airline-parts airline.txt /*airline-parts* +airline-pipeline airline.txt /*airline-pipeline* +airline-pipeline-return-codes airline.txt /*airline-pipeline-return-codes* +airline-po airline.txt /*airline-po* +airline-predefined-parts airline.txt /*airline-predefined-parts* +airline-promptline airline.txt /*airline-promptline* +airline-quickfix airline.txt /*airline-quickfix* +airline-sections airline.txt /*airline-sections* +airline-syntastic airline.txt /*airline-syntastic* +airline-tabline airline.txt /*airline-tabline* +airline-taboo airline.txt /*airline-taboo* +airline-tagbar airline.txt /*airline-tagbar* +airline-themes airline.txt /*airline-themes* +airline-tmuxline airline.txt /*airline-tmuxline* +airline-troubleshooting airline.txt /*airline-troubleshooting* +airline-vimagit airline.txt /*airline-vimagit* +airline-vimtex airline.txt /*airline-vimtex* +airline-virtualenv airline.txt /*airline-virtualenv* +airline-whitespace airline.txt /*airline-whitespace* +airline-windowswap airline.txt /*airline-windowswap* +airline-wordcount airline.txt /*airline-wordcount* +airline-writing-extensions airline.txt /*airline-writing-extensions* +airline-xkblayout airline.txt /*airline-xkblayout* +airline-xtabline airline.txt /*airline-xtabline* +airline-ycm airline.txt /*airline-ycm* +airline.txt airline.txt /*airline.txt* +b:neomake_<ft>_<name>_<property> neomake.txt /*b:neomake_<ft>_<name>_<property>* +b:neomake_<ft>_enabled_makers neomake.txt /*b:neomake_<ft>_enabled_makers* +b:neomake_<name>_<property> neomake.txt /*b:neomake_<name>_<property>* +b:neomake_enabled_makers neomake.txt /*b:neomake_enabled_makers* +b:neomake_list_height neomake.txt /*b:neomake_list_height* +b:neomake_open_list neomake.txt /*b:neomake_open_list* +g:airline#extensions#neomake#enabled neomake.txt /*g:airline#extensions#neomake#enabled* +g:neomake_<ft>_<name>_<property> neomake.txt /*g:neomake_<ft>_<name>_<property>* +g:neomake_<ft>_<name>_maker neomake.txt /*g:neomake_<ft>_<name>_maker* +g:neomake_<ft>_enabled_makers neomake.txt /*g:neomake_<ft>_enabled_makers* +g:neomake_<name>_<property> neomake.txt /*g:neomake_<name>_<property>* +g:neomake_<name>_maker neomake.txt /*g:neomake_<name>_maker* +g:neomake_cursormoved_delay neomake.txt /*g:neomake_cursormoved_delay* +g:neomake_echo_current_error neomake.txt /*g:neomake_echo_current_error* +g:neomake_enabled_makers neomake.txt /*g:neomake_enabled_makers* +g:neomake_error_sign neomake.txt /*g:neomake_error_sign* +g:neomake_highlight_columns neomake.txt /*g:neomake_highlight_columns* +g:neomake_highlight_lines neomake.txt /*g:neomake_highlight_lines* +g:neomake_info_sign neomake.txt /*g:neomake_info_sign* +g:neomake_list_height neomake.txt /*g:neomake_list_height* +g:neomake_logfile neomake.txt /*g:neomake_logfile* +g:neomake_message_sign neomake.txt /*g:neomake_message_sign* +g:neomake_open_list neomake.txt /*g:neomake_open_list* +g:neomake_place_signs neomake.txt /*g:neomake_place_signs* +g:neomake_remove_invalid_entries neomake.txt /*g:neomake_remove_invalid_entries* +g:neomake_serialize neomake.txt /*g:neomake_serialize* +g:neomake_serialize_abort_on_error neomake.txt /*g:neomake_serialize_abort_on_error* +g:neomake_verbose neomake.txt /*g:neomake_verbose* +g:neomake_virtualtext_current_error neomake.txt /*g:neomake_virtualtext_current_error* +g:neomake_virtualtext_prefix neomake.txt /*g:neomake_virtualtext_prefix* +g:neomake_warning_sign neomake.txt /*g:neomake_warning_sign* +neomake neomake.txt /*neomake* +neomake#CancelJob neomake.txt /*neomake#CancelJob* +neomake#ListJobs neomake.txt /*neomake#ListJobs* +neomake#Make neomake.txt /*neomake#Make* +neomake#Sh neomake.txt /*neomake#Sh* +neomake#signs#RedefineErrorSign neomake.txt /*neomake#signs#RedefineErrorSign* +neomake#signs#RedefineWarningSign neomake.txt /*neomake#signs#RedefineWarningSign* +neomake#statusline#LoclistCounts neomake.txt /*neomake#statusline#LoclistCounts* +neomake#statusline#LoclistStatus neomake.txt /*neomake#statusline#LoclistStatus* +neomake#statusline#QflistCounts neomake.txt /*neomake#statusline#QflistCounts* +neomake#statusline#QflistStatus neomake.txt /*neomake#statusline#QflistStatus* +neomake#statusline#get() neomake.txt /*neomake#statusline#get()* +neomake-args-file neomake.txt /*neomake-args-file* +neomake-autocmds neomake.txt /*neomake-autocmds* +neomake-automake neomake.txt /*neomake-automake* +neomake-automake-dynamic-delay neomake.txt /*neomake-automake-dynamic-delay* +neomake-commands neomake.txt /*neomake-commands* +neomake-configuration neomake.txt /*neomake-configuration* +neomake-disable neomake.txt /*neomake-disable* +neomake-enable neomake.txt /*neomake-enable* +neomake-faq neomake.txt /*neomake-faq* +neomake-faq-errorformat neomake.txt /*neomake-faq-errorformat* +neomake-functions neomake.txt /*neomake-functions* +neomake-highlight neomake.txt /*neomake-highlight* +neomake-hooks neomake.txt /*neomake-hooks* +neomake-introduction neomake.txt /*neomake-introduction* +neomake-job-makers neomake.txt /*neomake-job-makers* +neomake-makers neomake.txt /*neomake-makers* +neomake-makers-InitForJob neomake.txt /*neomake-makers-InitForJob* +neomake-makers-args neomake.txt /*neomake-makers-args* +neomake-makers-buffer_output neomake.txt /*neomake-makers-buffer_output* +neomake-makers-cwd neomake.txt /*neomake-makers-cwd* +neomake-makers-exe neomake.txt /*neomake-makers-exe* +neomake-makers-filter_output neomake.txt /*neomake-makers-filter_output* +neomake-makers-get_list_entries neomake.txt /*neomake-makers-get_list_entries* +neomake-makers-mapexpr neomake.txt /*neomake-makers-mapexpr* +neomake-makers-output_stream neomake.txt /*neomake-makers-output_stream* +neomake-makers-postprocess neomake.txt /*neomake-makers-postprocess* +neomake-makers-process_json neomake.txt /*neomake-makers-process_json* +neomake-makers-process_output neomake.txt /*neomake-makers-process_output* +neomake-makers-processing neomake.txt /*neomake-makers-processing* +neomake-makers-properties neomake.txt /*neomake-makers-properties* +neomake-makers-remove_invalid_entries neomake.txt /*neomake-makers-remove_invalid_entries* +neomake-makers-supports_stdin neomake.txt /*neomake-makers-supports_stdin* +neomake-makers-tempfile_dir neomake.txt /*neomake-makers-tempfile_dir* +neomake-makers-tempfile_enabled neomake.txt /*neomake-makers-tempfile_enabled* +neomake-makers-uses_stdin neomake.txt /*neomake-makers-uses_stdin* +neomake-object-jobinfo neomake.txt /*neomake-object-jobinfo* +neomake-object-maker neomake.txt /*neomake-object-maker* +neomake-objects neomake.txt /*neomake-objects* +neomake-options neomake.txt /*neomake-options* +neomake-signs neomake.txt /*neomake-signs* +neomake-statusline neomake.txt /*neomake-statusline* +neomake-toggle neomake.txt /*neomake-toggle* +neomake.txt neomake.txt /*neomake.txt* +remove_statusline_func airline.txt /*remove_statusline_func* +vim-airline airline.txt /*vim-airline* diff --git a/dotfiles/.local/share/nvim/site/ftdetect/node.vim b/dotfiles/.local/share/nvim/site/ftdetect/node.vim new file mode 100644 index 0000000..ed50604 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/ftdetect/node.vim @@ -0,0 +1,8 @@ +function! s:isNode() + let shebang = getline(1) + if shebang =~# '^#!.*/bin/env\s\+node\>' | return 1 | en + if shebang =~# '^#!.*/bin/node\>' | return 1 | en + return 0 +endfunction + +au BufRead,BufNewFile * if !did_filetype() && s:isNode() | setf javascript | en diff --git a/dotfiles/.local/share/nvim/site/ftdetect/toml.vim b/dotfiles/.local/share/nvim/site/ftdetect/toml.vim new file mode 100644 index 0000000..568dd82 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/ftdetect/toml.vim @@ -0,0 +1,2 @@ +" Go dep and Rust use several TOML config files that are not named with .toml. +autocmd BufNewFile,BufRead *.toml,Gopkg.lock,Cargo.lock,*/.cargo/config,*/.cargo/credentials,Pipfile setf toml diff --git a/dotfiles/.local/share/nvim/site/plugin/airline.vim b/dotfiles/.local/share/nvim/site/plugin/airline.vim new file mode 100644 index 0000000..c91ff20 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/airline.vim @@ -0,0 +1,208 @@ +" MIT License. Copyright (c) 2013-2018 Bailey Ling et al. +" vim: et ts=2 sts=2 sw=2 + +scriptencoding utf-8 + +if &cp || v:version < 702 || (exists('g:loaded_airline') && g:loaded_airline) + finish +endif +let g:loaded_airline = 1 + +let s:airline_initialized = 0 +function! s:init() + if s:airline_initialized + return + endif + let s:airline_initialized = 1 + + call airline#extensions#load() + call airline#init#sections() + + let s:theme_in_vimrc = exists('g:airline_theme') + if s:theme_in_vimrc + try + let palette = g:airline#themes#{g:airline_theme}#palette + catch + call airline#util#warning(printf('Could not resolve airline theme "%s". Themes have been migrated to github.com/vim-airline/vim-airline-themes.', g:airline_theme)) + let g:airline_theme = 'dark' + endtry + silent call airline#switch_theme(g:airline_theme) + else + let g:airline_theme = 'dark' + silent call s:on_colorscheme_changed() + endif + + call airline#util#doautocmd('AirlineAfterInit') +endfunction + +let s:active_winnr = -1 +function! s:on_window_changed() + let s:active_winnr = winnr() + + if pumvisible() && (!&previewwindow || g:airline_exclude_preview) + return + endif + " Handle each window only once, since we might come here several times for + " different autocommands. + let l:key = [bufnr('%'), s:active_winnr, winnr('$'), tabpagenr(), &ft] + if get(g:, 'airline_last_window_changed', []) == l:key + \ && &stl is# '%!airline#statusline('.s:active_winnr.')' + \ && &ft !~? 'gitcommit' + " fugitive is special, it changes names and filetypes several times, + " make sure the caching does not get into its way + return + endif + let g:airline_last_window_changed = l:key + call s:init() + call airline#update_statusline() +endfunction + +function! s:on_colorscheme_changed() + call s:init() + unlet! g:airline#highlighter#normal_fg_hi + call airline#highlighter#reset_hlcache() + let g:airline_gui_mode = airline#init#gui_mode() + if !s:theme_in_vimrc + call airline#switch_matching_theme() + endif + + " couldn't find a match, or theme was defined, just refresh + call airline#load_theme() +endfunction + +function! airline#cmdwinenter(...) + call airline#extensions#apply_left_override('Command Line', '') +endfunction + +function! s:airline_toggle() + if exists("#airline") + augroup airline + au! + augroup END + augroup! airline + + if exists("s:stl") + let &stl = s:stl + endif + call airline#highlighter#reset_hlcache() + + call airline#util#doautocmd('AirlineToggledOff') + else + let s:stl = &statusline + augroup airline + autocmd! + + autocmd CmdwinEnter * + \ call airline#add_statusline_func('airline#cmdwinenter') + \ | call <sid>on_window_changed() + autocmd CmdwinLeave * call airline#remove_statusline_func('airline#cmdwinenter') + + autocmd GUIEnter,ColorScheme * call <sid>on_colorscheme_changed() + if exists("##OptionSet") + " Make sure that g_airline_gui_mode is refreshed + autocmd OptionSet termguicolors call <sid>on_colorscheme_changed() + endif + " Set all statuslines to inactive + autocmd FocusLost * call airline#update_statusline_focuslost() + " Refresh airline for :syntax off + autocmd SourcePre */syntax/syntax.vim + \ call airline#extensions#tabline#buffers#invalidate() + autocmd VimEnter,WinEnter,BufWinEnter,FileType,BufUnload * + \ call <sid>on_window_changed() + if exists('##CompleteDone') + autocmd CompleteDone * call <sid>on_window_changed() + endif + " non-trivial number of external plugins use eventignore=all, so we need to account for that + autocmd CursorMoved * + \ if winnr() != s:active_winnr + \ | call <sid>on_window_changed() + \ | endif + + autocmd VimResized * unlet! w:airline_lastmode | :call <sid>airline_refresh() + if exists('*timer_start') && exists('*funcref') + " do not trigger FocusGained on startup, it might erase the intro screen (see #1817) + " needs funcref() (needs 7.4.2137) and timers (7.4.1578) + let Handler=funcref('<sid>FocusGainedHandler') + let s:timer=timer_start(5000, Handler) + else + autocmd FocusGained * unlet! w:airline_lastmode | :call <sid>airline_refresh() + endif + + if exists("##TerminalOpen") + " Using the same function with the TermOpen autocommand + " breaks for Neovim see #1828, looks like a neovim bug. + autocmd TerminalOpen * :call airline#load_theme() " reload current theme for Terminal, forces the terminal extension to be loaded + endif + autocmd TabEnter * :unlet! w:airline_lastmode | let w:airline_active=1 + autocmd BufWritePost */autoload/airline/themes/*.vim + \ exec 'source '.split(globpath(&rtp, 'autoload/airline/themes/'.g:airline_theme.'.vim', 1), "\n")[0] + \ | call airline#load_theme() + augroup END + + if &laststatus < 2 + set laststatus=2 + endif + if s:airline_initialized + call s:on_window_changed() + endif + + call airline#util#doautocmd('AirlineToggledOn') + endif +endfunction + +function! s:get_airline_themes(a, l, p) + return airline#util#themes(a:a) +endfunction + +function! s:airline_theme(...) + if a:0 + try + call airline#switch_theme(a:1) + catch " discard error + endtry + else + echo g:airline_theme + endif +endfunction + +function! s:airline_refresh() + if !exists("#airline") + " disabled + return + endif + call airline#util#doautocmd('AirlineBeforeRefresh') + call airline#highlighter#reset_hlcache() + call airline#load_theme() + call airline#update_statusline() +endfunction + +function! s:FocusGainedHandler(timer) + if exists("s:timer") && a:timer == s:timer + augroup airline + au FocusGained * unlet! w:airline_lastmode | :call <sid>airline_refresh() + augroup END + endif +endfu + +function! s:airline_extensions() + let loaded = airline#extensions#get_loaded_extensions() + let files = split(globpath(&rtp, "autoload/airline/extensions/*.vim"), "\n") + call map(files, 'fnamemodify(v:val, ":t:r")') + if !empty(files) + echohl Title + echo printf("%-15s\t%s", "Extension", "Status") + echohl Normal + endif + for ext in sort(files) + echo printf("%-15s\t%sloaded", ext, (index(loaded, ext) == -1 ? 'not ' : '')) + endfor +endfunction + +command! -bar -nargs=? -complete=customlist,<sid>get_airline_themes AirlineTheme call <sid>airline_theme(<f-args>) +command! -bar AirlineToggleWhitespace call airline#extensions#whitespace#toggle() +command! -bar AirlineToggle call s:airline_toggle() +command! -bar AirlineRefresh call s:airline_refresh() +command! AirlineExtensions call s:airline_extensions() + +call airline#init#bootstrap() +call s:airline_toggle() diff --git a/dotfiles/.local/share/nvim/site/plugin/dragvisuals.vim b/dotfiles/.local/share/nvim/site/plugin/dragvisuals.vim new file mode 100644 index 0000000..12c4f5d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/dragvisuals.vim @@ -0,0 +1,345 @@ +" Vim global plugin for dragging virtual blocks +" Last change: Tue Jul 24 07:19:35 EST 2012 +" Maintainer: Damian Conway +" License: This file is placed in the public domain. + +"######################################################################### +"## ## +"## Add the following (uncommented) to your .vimrc... ## +"## ## +"## runtime plugin/dragvisuals.vim ## +"## ## +"## vmap <expr> <LEFT> DVB_Drag('left') ## +"## vmap <expr> <RIGHT> DVB_Drag('right') ## +"## vmap <expr> <DOWN> DVB_Drag('down') ## +"## vmap <expr> <UP> DVB_Drag('up') ## +"## vmap <expr> D DVB_Duplicate() ## +"## ## +"## " Remove any introduced trailing whitespace after moving... ## +"## let g:DVB_TrimWS = 1 ## +"## ## +"## Or, if you use the arrow keys for normal motions, choose ## +"## four other keys for block dragging. For example: ## +"## ## +"## vmap <expr> h DVB_Drag('left') ## +"## vmap <expr> l DVB_Drag('right') ## +"## vmap <expr> j DVB_Drag('down') ## +"## vmap <expr> k DVB_Drag('up') ## +"## ## +"## Or: ## +"## ## +"## vmap <expr> <S-LEFT> DVB_Drag('left') ## +"## vmap <expr> <S-RIGHT> DVB_Drag('right') ## +"## vmap <expr> <S-DOWN> DVB_Drag('down') ## +"## vmap <expr> <S-UP> DVB_Drag('up') ## +"## ## +"## Or even: ## +"## ## +"## vmap <expr> <LEFT><LEFT> DVB_Drag('left') ## +"## vmap <expr> <RIGHT><RIGHT> DVB_Drag('right') ## +"## vmap <expr> <DOWN><DOWN> DVB_Drag('down') ## +"## vmap <expr> <UP><UP> DVB_Drag('up') ## +"## ## +"######################################################################### + + +" If already loaded, we're done... +if exists("loaded_dragvirtualblocks") + finish +endif +let loaded_dragvirtualblocks = 1 + +" Preserve external compatibility options, then enable full vim compatibility... +let s:save_cpo = &cpo +set cpo&vim + +"====[ Implementation ]==================================== + +" Toggle this to stop trimming on drags... +if !exists('g:DVB_TrimWS') + let g:DVB_TrimWS = 1 +endif + +function! DVB_Drag (dir) + " No-op in Visual mode... + if mode() ==# 'v' + return "\<ESC>gv" + + " Do Visual Line drag indirectly via temporary nmap + " (to ensure we have access to block position data)... + elseif mode() ==# 'V' + " Set up a temporary convenience... + exec "nnoremap <silent><expr><buffer> M \<SID>Drag_Lines('".a:dir."')" + + " Return instructions to implement the move and reset selection... + return '"vyM' + + " Otherwise do Visual Block drag indirectly via temporary nmap + " (to ensure we have access to block position data)... + else + " Set up a temporary convenience... + exec "nnoremap <silent><expr><buffer> M \<SID>Drag_Block('".a:dir."')" + + " Return instructions to implement the move and reset selection... + return '"vyM' + endif +endfunction + +" Duplicate selected block and place to the right... +function! DVB_Duplicate () + exec "nnoremap <silent><expr><buffer> M \<SID>DuplicateBlock()" + return '"vyM' +endfunction + +function! s:DuplicateBlock () + nunmap <buffer> M + " Locate block boundaries... + let [buf_left, line_left, col_left, offset_left ] = getpos("'<") + let [buf_right, line_right, col_right, offset_right] = getpos("'>") + + " Identify special '$' blocks... + let dollar_block = 0 + let start_col = min([col_left+offset_left, col_right+offset_right]) + let end_col = max([col_left+offset_left, col_right+offset_right]) + let visual_width = end_col - start_col + 1 + for visual_line in split(getreg("v"),"\n") + if strlen(visual_line) > visual_width + let dollar_block = 1 + let visual_width = strlen(visual_line) + endif + endfor + let square_up = (dollar_block ? (start_col+visual_width-2).'|' : '') + + set virtualedit=all + return 'gv'.square_up.'yPgv' + \. (visual_width-dollar_block) . 'lo' . (visual_width-dollar_block) . 'l' + \. "y:set virtualedit=block\<CR>gv" + \. (dollar_block ? 'o$' : '') +endfunction + + +" Kludge to hide change reporting inside implementation... +let s:NO_REPORT = ":let b:DVB_report=&report\<CR>:let &report=1000000000\<CR>" +let s:PREV_REPORT = ":let &report = b:DVB_report\<CR>" + + +" Drag in specified direction in Visual Line mode... +function! s:Drag_Lines (dir) + " Clean up the temporary convenience... + nunmap <buffer> M + + " Locate block being shifted... + let [buf_left, line_left, col_left, offset_left ] = getpos("'<") + let [buf_right, line_right, col_right, offset_right] = getpos("'>") + + " Drag entire lines left if possible... + if a:dir == 'left' + " Are all lines indented at least one space??? + let lines = getline(line_left, line_right) + let all_indented = match(lines, '^[^ ]') == -1 + nohlsearch + + " If can't trim one space from start of each line, be a no-op... + if !all_indented + return 'gv' + + " Otherwise drag left by removing one space from start of each line... + else + return s:NO_REPORT + \ . "gv:s/^ //\<CR>" + \ . s:PREV_REPORT + \ . "gv" + endif + + " To drag entire lines right, add a space in column 1... + elseif a:dir == 'right' + return s:NO_REPORT + \ . "gv:s/^/ /\<CR>:nohlsearch\<CR>" + \ . s:PREV_REPORT + \ . "gv" + + " To drag entire lines upwards... + elseif a:dir == 'up' + let EOF = line('$') + + " Can't drag up if at first line... + if line_left == 1 || line_right == 1 + return 'gv' + + " Needs special handling at EOF (because cursor moves up on delete)... + elseif line_left == EOF || line_right == EOF + let height = line_right - line_left + let select_extra = height ? height . 'j' : "" + return s:NO_REPORT + \ . 'gvxP' + \ . s:PREV_REPORT + \ . 'V' . select_extra + + " Otherwise just cut-move-paste-reselect... + else + let height = line_right - line_left + let select_extra = height ? height . 'j' : "" + return s:NO_REPORT + \ . 'gvxkP' + \ . s:PREV_REPORT + \ . 'V' . select_extra + endif + + " To drag entire lines downwards... + elseif a:dir == 'down' + let EOF = line('$') + + " This is how much extra we're going to have to reselect... + let height = line_right - line_left + let select_extra = height ? height . 'j' : "" + + " Needs special handling at EOF (to push selection down into new space)... + if line_left == EOF || line_right == EOF + return "O\<ESC>gv" + + " Otherwise, just cut-move-paste-reselect... + else + return s:NO_REPORT + \ . 'gvxp' + \ . s:PREV_REPORT + \ . 'V' . select_extra + endif + + endif +endfunction + +" Drag in specified direction in Visual Block mode... +function! s:Drag_Block (dir) + " Clean up the temporary convenience... + nunmap <buffer> M + + " Locate block being shifted... + let [buf_left, line_left, col_left, offset_left ] = getpos("'<") + let [buf_right, line_right, col_right, offset_right] = getpos("'>") + + " Identify special '$' blocks... + let dollar_block = 0 + let start_col = min([col_left+offset_left, col_right+offset_right]) + let end_col = max([col_left+offset_left, col_right+offset_right]) + let visual_width = end_col - start_col + 1 + for visual_line in split(getreg("v"),"\n") + if strlen(visual_line) > visual_width + let dollar_block = 1 + let visual_width = strlen(visual_line) + endif + endfor + let square_up = (dollar_block ? (start_col+visual_width-2).'|' : '') + + " Drag left... + if a:dir == 'left' + "Can't drag left at left margin... + if col_left == 1 || col_right == 1 + return 'gv' + + " Otherwise reposition one column left (and optionally trim any whitespace)... + elseif g:DVB_TrimWS + " May need to be able to temporarily step past EOL... + let prev_ve = &virtualedit + set virtualedit=all + + " Are we moving past other text??? + let square_up_final = "" + if dollar_block + let lines = getline(line_left, line_right) + if match(lines, '^.\{'.(start_col-2).'}\S') >= 0 + let dollar_block = 0 + let square_up_final = (start_col+visual_width-3).'|' + endif + endif + + let vcol = start_col - 2 + return 'gv'.square_up.'xhP' + \ . s:NO_REPORT + \ . "gvhoho:s/\\s*$//\<CR>gv\<ESC>" + \ . ':set virtualedit=' . prev_ve . "\<CR>" + \ . s:PREV_REPORT + \ . ":nohlsearch\<CR>gv" + \ . (dollar_block ? '$' : square_up_final ) + else + return 'gv'.square_up.'xhPgvhoho' + endif + + " Drag right... + elseif a:dir == 'right' + " May need to be able to temporarily step past EOL... + let prev_ve = &virtualedit + set virtualedit=all + + " Reposition block one column to the right... + if g:DVB_TrimWS + let vcol = start_col + return 'gv'.square_up.'xp' + \ . s:NO_REPORT + \ . "gvlolo" + \ . ":s/\\s*$//\<CR>gv\<ESC>" + \ . ':set virtualedit=' . prev_ve . "\<CR>" + \ . s:PREV_REPORT + \ . (dollar_block ? 'gv$' : 'gv') + else + return 'gv'.square_up.'xp:set virtualedit=' . prev_ve . "\<CR>gvlolo" + endif + + " Drag upwards... + elseif a:dir == 'up' + " Can't drag upwards at top margin... + if line_left == 1 || line_right == 1 + return 'gv' + endif + + " May need to be able to temporarily step past EOL... + let prev_ve = &virtualedit + set virtualedit=all + + " If trimming whitespace, jump to just below block to do it... + if g:DVB_TrimWS + let height = line_right - line_left + 1 + return 'gv'.square_up.'xkPgvkoko"vy' + \ . height + \ . 'j:s/\s*$//' + \ . "\<CR>:nohlsearch\<CR>:set virtualedit=" + \ . prev_ve + \ . "\<CR>gv" + \ . (dollar_block ? '$' : '') + + " Otherwise just move and reselect... + else + return 'gv'.square_up.'xkPgvkoko"vy:set virtualedit=' + \ . prev_ve + \ . "\<CR>gv" + \ . (dollar_block ? '$' : '') + endif + + " Drag downwards... + elseif a:dir == 'down' + " May need to be able to temporarily step past EOL... + let prev_ve = &virtualedit + set virtualedit=all + + " If trimming whitespace, move to just above block to do it... + if g:DVB_TrimWS + return 'gv'.square_up.'xjPgvjojo"vyk:s/\s*$//' + \ . "\<CR>:nohlsearch\<CR>:set virtualedit=" + \ . prev_ve + \ . "\<CR>gv" + \ . (dollar_block ? '$' : '') + + " Otherwise just move and reselect... + else + return 'gv'.square_up.'xjPgvjojo"vy' + \ . "\<CR>:set virtualedit=" + \ . prev_ve + \ . "\<CR>gv" + \ . (dollar_block ? '$' : '') + endif + endif +endfunction + + +" Restore previous external compatibility options +let &cpo = s:save_cpo + diff --git a/dotfiles/.local/share/nvim/site/plugin/gnupg.vim b/dotfiles/.local/share/nvim/site/plugin/gnupg.vim new file mode 100644 index 0000000..97539c5 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/gnupg.vim @@ -0,0 +1,1287 @@ +" Name: gnupg.vim +" Last Change: 2012 May 31 +" Maintainer: James McCoy <vega.james@gmail.com> +" Original Author: Markus Braun <markus.braun@krawel.de> +" Summary: Vim plugin for transparent editing of gpg encrypted files. +" License: This program is free software; you can redistribute it and/or +" modify it under the terms of the GNU General Public License +" as published by the Free Software Foundation; either version +" 2 of the License, or (at your option) any later version. +" See http://www.gnu.org/copyleft/gpl-2.0.txt +" +" Section: Documentation {{{1 +" +" Description: {{{2 +" +" This script implements transparent editing of gpg encrypted files. The +" filename must have a ".gpg", ".pgp" or ".asc" suffix. When opening such +" a file the content is decrypted, when opening a new file the script will +" ask for the recipients of the encrypted file. The file content will be +" encrypted to all recipients before it is written. The script turns off +" viminfo, swapfile, and undofile to increase security. +" +" Installation: {{{2 +" +" Copy the gnupg.vim file to the $HOME/.vim/plugin directory. +" Refer to ':help add-plugin', ':help add-global-plugin' and ':help +" runtimepath' for more details about Vim plugins. +" +" From "man 1 gpg-agent": +" +" ... +" You should always add the following lines to your .bashrc or whatever +" initialization file is used for all shell invocations: +" +" GPG_TTY=`tty` +" export GPG_TTY +" +" It is important that this environment variable always reflects the out‐ +" put of the tty command. For W32 systems this option is not required. +" ... +" +" Most distributions provide software to ease handling of gpg and gpg-agent. +" Examples are keychain or seahorse. +" +" Commands: {{{2 +" +" :GPGEditRecipients +" Opens a scratch buffer to change the list of recipients. Recipients that +" are unknown (not in your public key) are highlighted and have +" a prepended "!". Closing the buffer makes the changes permanent. +" +" :GPGViewRecipients +" Prints the list of recipients. +" +" :GPGEditOptions +" Opens a scratch buffer to change the options for encryption (symmetric, +" asymmetric, signing). Closing the buffer makes the changes permanent. +" WARNING: There is no check of the entered options, so you need to know +" what you are doing. +" +" :GPGViewOptions +" Prints the list of options. +" +" Variables: {{{2 +" +" g:GPGExecutable +" If set used as gpg executable, otherwise the system chooses what is run +" when "gpg" is called. Defaults to "gpg". +" +" g:GPGUseAgent +" If set to 0 a possible available gpg-agent won't be used. Defaults to 1. +" +" g:GPGPreferSymmetric +" If set to 1 symmetric encryption is preferred for new files. Defaults to 0. +" +" g:GPGPreferArmor +" If set to 1 armored data is preferred for new files. Defaults to 0 +" unless a "*.asc" file is being edited. +" +" g:GPGPreferSign +" If set to 1 signed data is preferred for new files. Defaults to 0. +" +" g:GPGDefaultRecipients +" If set, these recipients are used as defaults when no other recipient is +" defined. This variable is a Vim list. Default is unset. +" +" g:GPGUsePipes +" If set to 1, use pipes instead of temporary files when interacting with +" gnupg. When set to 1, this can cause terminal-based gpg agents to not +" display correctly when prompting for passwords. Defaults to 0. +" +" g:GPGHomedir +" If set, specifies the directory that will be used for GPG's homedir. +" This corresponds to gpg's --homedir option. This variable is a Vim +" string. +" +" Known Issues: {{{2 +" +" In some cases gvim can't decrypt files + +" This is caused by the fact that a running gvim has no TTY and thus gpg is +" not able to ask for the passphrase by itself. This is a problem for Windows +" and Linux versions of gvim and could not be solved unless a "terminal +" emulation" is implemented for gvim. To circumvent this you have to use any +" combination of gpg-agent and a graphical pinentry program: +" +" - gpg-agent only: +" you need to provide the passphrase for the needed key to gpg-agent +" in a terminal before you open files with gvim which require this key. +" +" - pinentry only: +" you will get a popup window every time you open a file that needs to +" be decrypted. +" +" - gpgagent and pinentry: +" you will get a popup window the first time you open a file that +" needs to be decrypted. +" +" Credits: {{{2 +" +" - Mathieu Clabaut for inspirations through his vimspell.vim script. +" - Richard Bronosky for patch to enable ".pgp" suffix. +" - Erik Remmelzwaal for patch to enable windows support and patient beta +" testing. +" - Lars Becker for patch to make gpg2 working. +" - Thomas Arendsen Hein for patch to convert encoding of gpg output. +" - Karl-Heinz Ruskowski for patch to fix unknown recipients and trust model +" and patient beta testing. +" - Giel van Schijndel for patch to get GPG_TTY dynamically. +" - Sebastian Luettich for patch to fix issue with symmetric encryption an set +" recipients. +" - Tim Swast for patch to generate signed files. +" - James Vega for patches for better '*.asc' handling, better filename +" escaping and better handling of multiple keyrings. +" +" Section: Plugin header {{{1 + +" guard against multiple loads {{{2 +if (exists("g:loaded_gnupg") || &cp || exists("#GnuPG")) + finish +endif +let g:loaded_gnupg = '2.5' +let s:GPGInitRun = 0 + +" check for correct vim version {{{2 +if (v:version < 702) + echohl ErrorMsg | echo 'plugin gnupg.vim requires Vim version >= 7.2' | echohl None + finish +endif + +" Section: Autocmd setup {{{1 + +augroup GnuPG + autocmd! + + " do the decryption + autocmd BufReadCmd *.\(gpg\|asc\|pgp\) call s:GPGInit(1) + autocmd BufReadCmd *.\(gpg\|asc\|pgp\) call s:GPGDecrypt(1) + autocmd BufReadCmd *.\(gpg\|asc\|pgp\) call s:GPGBufReadPost() + autocmd FileReadCmd *.\(gpg\|asc\|pgp\) call s:GPGInit(0) + autocmd FileReadCmd *.\(gpg\|asc\|pgp\) call s:GPGDecrypt(0) + + " convert all text to encrypted text before writing + autocmd BufWriteCmd *.\(gpg\|asc\|pgp\) call s:GPGBufWritePre() + autocmd BufWriteCmd,FileWriteCmd *.\(gpg\|asc\|pgp\) call s:GPGInit(0) + autocmd BufWriteCmd,FileWriteCmd *.\(gpg\|asc\|pgp\) call s:GPGEncrypt() + + " cleanup on leaving vim + autocmd VimLeave *.\(gpg\|asc\|pgp\) call s:GPGCleanup() +augroup END + +" Section: Constants {{{1 + +let s:GPGMagicString = "\t \t" +let s:keyPattern = '\%(0x\)\=[[:xdigit:]]\{8,16}' + +" Section: Highlight setup {{{1 + +highlight default link GPGWarning WarningMsg +highlight default link GPGError ErrorMsg +highlight default link GPGHighlightUnknownRecipient ErrorMsg + +" Section: Functions {{{1 + +" Function: s:GPGInit(bufread) {{{2 +" +" initialize the plugin +" The bufread argument specifies whether this was called due to BufReadCmd +" +function s:GPGInit(bufread) + call s:GPGDebug(3, printf(">>>>>>>> Entering s:GPGInit(%d)", a:bufread)) + + " For FileReadCmd, we're reading the contents into another buffer. If that + " buffer is also destined to be encrypted, then these settings will have + " already been set, otherwise don't set them since it limits the + " functionality of the cleartext buffer. + if a:bufread + " we don't want a swap file, as it writes unencrypted data to disk + setl noswapfile + + " if persistent undo is present, disable it for this buffer + if exists('+undofile') + setl noundofile + endif + + " first make sure nothing is written to ~/.viminfo while editing + " an encrypted file. + set viminfo= + endif + + " the rest only has to be run once + if s:GPGInitRun + return + endif + + " check what gpg command to use + if (!exists("g:GPGExecutable")) + let g:GPGExecutable = "gpg --trust-model always" + endif + + " check if gpg-agent is allowed + if (!exists("g:GPGUseAgent")) + let g:GPGUseAgent = 1 + endif + + " check if symmetric encryption is preferred + if (!exists("g:GPGPreferSymmetric")) + let g:GPGPreferSymmetric = 0 + endif + + " check if armored files are preferred + if (!exists("g:GPGPreferArmor")) + " .asc files should be armored as that's what the extension is used for + if expand('<afile>') =~ '\.asc$' + let g:GPGPreferArmor = 1 + else + let g:GPGPreferArmor = 0 + endif + endif + + " check if signed files are preferred + if (!exists("g:GPGPreferSign")) + let g:GPGPreferSign = 0 + endif + + " start with empty default recipients if none is defined so far + if (!exists("g:GPGDefaultRecipients")) + let g:GPGDefaultRecipients = [] + endif + + " prefer not to use pipes since it can garble gpg agent display + if (!exists("g:GPGUsePipes")) + let g:GPGUsePipes = 0 + endif + + " allow alternate gnupg homedir + if (!exists('g:GPGHomedir')) + let g:GPGHomedir = '' + endif + + " print version + call s:GPGDebug(1, "gnupg.vim ". g:loaded_gnupg) + + " determine if gnupg can use the gpg-agent + if (exists("$GPG_AGENT_INFO") && g:GPGUseAgent == 1) + if (!exists("$GPG_TTY") && !has("gui_running")) + let $GPG_TTY = system("tty") + if (v:shell_error) + let $GPG_TTY = "" + echohl GPGError + echom "The GPG_TTY is not set and no TTY could be found using the `tty` command!" + echom "gpg-agent might not work." + echohl None + endif + endif + let s:GPGCommand = g:GPGExecutable . " --use-agent" + else + let s:GPGCommand = g:GPGExecutable . " --no-use-agent" + endif + + " don't use tty in gvim except for windows: we get their a tty for free. + " FIXME find a better way to avoid an error. + " with this solution only --use-agent will work + if (has("gui_running") && !has("gui_win32")) + let s:GPGCommand = s:GPGCommand . " --no-tty" + endif + + " setup shell environment for unix and windows + let s:shellredirsave = &shellredir + let s:shellsave = &shell + let s:shelltempsave = &shelltemp + " noshelltemp isn't currently supported on Windows, but it doesn't cause any + " errors and this future proofs us against requiring changes if Windows + " gains noshelltemp functionality + let s:shelltemp = !g:GPGUsePipes + if (has("unix")) + " unix specific settings + let s:shellredir = ">%s 2>&1" + let s:shell = '/bin/sh' + let s:stderrredirnull = '2>/dev/null' + let s:GPGCommand = "LANG=C LC_ALL=C " . s:GPGCommand + else + " windows specific settings + let s:shellredir = '>%s' + let s:shell = &shell + let s:stderrredirnull = '2>nul' + endif + + call s:GPGDebug(3, "shellredirsave: " . s:shellredirsave) + call s:GPGDebug(3, "shellsave: " . s:shellsave) + call s:GPGDebug(3, "shelltempsave: " . s:shelltempsave) + + call s:GPGDebug(3, "shell: " . s:shell) + call s:GPGDebug(3, "shellcmdflag: " . &shellcmdflag) + call s:GPGDebug(3, "shellxquote: " . &shellxquote) + call s:GPGDebug(3, "shellredir: " . s:shellredir) + call s:GPGDebug(3, "stderrredirnull: " . s:stderrredirnull) + + call s:GPGDebug(3, "shell implementation: " . resolve(s:shell)) + + " find the supported algorithms + let output = s:GPGSystem({ 'level': 2, 'args': '--version' }) + + let s:GPGPubkey = substitute(output, ".*Pubkey: \\(.\\{-}\\)\n.*", "\\1", "") + let s:GPGCipher = substitute(output, ".*Cipher: \\(.\\{-}\\)\n.*", "\\1", "") + let s:GPGHash = substitute(output, ".*Hash: \\(.\\{-}\\)\n.*", "\\1", "") + let s:GPGCompress = substitute(output, ".*Compress.\\{-}: \\(.\\{-}\\)\n.*", "\\1", "") + + call s:GPGDebug(2, "public key algorithms: " . s:GPGPubkey) + call s:GPGDebug(2, "cipher algorithms: " . s:GPGCipher) + call s:GPGDebug(2, "hashing algorithms: " . s:GPGHash) + call s:GPGDebug(2, "compression algorithms: " . s:GPGCompress) + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGInit()") + let s:GPGInitRun = 1 +endfunction + +" Function: s:GPGCleanup() {{{2 +" +" cleanup on leaving vim +" +function s:GPGCleanup() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGCleanup()") + + " wipe out screen + new +only + redraw! + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGCleanup()") +endfunction + +" Function: s:GPGDecrypt(bufread) {{{2 +" +" decrypt the buffer and find all recipients of the encrypted file +" The bufread argument specifies whether this was called due to BufReadCmd +" +function s:GPGDecrypt(bufread) + call s:GPGDebug(3, printf(">>>>>>>> Entering s:GPGDecrypt(%d)", a:bufread)) + + " get the filename of the current buffer + let filename = expand("<afile>:p") + + " clear GPGRecipients and GPGOptions + let b:GPGRecipients = g:GPGDefaultRecipients + let b:GPGOptions = [] + + " File doesn't exist yet, so nothing to decrypt + if empty(glob(filename)) + return + endif + + " Only let this if the file actually exists, otherwise GPG functionality + " will be disabled when editing a buffer that doesn't yet have a backing + " file + let b:GPGEncrypted = 0 + + " find the recipients of the file + let cmd = { 'level': 3 } + let cmd.args = '--verbose --decrypt --list-only --dry-run --batch --no-use-agent --logger-fd 1 ' . shellescape(filename) + let output = s:GPGSystem(cmd) + + " Suppress the "N more lines" message when editing a file, not when reading + " the contents of a file into a buffer + let silent = a:bufread ? 'silent ' : '' + + let asymmPattern = 'gpg: public key is ' . s:keyPattern + " check if the file is symmetric/asymmetric encrypted + if (match(output, "gpg: encrypted with [[:digit:]]\\+ passphrase") >= 0) + " file is symmetric encrypted + let b:GPGEncrypted = 1 + call s:GPGDebug(1, "this file is symmetric encrypted") + + let b:GPGOptions += ["symmetric"] + + " find the used cipher algorithm + let cipher = substitute(output, ".*gpg: \\([^ ]\\+\\) encrypted data.*", "\\1", "") + if (match(s:GPGCipher, "\\<" . cipher . "\\>") >= 0) + let b:GPGOptions += ["cipher-algo " . cipher] + call s:GPGDebug(1, "cipher-algo is " . cipher) + else + echohl GPGWarning + echom "The cipher " . cipher . " is not known by the local gpg command. Using default!" + echo + echohl None + endif + elseif (match(output, asymmPattern) >= 0) + " file is asymmetric encrypted + let b:GPGEncrypted = 1 + call s:GPGDebug(1, "this file is asymmetric encrypted") + + let b:GPGOptions += ["encrypt"] + + " find the used public keys + let start = match(output, asymmPattern) + while (start >= 0) + let start = start + strlen("gpg: public key is ") + let recipient = matchstr(output, s:keyPattern, start) + call s:GPGDebug(1, "recipient is " . recipient) + let name = s:GPGNameToID(recipient) + if (strlen(name) > 0) + let b:GPGRecipients += [name] + call s:GPGDebug(1, "name of recipient is " . name) + else + let b:GPGRecipients += [recipient] + echohl GPGWarning + echom "The recipient \"" . recipient . "\" is not in your public keyring!" + echohl None + end + let start = match(output, asymmPattern, start) + endwhile + else + " file is not encrypted + let b:GPGEncrypted = 0 + call s:GPGDebug(1, "this file is not encrypted") + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + exe printf('%sr %s', silent, fnameescape(filename)) + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") + return + endif + + " check if the message is armored + if (match(output, "gpg: armor header") >= 0) + call s:GPGDebug(1, "this file is armored") + let b:GPGOptions += ["armor"] + endif + + " finally decrypt the buffer content + " since even with the --quiet option passphrase typos will be reported, + " we must redirect stderr (using shell temporarily) + call s:GPGDebug(1, "decrypting file") + let cmd = { 'level': 1, 'ex': silent . 'r !' } + let cmd.args = '--quiet --decrypt ' . shellescape(filename, 1) + call s:GPGExecute(cmd) + + if (v:shell_error) " message could not be decrypted + echohl GPGError + let blackhole = input("Message could not be decrypted! (Press ENTER)") + echohl None + " Only wipeout the buffer if we were creating one to start with. + " FileReadCmd just reads the content into the existing buffer + if a:bufread + silent bwipeout! + endif + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") + return + endif + + " refresh screen + redraw! + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGDecrypt()") +endfunction + +" Function: s:GPGBufReadPost() {{{2 +" +" Handle functionality specific to opening a file for reading rather than +" reading the contents of a file into a buffer +" +function s:GPGBufReadPost() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGBufReadPost()") + " In order to make :undo a no-op immediately after the buffer is read, + " we need to do this dance with 'undolevels'. Actually discarding the undo + " history requires performing a change after setting 'undolevels' to -1 and, + " luckily, we have one we need to do (delete the extra line from the :r + " command) + let levels = &undolevels + set undolevels=-1 + silent 1delete + let &undolevels = levels + " call the autocommand for the file minus .gpg$ + silent execute ':doautocmd BufReadPost ' . fnameescape(expand('<afile>:r')) + call s:GPGDebug(2, 'called autocommand for ' . fnameescape(expand('<afile>:r'))) + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGBufReadPost()") +endfunction + +" Function: s:GPGBufWritePre() {{{2 +" +" Handle functionality specific to saving an entire buffer to a file rather +" than saving a partial buffer +" +function s:GPGBufWritePre() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGBufWritePre()") + " call the autocommand for the file minus .gpg$ + silent execute ':doautocmd BufWritePre ' . fnameescape(expand('<afile>:r')) + call s:GPGDebug(2, 'called autocommand for ' . fnameescape(expand('<afile>:r'))) + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGBufWritePre()") +endfunction + +" Function: s:GPGEncrypt() {{{2 +" +" encrypts the buffer to all previous recipients +" +function s:GPGEncrypt() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEncrypt()") + + " store encoding and switch to a safe one + if (&fileencoding != &encoding) + let s:GPGEncoding = &encoding + let &encoding = &fileencoding + call s:GPGDebug(2, "encoding was \"" . s:GPGEncoding . "\", switched to \"" . &encoding . "\"") + else + let s:GPGEncoding = "" + call s:GPGDebug(2, "encoding and fileencoding are the same (\"" . &encoding . "\"), not switching") + endif + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGError + let blackhole = input("Message could not be encrypted! (Press ENTER)") + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") + return + endif + + " initialize GPGOptions if not happened before + if (!exists("b:GPGOptions") || len(b:GPGOptions) == 0) + let b:GPGOptions = [] + if (exists("g:GPGPreferSymmetric") && g:GPGPreferSymmetric == 1) + let b:GPGOptions += ["symmetric"] + let b:GPGRecipients = [] + else + let b:GPGOptions += ["encrypt"] + endif + if (exists("g:GPGPreferArmor") && g:GPGPreferArmor == 1) + let b:GPGOptions += ["armor"] + endif + if (exists("g:GPGPreferSign") && g:GPGPreferSign == 1) + let b:GPGOptions += ["sign"] + endif + call s:GPGDebug(1, "no options set, so using default options: " . string(b:GPGOptions)) + endif + + " built list of options + let options = "" + for option in b:GPGOptions + let options = options . " --" . option . " " + endfor + + if (!exists('b:GPGRecipients')) + let b:GPGRecipients = [] + endif + + " check here again if all recipients are available in the keyring + let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients) + + " check if there are unknown recipients and warn + if (len(unknownrecipients) > 0) + echohl GPGWarning + echom "Please use GPGEditRecipients to correct!!" + echo + echohl None + + " Let user know whats happend and copy known_recipients back to buffer + let dummy = input("Press ENTER to quit") + endif + + " built list of recipients + if (len(recipients) > 0) + for gpgid in recipients + let options = options . " -r " . gpgid + endfor + endif + + " encrypt the buffer + let destfile = tempname() + let cmd = { 'level': 1, 'ex': "'[,']w !" } + let cmd.args = '--quiet --no-encrypt-to ' . options + let cmd.redirect = '>' . shellescape(destfile, 1) + call s:GPGExecute(cmd) + + " restore encoding + if (s:GPGEncoding != "") + let &encoding = s:GPGEncoding + call s:GPGDebug(2, "restored encoding \"" . &encoding . "\"") + endif + + if (v:shell_error) " message could not be encrypted + " Command failed, so clean up the tempfile + call delete(destfile) + echohl GPGError + let blackhole = input("Message could not be encrypted! (Press ENTER)") + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") + return + endif + + call rename(destfile, resolve(expand('<afile>'))) + setl nomodified + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEncrypt()") +endfunction + +" Function: s:GPGViewRecipients() {{{2 +" +" echo the recipients +" +function s:GPGViewRecipients() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGViewRecipients()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewRecipients()") + return + endif + + let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(b:GPGRecipients) + + echo 'This file has following recipients (Unknown recipients have a prepended "!"):' + " echo the recipients + for name in recipients + let name = s:GPGIDToName(name) + echo name + endfor + + " echo the unknown recipients + echohl GPGWarning + for name in unknownrecipients + let name = "!" . name + echo name + endfor + echohl None + + " check if there is any known recipient + if (len(recipients) == 0) + echohl GPGError + echom 'There are no known recipients!' + echohl None + endif + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewRecipients()") +endfunction + +" Function: s:GPGEditRecipients() {{{2 +" +" create a scratch buffer with all recipients to add/remove recipients +" +function s:GPGEditRecipients() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEditRecipients()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditRecipients()") + return + endif + + " only do this if it isn't already a GPGRecipients_* buffer + if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0) + + " save buffer name + let buffername = bufname("%") + let editbuffername = "GPGRecipients_" . buffername + + " check if this buffer exists + if (!bufexists(editbuffername)) + " create scratch buffer + execute 'silent! split ' . fnameescape(editbuffername) + + " add a autocommand to regenerate the recipients after a write + autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer() + else + if (bufwinnr(editbuffername) >= 0) + " switch to scratch buffer window + execute 'silent! ' . bufwinnr(editbuffername) . "wincmd w" + else + " split scratch buffer window + execute 'silent! sbuffer ' . fnameescape(editbuffername) + + " add a autocommand to regenerate the recipients after a write + autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishRecipientsBuffer() + endif + + " empty the buffer + silent %delete + endif + + " Mark the buffer as a scratch buffer + setlocal buftype=acwrite + setlocal bufhidden=hide + setlocal noswapfile + setlocal nowrap + setlocal nobuflisted + setlocal nonumber + + " so we know for which other buffer this edit buffer is + let b:GPGCorrespondingTo = buffername + + " put some comments to the scratch buffer + silent put ='GPG: ----------------------------------------------------------------------' + silent put ='GPG: Please edit the list of recipients, one recipient per line.' + silent put ='GPG: Unknown recipients have a prepended \"!\".' + silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically.' + silent put ='GPG: Data after recipients between and including \"(\" and \")\" is ignored.' + silent put ='GPG: Closing this buffer commits changes.' + silent put ='GPG: ----------------------------------------------------------------------' + + " get the recipients + let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(getbufvar(b:GPGCorrespondingTo, "GPGRecipients")) + + " if there are no known or unknown recipients, use the default ones + if (len(recipients) == 0 && len(unknownrecipients) == 0) + if (type(g:GPGDefaultRecipients) == type([])) + let [ recipients, unknownrecipients ] = s:GPGCheckRecipients(g:GPGDefaultRecipients) + else + echohl GPGWarning + echom "g:GPGDefaultRecipients is not a Vim list, please correct this in your vimrc!" + echohl None + endif + endif + + " put the recipients in the scratch buffer + for name in recipients + let name = s:GPGIDToName(name) + silent put =name + endfor + + " put the unknown recipients in the scratch buffer + let syntaxPattern = "\\(nonexxistinwordinthisbuffer" + for name in unknownrecipients + let name = "!" . name + let syntaxPattern = syntaxPattern . "\\|" . fnameescape(name) + silent put =name + endfor + let syntaxPattern = syntaxPattern . "\\)" + + " define highlight + if (has("syntax") && exists("g:syntax_on")) + execute 'syntax match GPGUnknownRecipient "' . syntaxPattern . '"' + highlight clear GPGUnknownRecipient + highlight link GPGUnknownRecipient GPGHighlightUnknownRecipient + + syntax match GPGComment "^GPG:.*$" + execute 'syntax match GPGComment "' . s:GPGMagicString . '.*$"' + highlight clear GPGComment + highlight link GPGComment Comment + endif + + " delete the empty first line + silent 1delete + + " jump to the first recipient + silent $ + + endif + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditRecipients()") +endfunction + +" Function: s:GPGFinishRecipientsBuffer() {{{2 +" +" create a new recipient list from RecipientsBuffer +" +function s:GPGFinishRecipientsBuffer() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGFinishRecipientsBuffer()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()") + return + endif + + " go to buffer before doing work + if (bufnr("%") != expand("<abuf>")) + " switch to scratch buffer window + execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w" + endif + + " delete the autocommand + autocmd! * <buffer> + + " get the recipients from the scratch buffer + let recipients = [] + let lines = getline(1,"$") + for recipient in lines + let matches = matchlist(recipient, '^\(.\{-}\)\%(' . s:GPGMagicString . '(ID:\s\+\(' . s:keyPattern . '\)\s\+.*\)\=$') + + let recipient = matches[2] ? matches[2] : matches[1] + + " delete all spaces at beginning and end of the recipient + " also delete a '!' at the beginning of the recipient + let recipient = substitute(recipient, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "") + + " delete comment lines + let recipient = substitute(recipient, "^GPG:.*$", "", "") + + " only do this if the line is not empty + if (strlen(recipient) > 0) + let gpgid = s:GPGNameToID(recipient) + if (strlen(gpgid) > 0) + if (match(recipients, gpgid) < 0) + let recipients += [gpgid] + endif + else + if (match(recipients, recipient) < 0) + let recipients += [recipient] + echohl GPGWarning + echom "The recipient \"" . recipient . "\" is not in your public keyring!" + echohl None + endif + endif + endif + endfor + + " write back the new recipient list to the corresponding buffer and mark it + " as modified. Buffer is now for sure a encrypted buffer. + call setbufvar(b:GPGCorrespondingTo, "GPGRecipients", recipients) + call setbufvar(b:GPGCorrespondingTo, "&mod", 1) + call setbufvar(b:GPGCorrespondingTo, "GPGEncrypted", 1) + + " check if there is any known recipient + if (len(recipients) == 0) + echohl GPGError + echom 'There are no known recipients!' + echohl None + endif + + " reset modified flag + setl nomodified + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishRecipientsBuffer()") +endfunction + +" Function: s:GPGViewOptions() {{{2 +" +" echo the recipients +" +function s:GPGViewOptions() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGViewOptions()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewOptions()") + return + endif + + if (exists("b:GPGOptions")) + echo 'This file has following options:' + " echo the options + for option in b:GPGOptions + echo option + endfor + endif + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGViewOptions()") +endfunction + +" Function: s:GPGEditOptions() {{{2 +" +" create a scratch buffer with all recipients to add/remove recipients +" +function s:GPGEditOptions() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGEditOptions()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditOptions()") + return + endif + + " only do this if it isn't already a GPGOptions_* buffer + if (match(bufname("%"), "^\\(GPGRecipients_\\|GPGOptions_\\)") != 0 && match(bufname("%"), "\.\\(gpg\\|asc\\|pgp\\)$") >= 0) + + " save buffer name + let buffername = bufname("%") + let editbuffername = "GPGOptions_" . buffername + + " check if this buffer exists + if (!bufexists(editbuffername)) + " create scratch buffer + execute 'silent! split ' . fnameescape(editbuffername) + + " add a autocommand to regenerate the options after a write + autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer() + else + if (bufwinnr(editbuffername) >= 0) + " switch to scratch buffer window + execute 'silent! ' . bufwinnr(editbuffername) . "wincmd w" + else + " split scratch buffer window + execute 'silent! sbuffer ' . fnameescape(editbuffername) + + " add a autocommand to regenerate the options after a write + autocmd BufHidden,BufUnload,BufWriteCmd <buffer> call s:GPGFinishOptionsBuffer() + endif + + " empty the buffer + silent %delete + endif + + " Mark the buffer as a scratch buffer + setlocal buftype=nofile + setlocal noswapfile + setlocal nowrap + setlocal nobuflisted + setlocal nonumber + + " so we know for which other buffer this edit buffer is + let b:GPGCorrespondingTo = buffername + + " put some comments to the scratch buffer + silent put ='GPG: ----------------------------------------------------------------------' + silent put ='GPG: THERE IS NO CHECK OF THE ENTERED OPTIONS!' + silent put ='GPG: YOU NEED TO KNOW WHAT YOU ARE DOING!' + silent put ='GPG: IF IN DOUBT, QUICKLY EXIT USING :x OR :bd.' + silent put ='GPG: Please edit the list of options, one option per line.' + silent put ='GPG: Please refer to the gpg documentation for valid options.' + silent put ='GPG: Lines beginning with \"GPG:\" are removed automatically.' + silent put ='GPG: Closing this buffer commits changes.' + silent put ='GPG: ----------------------------------------------------------------------' + + " put the options in the scratch buffer + let options = getbufvar(b:GPGCorrespondingTo, "GPGOptions") + + for option in options + silent put =option + endfor + + " delete the empty first line + silent 1delete + + " jump to the first option + silent $ + + " define highlight + if (has("syntax") && exists("g:syntax_on")) + syntax match GPGComment "^GPG:.*$" + highlight clear GPGComment + highlight link GPGComment Comment + endif + endif + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGEditOptions()") +endfunction + +" Function: s:GPGFinishOptionsBuffer() {{{2 +" +" create a new option list from OptionsBuffer +" +function s:GPGFinishOptionsBuffer() + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGFinishOptionsBuffer()") + + " guard for unencrypted files + if (exists("b:GPGEncrypted") && b:GPGEncrypted == 0) + echohl GPGWarning + echom "File is not encrypted, all GPG functions disabled!" + echohl None + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()") + return + endif + + " go to buffer before doing work + if (bufnr("%") != expand("<abuf>")) + " switch to scratch buffer window + execute 'silent! ' . bufwinnr(expand("<afile>")) . "wincmd w" + endif + + " clear options and unknownOptions + let options = [] + let unknownOptions = [] + + " delete the autocommand + autocmd! * <buffer> + + " get the options from the scratch buffer + let lines = getline(1, "$") + for option in lines + " delete all spaces at beginning and end of the option + " also delete a '!' at the beginning of the option + let option = substitute(option, "^[[:space:]!]*\\(.\\{-}\\)[[:space:]]*$", "\\1", "") + " delete comment lines + let option = substitute(option, "^GPG:.*$", "", "") + + " only do this if the line is not empty + if (strlen(option) > 0 && match(options, option) < 0) + let options += [option] + endif + endfor + + " write back the new option list to the corresponding buffer and mark it + " as modified + call setbufvar(b:GPGCorrespondingTo, "GPGOptions", options) + call setbufvar(b:GPGCorrespondingTo, "&mod", 1) + + " reset modified flag + setl nomodified + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGFinishOptionsBuffer()") +endfunction + +" Function: s:GPGCheckRecipients(tocheck) {{{2 +" +" check if recipients are known +" Returns: two lists recipients and unknownrecipients +" +function s:GPGCheckRecipients(tocheck) + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGCheckRecipients()") + + let recipients = [] + let unknownrecipients = [] + + if (type(a:tocheck) == type([])) + for recipient in a:tocheck + let gpgid = s:GPGNameToID(recipient) + if (strlen(gpgid) > 0) + if (match(recipients, gpgid) < 0) + let recipients += [gpgid] + endif + else + if (match(unknownrecipients, recipient) < 0) + let unknownrecipients += [recipient] + echohl GPGWarning + echom "The recipient \"" . recipient . "\" is not in your public keyring!" + echohl None + endif + end + endfor + endif + + call s:GPGDebug(2, "recipients are: " . string(recipients)) + call s:GPGDebug(2, "unknown recipients are: " . string(unknownrecipients)) + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGCheckRecipients()") + return [ recipients, unknownrecipients ] +endfunction + +" Function: s:GPGNameToID(name) {{{2 +" +" find GPG key ID corresponding to a name +" Returns: ID for the given name +" +function s:GPGNameToID(name) + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGNameToID()") + + " ask gpg for the id for a name + let cmd = { 'level': 2 } + let cmd.args = '--quiet --with-colons --fixed-list-mode --list-keys ' . shellescape(a:name) + let output = s:GPGSystem(cmd) + + " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8, + " so convert it, if necessary + if (&encoding != "utf-8") + let output = iconv(output, "utf-8", &encoding) + endif + let lines = split(output, "\n") + + " parse the output of gpg + let pubseen = 0 + let counter = 0 + let gpgids = [] + let duplicates = {} + let choices = "The name \"" . a:name . "\" is ambiguous. Please select the correct key:\n" + for line in lines + + " check if this line has already been processed + if !has_key(duplicates, line) + let duplicates[line] = 1 + + let fields = split(line, ":") + + " search for the next uid + if pubseen + if (fields[0] == "uid") + let choices = choices . " " . fields[9] . "\n" + else + let pubseen = 0 + endif + " search for the next pub + else + if (fields[0] == "pub") + " Ignore keys which are not usable for encryption + if fields[11] !~? 'e' + continue + endif + + let identity = fields[4] + let gpgids += [identity] + if exists("*strftime") + let choices = choices . counter . ": ID: 0x" . identity . " created at " . strftime("%c", fields[5]) . "\n" + else + let choices = choices . counter . ": ID: 0x" . identity . "\n" + endif + let counter = counter+1 + let pubseen = 1 + endif + endif + endif + + endfor + + " counter > 1 means we have more than one results + let answer = 0 + if (counter > 1) + let choices = choices . "Enter number: " + let answer = input(choices, "0") + while (answer == "") + let answer = input("Enter number: ", "0") + endwhile + endif + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGNameToID()") + return get(gpgids, answer, "") +endfunction + +" Function: s:GPGIDToName(identity) {{{2 +" +" find name corresponding to a GPG key ID +" Returns: Name for the given ID +" +function s:GPGIDToName(identity) + call s:GPGDebug(3, ">>>>>>>> Entering s:GPGIDToName()") + + " TODO is the encryption subkey really unique? + + " ask gpg for the id for a name + let cmd = { 'level': 2 } + let cmd.args = '--quiet --with-colons --fixed-list-mode --list-keys ' . a:identity + let output = s:GPGSystem(cmd) + + " when called with "--with-colons" gpg encodes its output _ALWAYS_ as UTF-8, + " so convert it, if necessary + if (&encoding != "utf-8") + let output = iconv(output, "utf-8", &encoding) + endif + let lines = split(output, "\n") + + " parse the output of gpg + let pubseen = 0 + let uid = "" + for line in lines + let fields = split(line, ":") + + if !pubseen " search for the next pub + if (fields[0] == "pub") + " Ignore keys which are not usable for encryption + if fields[11] !~? 'e' + continue + endif + + let pubseen = 1 + endif + else " search for the next uid + if (fields[0] == "uid") + let pubseen = 0 + if exists("*strftime") + let uid = fields[9] . s:GPGMagicString . "(ID: 0x" . a:identity . " created at " . strftime("%c", fields[5]) . ")" + else + let uid = fields[9] . s:GPGMagicString . "(ID: 0x" . a:identity . ")" + endif + break + endif + endif + endfor + + call s:GPGDebug(3, "<<<<<<<< Leaving s:GPGIDToName()") + return uid +endfunction + +function s:GPGPreCmd() + let &shellredir = s:shellredir + let &shell = s:shell + let &shelltemp = s:shelltemp +endfunction + +function s:GPGPostCmd() + let &shellredir = s:shellredirsave + let &shell = s:shellsave + let &shelltemp = s:shelltempsave +endfunction + +" Function: s:GPGSystem(dict) {{{2 +" +" run g:GPGCommand using system(), logging the commandline and output +" Recognized keys are: +" level - Debug level at which the commandline and output will be logged +" args - Arguments to be given to g:GPGCommand +" +" Returns: command output +" +function s:GPGSystem(dict) + let commandline = printf('%s %s', s:GPGCommand, a:dict.args) + if (!empty(g:GPGHomedir)) + let commandline .= ' --homedir ' . shellescape(g:GPGHomedir) + endif + let commandline .= ' ' . s:stderrredirnull + call s:GPGDebug(a:dict.level, "command: ". commandline) + + call s:GPGPreCmd() + let output = system(commandline) + call s:GPGPostCmd() + + call s:GPGDebug(a:dict.level, "output: ". output) + return output +endfunction + +" Function: s:GPGExecute(dict) {{{2 +" +" run g:GPGCommand using :execute, logging the commandline +" Recognized keys are: +" level - Debug level at which the commandline will be logged +" args - Arguments to be given to g:GPGCommand +" ex - Ex command which will be :executed +" redirect - Shell redirect to use, if needed +" +function s:GPGExecute(dict) + let commandline = printf('%s%s %s', a:dict.ex, s:GPGCommand, a:dict.args) + if (!empty(g:GPGHomedir)) + let commandline .= ' --homedir ' . shellescape(g:GPGHomedir, 1) + endif + if (has_key(a:dict, 'redirect')) + let commandline .= ' ' . a:dict.redirect + endif + let commandline .= ' ' . s:stderrredirnull + call s:GPGDebug(a:dict.level, "command: " . commandline) + + call s:GPGPreCmd() + execute commandline + call s:GPGPostCmd() +endfunction + +" Function: s:GPGDebug(level, text) {{{2 +" +" output debug message, if this message has high enough importance +" only define function if GPGDebugLevel set at all +" +function s:GPGDebug(level, text) + if exists("g:GPGDebugLevel") && g:GPGDebugLevel >= a:level + if exists("g:GPGDebugLog") + execute "redir >> " . g:GPGDebugLog + silent echom "GnuPG: " . a:text + redir END + else + echom "GnuPG: " . a:text + endif + endif +endfunction + +" Section: Commands {{{1 + +command! GPGViewRecipients call s:GPGViewRecipients() +command! GPGEditRecipients call s:GPGEditRecipients() +command! GPGViewOptions call s:GPGViewOptions() +command! GPGEditOptions call s:GPGEditOptions() + +" Section: Menu {{{1 + +if (has("menu")) + amenu <silent> Plugin.GnuPG.View\ Recipients :GPGViewRecipients<CR> + amenu <silent> Plugin.GnuPG.Edit\ Recipients :GPGEditRecipients<CR> + amenu <silent> Plugin.GnuPG.View\ Options :GPGViewOptions<CR> + amenu <silent> Plugin.GnuPG.Edit\ Options :GPGEditOptions<CR> +endif + +" vim600: set foldmethod=marker foldlevel=0 : diff --git a/dotfiles/.local/share/nvim/site/plugin/latexlivepreview.vim b/dotfiles/.local/share/nvim/site/plugin/latexlivepreview.vim new file mode 100644 index 0000000..f4a315a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/latexlivepreview.vim @@ -0,0 +1,276 @@ +" Copyright (C) 2012 Hong Xu + +" This file is part of vim-live-preview. + +" vim-live-preview is free software: you can redistribute it and/or modify it +" under the terms of the GNU General Public License as published by the Free +" Software Foundation, either version 3 of the License, or (at your option) +" any later version. + +" vim-live-preview is distributed in the hope that it will be useful, but +" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +" or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +" more details. + +" You should have received a copy of the GNU General Public License along with +" vim-live-preview. If not, see <http://www.gnu.org/licenses/>. + + +if v:version < 700 + finish +endif + +" Check whether this script is already loaded +if exists("g:loaded_vim_live_preview") + finish +endif +let g:loaded_vim_live_preview = 1 + +" Check mkdir feature +if (!exists("*mkdir")) + echohl ErrorMsg + echo 'vim-llp: mkdir required' + echohl None + finish +endif + +" Setup python +if (has('python3')) + let s:py_exe = 'python3' +elseif (has('python')) + let s:py_exe = 'python' +else + echohl ErrorMsg + echo 'vim-llp: python required' + echohl None + finish +endif + +let s:saved_cpo = &cpo +set cpo&vim + +let s:previewer = '' + +" Run a shell command in background +function! s:RunInBackground(cmd) + +execute s:py_exe "<< EEOOFF" + +try: + subprocess.Popen( + vim.eval('a:cmd'), + shell = True, + universal_newlines = True, + stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT) + +except: + pass +EEOOFF +endfunction + +function! s:Compile() + + if !exists('b:livepreview_buf_data') || + \ has_key(b:livepreview_buf_data, 'preview_running') == 0 + return + endif + + " Change directory to handle properly sourced files with \input and bib + " TODO: get rid of lcd + execute 'lcd ' . b:livepreview_buf_data['root_dir'] + + " Write the current buffer in a temporary file + silent exec 'write! ' . b:livepreview_buf_data['tmp_src_file'] + + call s:RunInBackground(b:livepreview_buf_data['run_cmd']) + + lcd - +endfunction + +function! s:StartPreview(...) + let b:livepreview_buf_data = {} + + let b:livepreview_buf_data['py_exe'] = s:py_exe + + " Create a temp directory for current buffer + execute s:py_exe "<< EEOOFF" +vim.command("let b:livepreview_buf_data['tmp_dir'] = '" + + tempfile.mkdtemp(prefix="vim-latex-live-preview-") + "'") +EEOOFF + + let b:livepreview_buf_data['tmp_src_file'] = + \ b:livepreview_buf_data['tmp_dir'] . + \ expand('%:p:r') + + " Guess the root file which will be compiled, using first the argument + " passed, then the first line declaration of the source file and + " eventually fallback to the current file. + " TODO: emulate -parse-first-line properly + let l:root_line = substitute(getline(1), + \ '\v^\s*\%\s*!tex\s*root\s*\=\s*(.*)\s*$', + \ '\1', '') + if (a:0 > 0) + let l:root_file = fnamemodify(a:1, ':p') + elseif (l:root_line != getline(1) && strlen(l:root_line) > 0) " TODO: existence of `% !TEX` declaration condition must be cleaned... + let l:root_file = fnamemodify(l:root_line, ':p') + else + let l:root_file = b:livepreview_buf_data['tmp_src_file'] + endif + + " Hack for complex project trees: recreate the tree in tmp_dir + " Build tree for tmp_src_file (copy of the current buffer) + let l:tmp_src_dir = fnamemodify(b:livepreview_buf_data['tmp_src_file'], ':p:h') + if (!isdirectory(l:tmp_src_dir)) + silent call mkdir(l:tmp_src_dir, 'p') + endif + " Build tree for root_file (main tex file, which might be tmp_src_file, + " ie. the current file) + if (l:root_file == b:livepreview_buf_data['tmp_src_file']) " if root file is the current file + let l:tmp_root_dir = l:tmp_src_dir + else + let l:tmp_root_dir = b:livepreview_buf_data['tmp_dir'] . fnamemodify(l:root_file, ':p:h') + if (!isdirectory(l:tmp_root_dir)) + silent call mkdir(l:tmp_root_dir, 'p') + endif + endif + + " Escape pathnames + let l:root_file = fnameescape(l:root_file) + let l:tmp_root_dir = fnameescape(l:tmp_root_dir) + let b:livepreview_buf_data['tmp_dir'] = fnameescape(b:livepreview_buf_data['tmp_dir']) + let b:livepreview_buf_data['tmp_src_file'] = fnameescape(b:livepreview_buf_data['tmp_src_file']) + + " Change directory to handle properly sourced files with \input and bib + " TODO: get rid of lcd + if (l:root_file == b:livepreview_buf_data['tmp_src_file']) " if root file is the current file + let b:livepreview_buf_data['root_dir'] = fnameescape(expand('%:p:h')) + else + let b:livepreview_buf_data['root_dir'] = fnamemodify(l:root_file, ':p:h') + endif + execute 'lcd ' . b:livepreview_buf_data['root_dir'] + + " Write the current buffer in a temporary file + silent exec 'write! ' . b:livepreview_buf_data['tmp_src_file'] + + let l:tmp_out_file = l:tmp_root_dir . '/' . + \ fnamemodify(l:root_file, ':t:r') . '.pdf' + + let b:livepreview_buf_data['run_cmd'] = + \ 'env ' . + \ 'TEXMFOUTPUT=' . l:tmp_root_dir . ' ' . + \ 'TEXINPUTS=' . l:tmp_root_dir + \ . ':' . b:livepreview_buf_data['root_dir'] + \ . ': ' . + \ s:engine . ' ' . + \ '-shell-escape ' . + \ '-interaction=nonstopmode ' . + \ '-output-directory=' . l:tmp_root_dir . ' ' . + \ l:root_file + " lcd can be avoided thanks to root_dir in TEXINPUTS + + silent call system(b:livepreview_buf_data['run_cmd']) + if v:shell_error != 0 + echo 'Failed to compile' + lcd - + return + endif + + " Enable compilation of bibliography: + let l:bib_files = split(glob(b:livepreview_buf_data['root_dir'] . '/**/*.bib')) " TODO: fails if unused bibfiles + if len(l:bib_files) > 0 + for bib_file in l:bib_files + let bib_fn = fnamemodify(bib_file, ':t') + call writefile(readfile(bib_file), + \ l:tmp_root_dir . '/' . bib_fn) " TODO: may fail if same bibfile names in different dirs + endfor + + " Update compile command with bibliography + let b:livepreview_buf_data['run_cmd'] = + \ 'env ' . + \ 'TEXMFOUTPUT=' . l:tmp_root_dir . ' ' . + \ 'TEXINPUTS=' . l:tmp_root_dir + \ . ':' . b:livepreview_buf_data['root_dir'] + \ . ': ' . + \ 'bibtex ' . l:tmp_root_dir . '/*.aux' . + \ ' && ' . + \ b:livepreview_buf_data['run_cmd'] + + silent call system(b:livepreview_buf_data['run_cmd']) + endif + if v:shell_error != 0 + echo 'Failed to compile bibliography' + lcd - + return + endif + + call s:RunInBackground(s:previewer . ' ' . l:tmp_out_file) + + lcd - + + let b:livepreview_buf_data['preview_running'] = 1 +endfunction + +" Initialization code +function! s:Initialize() + let l:ret = 0 + execute s:py_exe "<< EEOOFF" +try: + import vim + import tempfile + import subprocess + import os +except: + vim.command('let l:ret = 1') +EEOOFF + + if l:ret != 0 + return 'Python initialization failed.' + endif + + " Get the tex engine + if exists('g:livepreview_engine') + let s:engine = g:livepreview_engine + else + for possible_engine in ['pdflatex', 'xelatex'] + if executable(possible_engine) + let s:engine = possible_engine + break + endif + endfor + endif + + " Get the previewer + if exists('g:livepreview_previewer') + let s:previewer = g:livepreview_previewer + else + for possible_previewer in ['evince', 'okular'] + if executable(possible_previewer) + let s:previewer = possible_previewer + break + endif + endfor + endif + + return 0 +endfunction + + +let s:init_msg = s:Initialize() + +if type(s:init_msg) == type('') + echohl ErrorMsg + echo 'vim-live-preview: ' . s:init_msg + echohl None +endif + +unlet! s:init_msg + +command! -nargs=* LLPStartPreview call s:StartPreview(<f-args>) + +autocmd CursorHold,CursorHoldI,BufWritePost * call s:Compile() + +let &cpo = s:saved_cpo +unlet! s:saved_cpo + +" vim703: cc=80 +" vim:fdm=marker et ts=4 tw=78 sw=4 diff --git a/dotfiles/.local/share/nvim/site/plugin/neomake.vim b/dotfiles/.local/share/nvim/site/plugin/neomake.vim new file mode 100644 index 0000000..781871a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/neomake.vim @@ -0,0 +1,50 @@ +if exists('g:loaded_neomake') || &compatible + finish +endif +let g:loaded_neomake = 1 + +command! -nargs=* -bang -bar -complete=customlist,neomake#cmd#complete_makers + \ Neomake call neomake#Make(<bang>1, [<f-args>]) + +" These commands are available for clarity +command! -nargs=* -bar -complete=customlist,neomake#cmd#complete_makers + \ NeomakeProject Neomake! <args> +command! -nargs=* -bar -complete=customlist,neomake#cmd#complete_makers + \ NeomakeFile Neomake <args> + +command! -nargs=+ -bang -complete=shellcmd + \ NeomakeSh call neomake#ShCommand(<bang>0, <q-args>) +command! NeomakeListJobs call neomake#ListJobs() +command! -bang -nargs=1 -complete=custom,neomake#cmd#complete_jobs + \ NeomakeCancelJob call neomake#CancelJob(<q-args>, <bang>0) +command! -bang NeomakeCancelJobs call neomake#CancelJobs(<bang>0) + +command! -bang -bar -nargs=? -complete=customlist,neomake#cmd#complete_makers + \ NeomakeInfo call neomake#debug#display_info(<bang>0, <f-args>) + +command! -bang -bar NeomakeClean call neomake#cmd#clean(<bang>1) + +" Enable/disable/toggle commands. +command! -bar NeomakeToggle call neomake#cmd#toggle(g:) +command! -bar NeomakeToggleBuffer call neomake#cmd#toggle(b:) +command! -bar NeomakeToggleTab call neomake#cmd#toggle(t:) +command! -bar NeomakeDisable call neomake#cmd#disable(g:) +command! -bar NeomakeDisableBuffer call neomake#cmd#disable(b:) +command! -bar NeomakeDisableTab call neomake#cmd#disable(t:) +command! -bar NeomakeEnable call neomake#cmd#enable(g:) +command! -bar NeomakeEnableBuffer call neomake#cmd#enable(b:) +command! -bar NeomakeEnableTab call neomake#cmd#enable(t:) + +command! NeomakeStatus call neomake#cmd#display_status() + +" NOTE: experimental, no default mappings. +" NOTE: uses -addr=lines (default), and therefore negative counts do not work +" (see https://github.com/vim/vim/issues/3654). +command! -bar -count=1 NeomakeNextLoclist call neomake#list#next(<count>, 1) +command! -bar -count=1 NeomakePrevLoclist call neomake#list#prev(<count>, 1) +command! -bar -count=1 NeomakeNextQuickfix call neomake#list#next(<count>, 0) +command! -bar -count=1 NeomakePrevQuickfix call neomake#list#prev(<count>, 0) + +call neomake#setup#setup_autocmds() + +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/plugin/node.vim b/dotfiles/.local/share/nvim/site/plugin/node.vim new file mode 100644 index 0000000..a541292 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/node.vim @@ -0,0 +1,47 @@ +if exists("g:loaded_node") || &cp || v:version < 700 | finish | endif +let g:loaded_node = 1 + +let s:filetypes = ["javascript", "json", "jsx"] +if exists("g:node_filetypes") | let s:filetypes = g:node_filetypes | endif + +function! s:detect(dir) + if exists("b:node_root") | return | endif + let dir = a:dir + + while 1 + let is_node = 0 + let is_node = is_node || filereadable(dir . "/package.json") + let is_node = is_node || isdirectory(dir . "/node_modules") + if is_node | return node#initialize(dir) | endif + + let parent = fnamemodify(dir, ":h") + if parent == dir | return | endif + let dir = parent + endwhile +endfunction + +function! s:permutate(ft) + " Don't know right now how to detect javascript.jsx and other permutations + " without precomputing them in advance. Please let me know if you do. + return [a:ft, a:ft . ".*", "*." . a:ft, "*." . a:ft . ".*"] +endfunction + +function! s:flatten(list) + let values = [] + for value in a:list + if type(value) == type([]) | call extend(values, value) + else | add(values, value) + endif + endfor + return values +endfunction + +augroup Node + au! + au VimEnter * if empty(expand("<amatch>")) | call s:detect(getcwd()) | endif + au BufRead,BufNewFile * call s:detect(expand("<amatch>:p")) + + let s:filetype_patterns = s:flatten(map(s:filetypes, "<SID>permutate(v:val)")) + let s:filetype_patterns_joined = join(s:filetype_patterns, ",") + execute "au FileType " s:filetype_patterns_joined " call node#javascript()" +augroup end diff --git a/dotfiles/.local/share/nvim/site/plugin/vmath.vim b/dotfiles/.local/share/nvim/site/plugin/vmath.vim new file mode 100644 index 0000000..0e10044 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/plugin/vmath.vim @@ -0,0 +1,152 @@ +" Vim global plugin for math on visual regions +" Maintainer: Damian Conway +" License: This file is placed in the public domain. + +"###################################################################### +"## ## +"## To use: ## +"## ## +"## vmap <expr> ++ VMATH_YankAndAnalyse() ## +"## nmap ++ vip++ ## +"## ## +"## (or whatever keys you prefer to remap these actions to) ## +"## ## +"###################################################################### + + +" If already loaded, we're done... +if exists("loaded_vmath") + finish +endif +let loaded_vmath = 1 + +" Preserve external compatibility options, then enable full vim compatibility... +let s:save_cpo = &cpo +set cpo&vim + +" Grab visual selection and do simple math on it... +function! VMATH_YankAndAnalyse () + if &showmode + " Don't reselect the visual region if showmode is enabled + " because it will clobber the sum/avg/etc report with the + " "-- VISUAL --" message. + return "y:call VMATH_Analyse()\<CR>" + else + return "y:call VMATH_Analyse()\<CR>gv" + endif +endfunction + +" What to consider a number... +let s:NUM_PAT = '^[+-]\?\d\+\%([.]\d\+\)\?\([eE][+-]\?\d\+\)\?$' + +" How widely to space the report components... +let s:REPORT_GAP = 3 "spaces between components + +" Do simple math on current yank buffer... +function! VMATH_Analyse () + " Extract data from selection... + let selection = getreg('') + let raw_numbers = filter(split(selection), 'v:val =~ s:NUM_PAT') + let numbers = map(copy(raw_numbers), 'str2float(v:val)') + + " Results include a newline if original selection did... + let newline = selection =~ "\n" ? "\n" : "" + + " Calculate and en-register various interesting metrics... + let summation = len(numbers) ? join( numbers, ' + ') : '0' + call setreg('s', s:tidy( eval( summation ) )) " Sum --> register s + call setreg('a', s:average(raw_numbers) ) " Average --> register a + call setreg('x', s:tidy( s:max(numbers) )) " Max --> register x + call setreg('n', s:tidy( s:min(numbers) )) " Min --> register n + call setreg('r', @n . ' to ' . @x ) " Range --> register r + call setreg('c', len(numbers) ) " Count --> register c + + " Default paste buffer should depend on original contents (TODO) + call setreg('', @s ) + + " Report... + let gap = repeat(" ", s:REPORT_GAP) + highlight NormalUnderlined term=underline cterm=underline gui=underline + echohl NormalUnderlined + echo 's' + echohl NONE + echon 'um: ' . @s . gap + echohl NormalUnderlined + echon 'a' + echohl NONE + echon 'vg: ' . @a . gap + echon 'mi' + echohl NormalUnderlined + echon 'n' + echohl NONE + echon ': ' . @n . gap + echon 'ma' + echohl NormalUnderlined + echon 'x' + echohl NONE + echon ': ' . @x . gap + echohl NormalUnderlined + echon 'c' + echohl NONE + echon 'ount: ' . @c + +endfunction + +" Prettify numbers... +function! s:tidy (number) + let tidied = printf('%g', a:number) + return substitute(tidied, '[.]0\+$', '', '') +endfunction + +" Compute average with meaningful number of decimal places... +function! s:average (numbers) + " Compute average... + let summation = eval( len(a:numbers) ? join( a:numbers, ' + ') : '0' ) + let avg = 1.0 * summation / s:max([len(a:numbers), 1]) + + " Determine significant figures... + let min_decimals = 15 + for num in a:numbers + let decimals = strlen(matchstr(num, '[.]\d\+$')) - 1 + if decimals < min_decimals + let min_decimals = decimals + endif + endfor + + " Adjust answer... + return min_decimals > 0 ? printf('%0.'.min_decimals.'f', avg) + \ : string(avg) +endfunction + +" Reimplement these because the builtins don't handle floats (!!!) +function! s:max (numbers) + if !len(a:numbers) + return 0 + endif + let numbers = copy(a:numbers) + let maxnum = numbers[0] + for nextnum in numbers[1:] + if nextnum > maxnum + let maxnum = nextnum + endif + endfor + return maxnum +endfunction + +function! s:min (numbers) + if !len(a:numbers) + return 0 + endif + let numbers = copy(a:numbers) + let minnum = numbers[0] + for nextnum in numbers[1:] + if nextnum < minnum + let minnum = nextnum + endif + endfor + return minnum +endfunction + + +" Restore previous external compatibility options +let &cpo = s:save_cpo diff --git a/dotfiles/.local/share/nvim/site/spell/es.utf-8.spl b/dotfiles/.local/share/nvim/site/spell/es.utf-8.spl Binary files differnew file mode 100644 index 0000000..62d848d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/spell/es.utf-8.spl diff --git a/dotfiles/.local/share/nvim/site/spell/es.utf-8.sug b/dotfiles/.local/share/nvim/site/spell/es.utf-8.sug Binary files differnew file mode 100644 index 0000000..9064321 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/spell/es.utf-8.sug diff --git a/dotfiles/.local/share/nvim/site/spell/ru.utf-8.spl b/dotfiles/.local/share/nvim/site/spell/ru.utf-8.spl Binary files differnew file mode 100644 index 0000000..43d0e4b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/spell/ru.utf-8.spl diff --git a/dotfiles/.local/share/nvim/site/spell/ru.utf-8.sug b/dotfiles/.local/share/nvim/site/spell/ru.utf-8.sug Binary files differnew file mode 100644 index 0000000..b418a0d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/spell/ru.utf-8.sug diff --git a/dotfiles/.local/share/nvim/site/syntax/i3.vim b/dotfiles/.local/share/nvim/site/syntax/i3.vim new file mode 100644 index 0000000..fb93437 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/syntax/i3.vim @@ -0,0 +1,110 @@ +" Vim syntax file +" Language: i3-wm config file +" Maintainer: Emanuel Guével +" Latest Revision: 16 October 2012 + +if exists("b:current_syntax") + finish +endif + +" Symbols +syn match i3Operators "+\|→" +syn match i3ChainDelimiter ";" + +syn match i3Var "\$\w\+" + +" Key modifiers +syn keyword i3KeyModifier Shift Control Mod1 Mod2 Mod3 Mod4 Mod5 + +" Strings +syn region i3SimpleString keepend start='[^ \t]' end='$\|;' contained contains=i3ChainDelimiter,i3Var +syn match i3QuotedString '"[^"]\+"' contained +syn cluster i3String contains=i3SimpleString,i3QuotedString + +" Config commands +syn keyword i3ConfigCommand bind bindcode bindsym assign new_window popup_during_fullscreen font floating_modifier floating_minimum_size floating_maximum_size default_orientation workspace_layout for_window focus_folows_mouse bar position colors output tray_output workspace_buttons +syn match i3IpcSocket "ipc-socket" nextgroup=@i3String skipwhite + +" Command keywords +syn keyword i3Command exit reload restart kill fullscreen global layout border focus move open split append_layout mark resize grow shrink restore show +syn keyword i3Param 1pixel default stacked tabbed normal none tiling stacking floating enable disable up down horizontal vertical both up down left right parent child px or ppt leave_fullscreen toggle mode_toggle scratchpad width height top bottom client dock hide primary yes no all window container to +syn keyword i3WsSpecialParam next prev + +" Exec commands +syn region i3ExecCommand keepend start='[^ \t]' end='$\|;' contained contains=i3ChainDelimiter,i3Var +syn match i3QuotedExecCommand '"[^"]\+"' contained +syn keyword i3ExecKeyword exec exec_always nextgroup=i3QuotedExecCommand,i3ExecCommand skipwhite + +" Status command +syn match i3StatusCommand ".*$" contained +syn keyword i3StatusCommandKeyword status_command nextgroup=i3StatusCommand skipwhite + +" Font statement +syn keyword i3FontStatement font nextgroup=@i3String skipwhite + +" Set statement +syn match i3SetVar "\$\w\+" contained nextgroup=@i3String skipwhite +syn keyword i3SetKeyword set nextgroup=i3SetVar skipwhite + +" Workspaces +syn keyword i3WsKeyword workspace nextgroup=i3WsSpecialParam,@i3String skipwhite + +" Mode +syn keyword i3ModeKeyword mode nextgroup=@i3String skipwhite + +" Comments +syn keyword i3Todo contained TODO FIXME XXX NOTE +syn match i3Comment "^\s*#.*$" contains=i3Todo + +" Error (at end of line) +syn match i3Error ".*$" contained + +" Hex color code +syn match i3ColorLast "#[0-9a-fA-F]\{6\}" contained nextgroup=i3Error skipwhite +syn match i3Color2nd "#[0-9a-fA-F]\{6\}" contained nextgroup=i3ColorLast skipwhite +syn match i3Color1st "#[0-9a-fA-F]\{6\}" contained nextgroup=i3Color2nd skipwhite + +syn match i3ColorDef1 "client\.background\|statusline\|background\|separator" nextgroup=i3ColorLast skipwhite +syn match i3ColorDef3 "client\.\(focused_inactive\|focused\|unfocused\|urgent\)\|inactive_workspace\|urgent_workspace\|focused_workspace\|active_workspace" nextgroup=i3Color1st skipwhite + +highlight link i3ChainDelimiter Operator +highlight link i3Operators Operator + +highlight link i3ExecCommand Special +highlight link i3QuotedExecCommand Special +highlight link i3StatusCommand Special + +highlight link i3Param Constant +highlight link i3Color1st Constant +highlight link i3Color2nd Constant +highlight link i3ColorLast Constant +highlight link i3WsSpecialParam Constant + +highlight link i3Var Identifier +highlight link i3SetVar Identifier + +highlight link i3KeyModifier Function + +highlight link i3SimpleString String +highlight link i3QuotedString String +highlight link i3WsName String +highlight link i3QuotedWsName String +highlight link i3SetValue String +highlight link i3Font String + +highlight link i3ExecKeyword Keyword +highlight link i3Command Keyword +highlight link i3WsKeyword Keyword + +highlight link i3ColorDef1 Define +highlight link i3ColorDef3 Define +highlight link i3ConfigCommand Define +highlight link i3IpcSocket Define +highlight link i3SetKeyword Define +highlight link i3ModeKeyword Define +highlight link i3FontStatement Define +highlight link i3StatusCommandKeyword Define + +highlight link i3Todo Todo +highlight link i3Comment Comment +highlight link i3Error Error diff --git a/dotfiles/.local/share/nvim/site/syntax/javascript.vim b/dotfiles/.local/share/nvim/site/syntax/javascript.vim new file mode 100644 index 0000000..2ea2979 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/syntax/javascript.vim @@ -0,0 +1,310 @@ +" Vim syntax file +" Language: JavaScript +" Maintainer: Jose Elera Campana <https://github.com/jelera> +" Last Modified: Wed 24 Feb 2016 03:35:03 AM CST +" Version: 0.8.2 +" Credits: Zhao Yi, Claudio Fleiner, Scott Shattuck (This file is based +" on their hard work), gumnos (From the #vim IRC Channel in +" Freenode), all the contributors at this project's github page +" (https://github.com/jelera/vim-javascript-syntax/graphs/contributors) + +if !exists("main_syntax") + if version < 600 + syntax clear + elseif exists("b:current_syntax") + finish + endif + let main_syntax = 'javascript' +endif + +" Drop fold if it set but vim doesn't support it. +if version < 600 && exists("javaScript_fold") + unlet javaScript_fold +endif + +"" Remove dollar sign from identifier when embedded in a PHP file +if &filetype == 'javascript' + setlocal iskeyword+=$ +endif + +syntax sync fromstart + +"" syntax coloring for Node.js shebang line +syntax match shebang "^#!.*" +hi link shebang Comment + +" Statement Keywords {{{ +syntax keyword javaScriptSource import export from +syntax keyword javaScriptIdentifier arguments this let var void yield async await const +syntax keyword javaScriptOperator delete new instanceof typeof +syntax keyword javaScriptBoolean true false +syntax keyword javaScriptNull null undefined +syntax keyword javaScriptMessage alert confirm prompt status +syntax keyword javaScriptGlobal self top parent +syntax keyword javaScriptDeprecated escape unescape all applets alinkColor bgColor fgColor linkColor vlinkColor xmlEncoding +syntax keyword javaScriptConditional if else switch +syntax keyword javaScriptRepeat do while for in of +syntax keyword javaScriptBranch break continue +syntax keyword javaScriptLabel case default +syntax keyword javaScriptPrototype prototype +syntax keyword javaScriptStatement return with +syntax keyword javaScriptGlobalObjects Array Boolean Date Function Math Number Object RegExp String +syntax keyword javaScriptExceptions try catch throw finally Error EvalError RangeError ReferenceError SyntaxError TypeError URIError +syntax keyword javaScriptReserved abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws goto private transient debugger implements protected volatile double import public +"}}} +" Comments {{{ +syntax keyword javaScriptCommentTodo TODO FIXME XXX TBD OPTIMIZE HACK REVIEW contained +syntax match javaScriptLineComment "\/\/.*" contains=@Spell,javaScriptCommentTodo +syntax match javaScriptCommentSkip "^[ \t]*\*\($\|[ \t]\+\)" +syntax region javaScriptComment start="/\*" end="\*/" contains=@Spell,javaScriptCommentTodo +"}}} +" JSDoc support {{{ +if !exists("javascript_ignore_javaScriptdoc") + syntax case ignore + + " syntax coloring for JSDoc comments (HTML) + "unlet b:current_syntax + + syntax region javaScriptDocComment matchgroup=javaScriptComment start="/\*\*\s*$" end="\*/" contains=javaScriptDocTags,javaScriptCommentTodo,@javaScriptHtml,jsInJsdocExample,@Spell fold + syntax match javaScriptDocTags contained "@\(abstract\|access\|alias\|arg\|argument\|augments\|author\|borrows\|callback\|class\|classdesc\|const\|constant\|constructor\|constructs\|copyright\|default\|defaultvalue\|deprecated\|desc\|description\|emits\|enum\|event\|example\|exception\|exports\|extends\|external\|file\|fileoverview\|fires\|func\|function\|global\|host\|ignore\|implements\|inheritdoc\|inner\|instance\|interface\|kind\|lends\|license\|link\|linkcode\|linkplain\|listens\|member\|memberof\|method\|mixes\|mixin\|module\|name\|namespace\|override\|overview\|param\|private\|prop\|property\|cfg\|protected\|public\|readonly\|requires\|return\|returns\|see\|since\|static\|summary\|this\|throws\|todo\|tutorial\|tutorial\|type\|typedef\|var\|variation\|version\|virtual\)\>" nextgroup=javaScriptDocParam,javaScriptDocSeeTag skipwhite + syntax match javaScriptDocParam contained "\%(#\|\w\|\.\|:\|\/\)\+" + syntax region javaScriptDocSeeTag contained matchgroup=javaScriptDocSeeTag start="{" end="}" contains=javaScriptDocTags + + syntax case match +endif + syntax case match +"}}} +" Strings, Numbers and Regex Highlight {{{ +syntax match javaScriptSpecial "\\\d\d\d\|\\." +syntax region javaScriptString start=+"+ skip=+\\\\\|\\"+ end=+"\|$+ contains=javaScriptSpecial,@htmlPreproc +syntax region javaScriptString start=+'+ skip=+\\\\\|\\'+ end=+'\|$+ contains=javaScriptSpecial,@htmlPreproc + +syntax match javaScriptSpecialCharacter "'\\.'" +syntax match javaScriptNumber "-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>" +syntax region javaScriptRegexpString start=+/[^/*]+me=e-1 skip=+\\\\\|\\/+ end=+/[gim]\{0,2\}\s*$+ end=+/[gim]\{0,2\}\s*[;.,)\]}]+me=e-1 contains=@htmlPreproc oneline +syntax match javaScriptFloat /\<-\=\%(\d\+\.\d\+\|\d\+\.\|\.\d\+\)\%([eE][+-]\=\d\+\)\=\>/ +"}}} +" DOM, Browser and Ajax Support {{{ +syntax keyword javaScriptBrowserObjects window navigator screen history location console + +syntax keyword javaScriptDOMObjects document event HTMLElement Anchor Area Base Body Button Form Frame Frameset Image Link Meta Option Select Style Table TableCell TableRow Textarea +syntax keyword javaScriptDOMMethods createTextNode createElement insertBefore replaceChild removeChild appendChild hasChildNodes cloneNode normalize isSupported hasAttributes getAttribute setAttribute removeAttribute getAttributeNode setAttributeNode removeAttributeNode getElementsByTagName hasAttribute getElementById adoptNode close compareDocumentPosition createAttribute createCDATASection createComment createDocumentFragment createElementNS createEvent createExpression createNSResolver createProcessingInstruction createRange createTreeWalker elementFromPoint evaluate getBoxObjectFor getElementsByClassName getSelection getUserData hasFocus importNode +syntax keyword javaScriptDOMProperties nodeName nodeValue nodeType parentNode childNodes firstChild lastChild previousSibling nextSibling attributes ownerDocument namespaceURI prefix localName tagName + +syntax keyword javaScriptAjaxObjects XMLHttpRequest +syntax keyword javaScriptAjaxProperties readyState responseText responseXML statusText +syntax keyword javaScriptAjaxMethods onreadystatechange abort getAllResponseHeaders getResponseHeader open send setRequestHeader + +syntax keyword javaScriptPropietaryObjects ActiveXObject +syntax keyword javaScriptPropietaryMethods attachEvent detachEvent cancelBubble returnValue + +syntax keyword javaScriptHtmlElemProperties className clientHeight clientLeft clientTop clientWidth dir href id innerHTML lang length offsetHeight offsetLeft offsetParent offsetTop offsetWidth scrollHeight scrollLeft scrollTop scrollWidth style tabIndex target title + +syntax keyword javaScriptEventListenerKeywords blur click focus mouseover mouseout load item + +syntax keyword javaScriptEventListenerMethods scrollIntoView addEventListener dispatchEvent removeEventListener preventDefault stopPropagation +" }}} +" DOM/HTML5/CSS specified things {{{ + " Web API Interfaces (very long list of keywords) {{{ + syntax keyword javaScriptWebAPI AbstractWorker AnalyserNode AnimationEvent App Apps ArrayBuffer ArrayBufferView Attr AudioBuffer AudioBufferSourceNode AudioContext AudioDestinationNode AudioListener AudioNode AudioParam AudioProcessingEvent BatteryManager BiquadFilterNode Blob BlobBuilder BlobEvent CallEvent CameraCapabilities CameraControl CameraManager CanvasGradient CanvasImageSource CanvasPattern CanvasPixelArray CanvasRenderingContext2D CaretPosition CDATASection ChannelMergerNode ChannelSplitterNode CharacterData ChildNode ChromeWorker ClipboardEvent CloseEvent Comment CompositionEvent Connection Console ContactManager ConvolverNode Coordinates CSS CSSConditionRule CSSGroupingRule CSSKeyframeRule CSSKeyframesRule CSSMediaRule CSSNamespaceRule CSSPageRule CSSRule CSSRuleList CSSStyleDeclaration CSSStyleRule CSSStyleSheet CSSSupportsRule CustomEvent + syntax keyword javaScriptWebAPI DataTransfer DataView DedicatedWorkerGlobalScope DelayNode DeviceAcceleration DeviceLightEvent DeviceMotionEvent DeviceOrientationEvent DeviceProximityEvent DeviceRotationRate DeviceStorage DeviceStorageChangeEvent DirectoryEntry DirectoryEntrySync DirectoryReader DirectoryReaderSync Document DocumentFragment DocumentTouch DocumentType DOMConfiguration DOMCursor DOMError DOMErrorHandler DOMException DOMHighResTimeStamp DOMImplementation DOMImplementationList DOMImplementationSource DOMLocator DOMObject DOMParser DOMRequest DOMString DOMStringList DOMStringMap DOMTimeStamp DOMTokenList DOMUserData DynamicsCompressorNode + syntax keyword javaScriptWebAPI Element ElementTraversal Entity EntityReference Entry EntrySync ErrorEvent Event EventListener EventSource EventTarget Extensions File FileEntry FileEntrySync FileError FileException FileList FileReader FileSystem FileSystemSync Float32Array Float64Array FMRadio FocusEvent FormData GainNode Geolocation History + syntax keyword javaScriptWebAPI HTMLAnchorElement HTMLAreaElement HTMLAudioElement HTMLBaseElement HTMLBaseFontElement HTMLBodyElement HTMLBRElement HTMLButtonElement HTMLCanvasElement HTMLCollection HTMLDataElement HTMLDataListElement HTMLDivElement HTMLDListElement HTMLDocument HTMLElement HTMLEmbedElement HTMLFieldSetElement HTMLFormControlsCollection HTMLFormElement HTMLHeadElement HTMLHeadingElement HTMLHRElement HTMLHtmlElement HTMLIFrameElement HTMLImageElement HTMLInputElement HTMLIsIndexElement HTMLKeygenElement HTMLLabelElement HTMLLegendElement HTMLLIElement HTMLLinkElement HTMLMapElement HTMLMediaElement HTMLMetaElement HTMLMeterElement HTMLModElement HTMLObjectElement HTMLOListElement HTMLOptGroupElement HTMLOptionElement HTMLOptionsCollection HTMLOutputElement HTMLParagraphElement HTMLParamElement HTMLPreElement HTMLProgressElement HTMLQuoteElement HTMLScriptElement HTMLSelectElement HTMLSourceElement HTMLSpanElement HTMLStyleElement HTMLTableCaptionElement HTMLTableCellElement HTMLTableColElement HTMLTableElement HTMLTableRowElement HTMLTableSectionElement HTMLTextAreaElement HTMLTimeElement HTMLTitleElement HTMLTrackElement HTMLUListElement HTMLUnknownElement HTMLVideoElement + syntax keyword javaScriptWebAPI IDBCursor IDBCursorWithValue IDBDatabase IDBDatabaseException IDBEnvironment IDBFactory IDBIndex IDBKeyRange IDBObjectStore IDBOpenDBRequest IDBRequest IDBTransaction IDBVersionChangeEvent ImageData Int16Array Int32Array Int8Array KeyboardEvent LinkStyle LocalFileSystem LocalFileSystemSync Location MediaQueryList MediaQueryListListener MediaSource MediaStream MediaStreamTrack MessageEvent MouseEvent MouseScrollEvent MouseWheelEvent MozActivity MozActivityOptions MozActivityRequestHandler MozAlarmsManager MozContact MozContactChangeEvent MozIccManager MozMmsEvent MozMmsMessage MozMobileCellInfo MozMobileCFInfo MozMobileConnection MozMobileConnectionInfo MozMobileICCInfo MozMobileMessageManager MozMobileMessageThread MozMobileNetworkInfo MozNetworkStats MozNetworkStatsData MozNetworkStatsManager MozSettingsEvent MozSmsEvent MozSmsFilter MozSmsManager MozSmsMessage MozSmsSegmentInfo MozTimeManager MozWifiConnectionInfoEvent MutationObserver + syntax keyword javaScriptWebAPI NamedNodeMap NameList Navigator NavigatorGeolocation NavigatorID NavigatorLanguage NavigatorOnLine NavigatorPlugins NetworkInformation Node NodeFilter NodeIterator NodeList Notation Notification NotifyAudioAvailableEvent OfflineAudioCompletionEvent OfflineAudioContext PannerNode ParentNode Performance PerformanceNavigation PerformanceTiming Plugin PluginArray Position PositionError PositionOptions PowerManager ProcessingInstruction ProgressEvent Promise PromiseResolver PushManager + syntax keyword javaScriptWebAPI Range ScriptProcessorNode Selection SettingsLock SettingsManager SharedWorker StyleSheet StyleSheetList SVGAElement SVGAngle SVGAnimateColorElement SVGAnimatedAngle SVGAnimatedBoolean SVGAnimatedEnumeration SVGAnimatedInteger SVGAnimatedLengthList SVGAnimatedNumber SVGAnimatedNumberList SVGAnimatedPoints SVGAnimatedPreserveAspectRatio SVGAnimatedRect SVGAnimatedString SVGAnimatedTransformList SVGAnimateElement SVGAnimateMotionElement SVGAnimateTransformElement SVGAnimationElement SVGCircleElement SVGClipPathElement SVGCursorElement SVGDefsElement SVGDescElement SVGElement SVGEllipseElement SVGFilterElement SVGFontElement SVGFontFaceElement SVGFontFaceFormatElement SVGFontFaceNameElement SVGFontFaceSrcElement SVGFontFaceUriElement + syntax keyword javaScriptWebAPI SVGForeignObjectElement SVGGElement SVGGlyphElement SVGGradientElement SVGHKernElement SVGImageElement SVGLength SVGLengthList SVGLinearGradientElement SVGLineElement SVGMaskElement SVGMatrix SVGMissingGlyphElement SVGMPathElement SVGNumber SVGNumberList SVGPathElement SVGPatternElement SVGPolygonElement SVGPolylineElement SVGPreserveAspectRatio SVGRadialGradientElement SVGRect SVGRectElement SVGScriptElement SVGSetElement SVGStopElement SVGStringList SVGStylable SVGStyleElement SVGSVGElement SVGSwitchElement SVGSymbolElement SVGTests SVGTextElement SVGTextPositioningElement SVGTitleElement SVGTransform SVGTransformable SVGTransformList SVGTRefElement SVGTSpanElement SVGUseElement SVGViewElement SVGVKernElement TCPSocket Telephony TelephonyCall Text TextDecoder TextEncoder TextMetrics TimeRanges Touch TouchEvent TouchList Transferable TransitionEvent TreeWalker TypeInfo UIEvent Uint16Array Uint32Array Uint8Array Uint8ClampedArray URL URLUtils URLUtilsReadOnly + " }}} + " DOM2 CONSTANT {{{ + syntax keyword javaScriptDomErrNo INDEX_SIZE_ERR DOMSTRING_SIZE_ERR HIERARCHY_REQUEST_ERR WRONG_DOCUMENT_ERR INVALID_CHARACTER_ERR NO_DATA_ALLOWED_ERR NO_MODIFICATION_ALLOWED_ERR NOT_FOUND_ERR NOT_SUPPORTED_ERR INUSE_ATTRIBUTE_ERR INVALID_STATE_ERR SYNTAX_ERR INVALID_MODIFICATION_ERR NAMESPACE_ERR INVALID_ACCESS_ERR + syntax keyword javaScriptDomNodeConsts ELEMENT_NODE ATTRIBUTE_NODE TEXT_NODE CDATA_SECTION_NODE ENTITY_REFERENCE_NODE ENTITY_NODE PROCESSING_INSTRUCTION_NODE COMMENT_NODE DOCUMENT_NODE DOCUMENT_TYPE_NODE DOCUMENT_FRAGMENT_NODE NOTATION_NODE + "}}} + " HTML events and internal variables"{{{ + syntax case ignore + syntax keyword javaScriptHtmlEvents onblur onclick oncontextmenu ondblclick onfocus onkeydown onkeypress onkeyup onmousedown onmousemove onmouseout onmouseover onmouseup onresize onload onsubmit + syntax case match + "}}} + + " Follow stuff should be highligh within a special context + " While it can't be handled with context depended with Regex based highlight + " So, turn it off by default + if exists("javascript_enable_domhtmlcss") + " DOM2 things {{{ + syntax match javaScriptDomElemAttrs contained /\%(nodeName\|nodeValue\|nodeType\|parentNode\|childNodes\|firstChild\|lastChild\|previousSibling\|nextSibling\|attributes\|ownerDocument\|namespaceURI\|prefix\|localName\|tagName\)\>/ + syntax match javaScriptDomElemFuncs contained /\%(insertBefore\|replaceChild\|removeChild\|appendChild\|hasChildNodes\|cloneNode\|normalize\|isSupported\|hasAttributes\|getAttribute\|setAttribute\|removeAttribute\|getAttributeNode\|setAttributeNode\|removeAttributeNode\|getElementsByTagName\|getAttributeNS\|setAttributeNS\|removeAttributeNS\|getAttributeNodeNS\|setAttributeNodeNS\|getElementsByTagNameNS\|hasAttribute\|hasAttributeNS\)\>/ nextgroup=javaScriptParen skipwhite + "}}} + " HTML things {{{ + syntax match javaScriptHtmlElemAttrs contained /\%(className\|clientHeight\|clientLeft\|clientTop\|clientWidth\|dir\|id\|innerHTML\|lang\|length\|offsetHeight\|offsetLeft\|offsetParent\|offsetTop\|offsetWidth\|scrollHeight\|scrollLeft\|scrollTop\|scrollWidth\|style\|tabIndex\|title\)\>/ + syntax match javaScriptHtmlElemFuncs contained /\%(blur\|click\|focus\|scrollIntoView\|addEventListener\|dispatchEvent\|removeEventListener\|item\)\>/ nextgroup=javaScriptParen skipwhite + "}}} + " CSS Styles in JavaScript {{{ + syntax keyword javaScriptCssStyles contained color font fontFamily fontSize fontSizeAdjust fontStretch fontStyle fontVariant fontWeight letterSpacing lineBreak lineHeight quotes rubyAlign rubyOverhang rubyPosition + syntax keyword javaScriptCssStyles contained textAlign textAlignLast textAutospace textDecoration textIndent textJustify textJustifyTrim textKashidaSpace textOverflowW6 textShadow textTransform textUnderlinePosition + syntax keyword javaScriptCssStyles contained unicodeBidi whiteSpace wordBreak wordSpacing wordWrap writingMode + syntax keyword javaScriptCssStyles contained bottom height left position right top width zIndex + syntax keyword javaScriptCssStyles contained border borderBottom borderLeft borderRight borderTop borderBottomColor borderLeftColor borderTopColor borderBottomStyle borderLeftStyle borderRightStyle borderTopStyle borderBottomWidth borderLeftWidth borderRightWidth borderTopWidth borderColor borderStyle borderWidth borderCollapse borderSpacing captionSide emptyCells tableLayout + syntax keyword javaScriptCssStyles contained margin marginBottom marginLeft marginRight marginTop outline outlineColor outlineStyle outlineWidth padding paddingBottom paddingLeft paddingRight paddingTop + syntax keyword javaScriptCssStyles contained listStyle listStyleImage listStylePosition listStyleType + syntax keyword javaScriptCssStyles contained background backgroundAttachment backgroundColor backgroundImage gackgroundPosition backgroundPositionX backgroundPositionY backgroundRepeat + syntax keyword javaScriptCssStyles contained clear clip clipBottom clipLeft clipRight clipTop content counterIncrement counterReset cssFloat cursor direction display filter layoutGrid layoutGridChar layoutGridLine layoutGridMode layoutGridType + syntax keyword javaScriptCssStyles contained marks maxHeight maxWidth minHeight minWidth opacity MozOpacity overflow overflowX overflowY verticalAlign visibility zoom cssText + syntax keyword javaScriptCssStyles contained scrollbar3dLightColor scrollbarArrowColor scrollbarBaseColor scrollbarDarkShadowColor scrollbarFaceColor scrollbarHighlightColor scrollbarShadowColor scrollbarTrackColor + "}}} + " Highlight ways {{{ + syntax match javaScriptDotNotation "\." nextgroup=javaScriptPrototype,javaScriptDomElemAttrs,javaScriptDomElemFuncs,javaScriptHtmlElemAttrs,javaScriptHtmlElemFuncs + syntax match javaScriptDotNotation "\.style\." nextgroup=javaScriptCssStyles + "}}} + endif +" end DOM/HTML/CSS specified things }}} +" Code blocks"{{{ +syntax cluster javaScriptAll contains=javaScriptComment,javaScriptLineComment,javaScriptDocComment,javaScriptString,javaScriptRegexpString,javaScriptNumber,javaScriptFloat,javaScriptLabel,javaScriptSource,javaScriptWebAPI,javaScriptOperator,javaScriptBoolean,javaScriptNull,javaScriptFuncKeyword,javaScriptConditional,javaScriptGlobal,javaScriptRepeat,javaScriptBranch,javaScriptStatement,javaScriptGlobalObjects,javaScriptMessage,javaScriptIdentifier,javaScriptExceptions,javaScriptReserved,javaScriptDeprecated,javaScriptDomErrNo,javaScriptDomNodeConsts,javaScriptHtmlEvents,javaScriptDotNotation,javaScriptBrowserObjects,javaScriptDOMObjects,javaScriptAjaxObjects,javaScriptPropietaryObjects,javaScriptDOMMethods,javaScriptHtmlElemProperties,javaScriptDOMProperties,javaScriptEventListenerKeywords,javaScriptEventListenerMethods,javaScriptAjaxProperties,javaScriptAjaxMethods,javaScriptFuncArg + +if main_syntax == "javascript" + syntax sync clear + syntax sync ccomment javaScriptComment minlines=200 + " syntax sync match javaScriptHighlight grouphere javaScriptBlock /{/ +endif +"}}} +" Function and arguments highlighting {{{ +syntax keyword javaScriptFuncKeyword function contained +syntax region javaScriptFuncExp start=/\w\+\s\==\s\=function\>/ end="\([^)]*\)" contains=javaScriptFuncEq,javaScriptFuncKeyword,javaScriptFuncArg keepend +syntax match javaScriptFuncArg "\(([^()]*)\)" contains=javaScriptParens,javaScriptFuncComma,javaScriptComment contained +syntax match javaScriptFuncComma /,/ contained +syntax match javaScriptFuncEq /=/ contained +syntax region javaScriptFuncDef start="\<function\>" end="\([^)]*\)" contains=javaScriptFuncKeyword,javaScriptFuncArg keepend +syntax match javaScriptObjectKey /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\(\s*:\)\@=/ contains=javaScriptFunctionKey +syntax match javaScriptFunctionKey /\<[a-zA-Z_$][0-9a-zA-Z_$]*\>\(\s*:\s*function\s*\)\@=/ contained +"}}} +" Braces, Parens, symbols, colons {{{ +syntax match javaScriptBraces "[{}\[\]]" +syntax match javaScriptParens "[()]" +syntax match javaScriptOpSymbols "=\{1,3}\|!==\|!=\|<\|>\|>=\|<=\|++\|+=\|--\|-=" +syntax match javaScriptEndColons "[;,]" +syntax match javaScriptLogicSymbols "\(&&\)\|\(||\)" +"}}} +" ES6 String Interpolation {{{ +syntax match javaScriptTemplateDelim "\${\|}" contained +syntax region javaScriptTemplateVar start=+${+ end=+}+ contains=javaScriptTemplateDelim keepend +syntax region javaScriptTemplateString start=+`+ skip=+\\\(`\|$\)+ end=+`+ contains=javaScriptTemplateVar,javaScriptSpecial keepend +"}}} +" JavaScriptFold Function {{{ + +function! JavaScriptFold() + setl foldmethod=syntax + setl foldlevelstart=1 + syntax region foldBraces start=/{/ end=/}/ transparent fold keepend extend +endfunction + +" }}} +" Highlight links {{{ +" Define the default highlighting. +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_javascript_syn_inits") + if version < 508 + let did_javascript_syn_inits = 1 + command -nargs=+ HiLink hi link <args> + else + command -nargs=+ HiLink hi def link <args> + endif + HiLink javaScriptEndColons Operator + HiLink javaScriptOpSymbols Operator + HiLink javaScriptLogicSymbols Boolean + HiLink javaScriptBraces Function + HiLink javaScriptParens Operator + HiLink javaScriptTemplateDelim Operator + + HiLink javaScriptComment Comment + HiLink javaScriptLineComment Comment + HiLink javaScriptDocComment Comment + HiLink javaScriptCommentTodo Todo + + HiLink javaScriptDocTags Special + HiLink javaScriptDocSeeTag Function + HiLink javaScriptDocParam Function + + HiLink javaScriptString String + HiLink javaScriptRegexpString String + HiLink javaScriptTemplateString String + + HiLink javaScriptNumber Number + HiLink javaScriptFloat Number + + HiLink javaScriptGlobal Constant + HiLink javaScriptCharacter Character + HiLink javaScriptPrototype Type + HiLink javaScriptConditional Conditional + HiLink javaScriptBranch Conditional + HiLink javaScriptIdentifier Identifier + HiLink javaScriptRepeat Repeat + HiLink javaScriptStatement Statement + HiLink javaScriptMessage Keyword + HiLink javaScriptReserved Keyword + HiLink javaScriptOperator Operator + HiLink javaScriptNull Type + HiLink javaScriptBoolean Boolean + HiLink javaScriptLabel Label + HiLink javaScriptSpecial Special + HiLink javaScriptSource Special + HiLink javaScriptGlobalObjects Special + HiLink javaScriptExceptions Special + + HiLink javaScriptDeprecated Exception + HiLink javaScriptError Error + HiLink javaScriptParensError Error + HiLink javaScriptParensErrA Error + HiLink javaScriptParensErrB Error + HiLink javaScriptParensErrC Error + HiLink javaScriptDomErrNo Error + + HiLink javaScriptDomNodeConsts Constant + HiLink javaScriptDomElemAttrs Label + HiLink javaScriptDomElemFuncs Type + + HiLink javaScriptWebAPI Type + + HiLink javaScriptHtmlElemAttrs Label + HiLink javaScriptHtmlElemFuncs Type + + HiLink javaScriptCssStyles Type + + HiLink javaScriptBrowserObjects Constant + + HiLink javaScriptDOMObjects Constant + HiLink javaScriptDOMMethods Type + HiLink javaScriptDOMProperties Label + + HiLink javaScriptAjaxObjects Constant + HiLink javaScriptAjaxMethods Type + HiLink javaScriptAjaxProperties Label + + HiLink javaScriptFuncKeyword Function + HiLink javaScriptFuncDef PreProc + HiLink javaScriptFuncExp Title + HiLink javaScriptFuncArg Special + HiLink javaScriptFuncComma Operator + HiLink javaScriptFuncEq Operator + + HiLink javaScriptHtmlEvents Constant + HiLink javaScriptHtmlElemProperties Label + + HiLink javaScriptEventListenerKeywords Type + + HiLink javaScriptPropietaryObjects Constant + + delcommand HiLink +endif +" end Highlight links }}} + +" Define the htmlJavaScript for HTML syntax html.vim +"syntax clear htmlJavaScript +"syntax clear javaScriptExpression +syntax cluster htmlJavaScript contains=@javaScriptAll,javaScriptBracket,javaScriptParen,javaScriptBlock,javaScriptParenError +syntax cluster javaScriptExpression contains=@javaScriptAll,javaScriptBracket,javaScriptParen,javaScriptBlock,javaScriptParenError,@htmlPreproc + +let b:current_syntax = "javascript" +if main_syntax == 'javascript' + unlet main_syntax +endif +syntax region jsInJsdocExample matchgroup=Snip start="^\s*\* @example" end="\(^\s*\* [^[:space:]]\)\@=" containedin=@javaScriptComment contains=@javaScriptAll +hi link Snip SpecialComment diff --git a/dotfiles/.local/share/nvim/site/syntax/neomake/python.vim b/dotfiles/.local/share/nvim/site/syntax/neomake/python.vim new file mode 100644 index 0000000..c5f040e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/syntax/neomake/python.vim @@ -0,0 +1,8 @@ +syntax match neomakePythonLint "[EWFC]\d\+" containedin=ALL + +syntax keyword neomakePyLamaNames pycodestyle pydocstyle pyflakes mccabe pylint radon gjslint +syntax match neomakePyLamaLinter "\[\k\+]" contains=neomakePyLamaNames + +highlight default link neomakePythonLint ErrorMsg +highlight default link neomakePyLamaNames Special +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/syntax/neomake/qf.vim b/dotfiles/.local/share/nvim/site/syntax/neomake/qf.vim new file mode 100644 index 0000000..f065eeb --- /dev/null +++ b/dotfiles/.local/share/nvim/site/syntax/neomake/qf.vim @@ -0,0 +1,9 @@ +syntax clear + +let b:current_syntax = 'neomake_qf' + +highlight default link neomakeListNr LineNr +highlight default link neomakeCursorListNr CursorLineNr +highlight default link neomakeMakerName FoldColumn +highlight default link neomakeBufferName qfFileName +" vim: ts=4 sw=4 et diff --git a/dotfiles/.local/share/nvim/site/syntax/toml.vim b/dotfiles/.local/share/nvim/site/syntax/toml.vim new file mode 100644 index 0000000..7cf0c0a --- /dev/null +++ b/dotfiles/.local/share/nvim/site/syntax/toml.vim @@ -0,0 +1,76 @@ +" Language: TOML +" Maintainer: Caleb Spare <cespare@gmail.com> +" URL: https://github.com/cespare/vim-toml +" LICENSE: MIT + +if exists("b:current_syntax") + finish +endif + +syn match tomlEscape /\\[btnfr"/\\]/ display contained +syn match tomlEscape /\\u\x\{4}/ contained +syn match tomlEscape /\\U\x\{8}/ contained +hi def link tomlEscape SpecialChar + +syn match tomlLineEscape /\\$/ contained +hi def link tomlLineEscape SpecialChar + +" Basic strings +syn region tomlString oneline start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=tomlEscape +" Multi-line basic strings +syn region tomlString start=/"""/ end=/"""/ contains=tomlEscape,tomlLineEscape +" Literal strings +syn region tomlString oneline start=/'/ end=/'/ +" Multi-line literal strings +syn region tomlString start=/'''/ end=/'''/ +hi def link tomlString String + +syn match tomlInteger /[+-]\=\<[1-9]\(_\=\d\)*\>/ display +syn match tomlInteger /[+-]\=\<0\>/ display +syn match tomlInteger /[+-]\=\<0x[[:xdigit:]]\(_\=[[:xdigit:]]\)*\>/ display +syn match tomlInteger /[+-]\=\<0o[0-7]\(_\=[0-7]\)*\>/ display +syn match tomlInteger /[+-]\=\<0b[01]\(_\=[01]\)*\>/ display +syn match tomlInteger /[+-]\=\<\(inf\|nan\)\>/ display +hi def link tomlInteger Number + +syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\.\d\+\>/ display +syn match tomlFloat /[+-]\=\<\d\(_\=\d\)*\(\.\d\(_\=\d\)*\)\=[eE][+-]\=\d\(_\=\d\)*\>/ display +hi def link tomlFloat Float + +syn match tomlBoolean /\<\%(true\|false\)\>/ display +hi def link tomlBoolean Boolean + +" https://tools.ietf.org/html/rfc3339 +syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}/ display +syn match tomlDate /\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?/ display +syn match tomlDate /\d\{4\}-\d\{2\}-\d\{2\}[T ]\d\{2\}:\d\{2\}:\d\{2\}\%(\.\d\+\)\?\%(Z\|[+-]\d\{2\}:\d\{2\}\)\?/ display +hi def link tomlDate Constant + +syn match tomlKey /\v(^|[{,])\s*\zs[[:alnum:]._-]+\ze\s*\=/ display +hi def link tomlKey Identifier + +syn region tomlKeyDq oneline start=/\v(^|[{,])\s*\zs"/ end=/"\ze\s*=/ contains=tomlEscape +hi def link tomlKeyDq Identifier + +syn region tomlKeySq oneline start=/\v(^|[{,])\s*\zs'/ end=/'\ze\s*=/ +hi def link tomlKeySq Identifier + +syn region tomlTable oneline start=/^\s*\[[^\[]/ end=/\]/ contains=tomlKey,tomlKeyDq,tomlKeySq +hi def link tomlTable Title + +syn region tomlTableArray oneline start=/^\s*\[\[/ end=/\]\]/ contains=tomlKey,tomlKeyDq,tomlKeySq +hi def link tomlTableArray Title + +syn cluster tomlValue contains=tomlArray,tomlString,tomlInteger,tomlFloat,tomlBoolean,tomlDate,tomlComment +syn region tomlKeyValueArray start=/=\s*\[\zs/ end=/\]/ contains=@tomlValue +syn region tomlArray start=/\[/ end=/\]/ contains=@tomlValue contained + +syn keyword tomlTodo TODO FIXME XXX BUG contained +hi def link tomlTodo Todo + +syn match tomlComment /#.*/ contains=@Spell,tomlTodo +hi def link tomlComment Comment + +syn sync minlines=500 + +let b:current_syntax = "toml" diff --git a/dotfiles/.local/share/nvim/site/t/airline.vim b/dotfiles/.local/share/nvim/site/t/airline.vim new file mode 100644 index 0000000..1569cc4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/airline.vim @@ -0,0 +1,86 @@ +let g:airline_theme = 'dark' + +source plugin/airline.vim +doautocmd VimEnter + +function! MyFuncref(...) + call a:1.add_raw('hello world') + return 1 +endfunction + +function! MyIgnoreFuncref(...) + return -1 +endfunction + +function! MyAppend1(...) + call a:1.add_raw('hello') +endfunction + +function! MyAppend2(...) + call a:1.add_raw('world') +endfunction + +describe 'airline' + before + let g:airline_statusline_funcrefs = [] + end + + it 'should run user funcrefs first' + call airline#add_statusline_func('MyFuncref') + let &statusline = '' + call airline#update_statusline() + Expect airline#statusline(1) =~ 'hello world' + end + + it 'should not change the statusline with -1' + call airline#add_statusline_funcref(function('MyIgnoreFuncref')) + let &statusline = 'foo' + call airline#update_statusline() + Expect &statusline == 'foo' + end + + it 'should support multiple chained funcrefs' + call airline#add_statusline_func('MyAppend1') + call airline#add_statusline_func('MyAppend2') + call airline#update_statusline() + Expect airline#statusline(1) =~ 'helloworld' + end + + it 'should allow users to redefine sections' + let g:airline_section_a = airline#section#create(['mode', 'mode']) + call airline#update_statusline() + Expect airline#statusline(1) =~ '%{airline#util#wrap(airline#parts#mode(),0)}%#airline_a#%#airline_a_bold#%{airline#util#wrap(airline#parts#mode(),0)}%#airline_a#' + end + + it 'should remove funcrefs properly' + let c = len(g:airline_statusline_funcrefs) + call airline#add_statusline_func('MyIgnoreFuncref') + call airline#remove_statusline_func('MyIgnoreFuncref') + Expect len(g:airline_statusline_funcrefs) == c + end + + it 'should overwrite the statusline with active and inactive splits' + wincmd s + Expect airline#statusline(1) !~ 'inactive' + Expect airline#statusline(2) =~ 'inactive' + wincmd c + end + + it 'should collapse the inactive split if the variable is set true' + let g:airline_inactive_collapse = 1 + wincmd s + Expect getwinvar(2, '&statusline') !~ 'airline#parts#mode' + wincmd c + end + + it 'should not collapse the inactive split if the variable is set false' + let g:airline_inactive_collapse = 0 + wincmd s + Expect getwinvar(2, '&statusline') != 'airline#parts#mode' + wincmd c + end + + it 'should include check_mode' + Expect airline#statusline(1) =~ 'airline#check_mode' + end +end diff --git a/dotfiles/.local/share/nvim/site/t/builder.vim b/dotfiles/.local/share/nvim/site/t/builder.vim new file mode 100644 index 0000000..8128312 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/builder.vim @@ -0,0 +1,107 @@ +let g:airline_theme = 'dark' +call airline#init#bootstrap() + +describe 'active builder' + before + let s:builder = airline#builder#new({'active': 1}) + end + + it 'should start with an empty statusline' + let stl = s:builder.build() + Expect stl == '' + end + + it 'should transition colors from one to the next' + call s:builder.add_section('Normal', 'hello') + call s:builder.add_section('Search', 'world') + let stl = s:builder.build() + Expect stl =~ '%#Normal#hello%#Normal_to_Search#%#Search#world' + end + + it 'should reuse highlight group if background colors match' + call airline#highlighter#reset_hlcache() + highlight Foo1 ctermfg=1 ctermbg=2 + highlight Foo2 ctermfg=1 ctermbg=2 + call s:builder.add_section('Foo1', 'hello') + call s:builder.add_section('Foo2', 'world') + let stl = s:builder.build() + Expect stl =~ '%#Foo1#helloworld' + end + + it 'should switch highlight groups if foreground colors differ' + call airline#highlighter#reset_hlcache() + highlight Foo1 ctermfg=1 ctermbg=2 + highlight Foo2 ctermfg=2 ctermbg=2 + call s:builder.add_section('Foo1', 'hello') + call s:builder.add_section('Foo2', 'world') + let stl = s:builder.build() + Expect stl =~ '%#Foo1#hello%#Foo1_to_Foo2#%#Foo2#world' + end + + it 'should split left/right sections' + call s:builder.split() + let stl = s:builder.build() + Expect stl =~ '%=' + end + + it 'after split, sections use the right separator' + call s:builder.split() + call s:builder.add_section('Normal', 'hello') + call s:builder.add_section('Search', 'world') + let stl = s:builder.build() + Expect stl =~ 'hello%#Normal_to_Search#%#Search#world' + end + + it 'should not repeat the same highlight group' + call s:builder.add_section('Normal', 'hello') + call s:builder.add_section('Normal', 'hello') + let stl = s:builder.build() + Expect stl == '%#Normal#hellohello' + end + + it 'should replace accent groups with the specified group' + call s:builder.add_section('Normal', '%#__accent_foo#hello') + let stl = s:builder.build() + Expect stl == '%#Normal#%#Normal_foo#hello' + end + + it 'should replace two accent groups with correct groups' + call s:builder.add_section('Normal', '%#__accent_foo#hello%#__accent_bar#world') + let stl = s:builder.build() + Expect stl =~ '%#Normal_foo#hello%#Normal_bar#world' + end + + it 'should special restore group should go back to previous group' + call s:builder.add_section('Normal', '%#__restore__#') + let stl = s:builder.build() + Expect stl !~ '%#__restore__#' + Expect stl =~ '%#Normal#' + end + + it 'should blend colors from the left through the split to the right' + call s:builder.add_section('Normal', 'hello') + call s:builder.split() + call s:builder.add_section('Search', 'world') + let stl = s:builder.build() + Expect stl =~ 'Normal_to_Search' + end +end + +describe 'inactive builder' + before + let s:builder = airline#builder#new({'active': 0}) + end + + it 'should transition colors from one to the next' + call s:builder.add_section('Normal', 'hello') + call s:builder.add_section('Search', 'world') + let stl = s:builder.build() + Expect stl =~ '%#Normal_inactive#hello%#Normal_to_Search_inactive#%#Search_inactive#world' + end + + it 'should not render accents' + call s:builder.add_section('Normal', '%#__accent_foo#hello%#foo#foo%#__accent_bar#world') + let stl = s:builder.build() + Expect stl == '%#Normal_inactive#hello%#foo_inactive#fooworld' + end +end diff --git a/dotfiles/.local/share/nvim/site/t/commands.vim b/dotfiles/.local/share/nvim/site/t/commands.vim new file mode 100644 index 0000000..13338af --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/commands.vim @@ -0,0 +1,34 @@ +source plugin/airline.vim +doautocmd VimEnter + +describe 'commands' + it 'should toggle off and on' + execute 'AirlineToggle' + Expect exists('#airline') to_be_false + execute 'AirlineToggle' + Expect exists('#airline') to_be_true + end + + it 'should toggle whitespace off and on' + call airline#extensions#load() + execute 'AirlineToggleWhitespace' + Expect exists('#airline_whitespace') to_be_false + execute 'AirlineToggleWhitespace' + Expect exists('#airline_whitespace') to_be_true + end + + it 'should display theme name with no args' + execute 'AirlineTheme simple' + Expect g:airline_theme == 'simple' + execute 'AirlineTheme dark' + Expect g:airline_theme == 'dark' + execute 'AirlineTheme doesnotexist' + Expect g:airline_theme == 'dark' + colors molokai + Expect g:airline_theme == 'molokai' + end + + it 'should have a refresh command' + Expect exists(':AirlineRefresh') to_be_true + end +end diff --git a/dotfiles/.local/share/nvim/site/t/extensions_default.vim b/dotfiles/.local/share/nvim/site/t/extensions_default.vim new file mode 100644 index 0000000..00d4b04 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/extensions_default.vim @@ -0,0 +1,30 @@ +let g:airline#extensions#default#layout = [ + \ [ 'c', 'a', 'b', 'warning' ], + \ [ 'x', 'z', 'y' ] + \ ] + +source plugin/airline.vim +doautocmd VimEnter + +describe 'default' + before + let s:builder = airline#builder#new({'active': 1}) + end + + it 'should use the layout' + call airline#extensions#default#apply(s:builder, { 'winnr': 1, 'active': 1 }) + let stl = s:builder.build() + Expect stl =~ 'airline_c_to_airline_a' + Expect stl =~ 'airline_a_to_airline_b' + Expect stl =~ 'airline_b_to_airline_warning' + Expect stl =~ 'airline_x_to_airline_z' + Expect stl =~ 'airline_z_to_airline_y' + end + + it 'should only render warning section in active splits' + wincmd s + Expect airline#statusline(1) =~ 'warning' + Expect airline#statusline(2) !~ 'warning' + wincmd c + end +end diff --git a/dotfiles/.local/share/nvim/site/t/extensions_tabline.vim b/dotfiles/.local/share/nvim/site/t/extensions_tabline.vim new file mode 100644 index 0000000..9349b81 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/extensions_tabline.vim @@ -0,0 +1,21 @@ +let g:airline#extensions#tabline#enabled = 1 + +source plugin/airline.vim +doautocmd VimEnter + +describe 'default' + + it 'should use a tabline' + e! CHANGELOG.md + sp CONTRIBUTING.md + Expect airline#extensions#tabline#get() == "%#airline_tabhid#...| %(%{airline#extensions#tabline#get_buffer_name(3)}%) %#airline_tabhid_to_airline_tab# %#airline_tab#%(%{airline#extensions#tabline#get_buffer_name(4)}%) %#airline_tab_to_airline_tabsel# %#airline_tabsel#%(%{airline#extensions#tabline#get_buffer_name(5)}%) %#airline_tabsel_to_airline_tabfill# %#airline_tabfill#%=%#airline_tabfill_to_airline_tabfill#%#airline_tabfill#%#airline_tabfill_to_airline_tablabel#%#airline_tablabel# buffers " + end + + it 'Trigger on BufDelete autocommands' + e! CHANGELOG.md + sp CONTRIBUTING.md + sp README.md + 2bd + Expect airline#extensions#tabline#get() == "%#airline_tabhid#...%#airline_tabhid_to_airline_tab# %#airline_tab#%(%{airline#extensions#tabline#get_buffer_name(4)}%) | %(%{airline#extensions#tabline#get_buffer_name(5)}%) %#airline_tab_to_airline_tabsel# %#airline_tabsel#%(%{airline#extensions#tabline#get_buffer_name(6)}%) %#airline_tabsel_to_airline_tabfill# %#airline_tabfill#%=%#airline_tabfill_to_airline_tabfill#%#airline_tabfill#%#airline_tabfill_to_airline_tablabel#%#airline_tablabel# buffers " + end +end diff --git a/dotfiles/.local/share/nvim/site/t/highlighter.vim b/dotfiles/.local/share/nvim/site/t/highlighter.vim new file mode 100644 index 0000000..a38a5c6 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/highlighter.vim @@ -0,0 +1,20 @@ +let g:airline_theme = 'dark' + +describe 'highlighter' + it 'should create separator highlight groups' + hi Foo1 ctermfg=1 ctermbg=2 + hi Foo2 ctermfg=3 ctermbg=4 + call airline#highlighter#add_separator('Foo1', 'Foo2', 0) + let hl = airline#highlighter#get_highlight('Foo1_to_Foo2') + Expect hl == [ '', '', '4', '2', '' ] + end + + it 'should populate accent colors' + Expect exists('g:airline#themes#dark#palette.normal.airline_c_red') to_be_false + Expect hlID('airline_c_red') == 0 + call airline#themes#patch(g:airline#themes#dark#palette) + call airline#highlighter#add_accent('red') + call airline#highlighter#highlight(['normal']) + Expect hlID('airline_c_red') != 0 + end +end diff --git a/dotfiles/.local/share/nvim/site/t/init.vim b/dotfiles/.local/share/nvim/site/t/init.vim new file mode 100644 index 0000000..4f1340d --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/init.vim @@ -0,0 +1,88 @@ +let s:sections = ['a', 'b', 'c', 'gutter', 'x', 'y', 'z', 'warning'] + +function! s:clear() + for key in s:sections + unlet! g:airline_section_{key} + endfor +endfunction + +call airline#init#bootstrap() + +describe 'init sections' + before + call s:clear() + call airline#init#sections() + end + + after + call s:clear() + end + + it 'section a should have mode, paste, spell, iminsert' + Expect g:airline_section_a =~ 'mode' + Expect g:airline_section_a =~ 'paste' + Expect g:airline_section_a =~ 'spell' + Expect g:airline_section_a =~ 'iminsert' + end + + it 'section b should be blank because no extensions are installed' + Expect g:airline_section_b == '' + end + + it 'section c should be file' + Expect g:airline_section_c == '%<%f%m %#__accent_red#%{airline#util#wrap(airline#parts#readonly(),0)}%#__restore__#' + end + + it 'section x should be filetype' + Expect g:airline_section_x == '%{airline#util#prepend("",0)}%{airline#util#prepend("",0)}%{airline#util#wrap(airline#parts#filetype(),0)}' + end + + it 'section y should be fenc and ff' + Expect g:airline_section_y =~ 'ff' + Expect g:airline_section_y =~ 'fenc' + end + + it 'section z should be line numbers' + Expect g:airline_section_z =~ '%3p%%' + Expect g:airline_section_z =~ '%4l' + Expect g:airline_section_z =~ '%3v' + end + + it 'should not redefine sections already defined' + for s in s:sections + let g:airline_section_{s} = s + endfor + call airline#init#bootstrap() + for s in s:sections + Expect g:airline_section_{s} == s + endfor + end + + it 'all default statusline extensions should be blank' + Expect airline#parts#get('ale_error_count').raw == '' + Expect airline#parts#get('ale_warning_count').raw == '' + Expect airline#parts#get('hunks').raw == '' + Expect airline#parts#get('branch').raw == '' + Expect airline#parts#get('eclim').raw == '' + Expect airline#parts#get('neomake_error_count').raw == '' + Expect airline#parts#get('neomake_warning_count').raw == '' + Expect airline#parts#get('obsession').raw == '' + Expect airline#parts#get('syntastic-err').raw == '' + Expect airline#parts#get('syntastic-warn').raw == '' + Expect airline#parts#get('tagbar').raw == '' + Expect airline#parts#get('whitespace').raw == '' + Expect airline#parts#get('windowswap').raw == '' + Expect airline#parts#get('ycm_error_count').raw == '' + Expect airline#parts#get('ycm_warning_count').raw == '' + Expect airline#parts#get('languageclient_error_count').raw == '' + Expect airline#parts#get('languageclient_warning_count').raw == '' + end +end + +describe 'init parts' + it 'should not redefine parts already defined' + call airline#parts#define_raw('linenr', 'bar') + call airline#init#sections() + Expect g:airline_section_z =~ 'bar' + end +end diff --git a/dotfiles/.local/share/nvim/site/t/parts.vim b/dotfiles/.local/share/nvim/site/t/parts.vim new file mode 100644 index 0000000..5e30ca4 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/parts.vim @@ -0,0 +1,38 @@ +describe 'parts' + it 'overwrites existing values' + call airline#parts#define('foo', { 'test': '123' }) + Expect airline#parts#get('foo').test == '123' + call airline#parts#define('foo', { 'test': '321' }) + Expect airline#parts#get('foo').test == '321' + end + + it 'can define a function part' + call airline#parts#define_function('func', 'bar') + Expect airline#parts#get('func').function == 'bar' + end + + it 'can define a text part' + call airline#parts#define_text('text', 'bar') + Expect airline#parts#get('text').text == 'bar' + end + + it 'can define a raw part' + call airline#parts#define_raw('raw', 'bar') + Expect airline#parts#get('raw').raw == 'bar' + end + + it 'can define a minwidth' + call airline#parts#define_minwidth('mw', 123) + Expect airline#parts#get('mw').minwidth == 123 + end + + it 'can define a condition' + call airline#parts#define_condition('part', '1') + Expect airline#parts#get('part').condition == '1' + end + + it 'can define a accent' + call airline#parts#define_accent('part', 'red') + Expect airline#parts#get('part').accent == 'red' + end +end diff --git a/dotfiles/.local/share/nvim/site/t/section.vim b/dotfiles/.local/share/nvim/site/t/section.vim new file mode 100644 index 0000000..50717a7 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/section.vim @@ -0,0 +1,80 @@ +function! SectionSpec() +endfunction + +describe 'section' + before + call airline#parts#define_text('text', 'text') + call airline#parts#define_raw('raw', 'raw') + call airline#parts#define_function('func', 'SectionSpec') + end + + it 'should be able to reference default parts' + let s = airline#section#create(['paste']) + Expect s == '%{airline#util#wrap(airline#parts#paste(),0)}' + end + + it 'should create sections with no separators' + let s = airline#section#create(['text', 'raw', 'func']) + Expect s == '%{airline#util#wrap("text",0)}raw%{airline#util#wrap(SectionSpec(),0)}' + end + + it 'should create left sections with separators' + let s = airline#section#create_left(['text', 'text']) + Expect s == '%{airline#util#wrap("text",0)}%{airline#util#append("text",0)}' + end + + it 'should create right sections with separators' + let s = airline#section#create_right(['text', 'text']) + Expect s == '%{airline#util#prepend("text",0)}%{airline#util#wrap("text",0)}' + end + + it 'should prefix with accent group if provided and restore afterwards' + call airline#parts#define('hi', { + \ 'raw': 'hello', + \ 'accent': 'red', + \ }) + let s = airline#section#create(['hi']) + Expect s == '%#__accent_red#hello%#__restore__#' + end + + it 'should accent functions' + call airline#parts#define_function('hi', 'Hello') + call airline#parts#define_accent('hi', 'bold') + let s = airline#section#create(['hi']) + Expect s == '%#__accent_bold#%{airline#util#wrap(Hello(),0)}%#__restore__#' + end + + it 'should parse out a section from the distro' + call airline#extensions#load() + let s = airline#section#create(['whitespace']) + Expect s =~ 'airline#extensions#whitespace#check' + end + + it 'should use parts as is if they are not found' + let s = airline#section#create(['asdf', 'func']) + Expect s == 'asdf%{airline#util#wrap(SectionSpec(),0)}' + end + + it 'should force add separators for raw and missing keys' + let s = airline#section#create_left(['asdf', 'raw']) + Expect s == 'asdf raw' + let s = airline#section#create_left(['asdf', 'aaaa', 'raw']) + Expect s == 'asdf aaaa raw' + let s = airline#section#create_right(['raw', '%f']) + Expect s == 'raw %f' + let s = airline#section#create_right(['%t', 'asdf', '%{getcwd()}']) + Expect s == '%t asdf %{getcwd()}' + end + + it 'should empty out parts that do not pass their condition' + call airline#parts#define_text('conditional', 'conditional') + call airline#parts#define_condition('conditional', '0') + let s = airline#section#create(['conditional']) + Expect s == '%{0 ? airline#util#wrap("conditional",0) : ""}' + end + + it 'should not draw two separators after another' + let s = airline#section#create_right(['ffenc','%{strftime("%H:%M")}']) + Expect s == '%{airline#util#prepend(airline#parts#ffenc(),0)}%{strftime("%H:%M")}' + end +end diff --git a/dotfiles/.local/share/nvim/site/t/themes.vim b/dotfiles/.local/share/nvim/site/t/themes.vim new file mode 100644 index 0000000..bff302b --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/themes.vim @@ -0,0 +1,72 @@ +describe 'themes' + after + highlight clear Foo + highlight clear Normal + end + + it 'should extract correct colors' + call airline#highlighter#reset_hlcache() + highlight Foo ctermfg=1 ctermbg=2 + let colors = airline#themes#get_highlight('Foo') + Expect colors[2] == '1' + Expect colors[3] == '2' + end + + it 'should extract from normal if colors unavailable' + call airline#highlighter#reset_hlcache() + highlight Normal ctermfg=100 ctermbg=200 + highlight Foo ctermbg=2 + let colors = airline#themes#get_highlight('Foo') + Expect colors[2] == '100' + Expect colors[3] == '2' + end + + it 'should flip target group if it is reversed' + call airline#highlighter#reset_hlcache() + highlight Foo ctermbg=222 ctermfg=103 term=reverse + let colors = airline#themes#get_highlight('Foo') + Expect colors[2] == '222' + Expect colors[3] == '103' + end + + it 'should pass args through correctly' + call airline#highlighter#reset_hlcache() + hi clear Normal + let hl = airline#themes#get_highlight('Foo', 'bold', 'italic') + Expect hl == ['', '', 'NONE', 'NONE', 'bold,italic'] + + let hl = airline#themes#get_highlight2(['Foo','bg'], ['Foo','fg'], 'italic', 'bold') + Expect hl == ['', '', 'NONE', 'NONE', 'italic,bold'] + end + + it 'should generate color map with mirroring' + let map = airline#themes#generate_color_map( + \ [ 1, 1, 1, 1, '1' ], + \ [ 2, 2, 2, 2, '2' ], + \ [ 3, 3, 3, 3, '3' ], + \ ) + Expect map.airline_a[0] == 1 + Expect map.airline_b[0] == 2 + Expect map.airline_c[0] == 3 + Expect map.airline_x[0] == 3 + Expect map.airline_y[0] == 2 + Expect map.airline_z[0] == 1 + end + + it 'should generate color map with full set of colors' + let map = airline#themes#generate_color_map( + \ [ 1, 1, 1, 1, '1' ], + \ [ 2, 2, 2, 2, '2' ], + \ [ 3, 3, 3, 3, '3' ], + \ [ 4, 4, 4, 4, '4' ], + \ [ 5, 5, 5, 5, '5' ], + \ [ 6, 6, 6, 6, '6' ], + \ ) + Expect map.airline_a[0] == 1 + Expect map.airline_b[0] == 2 + Expect map.airline_c[0] == 3 + Expect map.airline_x[0] == 4 + Expect map.airline_y[0] == 5 + Expect map.airline_z[0] == 6 + end +end diff --git a/dotfiles/.local/share/nvim/site/t/util.vim b/dotfiles/.local/share/nvim/site/t/util.vim new file mode 100644 index 0000000..516938c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/t/util.vim @@ -0,0 +1,53 @@ +call airline#init#bootstrap() + +function! Util1() + let g:count += 1 +endfunction +function! Util2() + let g:count += 2 +endfunction +function! Util3(...) + let g:count = a:0 +endfunction + +describe 'util' + before + let g:count = 0 + end + + it 'has append wrapper function' + Expect airline#util#append('', 0) == '' + Expect airline#util#append('1', 0) == ' 1' + end + + it 'has prepend wrapper function' + Expect airline#util#prepend('', 0) == '' + Expect airline#util#prepend('1', 0) == '1 ' + end + + it 'has getwinvar function' + Expect airline#util#getwinvar(1, 'asdf', '123') == '123' + call setwinvar(1, 'vspec', 'is cool') + Expect airline#util#getwinvar(1, 'vspec', '') == 'is cool' + end + + it 'has exec funcrefs helper functions' + call airline#util#exec_funcrefs([function('Util1'), function('Util2')]) + Expect g:count == 3 + + call airline#util#exec_funcrefs([function('Util3')], 1, 2, 3, 4) + Expect g:count == 4 + end + + it 'should ignore minwidth if less than 0' + Expect airline#util#append('foo', -1) == ' foo' + Expect airline#util#prepend('foo', -1) == 'foo ' + Expect airline#util#wrap('foo', -1) == 'foo' + end + + it 'should return empty if winwidth() > minwidth' + Expect airline#util#append('foo', 99999) == '' + Expect airline#util#prepend('foo', 99999) == '' + Expect airline#util#wrap('foo', 99999) == '' + end +end diff --git a/dotfiles/.local/share/nvim/site/test/autoload/lib_test.rb b/dotfiles/.local/share/nvim/site/test/autoload/lib_test.rb new file mode 100644 index 0000000..e39280c --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/autoload/lib_test.rb @@ -0,0 +1,468 @@ +require_relative "../helper" +require "json" + +describe "Lib" do + include WithTemporaryDirectory + + before do + # Some tests may change the working directory, so reset it to a known good. + $vim.command "cd #{Dir.getwd}" + Dir.mkdir File.join(@dir, "node_modules") + end + + def set_node_version(version) + executable = File.join(@dir, "node") + touch executable, <<-end.strip + #!/bin/sh + [ $# != 1 -o "$1" != --version ] && exit 1 + echo "v#{version}" + end + File.chmod 0755, executable + $vim.command(%(let $PATH = "#@dir:" . $PATH)) + end + + describe "node#lib#find" do + def find(name) + path = $vim.echo(%(node#lib#find("#{name}", expand("%")))) + File.exists?(path) ? File.realpath(path) : path + end + + it "must return ./README before ./README.js" do + target = touch File.join(@dir, "README") + touch File.join(@dir, "README.js") + + $vim.edit File.join(@dir, "index.js") + find("./README").must_equal target + end + + it "must return ./README.txt relative to file" do + target = touch File.join(@dir, "lib", "README.txt") + $vim.edit File.join(@dir, "lib", "index.js") + find("./README.txt").must_equal target + end + + it "must return ../README.txt" do + target = touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("../README.txt").must_equal target + end + + it "must return /.../README.txt" do + target = touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("#@dir/README.txt").must_equal target + end + + it "must return ./other.js given ./other" do + target = touch File.join(@dir, "other.js") + $vim.edit File.join(@dir, "index.js") + find("./other").must_equal target + end + + it "must return ./other.jsx given ./other" do + target = touch File.join(@dir, "other.jsx") + $vim.edit File.join(@dir, "index.js") + find("./other").must_equal target + end + + it "must return ./other.es given ./other" do + target = touch File.join(@dir, "other.es") + $vim.edit File.join(@dir, "index.js") + find("./other").must_equal target + end + + it "must return ./other.js given ./other relative to file" do + target = touch File.join(@dir, "lib", "other.js") + $vim.edit File.join(@dir, "lib", "index.js") + find("./other").must_equal target + end + + it "must return ./other.js before ./other/index.js given ./other" do + target = touch File.join(@dir, "other.js") + touch File.join(@dir, "other", "index.js") + $vim.edit File.join(@dir, "index.js") + find("./other").must_equal target + end + + it "must return ../other.js given ../other" do + target = touch File.join(@dir, "other.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("../other").must_equal target + end + + it "must return /.../other.js given /.../other" do + target = touch File.join(@dir, "other.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("#@dir/other").must_equal target + end + + it "must return ./package.json given ./package" do + target = touch File.join(@dir, "package.json") + $vim.edit File.join(@dir, "index.js") + find("./package").must_equal target + end + + it "must return ./index.js given ." do + target = touch File.join(@dir, "index.js") + $vim.edit File.join(@dir, "other.js") + find(".").must_equal target + end + + it "must return ./index.js given ./" do + target = touch File.join(@dir, "index.js") + $vim.edit File.join(@dir, "other.js") + find("./").must_equal target + end + + it "must not find ./index/index.js given ./" do + touch File.join(@dir, "index", "index.js") + $vim.edit File.join(@dir, "other.js") + $vim.echo(%(empty(node#lib#find("./", expand("%"))))).must_equal "1" + end + + it "must not find ./.js given ./" do + touch File.join(@dir, ".js") + $vim.edit File.join(@dir, "other.js") + $vim.echo(%(empty(node#lib#find("./", expand("%"))))).must_equal "1" + end + + it "must return ../index.js given .." do + target = touch File.join(@dir, "index.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "other.js") + find("..").must_equal target + end + + it "must return ../index.js given ../" do + target = touch File.join(@dir, "index.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "other.js") + find("../").must_equal target + end + + it "must return /.../index.js given /..." do + target = touch File.join(@dir, "index.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("#@dir").must_equal target + end + + it "must return /.../index.js given /.../" do + target = touch File.join(@dir, "index.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "index.js") + find("#@dir/").must_equal target + end + + it "must return ./lib/index.js given ./lib" do + target = touch File.join(@dir, "lib", "index.js") + $vim.edit File.join(@dir, "index.js") + find("./lib").must_equal target + end + + it "must return ./lib/other.js given ./lib with main" do + target = touch File.join(@dir, "lib", "other.js") + touch File.join(@dir, "lib", "package.json"), JSON.dump(:main => "other") + $vim.edit File.join(@dir, "index.js") + find("./lib").must_equal target + end + + it "must return ./lib/index.js given ./lib with empty main" do + target = touch File.join(@dir, "lib", "index.js") + touch File.join(@dir, "lib", "package.json"), JSON.dump(:main => "") + $vim.edit File.join(@dir, "index.js") + find("./lib").must_equal target + end + + it "must return ./lib/index.js given ./lib with non-existent main" do + target = touch File.join(@dir, "lib", "index.js") + touch File.join(@dir, "lib", "package.json"), JSON.dump(:main => "new") + $vim.edit File.join(@dir, "index.js") + find("./lib").must_equal target + end + + it "must return ./other.js before ./other/index.js given . with main" do + touch File.join(@dir, "package.json"), JSON.dump(:main => "other") + target = touch File.join(@dir, "other.js") + touch File.join(@dir, "other", "index.js") + + $vim.edit File.join(@dir, "index.js") + find(".").must_equal target + end + + it "must return node_modules/foo/index.js given foo" do + index = File.join(@dir, "node_modules", "foo", "index.js") + touch index + $vim.edit File.join(@dir, "index.js") + find("foo").must_equal index + end + + it "must return node_modules/foo/other.js given foo/other" do + other = File.join(@dir, "node_modules", "foo", "other.js") + touch other + $vim.edit File.join(@dir, "index.js") + find("foo/other").must_equal other + end + + it "must return node_modules/foo/other.js given foo/other.js" do + other = File.join(@dir, "node_modules", "foo", "other.js") + touch other + $vim.edit File.join(@dir, "index.js") + find("foo/other.js").must_equal other + end + + # When package.json refers to a regular file. + it "must return node_modules/foo/other.js given foo with main" do + mod = File.join(@dir, "node_modules", "foo") + touch File.join(mod, "package.json"), JSON.dump(:main => "./other.js") + target = touch File.join(mod, "other.js") + + $vim.edit File.join(@dir, "index.js") + find("foo").must_equal target + end + + # When package.json refers to a directory. + it "must return node_modules/foo/lib/index.js given foo with main as ./lib" do + mod = File.join(@dir, "node_modules", "foo") + touch File.join(mod, "package.json"), JSON.dump(:main => "./lib") + target = touch File.join(mod, "lib/index.js") + + $vim.edit File.join(@dir, "index.js") + find("foo").must_equal target + end + + it "must return node_modules/foo/lib/index.js given foo with main as lib" do + mod = File.join(@dir, "node_modules", "foo") + touch File.join(mod, "package.json"), JSON.dump(:main => "lib") + target = touch File.join(mod, "lib/index.js") + + $vim.edit File.join(@dir, "index.js") + find("foo").must_equal target + end + + it "must return node_modules/@scope/foo/index.js given @scope/foo" do + target = File.join(@dir, "node_modules", "@scope", "foo", "index.js") + touch target + $vim.edit File.join(@dir, "index.js") + find("@scope/foo").must_equal target + end + + it "must return empty when looking for nothing" do + $vim.edit File.join(@dir, "index.js") + $vim.echo(%(empty(node#lib#find("", expand("%"))))).must_equal "1" + end + + it "must return empty when nothing found" do + $vim.edit File.join(@dir, "index.js") + $vim.echo(%(empty(node#lib#find("new", expand("%"))))).must_equal "1" + end + + it "must return URL for core module for current Node version" do + set_node_version "0.13.37" + $vim.edit File.join(@dir, "index.js") + url = "https://rawgit.com/nodejs/node/v0.13.37/lib/assert.js" + find("assert").must_equal url + end + + it "must return URL for core module on master if no Node version" do + touch File.join(@dir, "node"), "#!/bin/sh\nexit 1" + File.chmod 0755, File.join(@dir, "node") + $vim.edit File.join(@dir, "index.js") + $vim.command(%(let $PATH = "#@dir:" . $PATH)) + url = "https://rawgit.com/nodejs/node/master/lib/assert.js" + find("assert").must_equal url + end + + it "must return URL for node.js for current Node version" do + set_node_version "0.13.37" + $vim.edit File.join(@dir, "index.js") + url = "https://rawgit.com/nodejs/node/v0.13.37/src/node.js" + find("node").must_equal url + end + + it "must return URL for node.js on master if no Node version" do + touch File.join(@dir, "node"), "#!/bin/sh\nexit 1" + File.chmod 0755, File.join(@dir, "node") + $vim.edit File.join(@dir, "index.js") + $vim.command(%(let $PATH = "#@dir:" . $PATH)) + url = "https://rawgit.com/nodejs/node/master/src/node.js" + find("node").must_equal url + end + end + + describe "node#lib#glob" do + require "json" + + before do + $vim.edit File.join(@dir, "index.js") + end + + def glob(arg = "") + # Because of possible locale and filesystem case-sensitiveness + # differences, sort the output explicitly to be resistant. + JSON.parse($vim.echo(%(node#lib#glob("#{arg}"))).gsub("'", '"')).sort + end + + describe "given nothing" do + it "must return files and directories" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "test") + + files = %w[./README.txt ./index.js ./test/] + glob.must_equal (CORE_MODULES + files).sort + end + + it "must return modules and core modules" do + FileUtils.mkpath File.join(@dir, "node_modules", "require-guard") + FileUtils.mkpath File.join(@dir, "node_modules", "export") + FileUtils.mkpath File.join(@dir, "node_modules", "soul") + glob.must_equal (CORE_MODULES + %w[export/ require-guard/ soul/]).sort + end + + it "must return core modules without slashes" do + glob.must_equal CORE_MODULES + glob.wont_equal /\// + end + + # Even though node.js is the bootstrapper file in src/. + it "must return \"node\" as one of those core modules" do + glob.must_include "node" + end + + it "must return files, directories and modules" do + FileUtils.mkpath File.join(@dir, "node_modules", "export") + FileUtils.mkpath File.join(@dir, "node_modules", "soul") + touch File.join(@dir, "index.js") + touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "test") + + files = %w[./README.txt ./index.js ./test/ export/ soul/] + glob.must_equal (CORE_MODULES + files).sort + end + + it "must not return the node_modules directory" do + FileUtils.mkpath File.join(@dir, "node_modules") + glob.must_equal CORE_MODULES + end + end + + describe "given absolute path" do + it "must return files and directories given /" do + files = Dir.entries("/") + files.reject! {|f| f =~ /^\./ } + files.sort! + files.map! {|f| "/" + f } + files.map! {|f| File.directory?(f) ? f + "/" : f } + + glob("/").must_equal files + end + + it "must return files and directories given /.../" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README") + Dir.mkdir File.join(@dir, "test") + + files = %W[#@dir/README #@dir/index.js #@dir/node_modules/ #@dir/test/] + glob(@dir).must_equal files + end + + it "must return files and directories given /.../test" do + touch File.join(@dir, "test", "index_test.js") + touch File.join(@dir, "test", "helpers.js") + files = %W[#@dir/test/helpers.js #@dir/test/index_test.js] + glob(File.join(@dir, "test")).must_equal files + end + + it "must not return modules along with files" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README") + Dir.mkdir File.join(@dir, "test") + FileUtils.mkpath File.join(@dir, "node_modules", "soul") + + files = %W[#@dir/README #@dir/index.js #@dir/node_modules/ #@dir/test/] + glob(@dir).must_equal files + end + end + + describe "given relative path" do + it "must return files and directories given ." do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README") + Dir.mkdir File.join(@dir, "test") + glob(".").must_equal %W[./README ./index.js ./test/] + end + + it "must return files and directories given ./" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README") + Dir.mkdir File.join(@dir, "test") + glob("./").must_equal %W[./README ./index.js ./test/] + end + + it "must return files and directories given .//" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "test") + glob(".//").must_equal %W[.//README.txt .//index.js .//test/] + end + + it "must return files and directories given .///" do + touch File.join(@dir, "index.js") + touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "test") + glob(".///").must_equal %W[.///README.txt .///index.js .///test/] + end + + it "must return files and directories given ./test" do + touch File.join(@dir, "test", "test.js") + touch File.join(@dir, "test", "helpers.js") + glob("./test/").must_equal %W[./test/helpers.js ./test/test.js] + end + end + + describe "given module name" do + it "must return files and directories given soul" do + touch File.join(@dir, "node_modules", "soul", "index.js") + touch File.join(@dir, "node_modules", "soul", "README") + FileUtils.mkpath File.join(@dir, "node_modules", "soul", "test") + glob("soul").must_equal %w[soul/README soul/index.js soul/test/] + end + + it "must return files and directories given soul/" do + touch File.join(@dir, "node_modules", "soul", "index.js") + FileUtils.mkpath File.join(@dir, "node_modules", "soul", "test") + glob("soul/").must_equal %w[soul/index.js soul/test/] + end + + it "must return files and directories given soul//" do + touch File.join(@dir, "node_modules", "soul", "index.js") + FileUtils.mkpath File.join(@dir, "node_modules", "soul", "test") + glob("soul//").must_equal %w[soul//index.js soul//test/] + end + + it "must return files and directories given soul///" do + touch File.join(@dir, "node_modules", "soul", "index.js") + FileUtils.mkpath File.join(@dir, "node_modules", "soul", "test") + glob("soul///").must_equal %w[soul///index.js soul///test/] + end + + it "must return files and directories given soul/test" do + touch File.join(@dir, "node_modules", "soul", "test", "test.js") + touch File.join(@dir, "node_modules", "soul", "test", "helpers.js") + glob("soul/test").must_equal %w[soul/test/helpers.js soul/test/test.js] + end + end + end + + describe "node#lib#version" do + it "should return current Node's version" do + set_node_version "0.13.37" + $vim.echo("node#lib#version()").must_equal "0.13.37" + end + end +end diff --git a/dotfiles/.local/share/nvim/site/test/autoload_test.rb b/dotfiles/.local/share/nvim/site/test/autoload_test.rb new file mode 100644 index 0000000..aa9bb49 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/autoload_test.rb @@ -0,0 +1,561 @@ +require_relative "./helper" +require "json" + +describe "Autoloaded" do + include WithTemporaryDirectory + + before do + FileUtils.touch File.join(@dir, "package.json") + end + + after do + $vim.command("windo wincmd c") + end + + describe "Autocommand" do + it "must fire user autcommand \"Node\"" do + $vim.command "au User Node let node_autocommand = 1337" + $vim.edit File.join(@dir, "other.js") + $vim.echo(%(g:node_autocommand)).must_equal "1337" + end + end + + describe "Goto file" do + it "must define plug mapping in non-JavaScript files" do + $vim.edit File.join(@dir, "README") + $vim.echo(%(maparg("<Plug>NodeGotoFile", "n"))).wont_equal "" + end + + it "must not be mapped in non-JavaScript files" do + $vim.edit File.join(@dir, "README") + $vim.echo(%(hasmapto("<Plug>NodeGotoFile"))).must_equal "0" + end + + it "must edit README.txt" do + touch File.join(@dir, "index.js"), %(// Please read README.txt) + touch File.join(@dir, "README.txt") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$gf" + $vim.echo(%(bufname("%"))).must_equal File.join(@dir, "README.txt") + end + + it "must edit README before README.js" do + touch File.join(@dir, "index.js"), "// Please read README" + touch File.join(@dir, "README") + touch File.join(@dir, "README.js") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$gf" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "README") + end + + it "must edit ./README.txt relative to file" do + touch File.join(@dir, "foo", "index.js"), %(// Please read ./README.txt) + touch File.join(@dir, "foo", "README.txt") + + $vim.edit File.join(@dir, "foo", "index.js") + $vim.feedkeys "$gf" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "foo", "README.txt") + end + + it "must edit /.../README.txt" do + touch File.join(@dir, "index.js"), %(// Read #@dir/lib/README.txt) + touch File.join(@dir, "lib", "README.txt") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$gf" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "lib", "README.txt") + end + + it "must edit ./other.js relative to file" do + touch File.join(@dir, "foo", "index.js"), %(require("./other")) + touch File.join(@dir, "foo", "other.js") + + $vim.edit File.join(@dir, "foo", "index.js") + $vim.feedkeys "f.gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "foo", "other.js") + end + + it "must edit ./index.js given ." do + touch File.join(@dir, "other.js"), %(require(".")) + touch File.join(@dir, "index.js") + + $vim.edit File.join(@dir, "other.js") + $vim.feedkeys "f.gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ./index.js given ./" do + touch File.join(@dir, "other.js"), %(require("./")) + touch File.join(@dir, "index.js") + + $vim.edit File.join(@dir, "other.js") + $vim.feedkeys "f.gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ../index.js given .." do + touch File.join(@dir, "foo", "other.js"), %(require("..")) + touch File.join(@dir, "index.js") + + $vim.edit File.join(@dir, "foo", "other.js") + $vim.feedkeys "f.gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ../index.js given ../" do + touch File.join(@dir, "foo", "other.js"), %(require("../")) + touch File.join(@dir, "index.js") + + $vim.edit File.join(@dir, "foo", "other.js") + $vim.feedkeys "f.gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ./node_modules/foo/index.js given foo" do + touch File.join(@dir, "index.js"), %(require("foo")) + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must edit ./node_modules/@scope/foo/index.js given @scope/foo" do + touch File.join(@dir, "index.js"), %(require("@scope/foo")) + target = File.join(@dir, "node_modules", "@scope", "foo", "index.js") + touch target + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must edit ./foo.js given root/foo with root as symlink" do + touch File.join(@dir, "index.js"), %(require("root/foo")) + target = touch File.join(@dir, "foo.js") + FileUtils.mkpath File.join(@dir, "node_modules") + File.symlink "..", File.join(@dir, "node_modules", "root") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must relativize paths" do + touch File.join(@dir, "index.js"), %(require("root/foo")) + target = touch File.join(@dir, "foo.js") + FileUtils.mkpath File.join(@dir, "node_modules") + File.symlink "..", File.join(@dir, "node_modules", "root") + + $vim.edit File.join(@dir, "index.js") + $vim.command %(:cd %:h) + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal File.basename(target) + end + + it "must not show an error when searching for nothing" do + touch File.join(@dir, "index.js"), %("") + + $vim.edit File.join(@dir, "index.js") + $vim.command(%(let v:errmsg = "")) + $vim.feedkeys "gf" + + error = $vim.command("let v:errmsg").sub(/^\S+\s*/, "") + error.must_equal "" + end + + it "must show error when searching for a non-existent file" do + touch File.join(@dir, "index.js"), %(require("new")) + + $vim.edit File.join(@dir, "index.js") + $vim.command(%(let v:errmsg = "")) + $vim.feedkeys "$hhgf" + + error = $vim.command("let v:errmsg").sub(/^\S+\s*/, "") + error.must_equal %(E447: Can't find file "new" in path) + end + + it "must find when filetype is JavaScript and file exists" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + touch File.join(@dir, "index.js"), %(require("foo")) + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must find when filetype is JavaScript and file new" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + $vim.edit File.join(@dir, "index.js") + $vim.insert %(require("foo")) + $vim.normal + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must find when filetype is JSON" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + # NOTE: Use an extensionless file and set ft manually to not have + # filetype.vim set its filetype to JavaScript automatically. + $vim.command("au BufReadPre package set ft=json") + touch File.join(@dir, "package"), %({"dependencies": {"foo": "1.x"}}) + $vim.edit File.join(@dir, "package") + $vim.echo("&filetype").must_equal "json" + + $vim.feedkeys "/foo\\<CR>gf" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal target + end + + it "must find when filetype set to JavaScript after open" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + touch File.join(@dir, "index.react"), %(require("foo")) + $vim.edit File.join(@dir, "index.react") + $vim.echo("&filetype").must_equal "" + $vim.command("setfiletype javascript") + $vim.echo("&filetype").must_equal "javascript" + + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must find when filetype set to JSX after open" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + touch File.join(@dir, "index.react"), %(require("foo")) + $vim.edit File.join(@dir, "index.react") + $vim.echo("&filetype").must_equal "" + $vim.command("setfiletype jsx") + $vim.echo("&filetype").must_equal "jsx" + + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + it "must find when filetype set to JavaScript and Foo after open" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + touch File.join(@dir, "index.react"), %(require("foo")) + $vim.edit File.join(@dir, "index.react") + $vim.echo("&filetype").must_equal "" + $vim.command("setfiletype javascript.foo") + $vim.echo("&filetype").must_equal "javascript.foo" + + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + + # Ensure the autocommand detects both orderings. + it "must find when filetype set to Foo and JavaScript after open" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + + touch File.join(@dir, "index.react"), %(require("foo")) + $vim.edit File.join(@dir, "index.react") + $vim.echo("&filetype").must_equal "" + $vim.command("setfiletype foo.javascript") + $vim.echo("&filetype").must_equal "foo.javascript" + + $vim.feedkeys "$hhgf" + $vim.echo(%(bufname("%"))).must_equal target + end + end + + describe "Goto file with split" do + it "must edit file in a new split" do + touch File.join(@dir, "index.js"), %(require("./other")) + touch File.join(@dir, "other.js") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "f.\\<C-w>f" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "other.js") + $vim.echo(%(winnr("$"))).must_equal "2" + end + end + + describe "Goto file with tab" do + it "must edit file in a new tab" do + touch File.join(@dir, "index.js"), %(require("./other")) + touch File.join(@dir, "other.js") + + $vim.edit File.join(@dir, "index.js") + $vim.feedkeys "f.\\<C-w>gf" + + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "other.js") + $vim.echo(%(tabpagenr("$"))).must_equal "2" + end + end + + describe "Include file search pattern" do + it "must find matches given a require" do + touch File.join(@dir, "index.js"), <<-end.gsub(/^\s+/, "") + var awesome = require("foo") + awesome() + end + + definition = %(module.exports = function awesome() { return 1337 }) + touch File.join(@dir, "node_modules", "foo", "index.js"), definition + + $vim.edit File.join(@dir, "index.js") + $vim.command("normal G[i").must_equal definition + end + + it "must find matches given a relative require" do + touch File.join(@dir, "index.js"), <<-end.gsub(/^\s+/, "") + var awesome = require("./other") + awesome() + end + + definition = %(module.exports = function awesome() { return 1337 }) + touch File.join(@dir, "other.js"), definition + + $vim.edit File.join(@dir, "index.js") + $vim.command("normal G[i").must_equal definition + end + + it "must find matches given a relative require in another directory" do + touch File.join(@dir, "foo", "index.js"), <<-end.gsub(/^\s+/, "") + var awesome = require("./other") + awesome() + end + + definition = %(module.exports = function awesome() { return 1337 }) + touch File.join(@dir, "foo", "other.js"), definition + + $vim.edit File.join(@dir, "foo", "index.js") + $vim.command("normal G[i").must_equal definition + end + end + + describe ":Nedit" do + # NOTE: Test from a non-JavaScript file everywhere to make sure there are + # no dependencies on JavaScript specific settings. + FULL_COMMAND_MATCH = "2" + + it "must be available in non-JavaScript files" do + $vim.edit File.join(@dir, "README.txt") + $vim.echo("exists(':Nedit')").must_equal FULL_COMMAND_MATCH + end + + it "must be available in JavaScript files" do + $vim.edit File.join(@dir, "index.js") + $vim.echo("exists(':Nedit')").must_equal FULL_COMMAND_MATCH + end + + it "must edit ./README.txt" do + touch File.join(@dir, "README.txt") + $vim.edit File.join(@dir, "CHANGELOG.txt") + $vim.command "Nedit ./README.txt" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "README.txt") + end + + it "must edit ./README.txt relative to node_root" do + touch File.join(@dir, "README.txt") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "CHANGELOG.txt") + $vim.command "Nedit ./README.txt" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "README.txt") + end + + it "must edit /.../README.txt" do + touch File.join(@dir, "lib", "README.txt") + $vim.edit File.join(@dir, "CHANGELOG.txt") + $vim.command "Nedit #@dir/lib/README.txt" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "lib", "README.txt") + end + + it "must edit ./other.js relative to node_root" do + touch File.join(@dir, "other.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "CHANGELOG.txt") + $vim.command "Nedit ./other" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "other.js") + end + + it "must edit ./index.js given ." do + touch File.join(@dir, "index.js") + $vim.edit File.join(@dir, "CHANGELOG.txt") + $vim.command "Nedit ." + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ./index.js given . relative to node_root" do + touch File.join(@dir, "index.js") + Dir.mkdir File.join(@dir, "lib") + $vim.edit File.join(@dir, "lib", "CHANGELOG.txt") + $vim.command "Nedit ." + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit ./index.js given ./" do + touch File.join(@dir, "index.js") + $vim.edit File.join(@dir, "CHANGELOG.txt") + $vim.command "Nedit ./" + bufname = File.realpath($vim.echo(%(bufname("%")))) + bufname.must_equal File.join(@dir, "index.js") + end + + it "must edit /node_modules/foo/index.js given foo" do + target = touch File.join(@dir, "node_modules", "foo", "index.js") + $vim.edit File.join(@dir, "README.txt") + $vim.command("Nedit foo") + $vim.echo(%(bufname("%"))).must_equal target + end + + describe "completion" do + after do + $vim.command("set wildignorecase&") + $vim.command("set fileignorecase&") + end + + def complete(cmd) + cmdline = $vim.command(%(silent! normal! :#{cmd}e)) + cmdline.sub(/^:\w+\s+/, "") + end + + public_core_modules = CORE_MODULES.select {|m| m[0] != "_" } + private_core_modules = CORE_MODULES.select {|m| m[0] == "_" } + + it "must return files, directories, modules" do + Dir.mkdir File.join(@dir, "node_modules") + Dir.mkdir File.join(@dir, "node_modules", "require-guard") + Dir.mkdir File.join(@dir, "node_modules", "export") + Dir.mkdir File.join(@dir, "node_modules", "soul") + touch File.join(@dir, "index.js") + + $vim.edit File.join(@dir, "README.txt") + files = %w[export/ require-guard/ soul/ ./index.js ./package.json] + all = public_core_modules + files + complete("Nedit ").split.sort.must_equal all.sort + end + + it "must return only public core modules" do + $vim.edit File.join(@dir, "README.txt") + modules = public_core_modules + ["./package.json"] + complete("Nedit ").must_equal modules.join(" ") + end + + it "must return private core modules if explicitly asked" do + $vim.edit File.join(@dir, "README.txt") + complete("Nedit _").must_equal private_core_modules.join(" ") + end + + it "must return only matching modules" do + Dir.mkdir File.join(@dir, "node_modules") + Dir.mkdir File.join(@dir, "node_modules", "export") + Dir.mkdir File.join(@dir, "node_modules", "soul") + Dir.mkdir File.join(@dir, "node_modules", "soulstash") + + $vim.edit File.join(@dir, "README.txt") + modules = "smalloc stream string_decoder sys soul/ soulstash/" + complete("Nedit s").must_equal modules + end + + it "must not return modules with matching bit in the middle" do + Dir.mkdir File.join(@dir, "node_modules") + Dir.mkdir File.join(@dir, "node_modules", "soul") + Dir.mkdir File.join(@dir, "node_modules", "soulstash") + Dir.mkdir File.join(@dir, "node_modules", "asoul") + + $vim.edit File.join(@dir, "README.txt") + complete("Nedit sou").must_equal "soul/ soulstash/" + end + + it "must return files and directories in module's directory" do + touch File.join(@dir, "node_modules", "soul", "index.js") + touch File.join(@dir, "node_modules", "soul", "test", "test.js") + $vim.edit File.join(@dir, "README.txt") + complete("Nedit soul/").must_equal "soul/index.js soul/test/" + end + + it "must return files and directories given a double slash" do + touch File.join(@dir, "node_modules", "soul", "index.js") + touch File.join(@dir, "node_modules", "soul", "test", "test.js") + $vim.edit File.join(@dir, "README.txt") + complete("Nedit soul//").must_equal "soul//index.js soul//test/" + end + + it "must return files case-insensitively given &fileignorecase" do + skip if $vim.echo(%(exists("&fileignorecase"))) != "1" + + $vim.command("set fileignorecase") + $vim.command("set nowildignorecase") + + touch File.join(@dir, "node_modules", "soul", "index.js") + touch File.join(@dir, "node_modules", "soul", "CHANGELOG") + $vim.edit File.join(@dir, "README.txt") + complete("Nedit soul/chan").must_equal "soul/CHANGELOG" + end + + it "must return files case-insensitively given only &wildignorecase" do + skip if $vim.echo(%(exists("&wildignorecase"))) != "1" + + $vim.command("set nofileignorecase") + $vim.command("set wildignorecase") + + touch File.join(@dir, "node_modules", "soul", "index.js") + touch File.join(@dir, "node_modules", "soul", "CHANGELOG") + $vim.edit File.join(@dir, "README.txt") + complete("Nedit soul/chan").must_equal "soul/CHANGELOG" + end + end + end + + describe ":Nopen" do + it "must edit and lcd to module's directory" do + touch File.join(@dir, "node_modules", "foo", "package.json") + touch File.join(@dir, "node_modules", "foo", "index.js") + + $vim.edit File.join(@dir, "README.txt") + $vim.command("vsplit") + + $vim.command("Nopen foo") + $vim.echo(%(bufname("%"))).must_equal "index.js" + $vim.command("pwd").must_equal File.join(@dir, "node_modules", "foo") + + $vim.command("wincmd p") + $vim.command("pwd").must_equal Dir.pwd + end + + it "must edit and lcd to module's root directory" do + touch File.join(@dir, "node_modules", "foo", "package.json") + touch File.join(@dir, "node_modules", "foo", "lib", "utils.js") + + $vim.edit File.join(@dir, "README.txt") + $vim.command("vsplit") + + $vim.command("Nopen foo/lib/utils") + $vim.echo(%(bufname("%"))).must_equal "lib/utils.js" + $vim.command("pwd").must_equal File.join(@dir, "node_modules", "foo") + + $vim.command("wincmd p") + $vim.command("pwd").must_equal Dir.pwd + end + end +end diff --git a/dotfiles/.local/share/nvim/site/test/ftdetect_test.rb b/dotfiles/.local/share/nvim/site/test/ftdetect_test.rb new file mode 100644 index 0000000..b28326e --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/ftdetect_test.rb @@ -0,0 +1,45 @@ +require_relative "./helper" + +describe "Ftdetect" do + [ + "#!/usr/bin/env node", + "#!/usr/bin/env node --harmony-generators", + "#!/usr/local/bin/env node", + "#!/usr/local/bin/env node --harmony-generators", + "#!/usr/bin/node", + "#!/usr/bin/node --harmony-generators", + "#!/usr/local/bin/node", + "#!/usr/local/bin/node --harmony-generators", + + ].each do |shebang| + it %(must detect a file with "#{shebang}" shebang as JavaScript) do + file = Tempfile.new("bang") + file.write shebang + $/ + file.close + $vim.edit file.path + $vim.echo("&ft").must_equal "javascript" + end + end + + [ + "#!/usr/bin/env noder", + "#!/usr/bin/noder", + + ].each do |shebang| + it %(must not detect a file with "#{shebang}" shebang as JavaScript) do + file = Tempfile.new("bang") + file.write shebang + $/ + file.close + $vim.edit file.path + $vim.echo("&ft").wont_equal "javascript" + end + end + + it "must not detect a .c file as JavaScript even with Node's shebang" do + file = Tempfile.new(%w[tea .c]) + file.write "#!/usr/bin/node" + $/ + file.close + $vim.edit file.path + $vim.echo("&ft").wont_equal "javascript" + end +end diff --git a/dotfiles/.local/share/nvim/site/test/helper.rb b/dotfiles/.local/share/nvim/site/test/helper.rb new file mode 100644 index 0000000..5c50977 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/helper.rb @@ -0,0 +1,54 @@ +require "minitest/autorun" +require "vimrunner" +require "fileutils" +require "tempfile" + +MiniTest::Unit::TestCase.define_singleton_method(:test_order) do :alpha end + +begin + require "minitest/reporters" + MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new +rescue LoadError +end + +$vimrc = File.expand_path("../vimrc", __FILE__) +$vim = Vimrunner::Server.new(:vimrc => $vimrc).start +Minitest::Unit.after_tests { $vim.kill } + +module WithTemporaryDirectory + def self.included(base) + require "tmpdir" + end + + def setup + super + # Mac has the temporary directory symlinked, so need File.realpath to + # match the paths that Vim returns. + @dir = File.realpath(Dir.mktmpdir) + end + + def teardown + FileUtils.remove_entry_secure @dir + super + end +end + +def touch(path, contents = nil) + FileUtils.mkpath File.dirname(path) + + if contents.nil? || contents.empty? + FileUtils.touch(path) + else + File.open(path, "w") {|f| f.write contents } + end + + path +end + +CORE_MODULES = %w[_debugger _http_agent _http_client _http_common + _http_incoming _http_outgoing _http_server _linklist _stream_duplex + _stream_passthrough _stream_readable _stream_transform _stream_writable + _tls_legacy _tls_wrap assert buffer child_process cluster console + constants crypto dgram dns domain events freelist fs http https module + net node os path punycode querystring readline repl smalloc stream + string_decoder sys timers tls tty url util vm zlib] diff --git a/dotfiles/.local/share/nvim/site/test/plugin_test.rb b/dotfiles/.local/share/nvim/site/test/plugin_test.rb new file mode 100644 index 0000000..722c287 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/plugin_test.rb @@ -0,0 +1,85 @@ +require_relative "./helper" + +describe "Plugin" do + include WithTemporaryDirectory + + describe "b:node_root" do + it "must be set when in same directory with package.json" do + FileUtils.touch File.join(@dir, "package.json") + $vim.edit File.join(@dir, "index.js") + $vim.echo("b:node_root").must_equal @dir + end + + it "must be set when in same directory with node_modules" do + Dir.mkdir File.join(@dir, "node_modules") + $vim.edit File.join(@dir, "index.js") + $vim.echo("b:node_root").must_equal @dir + end + + it "must be set when ancestor directory has package.json" do + FileUtils.touch File.join(@dir, "package.json") + + nested = File.join(@dir, "lib", "awesomeness") + FileUtils.mkdir_p nested + $vim.edit File.join(nested, "index.js") + $vim.echo("b:node_root").must_equal @dir + end + + it "must be set when ancestor directory has node_modules" do + Dir.mkdir File.join(@dir, "node_modules") + + nested = File.join(@dir, "lib", "awesomeness") + FileUtils.mkdir_p nested + $vim.edit File.join(nested, "index.js") + $vim.echo("b:node_root").must_equal @dir + end + + it "must be set also for other filetypes" do + FileUtils.touch File.join(@dir, "package.json") + + $vim.edit File.join(@dir, "README.txt") + $vim.echo("b:node_root").must_equal @dir + end + + it "must be set in nested Node projects" do + nested = File.join(@dir, "node_modules", "require-guard") + FileUtils.mkdir_p nested + FileUtils.touch File.join(nested, "package.json") + + test = File.join(nested, "test") + FileUtils.mkdir_p test + $vim.edit File.join(test, "index_test.js") + $vim.echo("b:node_root").must_equal nested + end + + it "must not be set when no ancestor has one" do + $vim.edit File.join(@dir, "index_test.js") + $vim.echo(%(exists("b:node_root"))).must_equal "0" + end + + it "must be set from file, not working directory" do + $vim.command "cd #{@dir}" + FileUtils.touch File.join(@dir, "package.json") + + nested = File.join(@dir, "node_modules", "require-guard") + FileUtils.mkdir_p nested + FileUtils.touch File.join(nested, "package.json") + + $vim.edit File.join(nested, "index_test.js") + $vim.echo("b:node_root").must_equal nested + end + + it "must detect directory as Node's when opening Vim" do + begin + Dir.chdir @dir + FileUtils.touch File.join(@dir, "package.json") + + vim = Vimrunner::Server.new(:vimrc => $vimrc).start + vim.command("pwd").must_equal @dir + vim.echo("b:node_root").must_equal @dir + ensure + vim.kill if vim + end + end + end +end diff --git a/dotfiles/.local/share/nvim/site/test/vimrc b/dotfiles/.local/share/nvim/site/test/vimrc new file mode 100644 index 0000000..2f05b18 --- /dev/null +++ b/dotfiles/.local/share/nvim/site/test/vimrc @@ -0,0 +1,14 @@ +set nocompatible +set noswapfile +set nobackup +set hidden + +set runtimepath-=~/.vim +set runtimepath-=~/.vim/after +let &runtimepath = expand("<sfile>:p:h:h") . "," . &runtimepath + +filetype plugin indent on +syntax on + +set columns=80 lines=24 +winpos 1337 0 |