Skip to content

Commit

Permalink
Add support for storing tags files out of the way.
Browse files Browse the repository at this point in the history
  • Loading branch information
ludovicchabant committed Sep 1, 2014
1 parent 2ef43cc commit d8f178b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 19 deletions.
11 changes: 8 additions & 3 deletions plat/unix/update_tags.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ PROG_NAME=$0
CTAGS_EXE=ctags
CTAGS_ARGS=
TAGS_FILE=tags
PROJECT_ROOT=
UPDATED_SOURCE=
PAUSE_BEFORE_EXIT=0

Expand All @@ -16,14 +17,15 @@ ShowUsage() {
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 " -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 ""
}


while getopts "h?e:x:t:s:" opt; do
while getopts "h?e:x:t:p:s:" opt; do
case $opt in
h|\?)
ShowUsage
Expand All @@ -38,6 +40,9 @@ while getopts "h?e:x:t:s:" opt; do
t)
TAGS_FILE=$OPTARG
;;
p)
PROJECT_ROOT=$OPTARG
;;
s)
UPDATED_SOURCE=$OPTARG
;;
Expand Down Expand Up @@ -70,8 +75,8 @@ if [[ -f "$TAGS_FILE" ]]; then
fi

echo "Running ctags"
echo "$CTAGS_EXE -R -f \"$TAGS_FILE.temp\" $CTAGS_ARGS"
$CTAGS_EXE -R -f "$TAGS_FILE.temp" $CTAGS_ARGS
echo "$CTAGS_EXE -R -f \"$TAGS_FILE.temp\" $CTAGS_ARGS $PROJECT_ROOT"
$CTAGS_EXE -R -f "$TAGS_FILE.temp" $CTAGS_ARGS $PROJECT_ROOT

echo "Replacing tags file"
echo "mv -f \"$TAGS_FILE.temp\" \"$TAGS_FILE\""
Expand Down
11 changes: 9 additions & 2 deletions plat/win32/update_tags.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ rem ==========================================
set CTAGS_EXE=ctags
set CTAGS_ARGS=
set TAGS_FILE=tags
set PROJECT_ROOT=
set UPDATED_SOURCE=
set PAUSE_BEFORE_EXIT=0
set LOG_FILE=
Expand All @@ -29,6 +30,11 @@ if [%1]==[-t] (
shift
goto :LoopParseArgs
)
if [%1]==[-p] (
set PROJECT_ROOT=%~2
shift
goto :LoopParseArgs
)
if [%1]==[-s] (
set UPDATED_SOURCE=%~2
shift
Expand Down Expand Up @@ -77,8 +83,8 @@ if exist "%TAGS_FILE%" (
)

echo Running ctags >> %LOG_FILE%
echo "%CTAGS_EXE%" -R -f "%TAGS_FILE%.temp" %CTAGS_ARGS% >> %LOG_FILE%
"%CTAGS_EXE%" -R -f "%TAGS_FILE%.temp" %CTAGS_ARGS%
echo "%CTAGS_EXE%" -R -f "%TAGS_FILE%.temp" %CTAGS_ARGS% %PROJECT_ROOT% >> %LOG_FILE%
"%CTAGS_EXE%" -R -f "%TAGS_FILE%.temp" %CTAGS_ARGS% %PROJECT_ROOT%

echo Replacing tags file >> %LOG_FILE%
echo move /Y "%TAGS_FILE%.temp" "%TAGS_FILE%" >> %LOG_FILE%
Expand All @@ -105,6 +111,7 @@ 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 -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
Expand Down
52 changes: 38 additions & 14 deletions plugin/autotags.vim
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ if !exists('g:autotags_auto_set_tags')
let g:autotags_auto_set_tags = 1
endif

if !exists('g:autotags_cache_dir')
let g:autotags_cache_dir = ''
else
let g:autotags_cache_dir = s:stripslash(g:autotags_cache_dir)
endif

if g:autotags_cache_dir != '' && !isdirectory(g:autotags_cache_dir)
call mkdir(g:autotags_cache_dir, 'p')
endif

" }}}

" Utilities {{{
Expand Down Expand Up @@ -122,9 +132,9 @@ endfunction

let s:known_tagfiles = []

" Finds the tag file path for the given current directory
" (typically the directory of the file being edited)
function! s:get_tagfile_for(path) abort
" Finds the first directory with a project marker by walking up from the given
" file path.
function! s:get_project_root(path) abort
let l:path = s:stripslash(a:path)
let l:previous_path = ""
let l:markers = g:autotags_project_root[:]
Expand All @@ -134,7 +144,7 @@ function! s:get_tagfile_for(path) abort
while l:path != l:previous_path
for root in g:autotags_project_root
if getftype(l:path . '/' . root) != ""
return simplify(fnamemodify(l:path, ':p') . g:autotags_tagfile)
return simplify(fnamemodify(l:path, ':p'))
endif
endfor
let l:previous_path = l:path
Expand All @@ -143,6 +153,20 @@ function! s:get_tagfile_for(path) abort
call s:throw("Can't figure out what tag file to use for: " . a:path)
endfunction

" Get the tag filename for a given project root.
function! s:get_tagfile(root_dir) abort
let l:tag_path = s:stripslash(a:root_dir) . '/' . g:autotags_tagfile
if g:autotags_cache_dir != ""
" Put the tag file in the cache dir instead of inside the
" projet root.
let l:tag_path = g:autotags_cache_dir . '/' .
\tr(l:tag_path, '\/:', '---')
let l:tag_path = substitute(l:tag_path, '/\-', '/', '')
endif
let l:tag_path = s:normalizepath(l:tag_path)
return l:tag_path
endfunction

" Setup autotags for the current buffer.
function! s:setup_autotags() abort
if exists('b:autotags_file') && !g:autotags_debug
Expand All @@ -153,7 +177,8 @@ function! s:setup_autotags() abort
" Try and find what tags file we should manage.
call s:trace("Scanning buffer '" . bufname('%') . "' for autotags setup...")
try
let b:autotags_file = s:get_tagfile_for(expand('%:h'))
let b:autotags_root = s:get_project_root(expand('%:h'))
let b:autotags_file = s:get_tagfile(b:autotags_root)
catch /^autotags\:/
call s:trace("Can't figure out what tag file to use... no autotags support.")
return
Expand Down Expand Up @@ -260,8 +285,10 @@ function! s:update_tags(write_mode, queue_mode, ...) abort
" Figure out where to save.
if a:0 == 1
let l:tags_file = a:1
let l:proj_dir = fnamemodify(a:1, ':h')
else
let l:tags_file = b:autotags_file
let l:proj_dir = b:autotags_root
endif

" Check that there's not already an update in progress.
Expand Down Expand Up @@ -292,14 +319,11 @@ function! s:update_tags(write_mode, queue_mode, ...) abort
" Build the command line.
let l:cmd = s:get_execute_cmd() . s:runner_exe
let l:cmd .= ' -e "' . g:autotags_executable . '"'
let l:cmd .= ' -t "' . fnamemodify(l:tags_file, ':t') . '"'
let l:cmd .= ' -t "' . l:tags_file . '"'
let l:cmd .= ' -p "' . l:proj_dir . '"'
if a:write_mode == 0 && filereadable(l:tags_file)
" CTags specifies paths relative to the tags file with a `./`
" prefix, so we need to specify the same prefix otherwise it will
" think those are different files and we'll end up with duplicate
" entries.
let l:rel_path = s:normalizepath('./' . expand('%:.'))
let l:cmd .= ' -s "' . l:rel_path . '"'
let l:full_path = expand('%:p')
let l:cmd .= ' -s "' . l:full_path . '"'
endif
for ign in split(&wildignore, ',')
let l:cmd .= ' -x ' . ign
Expand All @@ -315,9 +339,9 @@ function! s:update_tags(write_mode, queue_mode, ...) abort
endif
if g:autotags_trace
if has('win32')
let l:cmd .= ' -l "' . fnamemodify(l:tags_file, ':t') . '.log"'
let l:cmd .= ' -l "' . l:tags_file . '.log"'
else
let l:cmd .= ' > "' . fnamemodify(l:tags_file, ':t') . '.log" 2>&1'
let l:cmd .= ' > "' . l:tags_file . '.log" 2>&1'
endif
else
if !has('win32')
Expand Down

0 comments on commit d8f178b

Please sign in to comment.