Mercurial > vim-gutentags
changeset 153:738ac7a89547
Merge branch 'master' into my-develop
author | Mark Wu <wuhsinyee@hotmail.com> |
---|---|
date | Fri, 16 Sep 2016 23:43:57 +0800 |
parents | a876a0df4008 (current diff) 851aec42057d (diff) |
children | e5f2be2fabd0 |
files | res/ctags.options |
diffstat | 11 files changed, 289 insertions(+), 125 deletions(-) [+] |
line wrap: on
line diff
--- a/autoload/gutentags.vim Mon May 16 02:09:40 2016 +0800 +++ b/autoload/gutentags.vim Fri Sep 16 23:43:57 2016 +0800 @@ -78,14 +78,45 @@ let s:known_projects[a:path] = l:result endfunction +function! gutentags#validate_cmd(cmd) abort + if !empty(a:cmd) && executable(split(a:cmd)[0]) + return a:cmd + endif + return "" +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 getftype(a:path . '/' . marker) != "" + return gutentags#validate_cmd(file_list_cmd) + endif + endfor + endif + 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 + let l:path = gutentags#stripslash(a:path) let l:previous_path = "" let l:markers = g:gutentags_project_root[:] if exists('g:ctrlp_root_markers') - let l:markers += 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 @@ -100,6 +131,15 @@ \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 @@ -119,7 +159,7 @@ 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 - " projet root. + " project root. let l:tag_path = g:gutentags_cache_dir . '/' . \tr(l:tag_path, '\/: ', '---_') let l:tag_path = substitute(l:tag_path, '/\-', '/', '') @@ -157,9 +197,11 @@ if g:gutentags_resolve_symlinks let l:buf_dir = fnamemodify(resolve(expand('%:p', 1)), ':p:h') endif - let b:gutentags_root = gutentags#get_project_root(l:buf_dir) + if !exists('b:gutentags_root') + let b:gutentags_root = gutentags#get_project_root(l:buf_dir) + endif if filereadable(b:gutentags_root . '/.notags') - call gutentags#trace("'notags' file found... no gutentags support.") + call gutentags#trace("'.notags' file found... no gutentags support.") return endif @@ -180,18 +222,22 @@ call call("gutentags#".module."#init", [b:gutentags_root]) endfor catch /^gutentags\:/ - call gutentags#trace("Can't figure out what tag file to use... no gutentags support.") + 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('%')) + 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()' + execute ' autocmd BufWritePost <buffer=' . l:bn . '> call s:write_triggered_update_tags(' . l:bn . ')' execute 'augroup end' " Miscellaneous commands. @@ -208,10 +254,10 @@ 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(module, 1, 1) + 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(module, 1, 1) + call s:update_tags(l:bn, module, 1, 1) endif endif endif @@ -259,17 +305,18 @@ " (Re)Generate the tags file for the current buffer's file. function! s:manual_update_tags(bang) abort + let l:bn = bufnr('%') for module in g:gutentags_modules - call s:update_tags(module, a:bang, 0) + call s:update_tags(l:bn, module, a:bang, 0) endfor silent doautocmd User GutentagsUpdated endfunction " (Re)Generate the tags file for a buffer that just go saved. -function! s:write_triggered_update_tags() abort +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(module, 0, 2) + call s:update_tags(a:bufno, module, 0, 2) endfor endif silent doautocmd User GutentagsUpdated @@ -284,10 +331,11 @@ " 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(module, write_mode, queue_mode) abort +function! s:update_tags(bufno, module, write_mode, queue_mode) abort " Figure out where to save. - let l:tags_file = b:gutentags_files[a:module] - let l:proj_dir = b:gutentags_root + 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:lock_file = l:tags_file . '.lock'
--- a/autoload/gutentags/cscope.vim Mon May 16 02:09:40 2016 +0800 +++ b/autoload/gutentags/cscope.vim Fri Sep 16 23:43:57 2016 +0800 @@ -55,6 +55,11 @@ 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(l:proj_dir) + if !empty(l:file_list_cmd) + let l:cmd .= ' -L "' . l:file_list_cmd . '"' + endif let l:cmd .= ' ' let l:cmd .= gutentags#get_execute_cmd_suffix()
--- a/autoload/gutentags/ctags.vim Mon May 16 02:09:40 2016 +0800 +++ b/autoload/gutentags/ctags.vim Fri Sep 16 23:43:57 2016 +0800 @@ -2,25 +2,11 @@ " Global Options {{{ -if !exists('g:gutentags_ctags_executable') - let g:gutentags_ctags_executable = 'ctags' -endif - -if !exists('g:gutentags_tagfile') - let g:gutentags_tagfile = 'tags' -endif - -if !exists('g:gutentags_auto_set_tags') - let g:gutentags_auto_set_tags = 1 -endif - -if !exists('g:gutentags_ctags_options_file') - let g:gutentags_ctags_options_file = '.gutctags' -endif - -if !exists('g:gutentags_ctags_check_tagfile') - let g:gutentags_ctags_check_tagfile = 0 -endif +let g:gutentags_ctags_executable = get(g:, 'gutentags_ctags_executable', 'ctags') +let g:gutentags_tagfile = get(g:, 'gutentags_tagfile', 'tags') +let g:gutentags_auto_set_tags = get(g:, 'gutentags_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) " }}} @@ -40,7 +26,7 @@ endif " Check if the ctags executable exists. - if g:gutentags_enabled && executable(g:gutentags_ctags_executable) == 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 " @@ -88,12 +74,23 @@ let l:cmd .= ' -t "' . l:actual_tags_file . '"' let l:cmd .= ' -p "' . l:actual_proj_dir . '"' if a:write_mode == 0 && l:tags_file_exists - let l:full_path = expand('%:p') - let l:cmd .= ' -s "' . l:full_path . '"' + let l:cur_file_path = expand('%:p') + if empty(g:gutentags_cache_dir) + 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) + let l:cmd .= ' -L ' . '"' . l:file_list_cmd. '"' + endif endif - " Pass the Gutentags options file first, and then the project specific - " one, so that users can override the default behaviour. - let l:cmd .= ' -o "' . gutentags#get_res_file('ctags.options') . '"' + 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 let l:proj_options_file = a:proj_dir . '/' . \g:gutentags_ctags_options_file if filereadable(l:proj_options_file) @@ -156,11 +153,9 @@ 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) - if exists('g:gutentags_ctags_executable_{l:type}') - return g:gutentags_ctags_executable_{l:type} - else - return g:gutentags_ctags_executable - endif + 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:process_options_file(proj_dir, path) abort
--- a/doc/gutentags.txt Mon May 16 02:09:40 2016 +0800 +++ b/doc/gutentags.txt Fri Sep 16 23:43:57 2016 +0800 @@ -54,12 +54,12 @@ 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 +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 to fast, or your project is really +multiple ctags processes if you save files too fast, or your project is really big. There are some similar Vim plugins out there ("vim-tags", "vim-autotag", @@ -76,8 +76,8 @@ 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 in Sublime Text or - Visual Studio or any other IDE. + project, it should start indexing it automatically, just like in Sublime Text + or Visual Studio or any other IDE. ============================================================================= @@ -239,9 +239,46 @@ file named after |gutentags_tagfile| will be created at the project root. Defaults to `[]` (an empty |List|). - A list of default markers will always be appended to - the user-defined ones: ['.git', '.hg', '.bzr', - '_darcs']. + 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', '.bzr', '_darcs', '_darcs', '_FOSSIL_', '.fslckout']` + + *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']`, which is the folder where + Homebrew is known to create a Git directory by default + on MacOS. + + *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 most + likely ignore |g:gutentags_project_root|. *gutentags_exclude* g:gutentags_exclude @@ -332,9 +369,11 @@ g:gutentags_enabled_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 open in a project. The function gets passed the + 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 also to manually set `b:gutentags_root` + (see |gutentags_project_root|). Defaults to "". *gutentags_define_advanced_commands* @@ -378,6 +417,40 @@ 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 + markerts 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. ============================================================================= 5. Project Settings *gutentags-project-settings*
--- a/plat/unix/update_scopedb.sh Mon May 16 02:09:40 2016 +0800 +++ b/plat/unix/update_scopedb.sh Fri Sep 16 23:43:57 2016 +0800 @@ -4,8 +4,10 @@ PROG_NAME=$0 CSCOPE_EXE=cscope +CSCOPE_ARGS= DB_FILE=cscope.out PROJECT_ROOT= +FILE_LIST_CMD= ShowUsage() { echo "Usage:" @@ -14,11 +16,12 @@ 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 "" } -while getopts "h?e:f:p:" opt; do +while getopts "h?e:f:p:L:" opt; do case $opt in h|\?) ShowUsage @@ -33,6 +36,9 @@ p) PROJECT_ROOT=$OPTARG ;; + L) + FILE_LIST_CMD=$OPTARG + ;; esac done @@ -47,16 +53,30 @@ echo $$ > "$DB_FILE.lock" # Remove lock and temp file if script is stopped unexpectedly. -trap 'rm -f "$DB_FILE.lock" "$DB_FILE.temp"' INT QUIT TERM EXIT +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 + $FILE_LIST_CMD > "${DB_FILE}.files" + else + # If using a tags cache directory, use absolute paths + $FILE_LIST_CMD | while read -r l; do + echo "${PROJECT_ROOT%/}/${l}" + done > "${DB_FILE}.files" + fi + CSCOPE_ARGS="${CSCOPE_ARGS} -i ${DB_FILE}.files" +else + CSCOPE_ARGS="${CSCOPE_ARGS} -R" +fi + echo "Running cscope" -echo "$CSCOPE_EXE -R -b -k -f \"$DB_FILE.temp\"" -"$CSCOPE_EXE" -R -v -b -k -f "$DB_FILE.temp" +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"
--- a/plat/unix/update_tags.sh Mon May 16 02:09:40 2016 +0800 +++ b/plat/unix/update_tags.sh Fri Sep 16 23:43:57 2016 +0800 @@ -7,6 +7,7 @@ CTAGS_ARGS= TAGS_FILE=tags PROJECT_ROOT= +FILE_LIST_CMD= UPDATED_SOURCE= PAUSE_BEFORE_EXIT=0 @@ -18,6 +19,7 @@ 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 [cmd=]: The file list command to run" 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" @@ -26,7 +28,7 @@ } -while getopts "h?e:x:t:p:s:o:c" opt; do +while getopts "h?e:x:t:p:L:s:o:c" opt; do case $opt in h|\?) ShowUsage @@ -44,6 +46,9 @@ p) PROJECT_ROOT=$OPTARG ;; + L) + FILE_LIST_CMD=$OPTARG + ;; s) UPDATED_SOURCE=$OPTARG ;; @@ -67,19 +72,32 @@ echo $$ > "$TAGS_FILE.lock" # Remove lock and temp file if script is stopped unexpectedly. -trap 'errorcode=$?; rm -f "$TAGS_FILE.lock" "$TAGS_FILE.temp"; exit $errorcode' INT QUIT TERM EXIT +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" - echo "grep -v \"$UPDATED_SOURCE\" \"$TAGS_FILE\" > \"$TAGS_FILE.temp\"" - grep -v "$UPDATED_SOURCE" "$TAGS_FILE" > "$TAGS_FILE.temp" + 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}" = "." ]; then + $FILE_LIST_CMD > "${TAGS_FILE}.files" + else + # If using a tags cache directory, use absolute paths + $FILE_LIST_CMD | while read -r l; do + echo "${PROJECT_ROOT%/}/${l}" + done > "${TAGS_FILE}.files" + fi + CTAGS_ARGS="${CTAGS_ARGS} -L ${TAGS_FILE}.files" + fi echo "Running ctags on whole project" echo "$CTAGS_EXE -f \"$TAGS_FILE.temp\" $CTAGS_ARGS \"$PROJECT_ROOT\"" $CTAGS_EXE -f "$TAGS_FILE.temp" $CTAGS_ARGS "$PROJECT_ROOT"
--- a/plat/win32/update_scopedb.cmd Mon May 16 02:09:40 2016 +0800 +++ b/plat/win32/update_scopedb.cmd Fri Sep 16 23:43:57 2016 +0800 @@ -6,7 +6,9 @@ rem ========================================== set CSCOPE_EXE=cscope +set CSCOPE_ARGS= set DB_FILE=cscope.out +set FILE_LIST_CMD= :ParseArgs if [%1]==[] goto :DoneParseArgs @@ -25,6 +27,11 @@ shift goto :LoopParseArgs ) +if [%1]==[-L] ( + set FILE_LIST_CMD=%~2 + shift + goto :LoopParseArgs +) echo Invalid Argument: %1 goto :Usage @@ -43,13 +50,25 @@ echo locked > "%DB_FILE%.lock" echo Running cscope -"%CSCOPE_EXE%" -R -b -k -f "%DB_FILE%" +if NOT ["%FILE_LIST_CMD%"]==[""] ( + if ["%PROJECT_ROOT%"]==["."] ( + call %FILE_LIST_CMD% > %DB_FILE%.files + ) else ( + rem Potentially useful: + rem http://stackoverflow.com/questions/9749071/cmd-iterate-stdin-piped-from-another-command + %FILE_LIST_CMD% | for /F "usebackq delims=" %%F in (`findstr "."`) do @echo %PROJECT_ROOT%\%%F > %DB_FILE%.files + ) + set CSCOPE_ARGS=%CSCOPE_ARGS% -i %TAGS_FILE%.files +) ELSE ( + set CSCOPE_ARGS=%CSCOPE_ARGS% -R +) +"%CSCOPE_EXE%" %CSCOPE_ARGS% -b -k -f "%DB_FILE%" if ERRORLEVEL 1 ( echo ERROR: Cscope executable returned non-zero code. ) echo Unlocking db file -del /F "%DB_FILE%.lock" +del /F "%DB_FILE%.files" "%DB_FILE%.lock" if ERRORLEVEL 1 ( echo ERROR: Unable to remove file lock. ) @@ -70,5 +89,6 @@ echo -e [exe=cscope]: The cscope executable to run echo -f [file=scope.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.
--- a/plat/win32/update_tags.cmd Mon May 16 02:09:40 2016 +0800 +++ b/plat/win32/update_tags.cmd Fri Sep 16 23:43:57 2016 +0800 @@ -9,6 +9,7 @@ set CTAGS_ARGS= set TAGS_FILE=tags set PROJECT_ROOT= +set FILE_LIST_CMD= set UPDATED_SOURCE= set PAUSE_BEFORE_EXIT=0 set LOG_FILE= @@ -35,6 +36,11 @@ shift goto :LoopParseArgs ) +if [%1]==[-L] ( + set FILE_LIST_CMD=%~2 + shift + goto :LoopParseArgs +) if [%1]==[-s] ( set UPDATED_SOURCE=%~2 shift @@ -77,7 +83,7 @@ if exist "%TAGS_FILE%" ( if not ["%UPDATED_SOURCE%"]==[""] ( echo Removing references to: %UPDATED_SOURCE% >> %LOG_FILE% - echo type "%TAGS_FILE%" ^| findstr /V /C:"%UPDATED_SOURCE%" ^> "%TAGS_FILE%.temp" >> %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 @@ -85,6 +91,20 @@ ) if ["%INDEX_WHOLE_PROJECT%"]==["1"] ( set CTAGS_ARGS=%CTAGS_ARGS% "%PROJECT_ROOT%" + if not ["%FILE_LIST_CMD%"]==[""] ( + echo Running custom file lister >> %LOG_FILE% + if ["%PROJECT_ROOT%"]==["."] ( + 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 + ) ) echo Running ctags >> %LOG_FILE% @@ -105,7 +125,7 @@ :Unlock echo Unlocking tags file... >> %LOG_FILE% -del /F "%TAGS_FILE%.lock" +del /F "%TAGS_FILE%.files" "%TAGS_FILE%.lock" if ERRORLEVEL 1 ( echo ERROR: Unable to remove file lock. >> %LOG_FILE% ) @@ -129,6 +149,7 @@ 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 [cmd=]: The file list command to run echo -s [file=]: The path to the source file that needs updating echo -l [log=]: The log file to output to echo -o [options=]: An options file to read additional options from
--- a/plugin/gutentags.vim Mon May 16 02:09:40 2016 +0800 +++ b/plugin/gutentags.vim Fri Sep 16 23:43:57 2016 +0800 @@ -9,9 +9,7 @@ finish endif -if !exists('g:gutentags_debug') - let g:gutentags_debug = 0 -endif +let g:gutentags_debug = get(g:, 'gutentags_debug', 0) if (exists('g:loaded_gutentags') || &cp) && !g:gutentags_debug finish @@ -21,64 +19,32 @@ endif let g:loaded_gutentags = 1 -if !exists('g:gutentags_trace') - let g:gutentags_trace = 0 -endif - -if !exists('g:gutentags_fake') - let g:gutentags_fake = 0 -endif - -if !exists('g:gutentags_background_update') - let g:gutentags_background_update = 1 -endif - -if !exists('g:gutentags_pause_after_update') - let g:gutentags_pause_after_update = 0 -endif +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_enabled_user_func = get(g:, 'gutentags_enabled_user_func', '') +let g:gutentags_modules = get(g:, 'gutentags_modules', ['ctags']) -if !exists('g:gutentags_enabled') - let g:gutentags_enabled = 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 - -if !exists('g:gutentags_enabled_user_func') - let g:gutentags_enabled_user_func = '' -endif +let g:gutentags_project_root_finder = '' -if !exists('g:gutentags_modules') - let g:gutentags_modules = ['ctags'] -endif - -if !exists('g:gutentags_project_root') - let g:gutentags_project_root = [] -endif -let g:gutentags_project_root += ['.git', '.hg', '.svn', '.bzr', '_darcs', '_FOSSIL_', '.fslckout'] - -if !exists('g:gutentags_project_info') - let g:gutentags_project_info = [] -endif +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'}) -if !exists('g:gutentags_exclude') - let g:gutentags_exclude = [] -endif - -if !exists('g:gutentags_resolve_symlinks') - let g:gutentags_resolve_symlinks = 0 -endif - -if !exists('g:gutentags_generate_on_new') - let g:gutentags_generate_on_new = 1 -endif - -if !exists('g:gutentags_generate_on_missing') - let g:gutentags_generate_on_missing = 1 -endif - -if !exists('g:gutentags_generate_on_write') - let g:gutentags_generate_on_write = 1 -endif +let g:gutentags_exclude = get(g:, 'gutentags_exclude', []) +let g:gutentags_exclude_project_root = get(g:, 'gutentags_exclude_project_root', ['/usr/local']) +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_file_list_command = get(g:, 'gutentags_file_list_command', '') if !exists('g:gutentags_cache_dir') let g:gutentags_cache_dir = '' @@ -89,9 +55,7 @@ let g:gutentags_cache_dir = fnamemodify(g:gutentags_cache_dir, ':s?[/\\]$??') endif -if !exists('g:gutentags_define_advanced_commands') - let g:gutentags_define_advanced_commands = 0 -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')