changeset 198:5fb056a9eefb

Don't change the current working directory more often than needed. Ctags/Cscope modules do this in their `generate` method when Gutentags already set the current directory to the project directory ahead of time.
author Ludovic Chabant <ludovic@chabant.com>
date Thu, 27 Jul 2017 22:38:02 -0700
parents eec9b72fe3df
children f7a417234dea
files autoload/gutentags/ctags.vim autoload/gutentags/gtags_cscope.vim
diffstat 2 files changed, 112 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/autoload/gutentags/ctags.vim	Thu Jul 27 22:10:09 2017 -0700
+++ b/autoload/gutentags/ctags.vim	Thu Jul 27 22:38:02 2017 -0700
@@ -67,11 +67,6 @@
 endfunction
 
 function! gutentags#ctags#generate(proj_dir, tags_file, write_mode) abort
-    " Get to the tags file directory because ctags is finicky about
-    " these things.
-    let l:prev_cwd = getcwd()
-    call gutentags#chdir(fnameescape(a:proj_dir))
-
     let l:tags_file_exists = filereadable(a:tags_file)
     let l:tags_file_relative = fnamemodify(a:tags_file, ':.')
     let l:tags_file_is_local = len(l:tags_file_relative) < len(a:tags_file)
@@ -94,10 +89,10 @@
         " 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...
+        " directory, for some reason... (which we are, our caller in
+        " `autoload/gutentags.vim` changed it).
         let l:actual_proj_dir = '.'
         let l:actual_tags_file = l:tags_file_relative
-        call gutentags#chdir(fnameescape(a:proj_dir))
     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.
@@ -105,96 +100,91 @@
         let l:actual_tags_file = a:tags_file
     endif
 
-    try
-        " Build the command line.
-        let l:cmd = gutentags#get_execute_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 a: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, ':.')
+    " Build the command line.
+    let l:cmd = gutentags#get_execute_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 a: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 .= ' -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 !empty(g:gutentags_ctags_extra_args)
-            let l:cmd .= ' -O '.shellescape(join(g:gutentags_ctags_extra_args))
-        endif
-        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 . '"'
+            let l:cmd .= ' -L ' . '"' . l:file_list_cmd. '"'
         endif
-        if g:gutentags_ctags_exclude_wildignore
-            for ign in split(&wildignore, ',')
-                let l:cmd .= ' -x ' . shellescape(ign, 1)
-            endfor
-        endif
-        for exc in g:gutentags_ctags_exclude
-            let l:cmd .= ' -x ' . '"' . exc . '"'
+    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 !empty(g:gutentags_ctags_extra_args)
+        let l:cmd .= ' -O '.shellescape(join(g:gutentags_ctags_extra_args))
+    endif
+    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
+        for ign in split(&wildignore, ',')
+            let l:cmd .= ' -x ' . shellescape(ign, 1)
         endfor
-        if g:gutentags_pause_after_update
-            let l:cmd .= ' -c'
-        endif
-        if g:gutentags_trace
-            if has('win32')
-                let l:cmd .= ' -l "' . l:actual_tags_file . '.log"'
-            else
-                let l:cmd .= ' ' . printf(s:unix_redir, '"' . l:actual_tags_file . '.log"')
-            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
+        if has('win32')
+            let l:cmd .= ' -l "' . l:actual_tags_file . '.log"'
         else
-            if !has('win32')
-                let l:cmd .= ' ' . printf(s:unix_redir, '/dev/null')
-            endif
+            let l:cmd .= ' ' . printf(s:unix_redir, '"' . l:actual_tags_file . '.log"')
         endif
-        let l:cmd .= gutentags#get_execute_cmd_suffix()
-
-        call gutentags#trace("Running: " . l:cmd)
-        call gutentags#trace("In:      " . getcwd())
-        if !g:gutentags_fake
-            " Run the background process.
-            if !g:gutentags_trace
-                silent execute l:cmd
-            else
-                execute l:cmd
-            endif
+    else
+        if !has('win32')
+            let l:cmd .= ' ' . printf(s:unix_redir, '/dev/null')
+        endif
+    endif
+    let l:cmd .= gutentags#get_execute_cmd_suffix()
 
-            " Flag this tags file as being in progress
-            let l:full_tags_file = fnamemodify(a:tags_file, ':p')
-            call gutentags#add_progress('ctags', l:full_tags_file)
+    call gutentags#trace("Running: " . l:cmd)
+    call gutentags#trace("In:      " . getcwd())
+    if !g:gutentags_fake
+        " Run the background process.
+        if !g:gutentags_trace
+            silent execute l:cmd
         else
-            call gutentags#trace("(fake... not actually running)")
+            execute l:cmd
         endif
-        call gutentags#trace("")
-    finally
-        " Restore the previous working directory.
-        call gutentags#chdir(fnameescape(l:prev_cwd))
-    endtry
+
+        " Flag this tags file as being in progress
+        let l:full_tags_file = fnamemodify(a:tags_file, ':p')
+        call gutentags#add_progress('ctags', l:full_tags_file)
+    else
+        call gutentags#trace("(fake... not actually running)")
+    endif
+    call gutentags#trace("")
 endfunction
 
 " }}}
--- a/autoload/gutentags/gtags_cscope.vim	Thu Jul 27 22:10:09 2017 -0700
+++ b/autoload/gutentags/gtags_cscope.vim	Thu Jul 27 22:38:02 2017 -0700
@@ -52,9 +52,9 @@
 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)
+	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')
@@ -149,48 +149,40 @@
 	endif
 
 	let l:use_jobs = has('job')
+	if has('win32')
+		let l:cmd = s:get_win32_cmd(l:use_jobs, l:proj_options, l:db_path)
+	else
+		let l:cmd = s:get_unix_cmd(l:use_jobs, l:proj_options, l:db_path)
+	endif
 
-	let l:prev_cwd = getcwd()
-	call gutentags#chdir(fnameescape(a:proj_dir))
-	try
-		if has('win32')
-			let l:cmd = s:get_win32_cmd(l:use_jobs, l:proj_options, l:db_path)
+	call gutentags#trace("Running: " . string(l:cmd))
+	call gutentags#trace("In:      " . getcwd())
+	if !g:gutentags_fake
+		if l:use_jobs
+			let l:job_opts = {
+						\'exit_cb': 'gutentags#gtags_cscope#on_job_exit',
+						\'out_cb': 'gutentags#gtags_cscope#on_job_out',
+						\'err_cb': 'gutentags#gtags_cscope#on_job_out'
+						\}
+			let l:job = job_start(l:cmd, job_opts)
+			call add(s:job_db_files, [l:job, a:db_file])
 		else
-			let l:cmd = s:get_unix_cmd(l:use_jobs, l:proj_options, l:db_path)
+			if !g:gutentags_trace
+				silent execute l:cmd
+			else
+				execute l:cmd
+			endif
+			if g:gutentags_auto_add_gtags_cscope
+				call s:add_db(a:db_file)
+			endif
 		endif
 
-		call gutentags#trace("Running: " . string(l:cmd))
-		call gutentags#trace("In:      " . getcwd())
-		if !g:gutentags_fake
-			if l:use_jobs
-				let l:job_opts = {
-							\'exit_cb': 'gutentags#gtags_cscope#on_job_exit',
-							\'out_cb': 'gutentags#gtags_cscope#on_job_out',
-							\'err_cb': 'gutentags#gtags_cscope#on_job_out'
-							\}
-				let l:job = job_start(l:cmd, job_opts)
-				call add(s:job_db_files, [l:job, a:db_file])
-			else
-				if !g:gutentags_trace
-					silent execute l:cmd
-				else
-					execute l:cmd
-				endif
-				if g:gutentags_auto_add_gtags_cscope
-					call s:add_db(a:db_file)
-				endif
-			endif
-
-			let l:full_gtags_file = fnamemodify(l:db_path, ':p')
-			call gutentags#add_progress('gtags_cscope', a:db_file)
-		else
-			call gutentags#trace("(fake... not actually running)")
-		endif
-		call gutentags#trace("")
-    finally
-        " Restore the previous working directory.
-        call gutentags#chdir(fnameescape(l:prev_cwd))
-    endtry
+		let l:full_gtags_file = fnamemodify(l:db_path, ':p')
+		call gutentags#add_progress('gtags_cscope', a:db_file)
+	else
+		call gutentags#trace("(fake... not actually running)")
+	endif
+	call gutentags#trace("")
 endfunction
 
 " }}}