commit 389ce64dffe271cf0493cf613d0128055d55a0fc
parent 641aee7737dae469ade75a0f2c0577d182672782
Author: Jake Bauer <jbauer@paritybit.ca>
Date: Tue, 7 Mar 2023 20:40:15 -0500
Add vim-gutentags
Diffstat:
18 files changed, 3115 insertions(+), 0 deletions(-)
diff --git a/.config/nvim/init.vim b/.config/nvim/init.vim
@@ -6,6 +6,11 @@
let mapleader = ","
+" Plugin Settings
+let g:buftabline_show = 1
+let g:gutentags_project_root = ['Makefile']
+let g:gutentags_add_default_project_roots = 1
+
" Syntax Highlighting and Colourscheme
syntax on
colorscheme monochrome-light
diff --git a/.config/nvim/pack/bundle/start/vim-fastline/plugin/statusline.vim b/.config/nvim/pack/bundle/start/vim-fastline/plugin/statusline.vim
@@ -98,6 +98,7 @@ function! StatusLine()
let statusline .= "%#Modi# %{CheckModified(&modified)} "
let statusline .= "%#Base#"
let statusline .= "%="
+ let statusline .= "%{gutentags#statusline('[', ']')} "
let statusline .= "%#FileType# %{CheckFileType(&filetype)} "
let statusline .= "%#LineCol# %p%% Ln %l/%L : %c "
return statusline
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/LICENSE b/.config/nvim/pack/bundle/start/vim-gutentags/LICENSE
@@ -0,0 +1,23 @@
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Ludovic Chabant
+
+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.
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags.vim b/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags.vim
@@ -0,0 +1,749 @@
+" gutentags.vim - Automatic ctags management for Vim
+
+" Utilities {{{
+
+function! gutentags#chdir(path)
+ if has('nvim')
+ let chdir = haslocaldir() ? 'lcd' : haslocaldir(-1, 0) ? 'tcd' : 'cd'
+ else
+ let chdir = haslocaldir() ? ((haslocaldir() == 1) ? 'lcd' : 'tcd') : 'cd'
+ endif
+ execute chdir fnameescape(a:path)
+endfunction
+
+" Throw an exception message.
+function! gutentags#throw(message)
+ throw "gutentags: " . a:message
+endfunction
+
+" Show an error message.
+function! gutentags#error(message)
+ let v:errmsg = "gutentags: " . a:message
+ echoerr v:errmsg
+endfunction
+
+" Show a warning message.
+function! gutentags#warning(message)
+ echohl WarningMsg
+ echom "gutentags: " . a:message
+ echohl None
+endfunction
+
+" Prints a message if debug tracing is enabled.
+function! gutentags#trace(message, ...)
+ if g:gutentags_trace || (a:0 && a:1)
+ let l:message = "gutentags: " . a:message
+ echom l:message
+ endif
+endfunction
+
+" Strips the ending slash in a path.
+function! gutentags#stripslash(path)
+ return fnamemodify(a:path, ':s?[/\\]$??')
+endfunction
+
+" Normalizes the slashes in a path.
+function! gutentags#normalizepath(path)
+ if exists('+shellslash') && &shellslash
+ return substitute(a:path, '\v/', '\\', 'g')
+ elseif has('win32')
+ return substitute(a:path, '\v/', '\\', 'g')
+ else
+ return a:path
+ endif
+endfunction
+
+" Shell-slashes the path (opposite of `normalizepath`).
+function! gutentags#shellslash(path)
+ if exists('+shellslash') && !&shellslash
+ return substitute(a:path, '\v\\', '/', 'g')
+ else
+ return a:path
+ endif
+endfunction
+
+" Gets a file path in the correct `plat` folder.
+function! gutentags#get_plat_file(filename) abort
+ return g:gutentags_plat_dir . a:filename . g:gutentags_script_ext
+endfunction
+
+" Gets a file path in the resource folder.
+function! gutentags#get_res_file(filename) abort
+ return g:gutentags_res_dir . a:filename
+endfunction
+
+" Generate a path for a given filename in the cache directory.
+function! gutentags#get_cachefile(root_dir, filename) abort
+ if gutentags#is_path_rooted(a:filename)
+ return a:filename
+ endif
+ let l:tag_path = gutentags#stripslash(a:root_dir) . '/' . a:filename
+ if g:gutentags_cache_dir != ""
+ " Put the tag file in the cache dir instead of inside the
+ " project root.
+ let l:tag_path = g:gutentags_cache_dir . '/' .
+ \tr(l:tag_path, '\/: ', '---_')
+ let l:tag_path = substitute(l:tag_path, '/\-', '/', '')
+ let l:tag_path = substitute(l:tag_path, '[\-_]*$', '', '')
+ endif
+ let l:tag_path = gutentags#normalizepath(l:tag_path)
+ return l:tag_path
+endfunction
+
+" Makes sure a given command starts with an executable that's in the PATH.
+function! gutentags#validate_cmd(cmd) abort
+ if !empty(a:cmd) && executable(split(a:cmd)[0])
+ return a:cmd
+ endif
+ return ""
+endfunction
+
+" Makes an appropriate command line for use with `job_start` by converting
+" a list of possibly quoted arguments into a single string on Windows, or
+" into a list of unquoted arguments on Unix/Mac.
+if has('win32') || has('win64')
+ function! gutentags#make_args(cmd) abort
+ if &shell == 'pwsh' || &shell == 'powershell'
+ return '& ' . join(a:cmd, ' ')
+ else
+ return join(a:cmd, ' ')
+ endif
+ endfunction
+else
+ function! gutentags#make_args(cmd) abort
+ let l:outcmd = []
+ for cmdarg in a:cmd
+ " Thanks Vimscript... you can use negative integers for strings
+ " in the slice notation, but not for indexing characters :(
+ let l:arglen = strlen(cmdarg)
+ if (cmdarg[0] == '"' && cmdarg[l:arglen - 1] == '"') ||
+ \(cmdarg[0] == "'" && cmdarg[l:arglen - 1] == "'")
+ " This was quoted, so there are probably things to escape.
+ let l:escapedarg = cmdarg[1:-2] " substitute(cmdarg[1:-2], '\ ', '\\ ', 'g')
+ call add(l:outcmd, l:escapedarg)
+ else
+ call add(l:outcmd, cmdarg)
+ endif
+ endfor
+ return l:outcmd
+ endfunction
+endif
+
+" Returns whether a path is rooted.
+if has('win32') || has('win64')
+ function! gutentags#is_path_rooted(path) abort
+ return len(a:path) >= 2 && (
+ \a:path[0] == '/' || a:path[0] == '\' || a:path[1] == ':')
+ endfunction
+else
+ function! gutentags#is_path_rooted(path) abort
+ return !empty(a:path) && a:path[0] == '/'
+ endfunction
+endif
+
+" }}}
+
+" Gutentags Setup {{{
+
+let s:known_files = []
+let s:known_projects = {}
+
+function! s:cache_project_root(path) abort
+ let l:result = {}
+
+ for proj_info in g:gutentags_project_info
+ let l:filematch = get(proj_info, 'file', '')
+ if l:filematch != '' && filereadable(a:path . '/'. l:filematch)
+ let l:result = copy(proj_info)
+ break
+ endif
+
+ let l:globmatch = get(proj_info, 'glob', '')
+ if l:globmatch != '' && glob(a:path . '/' . l:globmatch) != ''
+ let l:result = copy(proj_info)
+ break
+ endif
+ endfor
+
+ let s:known_projects[a:path] = l:result
+endfunction
+
+function! gutentags#get_project_file_list_cmd(path) abort
+ if type(g:gutentags_file_list_command) == type("")
+ return gutentags#validate_cmd(g:gutentags_file_list_command)
+ elseif type(g:gutentags_file_list_command) == type({})
+ let l:markers = get(g:gutentags_file_list_command, 'markers', [])
+ if type(l:markers) == type({})
+ for [marker, file_list_cmd] in items(l:markers)
+ if !empty(globpath(a:path, marker, 1))
+ return gutentags#validate_cmd(file_list_cmd)
+ endif
+ endfor
+ endif
+ return get(g:gutentags_file_list_command, 'default', "")
+ endif
+ return ""
+endfunction
+
+" Finds the first directory with a project marker by walking up from the given
+" file path.
+function! gutentags#get_project_root(path) abort
+ if g:gutentags_project_root_finder != ''
+ return call(g:gutentags_project_root_finder, [a:path])
+ endif
+ return gutentags#default_get_project_root(a:path)
+endfunction
+
+" Default implementation for finding project markers... useful when a custom
+" finder (`g:gutentags_project_root_finder`) wants to fallback to the default
+" behaviour.
+function! gutentags#default_get_project_root(path) abort
+ let l:path = gutentags#stripslash(a:path)
+ let l:previous_path = ""
+ let l:markers = g:gutentags_project_root[:]
+ if g:gutentags_add_ctrlp_root_markers && exists('g:ctrlp_root_markers')
+ for crm in g:ctrlp_root_markers
+ if index(l:markers, crm) < 0
+ call add(l:markers, crm)
+ endif
+ endfor
+ endif
+ while l:path != l:previous_path
+ for root in l:markers
+ if !empty(globpath(l:path, root, 1))
+ let l:proj_dir = simplify(fnamemodify(l:path, ':p'))
+ let l:proj_dir = gutentags#stripslash(l:proj_dir)
+ if l:proj_dir == ''
+ call gutentags#trace("Found project marker '" . root .
+ \"' at the root of your file-system! " .
+ \" That's probably wrong, disabling " .
+ \"gutentags for this file...",
+ \1)
+ call gutentags#throw("Marker found at root, aborting.")
+ endif
+ for ign in g:gutentags_exclude_project_root
+ if l:proj_dir == ign
+ call gutentags#trace(
+ \"Ignoring project root '" . l:proj_dir .
+ \"' because it is in the list of ignored" .
+ \" projects.")
+ call gutentags#throw("Ignore project: " . l:proj_dir)
+ endif
+ endfor
+ return l:proj_dir
+ endif
+ endfor
+ let l:previous_path = l:path
+ let l:path = fnamemodify(l:path, ':h')
+ endwhile
+ call gutentags#throw("Can't figure out what tag file to use for: " . a:path)
+endfunction
+
+" Get info on the project we're inside of.
+function! gutentags#get_project_info(path) abort
+ return get(s:known_projects, a:path, {})
+endfunction
+
+" Setup gutentags for the current buffer.
+function! gutentags#setup_gutentags() abort
+ if exists('b:gutentags_files') && !g:gutentags_debug
+ " This buffer already has gutentags support.
+ return
+ endif
+
+ " Don't setup gutentags for anything that's not a normal buffer
+ " (so don't do anything for help buffers and quickfix windows and
+ " other such things)
+ " Also don't do anything for the default `[No Name]` buffer you get
+ " after starting Vim.
+ if &buftype != '' ||
+ \(bufname('%') == '' && !g:gutentags_generate_on_empty_buffer)
+ return
+ endif
+
+ " Don't setup gutentags for things that don't need it, or that could
+ " cause problems.
+ if index(g:gutentags_exclude_filetypes, &filetype) >= 0
+ return
+ endif
+
+ " Let the user specify custom ways to disable Gutentags.
+ if g:gutentags_init_user_func != '' &&
+ \!call(g:gutentags_init_user_func, [expand('%:p')])
+ call gutentags#trace("Ignoring '" . bufname('%') . "' because of " .
+ \"custom user function.")
+ return
+ endif
+
+ " Try and find what tags file we should manage.
+ call gutentags#trace("Scanning buffer '" . bufname('%') . "' for gutentags setup...")
+ try
+ let l:buf_dir = expand('%:p:h', 1)
+ if g:gutentags_resolve_symlinks
+ let l:buf_dir = fnamemodify(resolve(expand('%:p', 1)), ':p:h')
+ endif
+ if !exists('b:gutentags_root')
+ let b:gutentags_root = gutentags#get_project_root(l:buf_dir)
+ endif
+ if !len(b:gutentags_root)
+ call gutentags#trace("no valid project root.. no gutentags support.")
+ return
+ endif
+ if filereadable(b:gutentags_root . '/.notags')
+ call gutentags#trace("'.notags' file found... no gutentags support.")
+ return
+ endif
+
+ if !has_key(s:known_projects, b:gutentags_root)
+ call s:cache_project_root(b:gutentags_root)
+ endif
+ if g:gutentags_trace
+ let l:projnfo = gutentags#get_project_info(b:gutentags_root)
+ if l:projnfo != {}
+ call gutentags#trace("Setting project type to ".l:projnfo['type'])
+ else
+ call gutentags#trace("No specific project type.")
+ endif
+ endif
+
+ let b:gutentags_files = {}
+ for module in g:gutentags_modules
+ call call("gutentags#".module."#init", [b:gutentags_root])
+ endfor
+ catch /^gutentags\:/
+ call gutentags#trace("No gutentags support for this buffer.")
+ return
+ endtry
+
+ " We know what tags file to manage! Now set things up.
+ call gutentags#trace("Setting gutentags for buffer '".bufname('%')."'")
+
+ " Autocommands for updating the tags on save.
+ " We need to pass the buffer number to the callback function in the rare
+ " case that the current buffer is changed by another `BufWritePost`
+ " callback. This will let us get that buffer's variables without causing
+ " errors.
+ let l:bn = bufnr('%')
+ execute 'augroup gutentags_buffer_' . l:bn
+ execute ' autocmd!'
+ execute ' autocmd BufWritePost <buffer=' . l:bn . '> call s:write_triggered_update_tags(' . l:bn . ')'
+ execute 'augroup end'
+
+ " Miscellaneous commands.
+ command! -buffer -bang GutentagsUpdate :call s:manual_update_tags(<bang>0)
+
+ " Add these tags files to the known tags files.
+ for module in keys(b:gutentags_files)
+ let l:tagfile = b:gutentags_files[module]
+ let l:found = index(s:known_files, l:tagfile)
+ if l:found < 0
+ call add(s:known_files, l:tagfile)
+
+ " Generate this new file depending on settings and stuff.
+ if g:gutentags_enabled
+ if g:gutentags_generate_on_missing && !filereadable(l:tagfile)
+ call gutentags#trace("Generating missing tags file: " . l:tagfile)
+ call s:update_tags(l:bn, module, 1, 1)
+ elseif g:gutentags_generate_on_new
+ call gutentags#trace("Generating tags file: " . l:tagfile)
+ call s:update_tags(l:bn, module, 1, 1)
+ endif
+ endif
+ endif
+ endfor
+endfunction
+
+" Set a variable on exit so that we don't complain when a job gets killed.
+function! gutentags#on_vim_leave_pre() abort
+ let g:__gutentags_vim_is_leaving = 1
+endfunction
+
+function! gutentags#on_vim_leave() abort
+ if has('win32') && !has('nvim')
+ " Vim8 doesn't seem to be killing child processes soon enough for
+ " us to clean things up inside this plugin, so do it ourselves.
+ " TODO: test other platforms and other vims
+ for module in g:gutentags_modules
+ for upd_info in s:update_in_progress[module]
+ let l:job = upd_info[1]
+ call job_stop(l:job, "term")
+ let l:status = job_status(l:job)
+ if l:status == "run"
+ call job_stop(l:job, "kill")
+ endif
+ endfor
+ endfor
+ endif
+endfunction
+
+" }}}
+
+" Job Management {{{
+
+" List of queued-up jobs, and in-progress jobs, per module.
+let s:update_queue = {}
+let s:update_in_progress = {}
+for module in g:gutentags_modules
+ let s:update_queue[module] = []
+ let s:update_in_progress[module] = []
+endfor
+
+" Adds a started job to the list of ongoing updates.
+" Must pass the tags file being created/updated, and the job data as
+" returned by the gutentags#start_job function
+function! gutentags#add_job(module, tags_file, data) abort
+ call add(s:update_in_progress[a:module], [a:tags_file, a:data])
+endfunction
+
+" Finds an ongoing job by tags file
+function! gutentags#find_job_index_by_tags_file(module, tags_file) abort
+ let l:idx = -1
+ for upd_info in s:update_in_progress[a:module]
+ let l:idx += 1
+ if upd_info[0] == a:tags_file
+ return l:idx
+ endif
+ endfor
+ return -1
+endfunction
+
+" Finds an ongoing job by job data
+function! gutentags#find_job_index_by_data(module, data) abort
+ let l:idx = -1
+ for upd_info in s:update_in_progress[a:module]
+ let l:idx += 1
+ if upd_info[1] == a:data
+ return l:idx
+ endif
+ endfor
+ return -1
+endfunction
+
+" Gets the tags file of a given job
+function! gutentags#get_job_tags_file(module, job_idx) abort
+ return s:update_in_progress[a:module][a:job_idx][0]
+endfunction
+
+" Gets the job data of the i-th job
+function! gutentags#get_job_data(module, job_idx) abort
+ return s:update_in_progress[a:module][a:job_idx][1]
+endfunction
+
+" Removes the i-th job from the ongoing jobs
+function! gutentags#remove_job(module, job_idx) abort
+ let [l:tags_file, l:job_data] = s:update_in_progress[a:module][a:job_idx]
+ call remove(s:update_in_progress[a:module], a:job_idx)
+
+ " Run the user callback for finished jobs.
+ silent doautocmd User GutentagsUpdated
+
+ " See if we had any more updates queued up for this.
+ let l:qu_idx = -1
+ for qu_info in s:update_queue[a:module]
+ let l:qu_idx += 1
+ if qu_info[0] == l:tags_file
+ break
+ endif
+ endfor
+ if l:qu_idx >= 0
+ let l:qu_info = s:update_queue[a:module][l:qu_idx]
+ call remove(s:update_queue[a:module], l:qu_idx)
+
+ if bufexists(l:qu_info[1])
+ call gutentags#trace("Finished ".a:module." job, ".
+ \"running queued update for '".l:tags_file."'.")
+ call s:update_tags(l:qu_info[1], a:module, l:qu_info[2], 2)
+ else
+ call gutentags#trace("Finished ".a:module." job, ".
+ \"but skipping queued update for '".l:tags_file."' ".
+ \"because originating buffer doesn't exist anymore.")
+ endif
+ else
+ call gutentags#trace("Finished ".a:module." job.")
+ endif
+
+ return [l:tags_file, l:job_data]
+endfunction
+
+" Removes the job from the ongoing jobs given its job data
+function! gutentags#remove_job_by_data(module, data) abort
+ let l:idx = gutentags#find_job_index_by_data(a:module, a:data)
+ return gutentags#remove_job(a:module, l:idx)
+endfunction
+
+" }}}
+
+" Tags File Management {{{
+
+" (Re)Generate the tags file for the current buffer's file.
+function! s:manual_update_tags(bang) abort
+ let l:restore_prev_trace = 0
+ let l:prev_trace = g:gutentags_trace
+ if &verbose > 0
+ let g:gutentags_trace = 1
+ let l:restore_prev_trace = 1
+ endif
+
+ try
+ let l:bn = bufnr('%')
+ for module in g:gutentags_modules
+ call s:update_tags(l:bn, module, a:bang, 0)
+ endfor
+ silent doautocmd User GutentagsUpdating
+ finally
+ if l:restore_prev_trace
+ let g:gutentags_trace = l:prev_trace
+ endif
+ endtry
+endfunction
+
+" (Re)Generate the tags file for a buffer that just go saved.
+function! s:write_triggered_update_tags(bufno) abort
+ if g:gutentags_enabled && g:gutentags_generate_on_write
+ for module in g:gutentags_modules
+ call s:update_tags(a:bufno, module, 0, 2)
+ endfor
+ endif
+ silent doautocmd User GutentagsUpdating
+endfunction
+
+" Update the tags file for the current buffer's file.
+" write_mode:
+" 0: update the tags file if it exists, generate it otherwise.
+" 1: always generate (overwrite) the tags file.
+"
+" queue_mode:
+" 0: if an update is already in progress, report it and abort.
+" 1: if an update is already in progress, abort silently.
+" 2: if an update is already in progress, queue another one.
+function! s:update_tags(bufno, module, write_mode, queue_mode) abort
+ " Figure out where to save.
+ let l:buf_gutentags_files = getbufvar(a:bufno, 'gutentags_files')
+ let l:tags_file = l:buf_gutentags_files[a:module]
+ let l:proj_dir = getbufvar(a:bufno, 'gutentags_root')
+
+ " Check that there's not already an update in progress.
+ let l:in_progress_idx = gutentags#find_job_index_by_tags_file(
+ \a:module, l:tags_file)
+ if l:in_progress_idx >= 0
+ if a:queue_mode == 2
+ let l:needs_queuing = 1
+ for qu_info in s:update_queue[a:module]
+ if qu_info[0] == l:tags_file
+ let l:needs_queuing = 0
+ break
+ endif
+ endfor
+ if l:needs_queuing
+ call add(s:update_queue[a:module],
+ \[l:tags_file, a:bufno, a:write_mode])
+ endif
+ call gutentags#trace("Tag file '" . l:tags_file .
+ \"' is already being updated. Queuing it up...")
+ elseif a:queue_mode == 1
+ call gutentags#trace("Tag file '" . l:tags_file .
+ \"' is already being updated. Skipping...")
+ elseif a:queue_mode == 0
+ echom "gutentags: The tags file is already being updated, " .
+ \"please try again later."
+ else
+ call gutentags#throw("Unknown queue mode: " . a:queue_mode)
+ endif
+
+ " Don't update the tags right now.
+ return
+ endif
+
+ " Switch to the project root to make the command line smaller, and make
+ " it possible to get the relative path of the filename to parse if we're
+ " doing an incremental update.
+ let l:prev_cwd = getcwd()
+ call gutentags#chdir(l:proj_dir)
+ try
+ call call("gutentags#".a:module."#generate",
+ \[l:proj_dir, l:tags_file,
+ \ {
+ \ 'write_mode': a:write_mode,
+ \ }])
+ catch /^gutentags\:/
+ echom "Error while generating ".a:module." file:"
+ echom v:exception
+ finally
+ " Restore the current directory...
+ call gutentags#chdir(l:prev_cwd)
+ endtry
+endfunction
+
+" }}}
+
+" Utility Functions {{{
+
+function! gutentags#rescan(...)
+ if exists('b:gutentags_files')
+ unlet b:gutentags_files
+ endif
+ if a:0 && a:1
+ let l:trace_backup = g:gutentags_trace
+ let l:gutentags_trace = 1
+ endif
+ call gutentags#setup_gutentags()
+ if a:0 && a:1
+ let g:gutentags_trace = l:trace_backup
+ endif
+endfunction
+
+function! gutentags#toggletrace(...)
+ let g:gutentags_trace = !g:gutentags_trace
+ if a:0 > 0
+ let g:gutentags_trace = a:1
+ endif
+ if g:gutentags_trace
+ echom "gutentags: Tracing is enabled."
+ else
+ echom "gutentags: Tracing is disabled."
+ endif
+ echom ""
+endfunction
+
+function! gutentags#fake(...)
+ let g:gutentags_fake = !g:gutentags_fake
+ if a:0 > 0
+ let g:gutentags_fake = a:1
+ endif
+ if g:gutentags_fake
+ echom "gutentags: Now faking gutentags."
+ else
+ echom "gutentags: Now running gutentags for real."
+ endif
+ echom ""
+endfunction
+
+function! gutentags#default_stdout_cb(chan, msg) abort
+ call gutentags#trace('[job stdout]: '.string(a:msg))
+endfunction
+
+function! gutentags#default_stderr_cb(chan, msg) abort
+ call gutentags#trace('[job stderr]: '.string(a:msg))
+endfunction
+
+if has('nvim')
+ " Neovim job API.
+ function! s:nvim_job_exit_wrapper(real_cb, job, exit_code, event_type) abort
+ call call(a:real_cb, [a:job, a:exit_code])
+ endfunction
+
+ function! s:nvim_job_out_wrapper(real_cb, job, lines, event_type) abort
+ call call(a:real_cb, [a:job, a:lines])
+ endfunction
+
+ function! gutentags#build_default_job_options(module) abort
+ " Neovim kills jobs on exit, which is what we want.
+ let l:job_opts = {
+ \'on_exit': function(
+ \ '<SID>nvim_job_exit_wrapper',
+ \ ['gutentags#'.a:module.'#on_job_exit']),
+ \'on_stdout': function(
+ \ '<SID>nvim_job_out_wrapper',
+ \ ['gutentags#default_stdout_cb']),
+ \'on_stderr': function(
+ \ '<SID>nvim_job_out_wrapper',
+ \ ['gutentags#default_stderr_cb'])
+ \}
+ return l:job_opts
+ endfunction
+
+ function! gutentags#start_job(cmd, opts) abort
+ return jobstart(a:cmd, a:opts)
+ endfunction
+else
+ " Vim8 job API.
+ function! gutentags#build_default_job_options(module) abort
+ let l:job_opts = {
+ \'exit_cb': 'gutentags#'.a:module.'#on_job_exit',
+ \'out_cb': 'gutentags#default_stdout_cb',
+ \'err_cb': 'gutentags#default_stderr_cb',
+ \'stoponexit': 'term'
+ \}
+ return l:job_opts
+ endfunction
+
+ function! gutentags#start_job(cmd, opts) abort
+ return job_start(a:cmd, a:opts)
+ endfunction
+endif
+
+" Returns which modules are currently generating something for the
+" current buffer.
+function! gutentags#inprogress()
+ " Does this buffer have gutentags enabled?
+ if !exists('b:gutentags_files')
+ return []
+ endif
+
+ " Find any module that has a job in progress for any of this buffer's
+ " tags files.
+ let l:modules_in_progress = []
+ for [module, tags_file] in items(b:gutentags_files)
+ let l:jobidx = gutentags#find_job_index_by_tags_file(module, tags_file)
+ if l:jobidx >= 0
+ call add(l:modules_in_progress, module)
+ endif
+ endfor
+ return l:modules_in_progress
+endfunction
+
+" }}}
+
+" Statusline Functions {{{
+
+" Prints whether a tag file is being generated right now for the current
+" buffer in the status line.
+"
+" Arguments can be passed:
+" - args 1 and 2 are the prefix and suffix, respectively, of whatever output,
+" if any, is going to be produced.
+" (defaults to empty strings)
+" - arg 3 is the text to be shown if tags are currently being generated.
+" (defaults to the name(s) of the modules currently generating).
+
+function! gutentags#statusline(...) abort
+ let l:modules_in_progress = gutentags#inprogress()
+ if empty(l:modules_in_progress)
+ return ''
+ endif
+
+ let l:prefix = ''
+ let l:suffix = ''
+ if a:0 > 0
+ let l:prefix = a:1
+ endif
+ if a:0 > 1
+ let l:suffix = a:2
+ endif
+
+ if a:0 > 2
+ let l:genmsg = a:3
+ else
+ let l:genmsg = join(l:modules_in_progress, ',')
+ endif
+
+ return l:prefix.l:genmsg.l:suffix
+endfunction
+
+" Same as `gutentags#statusline`, but the only parameter is a `Funcref` or
+" function name that will get passed the list of modules currently generating
+" something. This formatter function should return the string to display in
+" the status line.
+
+function! gutentags#statusline_cb(fmt_cb, ...) abort
+ let l:modules_in_progress = gutentags#inprogress()
+
+ if (a:0 == 0 || !a:1) && empty(l:modules_in_progress)
+ return ''
+ endif
+
+ return call(a:fmt_cb, [l:modules_in_progress])
+endfunction
+
+" }}}
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/cscope.vim b/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/cscope.vim
@@ -0,0 +1,99 @@
+" Cscope module for Gutentags
+
+if !has('cscope')
+ throw "Can't enable the cscope module for Gutentags, this Vim has ".
+ \"no support for cscope files."
+endif
+
+" Global Options {{{
+
+if !exists('g:gutentags_cscope_executable')
+ let g:gutentags_cscope_executable = 'cscope'
+endif
+
+if !exists('g:gutentags_scopefile')
+ let g:gutentags_scopefile = 'cscope.out'
+endif
+
+if !exists('g:gutentags_auto_add_cscope')
+ let g:gutentags_auto_add_cscope = 1
+endif
+
+if !exists('g:gutentags_cscope_build_inverted_index')
+ let g:gutentags_cscope_build_inverted_index = 0
+endif
+
+" }}}
+
+" Gutentags Module Interface {{{
+
+let s:runner_exe = gutentags#get_plat_file('update_scopedb')
+let s:unix_redir = (&shellredir =~# '%s') ? &shellredir : &shellredir . ' %s'
+let s:added_dbs = []
+
+function! gutentags#cscope#init(project_root) abort
+ let l:dbfile_path = gutentags#get_cachefile(
+ \a:project_root, g:gutentags_scopefile)
+ let b:gutentags_files['cscope'] = l:dbfile_path
+
+ if g:gutentags_auto_add_cscope && filereadable(l:dbfile_path)
+ if index(s:added_dbs, l:dbfile_path) < 0
+ call add(s:added_dbs, l:dbfile_path)
+ silent! execute 'cs add ' . fnameescape(l:dbfile_path)
+ endif
+ endif
+endfunction
+
+function! gutentags#cscope#generate(proj_dir, tags_file, gen_opts) abort
+ let l:cmd = [s:runner_exe]
+ let l:cmd += ['-e', g:gutentags_cscope_executable]
+ let l:cmd += ['-p', a:proj_dir]
+ let l:cmd += ['-f', a:tags_file]
+ let l:file_list_cmd =
+ \ gutentags#get_project_file_list_cmd(a:proj_dir)
+ if !empty(l:file_list_cmd)
+ let l:cmd += ['-L', '"' . l:file_list_cmd . '"']
+ endif
+ if g:gutentags_cscope_build_inverted_index
+ let l:cmd += ['-I']
+ endif
+ let l:cmd = gutentags#make_args(l:cmd)
+
+ call gutentags#trace("Running: " . string(l:cmd))
+ call gutentags#trace("In: " . getcwd())
+ if !g:gutentags_fake
+ let l:job_opts = gutentags#build_default_job_options('cscope')
+ let l:job = gutentags#start_job(l:cmd, l:job_opts)
+ call gutentags#add_job('cscope', a:tags_file, l:job)
+ else
+ call gutentags#trace("(fake... not actually running)")
+ endif
+endfunction
+
+function! gutentags#cscope#on_job_exit(job, exit_val) abort
+ let l:job_idx = gutentags#find_job_index_by_data('cscope', a:job)
+ let l:dbfile_path = gutentags#get_job_tags_file('cscope', l:job_idx)
+ call gutentags#remove_job('cscope', l:job_idx)
+
+ if a:exit_val == 0
+ if index(s:added_dbs, l:dbfile_path) < 0
+ call add(s:added_dbs, l:dbfile_path)
+ silent! execute 'cs add ' . fnameescape(l:dbfile_path)
+ else
+ silent! execute 'cs reset'
+ endif
+ elseif !g:__gutentags_vim_is_leaving
+ call gutentags#warning(
+ \"cscope job failed, returned: ".
+ \string(a:exit_val))
+ endif
+ if has('win32') && g:__gutentags_vim_is_leaving
+ " The process got interrupted because Vim is quitting.
+ " Remove the db file on Windows because there's no `trap`
+ " statement in the update script.
+ try | call delete(l:dbfile_path) | endtry
+ endif
+endfunction
+
+" }}}
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/ctags.vim b/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/ctags.vim
@@ -0,0 +1,343 @@
+" Ctags module for Gutentags
+
+" Global Options {{{
+
+let g:gutentags_ctags_executable = get(g:, 'gutentags_ctags_executable', 'ctags')
+let g:gutentags_ctags_tagfile = get(g:, 'gutentags_ctags_tagfile', 'tags')
+let g:gutentags_ctags_auto_set_tags = get(g:, 'gutentags_ctags_auto_set_tags', 1)
+
+let g:gutentags_ctags_options_file = get(g:, 'gutentags_ctags_options_file', '.gutctags')
+let g:gutentags_ctags_check_tagfile = get(g:, 'gutentags_ctags_check_tagfile', 0)
+let g:gutentags_ctags_extra_args = get(g:, 'gutentags_ctags_extra_args', [])
+let g:gutentags_ctags_post_process_cmd = get(g:, 'gutentags_ctags_post_process_cmd', '')
+
+let g:gutentags_ctags_exclude = get(g:, 'gutentags_ctags_exclude', [])
+let g:gutentags_ctags_exclude_wildignore = get(g:, 'gutentags_ctags_exclude_wildignore', 1)
+
+" Backwards compatibility.
+function! s:_handleOldOptions() abort
+ let l:renamed_options = {
+ \'gutentags_exclude': 'gutentags_ctags_exclude',
+ \'gutentags_tagfile': 'gutentags_ctags_tagfile',
+ \'gutentags_auto_set_tags': 'gutentags_ctags_auto_set_tags'
+ \}
+ for key in keys(l:renamed_options)
+ if exists('g:'.key)
+ let newname = l:renamed_options[key]
+ echom "gutentags: Option 'g:'".key." has been renamed to ".
+ \"'g:'".newname." Please update your vimrc."
+ let g:[newname] = g:[key]
+ endif
+ endfor
+endfunction
+call s:_handleOldOptions()
+" }}}
+
+" Gutentags Module Interface {{{
+
+let s:did_check_exe = 0
+let s:runner_exe = '"' . gutentags#get_plat_file('update_tags') . '"'
+let s:unix_redir = (&shellredir =~# '%s') ? &shellredir : &shellredir . ' %s'
+let s:wildignores_options_path = ''
+let s:last_wildignores = ''
+
+function! gutentags#ctags#init(project_root) abort
+ " Figure out the path to the tags file.
+ " Check the old name for this option, too, before falling back to the
+ " globally defined name.
+ let l:tagfile = getbufvar("", 'gutentags_ctags_tagfile',
+ \getbufvar("", 'gutentags_tagfile',
+ \g:gutentags_ctags_tagfile))
+ let b:gutentags_files['ctags'] = gutentags#get_cachefile(
+ \a:project_root, l:tagfile)
+
+ " Set the tags file for Vim to use.
+ if g:gutentags_ctags_auto_set_tags
+ if has('win32') || has('win64')
+ execute 'setlocal tags^=' . fnameescape(b:gutentags_files['ctags'])
+ else
+ " spaces must be literally escaped in tags path
+ let l:literal_space_escaped = substitute(fnameescape(b:gutentags_files['ctags']), '\ ', '\\\\ ', 'g')
+ execute 'setlocal tags^=' . l:literal_space_escaped
+ endif
+ endif
+
+ " Check if the ctags executable exists.
+ if s:did_check_exe == 0
+ if g:gutentags_enabled && executable(expand(g:gutentags_ctags_executable, 1)) == 0
+ let g:gutentags_enabled = 0
+ echoerr "Executable '".g:gutentags_ctags_executable."' can't be found. "
+ \."Gutentags will be disabled. You can re-enable it by "
+ \."setting g:gutentags_enabled back to 1."
+ endif
+ let s:did_check_exe = 1
+ endif
+endfunction
+
+function! gutentags#ctags#generate(proj_dir, tags_file, gen_opts) abort
+ let l:write_mode = a:gen_opts['write_mode']
+
+ let l:tags_file_exists = filereadable(a:tags_file)
+
+ " If the tags file exists, we may want to do a sanity check to prevent
+ " weird errors that are hard to troubleshoot.
+ if l:tags_file_exists && g:gutentags_ctags_check_tagfile
+ let l:first_lines = readfile(a:tags_file, '', 1)
+ if len(l:first_lines) == 0 || stridx(l:first_lines[0], '!_TAG_') != 0
+ call gutentags#throw(
+ \"File ".a:tags_file." doesn't appear to be ".
+ \"a ctags file. Please delete it and run ".
+ \":GutentagsUpdate!.")
+ return
+ endif
+ endif
+
+ " Get a tags file path relative to the current directory, which
+ " happens to be the project root in this case.
+ " Since the given tags file path is absolute, and since Vim won't
+ " change the path if it is not inside the current directory, we
+ " know that the tags file is "local" (i.e. inside the project)
+ " if the path was shortened (an absolute path will always be
+ " longer than a true relative path).
+ let l:tags_file_relative = fnamemodify(a:tags_file, ':.')
+ let l:tags_file_is_local = len(l:tags_file_relative) < len(a:tags_file)
+ let l:use_tag_relative_opt = 0
+
+ if empty(g:gutentags_cache_dir) && l:tags_file_is_local
+ " If we don't use the cache directory, we can pass relative paths
+ " around.
+ "
+ " Note that if we don't do this and pass a full path for the project
+ " root, some `ctags` implementations like Exhuberant Ctags can get
+ " confused if the paths have spaces -- but not if you're *in* the root
+ " directory, for some reason... (which will be the case, we're running
+ " the jobs from the project root).
+ let l:actual_proj_dir = '.'
+ let l:actual_tags_file = l:tags_file_relative
+
+ let l:tags_file_dir = fnamemodify(l:actual_tags_file, ':h')
+ if l:tags_file_dir != '.'
+ " Ok so now the tags file is stored in a subdirectory of the
+ " project root, instead of at the root. This happens if, say,
+ " someone set `gutentags_ctags_tagfile` to `.git/tags`, which
+ " seems to be fairly popular.
+ "
+ " By default, `ctags` writes paths relative to the current
+ " directory (the project root) but in this case we need it to
+ " be relative to the tags file (e.g. adding `../` in front of
+ " everything if the tags file is `.git/tags`).
+ "
+ " Thankfully most `ctags` implementations support an option
+ " just for this.
+ let l:use_tag_relative_opt = 1
+ endif
+ else
+ " else: the tags file goes in a cache directory, so we need to specify
+ " all the paths absolutely for `ctags` to do its job correctly.
+ let l:actual_proj_dir = a:proj_dir
+ let l:actual_tags_file = a:tags_file
+ endif
+
+ " Build the command line.
+ let l:cmd = [s:runner_exe]
+ let l:cmd += ['-e', '"' . s:get_ctags_executable(a:proj_dir) . '"']
+ let l:cmd += ['-t', '"' . l:actual_tags_file . '"']
+ let l:cmd += ['-p', '"' . l:actual_proj_dir . '"']
+ if l:write_mode == 0 && l:tags_file_exists
+ let l:cur_file_path = expand('%:p')
+ if empty(g:gutentags_cache_dir) && l:tags_file_is_local
+ let l:cur_file_path = fnamemodify(l:cur_file_path, ':.')
+ endif
+ let l:cmd += ['-s', '"' . l:cur_file_path . '"']
+ else
+ let l:file_list_cmd = gutentags#get_project_file_list_cmd(l:actual_proj_dir)
+ if !empty(l:file_list_cmd)
+ if match(l:file_list_cmd, '///') > 0
+ let l:suffopts = split(l:file_list_cmd, '///')
+ let l:suffoptstr = l:suffopts[1]
+ let l:file_list_cmd = l:suffopts[0]
+ if l:suffoptstr == 'absolute'
+ let l:cmd += ['-A']
+ endif
+ endif
+ let l:cmd += ['-L', '"' . l:file_list_cmd. '"']
+ endif
+ endif
+ if empty(get(l:, 'file_list_cmd', ''))
+ " Pass the Gutentags recursive options file before the project
+ " options file, so that users can override --recursive.
+ " Omit --recursive if this project uses a file list command.
+ let l:cmd += ['-o', '"' . gutentags#get_res_file('ctags_recursive.options') . '"']
+ endif
+ if l:use_tag_relative_opt
+ let l:cmd += ['-O', shellescape("--tag-relative=yes")]
+ endif
+ for extra_arg in g:gutentags_ctags_extra_args
+ let l:cmd += ['-O', shellescape(extra_arg)]
+ endfor
+ if !empty(g:gutentags_ctags_post_process_cmd)
+ let l:cmd += ['-P', shellescape(g:gutentags_ctags_post_process_cmd)]
+ endif
+ let l:proj_options_file = a:proj_dir . '/' .
+ \g:gutentags_ctags_options_file
+ if filereadable(l:proj_options_file)
+ let l:proj_options_file = s:process_options_file(
+ \a:proj_dir, l:proj_options_file)
+ let l:cmd += ['-o', '"' . l:proj_options_file . '"']
+ endif
+ if g:gutentags_ctags_exclude_wildignore
+ call s:generate_wildignore_options()
+ if !empty(s:wildignores_options_path)
+ let l:cmd += ['-x', shellescape('@'.s:wildignores_options_path, 1)]
+ endif
+ endif
+ for exc in g:gutentags_ctags_exclude
+ let l:cmd += ['-x', '"' . exc . '"']
+ endfor
+ if g:gutentags_pause_after_update
+ let l:cmd += ['-c']
+ endif
+ if g:gutentags_trace
+ let l:cmd += ['-l', '"' . l:actual_tags_file . '.log"']
+ endif
+ let l:cmd = gutentags#make_args(l:cmd)
+
+ call gutentags#trace("Running: " . string(l:cmd))
+ call gutentags#trace("In: " . getcwd())
+ if !g:gutentags_fake
+ let l:job_opts = gutentags#build_default_job_options('ctags')
+ let l:job = gutentags#start_job(l:cmd, l:job_opts)
+ call gutentags#add_job('ctags', a:tags_file, l:job)
+ else
+ call gutentags#trace("(fake... not actually running)")
+ endif
+endfunction
+
+function! gutentags#ctags#on_job_exit(job, exit_val) abort
+ let [l:tags_file, l:job_data] = gutentags#remove_job_by_data('ctags', a:job)
+
+ if a:exit_val != 0 && !g:__gutentags_vim_is_leaving
+ call gutentags#warning("ctags job failed, returned: ".
+ \string(a:exit_val))
+ endif
+ if has('win32') && g:__gutentags_vim_is_leaving
+ " The process got interrupted because Vim is quitting.
+ " Remove the tags and lock files on Windows because there's no `trap`
+ " statement in update script.
+ try | call delete(l:tags_file) | endtry
+ try | call delete(l:tags_file.'.temp') | endtry
+ try | call delete(l:tags_file.'.lock') | endtry
+ endif
+endfunction
+
+" }}}
+
+" Utilities {{{
+
+" Get final ctags executable depending whether a filetype one is defined
+function! s:get_ctags_executable(proj_dir) abort
+ "Only consider the main filetype in cases like 'python.django'
+ let l:ftype = get(split(&filetype, '\.'), 0, '')
+ let l:proj_info = gutentags#get_project_info(a:proj_dir)
+ let l:type = get(l:proj_info, 'type', l:ftype)
+ let exepath = exists('g:gutentags_ctags_executable_{l:type}')
+ \ ? g:gutentags_ctags_executable_{l:type} : g:gutentags_ctags_executable
+ return expand(exepath, 1)
+endfunction
+
+function! s:generate_wildignore_options() abort
+ if s:last_wildignores == &wildignore
+ " The 'wildignore' setting didn't change since last time we did this,
+ " but check if file still exist (could have been deleted if temp file)
+ if filereadable(s:wildignores_options_path)
+ call gutentags#trace("Wildignore options file is up to date.")
+ return
+ endif
+ call gutentags#trace("Wildignore options file is not readable.")
+ endif
+
+ if s:wildignores_options_path == ''
+ if empty(g:gutentags_cache_dir)
+ let s:wildignores_options_path = tempname()
+ else
+ let s:wildignores_options_path =
+ \gutentags#stripslash(g:gutentags_cache_dir).
+ \'/_wildignore.options'
+ endif
+ endif
+
+ call gutentags#trace("Generating wildignore options: ".s:wildignores_options_path)
+ let l:opt_lines = []
+ for ign in split(&wildignore, ',')
+ call add(l:opt_lines, ign)
+ endfor
+ call writefile(l:opt_lines, s:wildignores_options_path)
+ let s:last_wildignores = &wildignore
+endfunction
+
+function! s:process_options_file(proj_dir, path) abort
+ if empty(g:gutentags_cache_dir)
+ " If we're not using a cache directory to store tag files, we can
+ " use the options file straight away.
+ return a:path
+ endif
+
+ " See if we need to process the options file.
+ let l:do_process = 0
+ let l:proj_dir = gutentags#stripslash(a:proj_dir)
+ let l:out_path = gutentags#get_cachefile(l:proj_dir, 'options')
+ if !filereadable(l:out_path)
+ call gutentags#trace("Processing options file '".a:path."' because ".
+ \"it hasn't been processed yet.")
+ let l:do_process = 1
+ elseif getftime(a:path) > getftime(l:out_path)
+ call gutentags#trace("Processing options file '".a:path."' because ".
+ \"it has changed.")
+ let l:do_process = 1
+ endif
+ if l:do_process == 0
+ " Nothing's changed, return the existing processed version of the
+ " options file.
+ return l:out_path
+ endif
+
+ " We have to process the options file. Right now this only means capturing
+ " all the 'exclude' rules, and rewrite them to make them absolute.
+ "
+ " This is because since `ctags` is run with absolute paths (because we
+ " want the tag file to be in a cache directory), it will do its path
+ " matching with absolute paths too, so the exclude rules need to be
+ " absolute.
+ let l:lines = readfile(a:path)
+ let l:outlines = []
+ for line in l:lines
+ let l:exarg_idx = matchend(line, '\v^\-\-exclude=')
+ if l:exarg_idx < 0
+ call add(l:outlines, line)
+ continue
+ endif
+
+ " Don't convert things that don't look like paths.
+ let l:exarg = strpart(line, l:exarg_idx + 1)
+ let l:do_convert = 1
+ if l:exarg[0] == '@' " Manifest file path
+ let l:do_convert = 0
+ endif
+ if stridx(l:exarg, '/') < 0 && stridx(l:exarg, '\\') < 0 " Filename
+ let l:do_convert = 0
+ endif
+ if l:do_convert == 0
+ call add(l:outlines, line)
+ continue
+ endif
+
+ let l:fullp = l:proj_dir . gutentags#normalizepath('/'.l:exarg)
+ let l:ol = '--exclude='.l:fullp
+ call add(l:outlines, l:ol)
+ endfor
+
+ call writefile(l:outlines, l:out_path)
+ return l:out_path
+endfunction
+
+" }}}
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/gtags_cscope.vim b/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/gtags_cscope.vim
@@ -0,0 +1,136 @@
+" gtags_cscope module for Gutentags
+
+if !has('cscope')
+ throw "Can't enable the gtags-cscope module for Gutentags, "
+ \"this Vim has no support for cscope files."
+endif
+
+" Global Options {{{
+
+if !exists('g:gutentags_gtags_executable')
+ let g:gutentags_gtags_executable = 'gtags'
+endif
+
+if !exists('g:gutentags_gtags_dbpath')
+ let g:gutentags_gtags_dbpath = ''
+endif
+
+if !exists('g:gutentags_gtags_options_file')
+ let g:gutentags_gtags_options_file = '.gutgtags'
+endif
+
+if !exists('g:gutentags_gtags_cscope_executable')
+ let g:gutentags_gtags_cscope_executable = 'gtags-cscope'
+endif
+
+if !exists('g:gutentags_auto_add_gtags_cscope')
+ let g:gutentags_auto_add_gtags_cscope = 1
+endif
+
+" }}}
+
+" Gutentags Module Interface {{{
+
+let s:runner_exe = gutentags#get_plat_file('update_gtags')
+let s:added_db_files = {}
+
+function! s:add_db(db_file) abort
+ if filereadable(a:db_file)
+ call gutentags#trace(
+ \"Adding cscope DB file: " . a:db_file)
+ set nocscopeverbose
+ execute 'cs add ' . fnameescape(a:db_file)
+ set cscopeverbose
+ let s:added_db_files[a:db_file] = 1
+ else
+ call gutentags#trace(
+ \"Not adding cscope DB file because it doesn't " .
+ \"exist yet: " . a:db_file)
+ endif
+endfunction
+
+function! gutentags#gtags_cscope#init(project_root) abort
+ let l:db_path = gutentags#get_cachefile(
+ \a:project_root, g:gutentags_gtags_dbpath)
+ let l:db_path = gutentags#stripslash(l:db_path)
+ let l:db_file = l:db_path . '/GTAGS'
+ let l:db_file = gutentags#normalizepath(l:db_file)
+
+ if !isdirectory(l:db_path)
+ call mkdir(l:db_path, 'p')
+ endif
+
+ let b:gutentags_files['gtags_cscope'] = l:db_file
+
+ execute 'set cscopeprg=' . fnameescape(g:gutentags_gtags_cscope_executable)
+
+ " The combination of gtags-cscope, vim's cscope and global files is
+ " a bit flaky. Environment variables are safer than vim passing
+ " paths around and interpreting input correctly.
+ let $GTAGSDBPATH = l:db_path
+ let $GTAGSROOT = a:project_root
+
+ if g:gutentags_auto_add_gtags_cscope &&
+ \!has_key(s:added_db_files, l:db_file)
+ let s:added_db_files[l:db_file] = 0
+ call s:add_db(l:db_file)
+ endif
+endfunction
+
+function! gutentags#gtags_cscope#generate(proj_dir, tags_file, gen_opts) abort
+ let l:cmd = [s:runner_exe]
+ let l:cmd += ['-e', '"' . g:gutentags_gtags_executable . '"']
+
+ let l:file_list_cmd = gutentags#get_project_file_list_cmd(a:proj_dir)
+ if !empty(l:file_list_cmd)
+ let l:cmd += ['-L', '"' . l:file_list_cmd . '"']
+ endif
+
+ let l:proj_options_file = a:proj_dir . '/' . g:gutentags_gtags_options_file
+ if filereadable(l:proj_options_file)
+ let l:proj_options = readfile(l:proj_options_file)
+ let l:cmd += l:proj_options
+ endif
+
+ " gtags doesn't honour GTAGSDBPATH and GTAGSROOT, so PWD and dbpath
+ " have to be set
+ let l:db_path = fnamemodify(a:tags_file, ':p:h')
+ let l:cmd += ['--incremental', '"'.l:db_path.'"']
+
+ let l:cmd = gutentags#make_args(l:cmd)
+
+ call gutentags#trace("Running: " . string(l:cmd))
+ call gutentags#trace("In: " . getcwd())
+ if !g:gutentags_fake
+ let l:job_opts = gutentags#build_default_job_options('gtags_cscope')
+ let l:job = gutentags#start_job(l:cmd, l:job_opts)
+ call gutentags#add_job('gtags_cscope', a:tags_file, l:job)
+ else
+ call gutentags#trace("(fake... not actually running)")
+ endif
+ call gutentags#trace("")
+endfunction
+
+function! gutentags#gtags_cscope#on_job_exit(job, exit_val) abort
+ let l:job_idx = gutentags#find_job_index_by_data('gtags_cscope', a:job)
+ let l:dbfile_path = gutentags#get_job_tags_file('gtags_cscope', l:job_idx)
+ call gutentags#remove_job('gtags_cscope', l:job_idx)
+
+ if g:gutentags_auto_add_gtags_cscope
+ call s:add_db(l:dbfile_path)
+ endif
+
+ if a:exit_val != 0 && !g:__gutentags_vim_is_leaving
+ call gutentags#warning(
+ \"gtags-cscope job failed, returned: ".
+ \string(a:exit_val))
+ endif
+ if has('win32') && g:__gutentags_vim_is_leaving
+ " The process got interrupted because Vim is quitting.
+ " Remove the db file on Windows because there's no `trap`
+ " statement in the update script.
+ try | call delete(l:dbfile_path) | endtry
+ endif
+endfunction
+
+" }}}
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/pycscope.vim b/.config/nvim/pack/bundle/start/vim-gutentags/autoload/gutentags/pycscope.vim
@@ -0,0 +1,86 @@
+" Pycscope module for Gutentags
+
+if !has('cscope')
+ throw "Can't enable the pycscope module for Gutentags, this Vim has ".
+ \"no support for cscope files."
+endif
+
+" Global Options {{{
+
+if !exists('g:gutentags_pycscope_executable')
+ let g:gutentags_pycscope_executable = 'pycscope'
+endif
+
+if !exists('g:gutentags_pyscopefile')
+ let g:gutentags_pyscopefile = 'pycscope.out'
+endif
+
+if !exists('g:gutentags_auto_add_pycscope')
+ let g:gutentags_auto_add_pycscope = 1
+endif
+
+" }}}
+
+" Gutentags Module Interface {{{
+
+let s:runner_exe = gutentags#get_plat_file('update_pyscopedb')
+let s:unix_redir = (&shellredir =~# '%s') ? &shellredir : &shellredir . ' %s'
+let s:added_dbs = []
+
+function! gutentags#pycscope#init(project_root) abort
+ let l:dbfile_path = gutentags#get_cachefile(
+ \a:project_root, g:gutentags_pyscopefile)
+ let b:gutentags_files['pycscope'] = l:dbfile_path
+
+ if g:gutentags_auto_add_pycscope && filereadable(l:dbfile_path)
+ if index(s:added_dbs, l:dbfile_path) < 0
+ call add(s:added_dbs, l:dbfile_path)
+ silent! execute 'cs add ' . fnameescape(l:dbfile_path)
+ endif
+ endif
+endfunction
+
+function! gutentags#pycscope#generate(proj_dir, tags_file, gen_opts) abort
+ let l:cmd = [s:runner_exe]
+ let l:cmd += ['-e', g:gutentags_pycscope_executable]
+ let l:cmd += ['-p', a:proj_dir]
+ let l:cmd += ['-f', a:tags_file]
+ let l:file_list_cmd =
+ \ gutentags#get_project_file_list_cmd(a:proj_dir)
+ if !empty(l:file_list_cmd)
+ let l:cmd += ['-L', '"' . l:file_list_cmd . '"']
+ endif
+ let l:cmd = gutentags#make_args(l:cmd)
+
+ call gutentags#trace("Running: " . string(l:cmd))
+ call gutentags#trace("In: " . getcwd())
+ if !g:gutentags_fake
+ let l:job_opts = gutentags#build_default_job_options('pycscope')
+ let l:job = gutentags#start_job(l:cmd, l:job_opts)
+ call gutentags#add_job('pycscope', a:tags_file, l:job)
+ else
+ call gutentags#trace("(fake... not actually running)")
+ endif
+endfunction
+
+function! gutentags#pycscope#on_job_exit(job, exit_val) abort
+ let l:job_idx = gutentags#find_job_index_by_data('pycscope', a:job)
+ let l:dbfile_path = gutentags#get_job_tags_file('pycscope', l:job_idx)
+ call gutentags#remove_job('pycscope', l:job_idx)
+
+ if a:exit_val == 0
+ if index(s:added_dbs, l:dbfile_path) < 0
+ call add(s:added_dbs, l:dbfile_path)
+ silent! execute 'cs add ' . fnameescape(l:dbfile_path)
+ else
+ silent! execute 'cs reset'
+ endif
+ else
+ call gutentags#warning(
+ \"gutentags: pycscope job failed, returned: ".
+ \string(a:exit_val))
+ endif
+endfunction
+
+" }}}
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/doc/gutentags.txt b/.config/nvim/pack/bundle/start/vim-gutentags/doc/gutentags.txt
@@ -0,0 +1,748 @@
+*gutentags.txt* Automatic ctags management for VIM
+ ___ ___ ___ ___ ___
+ /\__\ /\ \ /\__\ /\__\ /\ \
+ /:/ _/_ \:\ \ /:/ / /:/ _/_ \:\ \
+ /:/ /\ \ \:\ \ /:/__/ /:/ /\__\ \:\ \
+ /:/ /::\ \ ___ \:\ \ /::\ \ /:/ /:/ _/_ _____\:\ \
+ /:/__\/\:\__\ /\ \ \:\__\ /:/\:\ \ /:/_/:/ /\__\ /::::::::\__\
+ \:\ \ /:/ / \:\ \ /:/ / \/__\:\ \ \:\/:/ /:/ / \:\~~\~~\/__/
+ \:\ /:/ / \:\ /:/ / \:\__\ \::/_/:/ / \:\ \
+ \:\/:/ / \:\/:/ / \/__/ \:\/:/ / \:\ \
+ \::/ / \::/ / \::/ / \:\__\
+ \/__/ \/__/ \/__/ \/__/
+ ___ ___ ___ ___
+ /\__\ /\ \ /\__\ /\__\
+ /:/ / /::\ \ /:/ _/_ /:/ _/_
+ /:/__/ /:/\:\ \ /:/ /\ \ /:/ /\ \
+ /::\ \ /:/ /::\ \ /:/ /::\ \ /:/ /::\ \
+ /:/\:\ \ /:/_/:/\:\__\ /:/__\/\:\__\ /:/_/:/\:\__\
+ \/__\:\ \ \:\/:/ \/__/ \:\ \ /:/ / \:\/:/ /:/ /
+ \:\__\ \::/__/ \:\ /:/ / \::/ /:/ /
+ \/__/ \:\ \ \:\/:/ / \/_/:/ /
+ \:\__\ \::/ / /:/ /
+ \/__/ \/__/ \/__/
+
+
+ GUTENTAGS REFERENCE MANUAL
+ by Ludovic Chabant
+
+ *gutentags*
+
+1. Introduction |gutentags-intro|
+2. Commands |gutentags-commands|
+3. Status Line |gutentags-status-line|
+4. Global Settings |gutentags-settings|
+5. Project Settings |gutentags-project-settings|
+
+=============================================================================
+1. Introduction *gutentags-intro*
+
+Gutentags is a plugin that takes care of the much needed management of tags
+files in Vim. It will (re)generate tag files as you work while staying
+completely out of your way. It will even do its best to keep those tag files
+out of your way too. It has no dependencies and just works.
+
+In order to generate tag files, Gutentags will have to figure out what's in
+your project. To do this, it will locate well-known project root markers like
+SCM folders (.git, .hg, etc.), any custom tags you define (with
+|gutentags_project_root|), and even things you may have defined already with
+other plugins, like CtrlP.
+
+If the current file you're editing is found to be in such a project, Gutentags
+will make sure the tag file for that project is up to date. Then, as you work
+in files in that project, it will partially re-generate the tag file. Every
+time you save, it will silently, in the background, update the tags for that
+file.
+
+Usually, `ctags` can only append tags to an existing tag file, so Gutentags
+removes the tags for the current file first, to make sure the tag file is
+always consistent with the source code.
+
+Also, Gutentags is clever enough to not stumble upon itself by triggering
+multiple ctags processes if you save files too fast, or if your project is
+really big.
+
+
+1.1 Requirements
+ *gutentags-ctags-requirements*
+
+If you're using the `ctags` modules (which is the default and only working one
+at this point, really), you will need a `tags` generator that supports the
+following arguments:
+
+* `-f` (to specify the output file)
+* `--append` (to append to an existing file while keeping it sorted)
+* `--exclude` (to exclude file patterns)
+* `--options` (to specify an options file)
+
+This means you probably want Exuberant Ctags or Universal Ctags. The basic
+old BSD Ctags WON'T WORK. Other language-specific versions may or may not
+work. Check with their help or man page.
+
+
+1.2 Similar Plugins
+ *gutentags-similar-plugins*
+
+There are some similar Vim plugins out there ("vim-tags", "vim-autotag",
+"vim-automatic-ctags", etc.). They all fail on one or more of the requirements
+I set for myself with Gutentags:
+
+* No other dependency than running Vim: no Python, Ruby, or whatever.
+* Cross-platform: should work on at least Mac and Windows.
+* Incremental tags generation: don't re-generate the whole project all the
+ time. This may be fine for small projects, but it doesn't scale.
+* External process management: if the ctags process is taking a long time,
+ don't run another one because I saved the file again.
+* Keep the tag file consistent: don't just append the current file's tags to
+ the tag file, otherwise you will still "see" tags for deleted or renamed
+ classes and functions.
+* Automatically create the tag file: you open something from a freshly forked
+ project, it should start indexing it automatically, just like in Sublime Text
+ or Visual Studio or any other IDE.
+
+
+=============================================================================
+2. Commands *gutentags-commands*
+
+ *gutentags-project-commands*
+The following commands are only available in buffers that have been found to
+belong to a project that should be managed by Gutentags. See
+|gutentags_project_root| for how Gutentags figures out the project a file
+belongs to. When no project is found (i.e. the file is not under any of the
+known project markers), Gutentags is disabled for that buffer, and the
+following commands and remarks don't apply.
+
+If you want to force-disable Gutentags for a given project even though it does
+match one of the items in |gutentags_project_root|, create a file named
+"`.notags`" at the root of the project.
+
+The tag file that Gutentags creates and manages will be named after
+|gutentags_ctags_tagfile|, relative to the project's root directory. When
+Gutentags finds a valid project root, it will prepend the tag file's path to
+'tags', unless |gutentags_ctags_auto_set_tags| is set to 0. This is to make
+sure Vim will use that file first.
+
+If a file managed by Gutentags is opened and no tag file already exists,
+Gutentags will start generating it right away in the background, unless
+|gutentags_generate_on_missing| is set to 0. If you have a large project, you
+may want to know when Gutentags is generating tags: see
+|gutentags-status-line| to display an indicator in your status line.
+
+When a file managed by Gutentags is saved, the tag file will be incrementally
+updated, i.e. references to the recently saved file are removed, and that file
+is re-parsed for tags, with the result being merged into the tag file. This
+makes the tag file 100% consistent with the latest changes. This doesn't
+happen however if |gutentags_generate_on_write| is set to 0, in which case you
+have to run |GutentagsUpdate| manually.
+
+
+ *:GutentagsUpdate*
+:GutentagsUpdate
+ Forces an update of the current tag file with the
+ current buffer. If tags are already being generated,
+ you will be notified and the command will abort.
+
+:GutentagsUpdate!
+ Like |GutentagsUpdate|, but updates the current tags
+ file with the whole project instead of just the
+ current buffer.
+
+
+Some debugging/troubleshooting commands are also available if the
+|gutentags_define_advanced_commands| global setting is set to 1.
+
+ *:GutentagsToggleEnabled*
+:GutentagsToggleEnabled
+ Disables and re-enables Gutentags.
+ When Gutentags is disabled, it won't update your tag
+ file when you save a buffer. It will however still
+ look for project markers as you open new buffers so
+ that they can start working again when you re-enable
+ Gutentags.
+
+ {only available when
+ |gutentags_define_advanced_commands| is set}
+
+ *GutentagsToggleTrace*
+:GutentagsToggleTrace
+ If you want to keep an eye on what Gutentags is doing,
+ you can enable tracing. This will show messages every
+ time Gutentags does something. It can get annoying
+ quickly, since it will require you to press a key to
+ dismiss those messages, but it can be useful to
+ troubleshoot a problem.
+ In addition to messages in Vim, it will also make
+ Gutentags redirect the output of the tag generation
+ script to a `.log` file in the project root.
+
+ {only available when
+ |gutentags_define_advanced_commands| is set}
+
+
+Gutentags also has some user auto-commands (see |User| and |:doautocmd|):
+
+ *GutentagsUpdating*
+GutentagsUpdating
+ This auto-command is triggered when a background
+ update job has started.
+
+ *GutentagsUpdated*
+GutentagsUpdated
+ This auto-command is triggered when a background
+ update job has finished.
+
+
+=============================================================================
+3. Status Line *gutentags-status-line*
+
+Tag file generation can take a while if you're working on a project big
+enough. In that case, you may want to know when `ctags` is running, so you
+have a heads up if some of the tags aren't recognized yet.
+
+ *gutentags#statusline()*
+You can display an indicator of tag generation progress in your |status-line|
+with the following function: >
+ :set statusline+=%{gutentags#statusline()}
+
+The function will, by default, print a list of modules in the status line. So
+if the `ctags` module (see |g:gutentags_modules|) is currently generating
+a tags file, you will see "ctags" printed in the status line. If nothing is
+happening, nothing will be printed in the status line.
+
+You can pass some parameters to customize this:
+
+1. A prefix string (defaults to `""`).
+2. A suffix string (defaults to `""`).
+3. The text to print (defaults to the names of modules currently generating
+ something).
+
+So using `gutentags#statusline('[', ']')` would print `"[ctags]"` instead of
+`"ctags"`.
+
+Because Gutentags runs the tag generation in the background, the statusline
+indicator might stay there even after the background process has ended. It
+would only go away when Vim decides to refresh the statusline. You can force
+refresh it in a callback on |GutentagsUpdating| and |GutentagsUpdated|.
+
+For instance, with the `lightline` plugin:
+
+ augroup MyGutentagsStatusLineRefresher
+ autocmd!
+ autocmd User GutentagsUpdating call lightline#update()
+ autocmd User GutentagsUpdated call lightline#update()
+ augroup END
+
+ *gutentags#statusline_cb*
+As an alternative to the previous function, `gutentags#statusline_cb` takes
+a single parameter which should be a |Funcref| or a function name. This
+function should take a list of active module names, and return a string. This
+lets you completely control what the status line will print.
+
+For instance:
+ function! s:get_gutentags_status(mods) abort
+ let l:msg = ''
+ if index(a:mods, 'ctags') >= 0
+ let l:msg .= '♨'
+ endif
+ if index(a:mods, 'cscope') >= 0
+ let l:msg .= '♺'
+ endif
+ return l:msg
+ endfunction
+
+ :set statusline+=%{gutentags#statusline_cb(
+ \function('<SID>get_gutentags_status'))}
+
+By default, the callback function doesn't get called if no tags generation is
+currently happening. You can pass `1` as a second argument so that the
+callback function is always called.
+
+
+=============================================================================
+4. Global Settings *gutentags-settings*
+
+The following settings can be defined in your |vimrc| to change the default
+behaviour of Gutentags.
+
+ *gutentags_enabled*
+g:gutentags_enabled
+ Defines whether Gutentags should be enabled. When
+ disabled, Gutentags will still scan for project root
+ markers when opening buffers. This is so that when you
+ re-enable Gutentags, you won't have some buffers
+ mysteriously working while others (those open last)
+ don't.
+ Defaults to `1`.
+
+ *gutentags_trace*
+g:gutentags_trace
+ When true, Gutentags will spit out debugging
+ information as Vim messages (which you can later read
+ with |:messages|). It also runs its background scripts
+ with extra parameters to log activity to a `tags.log`
+ file that you can also inspect for more information.
+
+ Note: you can run `:verbose GutentagsUpdate` to
+ temporarily set |g:gutentags_trace| to `1` for that
+ update only.
+
+ Defaults to `0`.
+
+ *gutentags_dont_load*
+g:gutentags_dont_load
+ Prevents Gutentags from loading at all on Vim startup.
+
+ The difference between this and |gutentags_enabled| is
+ that |gutentags_enabled| can be turned on and off in
+ the same Vim session -- Gutentags as a plugin stays
+ loaded and will keep track of what happened while it
+ was disabled. However, |gutentags_dont_load| only
+ works on Vim startup and will prevent Gutentags from
+ loading at all, as if it wasn't there.
+
+ *gutentags_modules*
+g:gutentags_modules
+ A list of modules to load with Gutentags. Each module
+ is responsible for generating a specific type of tags
+ file.
+ Valid values are:
+
+ - `ctags`: generates a `tags` file using
+ a `ctags`-compatible program like Exhuberant Ctags
+ or Universal Ctags.
+
+ - `cscope`: generates a code database file using
+ `cscope`.
+
+ - `pycscope`: generates a code database file using
+ `pycscope`.
+
+ - `gtags_cscope`: same as `cscope` but uses GNU's
+ `gtags` executable and database.
+
+ Defaults to `[ctags]`.
+
+ *gutentags_project_root*
+g:gutentags_project_root
+ When a buffer is loaded, Gutentags will figure out if
+ it's part of a project that should have tags managed
+ automatically. To do this, it looks for "root markers"
+ in the current file's directory and its parent
+ directories. If it finds any of those markers,
+ Gutentags will be enabled for the project, and a tags
+ file named after |gutentags_ctags_tagfile| will be
+ created at the project root.
+ Defaults to `[]` (an empty |List|).
+ A list of default markers will be appended to the
+ user-defined ones unless
+ |gutentags_add_default_project_roots| is set to 0.
+
+ *gutentags_add_default_project_roots*
+g:gutentags_add_default_project_roots
+ Defines whether Gutentags should always define some
+ default project roots (see |gutentags_project_root|).
+ This can be useful to prevent unnecessary disk access
+ when Gutentags searches for a project root.
+ The default markers are:
+ `['.git', '.hg', '.svn', '.bzr', '_darcs', '_darcs', '_FOSSIL_', '.fslckout']`
+
+ *gutentags_add_ctrlp_root_markers*
+g:gutentags_add_ctrlp_root_markers
+ If Gutentags finds `g:ctrlp_root_markers` (used by the
+ CtrlP plugin), it will append those root markers to
+ the existing ones (see |g:gutentags_project_root|).
+ Set this to 0 to stop it from happening.
+ Defaults to 1.
+
+ *gutentags_exclude_filetypes*
+g:gutentags_exclude_filetypes
+ A |List| of file types (see |'filetype'|) that Gutentags
+ should ignore. When a buffer is opened, if its
+ 'filetype' is found in this list, Gutentags features
+ won't be available for this buffer.
+ Defaults to an empty list (`[]`).
+
+ *gutentags_exclude_project_root*
+g:gutentags_exclude_project_root
+ A list of project roots to generally ignore. If a file
+ is opened inside one of those projects, Gutentags
+ won't be activated. This is similar to placing
+ a `.notags` file in the root of those projects, but
+ can be useful when you don't want to, or can't, place
+ such a file there.
+ Defaults to `['/usr/local', '/opt/homebrew', '/home/linuxbrew/.linuxbrew']`,
+ which are the folders where Homebrew is known to
+ create a Git repository by default.
+
+ *gutentags_project_root_finder*
+g:gutentags_project_root_finder
+ When a buffer is loaded, Gutentags uses a default
+ (internal) implementation to find that file's
+ project's root directory, using settings like
+ |g:gutentags_project_root|. When you specify
+ |g:gutentags_project_root_finder|, you can tell
+ Gutentags to use a custom implementation, such as
+ `vim-projectroot`. The value of this setting must be
+ the name of a function that takes a single string
+ argument (the path to the current buffer's file) and
+ returns a string value (the project's root directory).
+ Defaults to `''`.
+ Note: when set, the called implementation will
+ possibly ignore |g:gutentags_project_root|.
+ Note: an implementation can fallback to the default
+ behaviour by calling
+ `gutentags#default_get_project_root`.
+
+ *gutentags_generate_on_missing*
+g:gutentags_generate_on_missing
+ If set to 1, Gutentags will start generating an initial
+ tag file if a file is open in a project where no tags
+ file is found. See |gutentags_project_root| for how
+ Gutentags locates the project.
+ When set to 0, Gutentags will only generate the first
+ time the file is saved (if
+ |gutentags_generate_on_write| is set to 1), or when
+ |GutentagsUpdate| or |GutentagsGenerate| is run.
+ Defaults to 1.
+
+ *gutentags_generate_on_new*
+g:gutentags_generate_on_new
+ If set to 1, Gutentags will start generating the tag
+ file when a new project is open. A new project is
+ considered open when a buffer is created for a file
+ whose corresponding tag file has not been "seen" yet
+ in the current Vim session -- which pretty much means
+ when you open the first file in a given source control
+ repository.
+ When set to 0, Gutentags won't do anything special.
+ See also |gutentags_generate_on_missing| and
+ |gutentags_generate_on_write|.
+ Defaults to 1.
+
+ *gutentags_generate_on_write*
+g:gutentags_generate_on_write
+ If set to 1, Gutentags will update the current
+ project's tag file when a file inside that project is
+ saved. See |gutentags_project_root| for how Gutentags
+ locates the project.
+ When set to 0, Gutentags won't do anything on save.
+ This means that the project's tag file won't reflect
+ the latest changes, and you will have to run
+ |GutentagsUpdate| manually.
+ Defaults to 1.
+
+ *gutentags_generate_on_empty_buffer*
+g:gutentags_generate_on_empty_buffer
+ If set to 1, Gutentags will start generating the tag
+ file even if there's no buffer currently open, as long
+ as the current working directory (as returned by
+ |:cd|) is inside a known project.
+ This is useful if you want Gutentags to generate the
+ tag file right after opening Vim.
+ Defaults to 0.
+
+ *gutentags_background_update*
+g:gutentags_background_update
+ Specifies whether the process that updates the tags
+ file should be run in the background or in the
+ foreground. If run in the foreground, Vim will block
+ until the process is complete.
+ Defaults to 1.
+
+ *gutentags_cache_dir*
+g:gutentags_cache_dir
+ Specifies a directory in which to create all the tags
+ files, instead of writing them at the root of each
+ project. This is handy to keep tags files from
+ polluting many directories all across your computer.
+
+ *gutentags_resolve_symlinks*
+g:gutentags_resolve_symlinks
+ When set to 1, Gutentags will resolve any symlinks in
+ the current buffer's path in order to find the project
+ it belongs to. This is what you want if you're editing
+ a symlink located outside of the project, and it
+ points to a file inside the project. However, this is
+ maybe not what you want if the symlink itself is
+ part of the project.
+ Defaults to 0.
+
+ *gutentags_init_user_func*
+g:gutentags_init_user_func
+ When set to a non-empty string, it is expected to be
+ the name of a function that will be called when a file
+ is opened in a project. The function gets passed the
+ path of the file and if it returns 0, Gutentags won't
+ be enabled for that file.
+
+ You can use this to manually set buffer-local
+ settings:
+
+ * `b:gutentags_ctags_tagfile` (see |gutentags_ctags_tagfile|).
+
+ This setting was previously called
+ `gutentags_enabled_user_func`. The old setting is
+ still used as a fallback.
+
+ Defaults to "".
+
+ *gutentags_define_advanced_commands*
+g:gutentags_define_advanced_commands
+ Defines some advanced commands like
+ |GutentagsToggleEnabled| and |GutentagsUnlock|.
+
+ *gutentags_project_info*
+g:gutentags_project_info
+ Defines ways for Gutentags to figure out what kind of
+ project any given file belongs to. This should be
+ a list of dictionaries:
+
+ let g:gutentags_project_info = []
+ call add(g:gutentags_project_info, {...})
+
+ Each dictionary item must contain at least a `type`
+ key, indicating the type of project:
+
+ {"type": "python"}
+
+ Other items will be used to figure out if a project is
+ of the given type.
+
+ "file": any existing file with this path (relative to
+ the project root) will make the current project match
+ the given info.
+
+ "glob": any result found with this glob pattern
+ (relative to the project root) will make the current
+ project match the given info. See |glob()| for more
+ information.
+
+ Gutentags adds by default the following definitions:
+
+ call add(g:gutentags_project_info, {'type': 'python', 'file': 'setup.py'})
+ call add(g:gutentags_project_info, {'type': 'ruby', 'file': 'Gemfile'})
+
+ This means, for example, that you can use
+ `g:gutentags_ctags_executable_ruby` out of the box.
+ See |gutentags_ctags_executable_{filetype}| for more
+ information.
+
+ *gutentags_file_list_command*
+g:gutentags_file_list_command
+ Specifies command(s) to use to list files for which
+ tags should be generated, instead of recursively
+ examining all files within the project root. When
+ invoked, file list commands will execute in the
+ project root directory.
+
+ This setting is useful in projects using source
+ control to restrict tag generation to only files
+ tracked in the repository.
+
+ This variable may be set in one of two ways. If
+ set as a |String|, the specified command will be used to
+ list files for all projects. For example: >
+
+ let g:gutentags_file_list_command = 'find . -type f'
+<
+ If set as a |Dictionary|, this variable should be set
+ as a mapping of project root markers to the desired
+ file list command for that root marker. (See
+ |gutentags_project_root| for how Gutentags uses root
+ markers to locate the project.) For example: >
+
+ let g:gutentags_file_list_command = {
+ \ 'markers': {
+ \ '.git': 'git ls-files',
+ \ '.hg': 'hg files',
+ \ },
+ \ }
+<
+ Note: If a custom ctags executable is specified, it
+ must support the '-L' command line option in order to
+ read the list of files to be examined.
+
+
+The following settings are valid for the `ctags` module.
+
+ *gutentags_ctags_executable*
+g:gutentags_ctags_executable
+ Specifies the ctags executable to launch.
+ Defaults to `ctags`.
+
+ *gutentags_ctags_executable_{filetype}*
+g:gutentags_ctags_executable_{type}
+ Specifies the ctags executable to launch for a project
+ of type {type}. See |gutentags_project_info| for more
+ information.
+ IMPORTANT: please see |gutentags-ctags-requirements|.
+ Example: >
+ let g:gutentags_ctags_executable_ruby = 'ripper-tags'
+<
+
+ *gutentags_ctags_tagfile*
+g:gutentags_ctags_tagfile
+ Specifies the name of the tag file to create. This
+ will be appended to the project's root. See
+ |gutentags_project_root| for how Gutentags locates the
+ project.
+ Defaults to `tags`.
+
+ *gutentags_ctags_exclude*
+g:gutentags_ctags_exclude
+ A list of file patterns to pass to the
+ |gutentags_ctags_executable| so that they will be
+ excluded from parsing for the tags generation.
+ See also |gutentags_ctags_exclude_wildignore|.
+ Defaults to `[]` (an empty |List|).
+
+ *gutentags_ctags_exclude_wildignore*
+g:gutentags_ctags_exclude_wildignore
+ When 1, Gutentags will automatically pass your
+ 'wildignore' file patterns to the
+ |gutentags_ctags_executable| so that they are ignored.
+ Set also |gutentags_ctags_exclude| to pass custom
+ patterns.
+ Defaults to 1.
+
+ *gutentags_ctags_auto_set_tags*
+g:gutentags_ctags_auto_set_tags
+ If set to 1, Gutentags will automatically prepend
+ 'tags' with the exact path to the tag file for the
+ current project. See |gutentags_project_root| for how
+ Gutentags locates the project.
+ When set to 0, Gutentags doesn't change 'tags', and
+ this means that whatever tag file it generates may
+ not be picked up by Vim. See |tagfiles()| to know what
+ tag files Vim knows about.
+ Defaults to 1.
+
+ *gutentags_ctags_extra_args*
+g:gutentags_ctags_extra_args
+ A list of arguments to pass to `ctags`.
+ Defaults to `[]`.
+
+ *gutentags_ctags_post_process_cmd*
+g:gutentags_ctags_post_process_cmd
+ If defined, the tags generation script will run the
+ command with an argument that points to a temporary
+ copy of the tags file. If the post-process step is
+ modifying the tags file, it needs to do so in-place.
+ This is useful for cleaning up a tags file that may
+ contain tags with non-ASCII names that somehow upsets
+ Vim.
+ Defaults to `""` (an empty |String|).
+
+
+The following settings are valid for the `cscope` module.
+
+ *gutentags_cscope_executable*
+g:gutentags_cscope_executable
+ Specifies the name or path of the `cscope` executable
+ to use to generate the code database.
+ Defaults to `"cscope"`.
+
+ *gutentags_scopefile*
+g:gutentags_scopefile
+ Specifies the name of the scope file to create. This
+ will be appended to the project's root. See
+ |gutentags_project_root| for how Gutentags locates the
+ project.
+ Defaults to `"cscope.out"`.
+
+ *gutentags_auto_add_cscope*
+g:gutentags_auto_add_cscope
+ If set to 1, Gutentags will automatically add the
+ generated code database to Vim by running `:cs add`
+ (see |:cscope|).
+ Defaults to 1.
+
+ *gutentags_cscope_build_inverted_index*
+g:gutentags_cscope_build_inverted_index
+ If set to 1, Gutentags will make `cscope` build an
+ inverted index.
+ Defaults to 0.
+
+
+The following settings are valid for the `pycscope` module.
+
+ *gutentags_pycscope_executable*
+g:gutentags_pycscope_executable
+ Specifies the name or path of the `pycscope` executable
+ to use to generate the code database.
+ Defaults to `"pycscope"`.
+
+ *gutentags_auto_add_pycscope*
+g:gutentags_auto_add_pycscope
+ If set to 1, Gutentags will automatically add the
+ generated code database to Vim by running `:cs add`
+ (see |:pycscope|).
+ Defaults to 1.
+
+
+The following settings are valid for the `gtags_cscope` module.
+
+ *gutentags_gtags_executable*
+g:gutentags_gtags_executable
+ Specifies the name or path of the `gtags` executable
+ to use to generate the code database.
+ Defaults to `"gtags"`.
+
+ *gutentags_gtags_cscope_executable*
+g:gutentags_gtags_cscope_executable
+ Specifies the name or path of the `gtags-cscope`
+ executable to use to generate the code database.
+ Defaults to `"gtags-cscope"`.
+
+ *gutentags_gtags_dbpath*
+g:gutentags_gtags_dbpath
+ Path from the cache directory (|gutentags_cache_dir|
+ or project root) to the folder containing the
+ definition database file (usually called `GTAGS`).
+ Defaults to `""`.
+
+ *gutentags_gtags_options_file*
+g:gutentags_gtags_options_file
+ The name of a file that will be looked for in
+ a project root directory. The file is expected to
+ contain `gtags` options (one per line).
+ Defaults to `".gutgtags"`.
+
+ *gutentags_auto_add_gtags_cscope*
+g:gutentags_auto_add_gtags_cscope
+ If set to 1, Gutentags will automatically add the
+ generated code database to Vim by running `:cs add`
+ (see |:cscope|).
+ Defaults to 1.
+
+
+People using `cscope`, `pycscope` or `gtags_cscope` across multiple projects in the same
+Vim instance might be interested in the `gutentags_plus` plugin, which handles
+switching databases automatically before performing a query.
+See https://github.com/skywind3000/gutentags_plus.
+
+=============================================================================
+5. Project Settings *gutentags-project-settings*
+
+Gutentags can be customized to some extent on a per-project basis with the
+following files present in the project root directory:
+
+ *gutentags-.gutctags*
+`.gutctags`: if this file exists, Ctags will be told to load additional
+command-line parameters by reading it line by line (see the Ctags
+documentation for more information).
+
+Note that for complex reasons, Gutentags can't run `ctags` from the project
+root if you're using |gutentags_cache_dir|, so if the `.gutctags` file exists,
+it will be pre-processed in order to make all `--exclude=` clauses into
+absolute paths (by prepending the project root). The resulting file will be
+saved into the cache directory, and passed to `ctags` via the `--options=`
+parameter. If you're _not_ using |gutentags_cache_dir|, the `.gutctags` file
+is _not_ pre-processed, and is passed as-is via the `--options=` parameter.
+
+ *gutentags-.notags*
+`.notags`: if this file exists, Gutentags will be disabled completely for that
+project.
+
+
+ vim:tw=78:et:ft=help:norl:
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_gtags.sh b/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_gtags.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env bash
+
+set -e
+
+PROG_NAME=$0
+GTAGS_EXE=gtags
+FILE_LIST_CMD=
+
+ShowUsage() {
+ echo "Usage:"
+ echo " $PROG_NAME <options>"
+ echo ""
+ echo " -e [exe=gtags]: The gtags executable to run."
+ echo " -L [cmd=]: The file list command to run."
+ echo ""
+}
+
+while [[ $# -ne 0 ]]; do
+ case "$1" in
+ -h)
+ ShowUsage
+ exit 0
+ ;;
+ -e)
+ GTAGS_EXE=$2
+ shift 2
+ ;;
+ -L)
+ FILE_LIST_CMD=$2
+ shift 2
+ ;;
+ *)
+ GTAGS_ARGS="$GTAGS_ARGS $1"
+ shift
+ ;;
+ esac
+done
+
+if [ -n "$FILE_LIST_CMD" ]; then
+ CMD="$FILE_LIST_CMD | $GTAGS_EXE -f- $GTAGS_ARGS"
+else
+ CMD="$GTAGS_EXE $GTAGS_ARGS"
+fi
+
+echo "Running gtags:"
+echo "$CMD"
+eval "$CMD"
+echo "Done."
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_pyscopedb.sh b/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_pyscopedb.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+
+set -e
+
+PROG_NAME=$0
+PYCSCOPE_EXE=pycscope
+PYCSCOPE_ARGS=
+DB_FILE=pycscope.out
+# Note that we keep the same name
+PROJECT_ROOT=
+FILE_LIST_CMD=
+
+ShowUsage() {
+ echo "Usage:"
+ echo " $PROG_NAME <options>"
+ echo ""
+ echo " -e [exe=pycscope]: The pycscope executable to run"
+ echo " -f [file=pycscope.out]: The path to the ctags file to update"
+ echo " -p [dir=]: The path to the project root"
+ echo " -L [cmd=]: The file list command to run"
+ echo ""
+}
+
+
+while getopts "h?e:f:p:L:" opt; do
+ case $opt in
+ h|\?)
+ ShowUsage
+ exit 0
+ ;;
+ e)
+ PYCSCOPE_EXE=$OPTARG
+ ;;
+ f)
+ DB_FILE=$OPTARG
+ ;;
+ p)
+ PROJECT_ROOT=$OPTARG
+ ;;
+ L)
+ FILE_LIST_CMD=$OPTARG
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+if [ "$1" != "" ]; then
+ echo "Invalid Argument: $1"
+ exit 1
+fi
+
+echo "Locking pycscope DB file..."
+echo $$ > "$DB_FILE.lock"
+
+# Remove lock and temp file if script is stopped unexpectedly.
+trap 'rm -f "$DB_FILE.lock" "$DB_FILE.files" "$DB_FILE.temp"' INT QUIT TERM EXIT
+
+PREVIOUS_DIR=$(pwd)
+if [ -d "$PROJECT_ROOT" ]; then
+ cd "$PROJECT_ROOT"
+fi
+
+if [ -n "${FILE_LIST_CMD}" ]; then
+ if [ "${PROJECT_ROOT}" = "." ]; then
+ eval "$FILE_LIST_CMD" > "${DB_FILE}.files"
+ else
+ # If using a tags cache directory, use absolute paths
+ eval "$FILE_LIST_CMD" | while read -r l; do
+ echo "${PROJECT_ROOT%/}/${l}"
+ done > "${DB_FILE}.files"
+ fi
+else
+ find . -type f > "${DB_FILE}.files"
+fi
+PYCSCOPE_ARGS="${PYCSCOPE_ARGS} -i ${DB_FILE}.files"
+
+echo "Running pycscope"
+echo "$PYCSCOPE_EXE -f \"$DB_FILE.temp\" "$PYCSCOPE_ARGS
+"$PYCSCOPE_EXE" -f "$DB_FILE.temp" $PYCSCOPE_ARGS
+
+if [ -d "$PROJECT_ROOT" ]; then
+ cd "$PREVIOUS_DIR"
+fi
+
+echo "Replacing pycscope DB file"
+echo "mv -f \"$DB_FILE.temp\" \"$DB_FILE\""
+mv -f "$DB_FILE.temp" "$DB_FILE"
+
+echo "Unlocking pycscope DB file..."
+rm -f "$DB_FILE.lock"
+
+echo "Done."
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_scopedb.sh b/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_scopedb.sh
@@ -0,0 +1,124 @@
+#!/bin/sh
+
+set -e
+
+PROG_NAME=$0
+CSCOPE_EXE=cscope
+CSCOPE_ARGS=
+DB_FILE=cscope.out
+PROJECT_ROOT=
+FILE_LIST_CMD=
+BUILD_INVERTED_INDEX=0
+
+ShowUsage() {
+ echo "Usage:"
+ echo " $PROG_NAME <options>"
+ echo ""
+ echo " -e [exe=cscope]: The cscope executable to run"
+ echo " -f [file=cscope.out]: The path to the ctags file to update"
+ echo " -p [dir=]: The path to the project root"
+ echo " -L [cmd=]: The file list command to run"
+ echo " -I: Builds an inverted index"
+ echo ""
+}
+
+
+while getopts "h?e:f:p:L:I" opt; do
+ case $opt in
+ h|\?)
+ ShowUsage
+ exit 0
+ ;;
+ e)
+ CSCOPE_EXE=$OPTARG
+ ;;
+ f)
+ DB_FILE=$OPTARG
+ ;;
+ p)
+ PROJECT_ROOT=$OPTARG
+ ;;
+ L)
+ FILE_LIST_CMD=$OPTARG
+ ;;
+ I)
+ BUILD_INVERTED_INDEX=1
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+if [ "$1" != "" ]; then
+ echo "Invalid Argument: $1"
+ exit 1
+fi
+
+echo "Locking cscope DB file..."
+echo $$ > "$DB_FILE.lock"
+
+# Remove lock and temp file if script is stopped unexpectedly.
+CleanUp() {
+ rm -f "$DB_FILE.lock" "$DB_FILE.files" "$DB_FILE.temp"
+ if [ "$BUILD_INVERTED_INDEX" -eq 1 ]; then
+ rm -f "$DB_FILE.temp.in" "$DB_FILE.temp.po"
+ fi
+}
+
+trap CleanUp INT QUIT TERM EXIT
+
+PREVIOUS_DIR=$(pwd)
+if [ -d "$PROJECT_ROOT" ]; then
+ cd "$PROJECT_ROOT"
+fi
+
+if [ -n "${FILE_LIST_CMD}" ]; then
+ if [ "${PROJECT_ROOT}" = "." ]; then
+ eval "$FILE_LIST_CMD" | while read -r l; do
+ echo "\"${l}\""
+ done > "${DB_FILE}.files"
+ else
+ # If using a tags cache directory, use absolute paths
+ eval "$FILE_LIST_CMD" | while read -r l; do
+ echo "\"${PROJECT_ROOT%/}/${l}\""
+ done > "${DB_FILE}.files"
+ fi
+else
+ find . -type f ! -name ${DB_FILE} | while read -r l; do
+ echo "\"${l}\""
+ done > "${DB_FILE}.files"
+fi
+
+if [ ! -s "${DB_FILE}.files" ]; then
+ echo "There is no files to generate cscope DB"
+ exit
+fi
+
+CSCOPE_ARGS="${CSCOPE_ARGS} -i ${DB_FILE}.files"
+
+if [ "$BUILD_INVERTED_INDEX" -eq 1 ]; then
+ CSCOPE_ARGS="$CSCOPE_ARGS -q"
+fi
+
+echo "Running cscope"
+echo "$CSCOPE_EXE $CSCOPE_ARGS -b -k -f \"$DB_FILE.temp\""
+"$CSCOPE_EXE" $CSCOPE_ARGS -v -b -k -f "$DB_FILE.temp"
+
+if [ -d "$PROJECT_ROOT" ]; then
+ cd "$PREVIOUS_DIR"
+fi
+
+echo "Replacing cscope DB file"
+if [ "$BUILD_INVERTED_INDEX" -eq 1 ]; then
+ echo "mv -f \"$DB_FILE.temp.in\" \"$DB_FILE.in\""
+ mv -f "$DB_FILE.temp.in" "$DB_FILE.in"
+ echo "mv -f \"$DB_FILE.temp.po\" \"$DB_FILE.po\""
+ mv -f "$DB_FILE.temp.po" "$DB_FILE.po"
+fi
+echo "mv -f \"$DB_FILE.temp\" \"$DB_FILE\""
+mv -f "$DB_FILE.temp" "$DB_FILE"
+
+echo "Unlocking cscope DB file..."
+rm -f "$DB_FILE.lock"
+
+echo "Done."
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_tags.sh b/.config/nvim/pack/bundle/start/vim-gutentags/plat/unix/update_tags.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+
+set -e
+
+PROG_NAME=$0
+CTAGS_EXE=ctags
+CTAGS_ARGS=
+CTAGS_OPT_FILE=
+TAGS_FILE=tags
+PROJECT_ROOT=
+LOG_FILE=
+FILE_LIST_CMD=
+FILE_LIST_CMD_IS_ABSOLUTE=0
+UPDATED_SOURCE=
+POST_PROCESS_CMD=
+PAUSE_BEFORE_EXIT=0
+
+
+ShowUsage() {
+ echo "Usage:"
+ echo " $PROG_NAME <options>"
+ echo ""
+ echo " -e [exe=ctags]: The ctags executable to run"
+ echo " -t [file=tags]: The path to the ctags file to update"
+ echo " -p [dir=]: The path to the project root"
+ echo " -l [file=]: The path to a log file"
+ echo " -L [cmd=]: The file list command to run"
+ echo " -A: Specifies that the file list command returns "
+ echo " absolute paths"
+ echo " -s [file=]: The path to the source file that needs updating"
+ echo " -x [pattern=]: A pattern of files to exclude"
+ echo " -o [options=]: An options file to read additional options from"
+ echo " -O [params=]: Parameters to pass to ctags"
+ echo " -P [cmd=]: Post process command to run on the tags file"
+ echo " -c: Ask for confirmation before exiting"
+ echo ""
+}
+
+while getopts "h?e:x:t:p:l:L:s:o:O:P:cA" opt; do
+ case $opt in
+ h|\?)
+ ShowUsage
+ exit 0
+ ;;
+ e)
+ CTAGS_EXE="$OPTARG"
+ ;;
+ x)
+ CTAGS_ARGS="$CTAGS_ARGS --exclude=$OPTARG"
+ ;;
+ t)
+ TAGS_FILE="$OPTARG"
+ ;;
+ p)
+ PROJECT_ROOT="$OPTARG"
+ ;;
+ l)
+ LOG_FILE="$OPTARG"
+ ;;
+ L)
+ FILE_LIST_CMD="$OPTARG"
+ ;;
+ A)
+ FILE_LIST_CMD_IS_ABSOLUTE=1
+ ;;
+ s)
+ UPDATED_SOURCE="$OPTARG"
+ ;;
+ c)
+ PAUSE_BEFORE_EXIT=1
+ ;;
+ o)
+ CTAGS_OPT_FILE="--options=$OPTARG"
+ ;;
+ O)
+ CTAGS_ARGS="$CTAGS_ARGS $OPTARG"
+ ;;
+ P)
+ POST_PROCESS_CMD="$OPTARG"
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+if [ "$1" != "" ]; then
+ echo "Invalid Argument: $1"
+ exit 1
+fi
+
+echo "Locking tags file..."
+echo $$ > "$TAGS_FILE.lock"
+
+# Remove lock and temp file if script is stopped unexpectedly.
+trap 'errorcode=$?; rm -f "$TAGS_FILE.lock" "$TAGS_FILE.files" "$TAGS_FILE.temp"; exit $errorcode' INT QUIT TERM EXIT
+
+INDEX_WHOLE_PROJECT=1
+if [ -f "$TAGS_FILE" ]; then
+ if [ "$UPDATED_SOURCE" != "" ]; then
+ echo "Removing references to: $UPDATED_SOURCE"
+ tab=" "
+ cmd="grep --text -Ev '^[^$tab]+$tab$UPDATED_SOURCE$tab' '$TAGS_FILE' > '$TAGS_FILE.temp'"
+ echo "$cmd"
+ eval "$cmd" || true
+ INDEX_WHOLE_PROJECT=0
+ fi
+fi
+
+if [ $INDEX_WHOLE_PROJECT -eq 1 ]; then
+ if [ -n "${FILE_LIST_CMD}" ]; then
+ if [ "${PROJECT_ROOT}" = "." ] || [ $FILE_LIST_CMD_IS_ABSOLUTE -eq 1 ]; then
+ echo "Running file list command"
+ echo "eval $FILE_LIST_CMD > \"${TAGS_FILE}.files\""
+ eval "$FILE_LIST_CMD" > "${TAGS_FILE}.files"
+ else
+ # If using a tags cache directory, use absolute paths
+ echo "Running file list command, patching for absolute paths"
+ echo "eval $FILE_LIST_CMD"
+ eval "$FILE_LIST_CMD" | while read -r l; do
+ echo "${PROJECT_ROOT%/}/${l}"
+ done > "${TAGS_FILE}.files"
+ fi
+ CTAGS_ARGS="${CTAGS_ARGS} -L"
+ CTAGS_ARG_LAST="${TAGS_FILE}.files"
+ else
+ CTAGS_ARG_LAST="${PROJECT_ROOT}"
+ fi
+
+ echo "Running ctags on whole project"
+ if [ "$CTAGS_OPT_FILE" != "" ]; then
+ echo "$CTAGS_EXE -f \"$TAGS_FILE.temp\" \"$CTAGS_OPT_FILE\" $CTAGS_ARGS \"$CTAGS_ARG_LAST\""
+ "$CTAGS_EXE" -f "$TAGS_FILE.temp" "$CTAGS_OPT_FILE" $CTAGS_ARGS "$CTAGS_ARG_LAST"
+ else
+ echo "$CTAGS_EXE -f \"$TAGS_FILE.temp\" $CTAGS_ARGS \"$CTAGS_ARG_LAST\""
+ "$CTAGS_EXE" -f "$TAGS_FILE.temp" $CTAGS_ARGS "$CTAGS_ARG_LAST"
+ fi
+else
+ echo "Running ctags on \"$UPDATED_SOURCE\""
+ if [ "$CTAGS_OPT_FILE" != "" ]; then
+ echo "$CTAGS_EXE -f \"$TAGS_FILE.temp\" \"$CTAGS_OPT_FILE\" $CTAGS_ARGS --append \"$UPDATED_SOURCE\""
+ "$CTAGS_EXE" -f "$TAGS_FILE.temp" "$CTAGS_OPT_FILE" $CTAGS_ARGS --append "$UPDATED_SOURCE"
+ else
+ echo "$CTAGS_EXE -f \"$TAGS_FILE.temp\" $CTAGS_ARGS --append \"$UPDATED_SOURCE\""
+ "$CTAGS_EXE" -f "$TAGS_FILE.temp" $CTAGS_ARGS --append "$UPDATED_SOURCE"
+ fi
+fi
+
+if [ "$POST_PROCESS_CMD" != "" ]; then
+ echo "Running post process"
+ echo "$POST_PROCESS_CMD \"$TAGS_FILE.temp\""
+ $POST_PROCESS_CMD "$TAGS_FILE.temp"
+fi
+
+echo "Replacing tags file"
+echo "mv -f \"$TAGS_FILE.temp\" \"$TAGS_FILE\""
+if [ -f "$TAGS_FILE.temp" ]; then
+ mv -f "$TAGS_FILE.temp" "$TAGS_FILE"
+fi
+
+echo "Unlocking tags file..."
+rm -f "$TAGS_FILE.lock"
+
+echo "Done."
+
+if [ $PAUSE_BEFORE_EXIT -eq 1 ]; then
+ printf "Press ENTER to exit..."
+ read -r
+fi
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_gtags.cmd b/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_gtags.cmd
@@ -0,0 +1,56 @@
+@echo off
+
+setlocal EnableExtensions EnableDelayedExpansion
+
+rem ==========================================
+rem PARSE ARGUMENTS
+rem ==========================================
+set "GTAGS_EXE=gtags"
+set "GTAGS_ARGS="
+set "FILE_LIST_CMD="
+
+if [%1]==[] goto :Usage
+
+:ParseArgs
+if [%1]==[] goto :DoneParseArgs
+if [%1]==[-e] (
+ set GTAGS_EXE=%~2
+ shift /1
+ shift /1
+ goto :ParseArgs
+)
+if [%1]==[-L] (
+ set FILE_LIST_CMD=%~2
+ shift /1
+ shift /1
+ goto :ParseArgs
+)
+set "GTAGS_ARGS=%GTAGS_ARGS% %1"
+shift /1
+goto :ParseArgs
+
+:DoneParseArgs
+rem ==========================================
+rem GENERATE GTAGS
+rem ==========================================
+set "GTAGS_CMD=%GTAGS_EXE% %GTAGS_ARGS%"
+if /i not "%FILE_LIST_CMD%"=="" (
+ set "GTAGS_CMD=%FILE_LIST_CMD% | %GTAGS_EXE% -f- %GTAGS_ARGS%"
+)
+echo Running gtags:
+echo "%GTAGS_CMD%"
+call %GTAGS_CMD%
+echo Done.
+goto :EOF
+rem ==========================================
+rem USAGE
+rem ==========================================
+
+:Usage
+echo Usage:
+echo %~n0 ^<options^>
+echo.
+echo -e [exe=gtags]: The gtags executable to run.
+echo -L [cmd=]: The file list command to run
+echo.
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_scopedb.cmd b/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_scopedb.cmd
@@ -0,0 +1,120 @@
+@echo off
+setlocal EnableExtensions EnableDelayedExpansion
+
+rem ==========================================
+rem PARSE ARGUMENTS
+rem ==========================================
+
+set CSCOPE_EXE=cscope
+set CSCOPE_ARGS=
+set DB_FILE=cscope.out
+set FILE_LIST_CMD=
+set LOG_FILE=
+set BUILD_INVERTED_INDEX=0
+
+:ParseArgs
+if [%1]==[] goto :DoneParseArgs
+if [%1]==[-e] (
+ set CSCOPE_EXE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-f] (
+ set DB_FILE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-p] (
+ set PROJ_ROOT=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-L] (
+ set FILE_LIST_CMD=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-l] (
+ set LOG_FILE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-I] (
+ set BUILD_INVERTED_INDEX=1
+ goto :LoopParseArgs
+)
+echo Invalid Argument: %1
+goto :Usage
+
+:LoopParseArgs
+shift
+goto :ParseArgs
+
+:DoneParseArgs
+
+
+rem ==========================================
+rem GENERATE DATABASE
+rem ==========================================
+
+if [%LOG_FILE%]==[] set LOG_FILE=CON
+
+echo Locking db file > %LOG_FILE%
+echo locked > "%DB_FILE%.lock"
+
+echo Running cscope >> %LOG_FILE%
+if NOT ["%FILE_LIST_CMD%"]==[""] (
+ if ["%PROJECT_ROOT%"]==["."] (
+ for /F "usebackq delims=" %%F in (`%FILE_LIST_CMD%`) do @echo "%%F">%DB_FILE%.files
+ ) else (
+ rem Potentially useful:
+ rem http://stackoverflow.com/questions/9749071/cmd-iterate-stdin-piped-from-another-command
+ for /F "usebackq delims=" %%F in (`%FILE_LIST_CMD%`) do @echo "%PROJECT_ROOT%\%%F">%DB_FILE%.files
+ )
+) ELSE (
+ for /F "usebackq delims=" %%F in (`dir /S /B /A-D .`) do @echo "%%F">%DB_FILE%.files
+)
+
+set FILESIZE=0
+for /F %%F in ("%DB_FILE%.files") do set FILESIZE=%%~zF
+if %FILESIZE% EQU 0 (
+ echo There is no files to generate cscope DB
+ goto :EOF
+)
+
+set CSCOPE_ARGS=%CSCOPE_ARGS% -i %DB_FILE%.files
+if ["%BUILD_INVERTED_INDEX%"]==["1"] (
+ set CSCOPE_ARGS=%CSCOPE_ARGS% -q
+)
+"%CSCOPE_EXE%" %CSCOPE_ARGS% -b -k -f "%DB_FILE%"
+if ERRORLEVEL 1 (
+ echo ERROR: Cscope executable returned non-zero code. >> %LOG_FILE%
+)
+
+echo Unlocking db file >> %LOG_FILE%
+del /F "%DB_FILE%.files" "%DB_FILE%.lock"
+if ERRORLEVEL 1 (
+ echo ERROR: Unable to remove file lock. >> %LOG_FILE%
+)
+
+echo Done. >> %LOG_FILE%
+
+goto :EOF
+
+
+rem ==========================================
+rem USAGE
+rem ==========================================
+
+:Usage
+echo Usage:
+echo %~n0 ^<options^>
+echo.
+echo -e [exe=cscope]: The cscope executable to run
+echo -f [file=cscope.out]: The path to the database file to create
+echo -p [dir=]: The path to the project root
+echo -L [cmd=]: The file list command to run
+echo -l [log=]: The log file to output to
+echo -I: Builds an inverted index
+echo.
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_tags.cmd b/.config/nvim/pack/bundle/start/vim-gutentags/plat/win32/update_tags.cmd
@@ -0,0 +1,194 @@
+@echo off
+setlocal EnableExtensions EnableDelayedExpansion
+
+rem ==========================================
+rem PARSE ARGUMENTS
+rem ==========================================
+
+set CTAGS_EXE=ctags
+set CTAGS_ARGS=
+set TAGS_FILE=tags
+set PROJECT_ROOT=
+set FILE_LIST_CMD=
+set FILE_LIST_CMD_IS_ABSOLUTE=0
+set UPDATED_SOURCE=
+set POST_PROCESS_CMD=
+set PAUSE_BEFORE_EXIT=0
+set LOG_FILE=
+
+:ParseArgs
+if [%1]==[] goto :DoneParseArgs
+if [%1]==[-e] (
+ set CTAGS_EXE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-x] (
+ set CTAGS_ARGS=%CTAGS_ARGS% --exclude=%2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-t] (
+ set TAGS_FILE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-p] (
+ set PROJECT_ROOT=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-L] (
+ set FILE_LIST_CMD=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-A] (
+ set FILE_LIST_CMD_IS_ABSOLUTE=1
+ goto :LoopParseArgs
+)
+if [%1]==[-s] (
+ set UPDATED_SOURCE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-c] (
+ set PAUSE_BEFORE_EXIT=1
+ goto :LoopParseArgs
+)
+if [%1]==[-l] (
+ set LOG_FILE=%~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-o] (
+ set CTAGS_ARGS=%CTAGS_ARGS% --options=%2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-O] (
+ set CTAGS_ARGS=%CTAGS_ARGS% %~2
+ shift
+ goto :LoopParseArgs
+)
+if [%1]==[-P] (
+ set POST_PROCESS_CMD=%~2
+ shift
+ goto :LoopParseArgs
+)
+echo Invalid Argument: %1
+goto :Usage
+
+:LoopParseArgs
+shift
+goto :ParseArgs
+
+:DoneParseArgs
+
+
+rem ==========================================
+rem GENERATE TAGS
+rem ==========================================
+
+if [%LOG_FILE%]==[] set LOG_FILE=CON
+
+echo Locking tags file... > %LOG_FILE%
+echo locked > "%TAGS_FILE%.lock"
+
+set INDEX_WHOLE_PROJECT=1
+if exist "%TAGS_FILE%" (
+ if not ["%UPDATED_SOURCE%"]==[""] (
+ echo Removing references to: %UPDATED_SOURCE% >> %LOG_FILE%
+ echo findstr /V /C:"%UPDATED_SOURCE%" "%TAGS_FILE%" ^> "%TAGS_FILE%.temp" >> %LOG_FILE%
+ findstr /V /C:"%UPDATED_SOURCE%" "%TAGS_FILE%" > "%TAGS_FILE%.temp"
+ set CTAGS_ARGS=%CTAGS_ARGS% --append "%UPDATED_SOURCE%"
+ set INDEX_WHOLE_PROJECT=0
+ )
+)
+if ["%INDEX_WHOLE_PROJECT%"]==["1"] (
+ if not ["%FILE_LIST_CMD%"]==[""] (
+ echo Running file list command >> %LOG_FILE%
+ set use_raw_list=0
+ if ["%PROJECT_ROOT%"]==["."] set use_raw_list=1
+ if ["%FILE_LIST_CMD_IS_ABSOLUTE%"]==["1"] set use_raw_list=1
+ rem No idea why we need to use delayed expansion here to make it work :(
+ if ["!use_raw_list!"]==["1"] (
+ echo call %FILE_LIST_CMD% ^> %TAGS_FILE%.files >> %LOG_FILE%
+ call %FILE_LIST_CMD% > %TAGS_FILE%.files
+ ) else (
+ rem Potentially useful:
+ rem http://stackoverflow.com/questions/9749071/cmd-iterate-stdin-piped-from-another-command
+ echo call %FILE_LIST_CMD% -- with loop for prepending project root >> %LOG_FILE%
+ type NUL > %TAGS_FILE%.files
+ for /F "usebackq delims=" %%F in (`%FILE_LIST_CMD%`) do @echo %PROJECT_ROOT%\%%F >> %TAGS_FILE%.files
+ )
+ set CTAGS_ARGS=%CTAGS_ARGS% -L %TAGS_FILE%.files
+ ) else (
+ set CTAGS_ARGS=%CTAGS_ARGS% "%PROJECT_ROOT%"
+ )
+)
+
+echo Running ctags >> %LOG_FILE%
+echo call "%CTAGS_EXE%" -f "%TAGS_FILE%.temp" %CTAGS_ARGS% >> %LOG_FILE%
+call "%CTAGS_EXE%" -f "%TAGS_FILE%.temp" %CTAGS_ARGS% >> %LOG_FILE% 2>&1
+if ERRORLEVEL 1 (
+ echo ERROR: Ctags executable returned non-zero code. >> %LOG_FILE%
+ goto :Unlock
+)
+
+if not ["%POST_PROCESS_CMD%"]==[""] (
+ echo Running post process >> %LOG_FILE%
+ echo call %POST_PROCESS_CMD% %TAGS_FILE%.temp >> %LOG_FILE%
+ call %POST_PROCESS_CMD% %TAGS_FILE%.temp >> %LOG_FILE% 2>&1
+ if ERRORLEVEL 1 (
+ echo ERROR: Post process returned non-zero code. >> %LOG_FILE%
+ goto :Unlock
+ )
+)
+
+echo Replacing tags file >> %LOG_FILE%
+echo move /Y "%TAGS_FILE%.temp" "%TAGS_FILE%" >> %LOG_FILE%
+move /Y "%TAGS_FILE%.temp" "%TAGS_FILE%" >> %LOG_FILE% 2>&1
+if ERRORLEVEL 1 (
+ echo ERROR: Unable to rename temp tags file into actual tags file. >> %LOG_FILE%
+ goto :Unlock
+)
+
+:Unlock
+echo Unlocking tags file... >> %LOG_FILE%
+del /F "%TAGS_FILE%.files" "%TAGS_FILE%.lock"
+if ERRORLEVEL 1 (
+ echo ERROR: Unable to remove file lock. >> %LOG_FILE%
+)
+
+echo Done. >> %LOG_FILE%
+if [%PAUSE_BEFORE_EXIT%]==[1] (
+ pause
+)
+
+goto :EOF
+
+
+rem ==========================================
+rem USAGE
+rem ==========================================
+
+:Usage
+echo Usage:
+echo %~n0 ^<options^>
+echo.
+echo -e [exe=ctags]: The ctags executable to run
+echo -t [file=tags]: The path to the ctags file to update
+echo -p [dir=]: The path to the project root
+echo -l [log=]: The log file to output to
+echo -L [cmd=]: The file list command to run
+echo -A: Specifies that the file list command returns
+echo absolute paths
+echo -s [file=]: The path to the source file that needs updating
+echo -x [pattern=]: A pattern of files to exclude
+echo -o [options=]: An options file to read additional options from
+echo -O [params=]: Parameters to pass to ctags
+echo -P [cmd=]: Post process command to run on the tags file
+echo -c: Ask for confirmation before exiting
+echo.
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/plugin/gutentags.vim b/.config/nvim/pack/bundle/start/vim-gutentags/plugin/gutentags.vim
@@ -0,0 +1,120 @@
+" gutentags.vim - Automatic ctags management for Vim
+" Maintainer: Ludovic Chabant <http://ludovic.chabant.com>
+" Version: 2.0.0
+
+" Globals {{{
+
+if (&cp || get(g:, 'gutentags_dont_load', 0))
+ finish
+endif
+
+if v:version < 704
+ echoerr "gutentags: this plugin requires vim >= 7.4."
+ finish
+endif
+
+if !(has('job') || (has('nvim') && exists('*jobwait')))
+ echoerr "gutentags: this plugin requires the job API from Vim8 or Neovim."
+ finish
+endif
+
+let g:gutentags_debug = get(g:, 'gutentags_debug', 0)
+
+if (exists('g:loaded_gutentags') && !g:gutentags_debug)
+ finish
+endif
+if (exists('g:loaded_gutentags') && g:gutentags_debug)
+ echom "Reloaded gutentags."
+endif
+let g:loaded_gutentags = 1
+
+let g:gutentags_trace = get(g:, 'gutentags_trace', 0)
+let g:gutentags_fake = get(g:, 'gutentags_fake', 0)
+let g:gutentags_background_update = get(g:, 'gutentags_background_update', 1)
+let g:gutentags_pause_after_update = get(g:, 'gutentags_pause_after_update', 0)
+let g:gutentags_enabled = get(g:, 'gutentags_enabled', 1)
+let g:gutentags_modules = get(g:, 'gutentags_modules', ['ctags'])
+
+let g:gutentags_init_user_func = get(g:, 'gutentags_init_user_func',
+ \get(g:, 'gutentags_enabled_user_func', ''))
+
+let g:gutentags_add_ctrlp_root_markers = get(g:, 'gutentags_add_ctrlp_root_markers', 1)
+let g:gutentags_add_default_project_roots = get(g:, 'gutentags_add_default_project_roots', 1)
+let g:gutentags_project_root = get(g:, 'gutentags_project_root', [])
+if g:gutentags_add_default_project_roots
+ let g:gutentags_project_root += ['.git', '.hg', '.svn', '.bzr', '_darcs', '_FOSSIL_', '.fslckout']
+endif
+
+let g:gutentags_project_root_finder = get(g:, 'gutentags_project_root_finder', '')
+
+let g:gutentags_project_info = get(g:, 'gutentags_project_info', [])
+call add(g:gutentags_project_info, {'type': 'python', 'file': 'setup.py'})
+call add(g:gutentags_project_info, {'type': 'ruby', 'file': 'Gemfile'})
+
+let g:gutentags_exclude_project_root = get(g:, 'gutentags_exclude_project_root',
+ \['/usr/local', '/opt/homebrew', '/home/linuxbrew/.linuxbrew'])
+
+let g:gutentags_exclude_filetypes = get(g:, 'gutentags_exclude_filetypes', [])
+let g:gutentags_resolve_symlinks = get(g:, 'gutentags_resolve_symlinks', 0)
+let g:gutentags_generate_on_new = get(g:, 'gutentags_generate_on_new', 1)
+let g:gutentags_generate_on_missing = get(g:, 'gutentags_generate_on_missing', 1)
+let g:gutentags_generate_on_write = get(g:, 'gutentags_generate_on_write', 1)
+let g:gutentags_generate_on_empty_buffer = get(g:, 'gutentags_generate_on_empty_buffer', 0)
+let g:gutentags_file_list_command = get(g:, 'gutentags_file_list_command', '')
+
+let g:gutentags_use_jobs = get(g:, 'gutentags_use_jobs', has('job'))
+
+if !exists('g:gutentags_cache_dir')
+ let g:gutentags_cache_dir = ''
+elseif !empty(g:gutentags_cache_dir)
+ " Make sure we get an absolute/resolved path (e.g. expanding `~/`), and
+ " strip any trailing slash.
+ let g:gutentags_cache_dir = fnamemodify(g:gutentags_cache_dir, ':p')
+ let g:gutentags_cache_dir = fnamemodify(g:gutentags_cache_dir, ':s?[/\\]$??')
+endif
+
+let g:gutentags_define_advanced_commands = get(g:, 'gutentags_define_advanced_commands', 0)
+
+if g:gutentags_cache_dir != '' && !isdirectory(g:gutentags_cache_dir)
+ call mkdir(g:gutentags_cache_dir, 'p')
+endif
+
+if has('win32')
+ let g:gutentags_plat_dir = expand('<sfile>:h:h:p') . "\\plat\\win32\\"
+ let g:gutentags_res_dir = expand('<sfile>:h:h:p') . "\\res\\"
+ let g:gutentags_script_ext = '.cmd'
+else
+ let g:gutentags_plat_dir = expand('<sfile>:h:h:p') . '/plat/unix/'
+ let g:gutentags_res_dir = expand('<sfile>:h:h:p') . '/res/'
+ let g:gutentags_script_ext = '.sh'
+endif
+
+let g:__gutentags_vim_is_leaving = 0
+
+" }}}
+
+" Gutentags Setup {{{
+
+augroup gutentags_detect
+ autocmd!
+ autocmd BufNewFile,BufReadPost * call gutentags#setup_gutentags()
+ autocmd VimEnter * if expand('<amatch>')==''|call gutentags#setup_gutentags()|endif
+ autocmd VimLeavePre * call gutentags#on_vim_leave_pre()
+ autocmd VimLeave * call gutentags#on_vim_leave()
+augroup end
+
+" }}}
+
+" Toggles and Miscellaneous Commands {{{
+
+if g:gutentags_define_advanced_commands
+ command! GutentagsToggleEnabled :let g:gutentags_enabled=!g:gutentags_enabled
+ command! GutentagsToggleTrace :call gutentags#toggletrace()
+endif
+
+if g:gutentags_debug
+ command! GutentagsToggleFake :call gutentags#fake()
+endif
+
+" }}}
+
diff --git a/.config/nvim/pack/bundle/start/vim-gutentags/res/ctags_recursive.options b/.config/nvim/pack/bundle/start/vim-gutentags/res/ctags_recursive.options
@@ -0,0 +1,2 @@
+--recurse=yes
+