changeset 73:130905a7fb9a

Merge pull-request #23 from GitHub.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 16 Jul 2015 21:55:28 -0700
parents 661a97eaf608 (diff) 99b95da1bed7 (current diff)
children cb1cf815052e
files
diffstat 4 files changed, 115 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/autoload/gutentags.vim	Sat May 02 00:21:19 2015 +0200
+++ b/autoload/gutentags.vim	Thu Jul 16 21:55:28 2015 -0700
@@ -95,6 +95,13 @@
         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)
+    if &buftype != ''
+        return
+    endif
+
     " Try and find what tags file we should manage.
     call gutentags#trace("Scanning buffer '" . bufname('%') . "' for gutentags setup...")
     try
@@ -208,18 +215,10 @@
 " queue_mode:
 "   0: if an update is already in progress, report it and abort.
 "   1: if an update is already in progress, queue another one.
-"
-" An additional argument specifies where to write the tags file. If nothing
-" is specified, it will go to the gutentags-defined file.
-function! s:update_tags(module, write_mode, queue_mode, ...) abort
+function! s:update_tags(module, 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:gutentags_files[a:module]
-        let l:proj_dir = b:gutentags_root
-    endif
+    let l:tags_file = b:gutentags_files[a:module]
+    let l:proj_dir = b:gutentags_root
 
     " Check that there's not already an update in progress.
     let l:lock_file = l:tags_file . '.lock'
@@ -256,16 +255,6 @@
 
 " }}}
 
-" Manual Tagfile Generation {{{
-
-function! s:generate_tags(bang, ...) abort
-    call s:update_tags(1, 0, a:1)
-endfunction
-
-command! -bang -nargs=1 -complete=file GutentagsGenerate :call s:generate_tags(<bang>0, <f-args>)
-
-" }}}
-
 " Utility Functions {{{
 
 function! gutentags#rescan(...)
--- a/autoload/gutentags/ctags.vim	Sat May 02 00:21:19 2015 +0200
+++ b/autoload/gutentags/ctags.vim	Thu Jul 16 21:55:28 2015 -0700
@@ -3,7 +3,7 @@
 " Global Options {{{
 
 if !exists('g:gutentags_ctags_executable')
-    let g:gutentags_executable = 'ctags'
+    let g:gutentags_ctags_executable = 'ctags'
 endif
 
 if !exists('g:gutentags_tagfile')
@@ -14,6 +14,10 @@
     let g:gutentags_auto_set_tags = 1
 endif
 
+if !exists('g:gutentags_ctags_options_file')
+    let g:gutentags_ctags_options_file = '.gutctags'
+endif
+
 " }}}
 
 " Gutentags Module Interface {{{
@@ -41,7 +45,7 @@
     try
         " Build the command line.
         let l:cmd = gutentags#get_execute_cmd() . s:runner_exe
-        let l:cmd .= ' -e "' . g:gutentags_executable . '"'
+        let l:cmd .= ' -e "' . s:get_ctags_executable() . '"'
         let l:cmd .= ' -t "' . a:tags_file . '"'
         let l:cmd .= ' -p "' . a:proj_dir . '"'
         if a:write_mode == 0 && filereadable(a:tags_file)
@@ -57,8 +61,11 @@
         if g:gutentags_pause_after_update
             let l:cmd .= ' -c'
         endif
-        let l:proj_options_file = a:proj_dir . '/.ctags'
+        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_trace
@@ -99,3 +106,69 @@
 
 " }}}
 
+" Utilities {{{
+
+" Get final ctags executable depending whether a filetype one is defined
+function! s:get_ctags_executable() abort
+    "Only consider the main filetype in cases like 'python.django'
+    let l:ftype = get(split(&filetype, '\.'), 0, '')
+    if exists('g:gutentags_ctags_executable_{l:ftype}')
+        return g:gutentags_ctags_executable_{l:ftype}
+    else
+        return g:gutentags_ctags_executable
+    endif
+endfunction
+
+function! s:process_options_file(proj_dir, path) abort
+    if 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 = matchend(line, '\v^\-\-exclude=')
+        if l:exarg < 0
+            call add(l:outlines, line)
+            continue
+        endif
+        let l:fullp = gutentags#normalizepath(l:proj_dir.'/'.
+                    \strpart(line, l:exarg + 1))
+        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
+
+" }}}
+
--- a/doc/gutentags.txt	Sat May 02 00:21:19 2015 +0200
+++ b/doc/gutentags.txt	Thu Jul 16 21:55:28 2015 -0700
@@ -223,6 +223,15 @@
                         Specifies the ctags executable to launch.
                         Defaults to `ctags`.
 
+                                     *gutentags_ctags_executable_{filetype}*
+g:gutentags_ctags_executable_{filetype}
+                        Specifies the ctags executable to launch for
+                        {filetype} files. It has precedence over
+                        g:gutentags_ctags_executable.
+                        Example: >
+                         let g:gutentags_ctags_executable_ruby = 'ripper-tags'
+<
+
                                                 *gutentags_tagfile*
 g:gutentags_tagfile
                         Specifies the name of the tag file to create. This
@@ -249,11 +258,11 @@
                                                 *gutentags_exclude*
 g:gutentags_exclude
                         A list of file patterns to pass to the
-                        |gutentags_executable| so that they will be excluded
-                        from parsing for the tags generation.
-                        Defaults to `[]` (an empty |List|).
-                        Patterns defined in 'wildignore' will also be given as
-                        exclude patterns to the `ctags` executable.
+                        |gutentags_ctags_executable| so that they will be
+                        excluded from parsing for the tags generation.
+                        Defaults to `[]` (an empty |List|).  Patterns defined
+                        in 'wildignore' will also be given as exclude patterns
+                        to the `ctags` executable.
 
                                                 *gutentags_auto_set_tags*
 g:gutentags_auto_set_tags
@@ -279,6 +288,20 @@
                         |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
--- a/plat/unix/update_tags.sh	Sat May 02 00:21:19 2015 +0200
+++ b/plat/unix/update_tags.sh	Thu Jul 16 21:55:28 2015 -0700
@@ -67,7 +67,7 @@
 echo $$ > "$TAGS_FILE.lock"
 
 # Remove lock and temp file if script is stopped unexpectedly.
-trap "rm -f \"$TAGS_FILE.lock\" \"$TAGS_FILE.temp\"" 0 3 4 15
+trap "errorcode=$?; rm -f \"$TAGS_FILE.lock\" \"$TAGS_FILE.temp\"; exit $errorcode" INT TERM EXIT
 
 if [ -f "$TAGS_FILE" ]; then
     if [ "$UPDATED_SOURCE" != "" ]; then