comparison plugin/autotags.vim @ 19:d48b0e48283b

Add support for storing tags files out of the way.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 31 Aug 2014 21:32:24 -0700
parents c11616828595
children 1f6ecd4258d7
comparison
equal deleted inserted replaced
18:b13e1141aa5c 19:d48b0e48283b
69 let g:autotags_generate_on_write = 1 69 let g:autotags_generate_on_write = 1
70 endif 70 endif
71 71
72 if !exists('g:autotags_auto_set_tags') 72 if !exists('g:autotags_auto_set_tags')
73 let g:autotags_auto_set_tags = 1 73 let g:autotags_auto_set_tags = 1
74 endif
75
76 if !exists('g:autotags_cache_dir')
77 let g:autotags_cache_dir = ''
78 else
79 let g:autotags_cache_dir = s:stripslash(g:autotags_cache_dir)
80 endif
81
82 if g:autotags_cache_dir != '' && !isdirectory(g:autotags_cache_dir)
83 call mkdir(g:autotags_cache_dir, 'p')
74 endif 84 endif
75 85
76 " }}} 86 " }}}
77 87
78 " Utilities {{{ 88 " Utilities {{{
120 130
121 " Autotags Setup {{{ 131 " Autotags Setup {{{
122 132
123 let s:known_tagfiles = [] 133 let s:known_tagfiles = []
124 134
125 " Finds the tag file path for the given current directory 135 " Finds the first directory with a project marker by walking up from the given
126 " (typically the directory of the file being edited) 136 " file path.
127 function! s:get_tagfile_for(path) abort 137 function! s:get_project_root(path) abort
128 let l:path = s:stripslash(a:path) 138 let l:path = s:stripslash(a:path)
129 let l:previous_path = "" 139 let l:previous_path = ""
130 let l:markers = g:autotags_project_root[:] 140 let l:markers = g:autotags_project_root[:]
131 if exists('g:ctrlp_root_markers') 141 if exists('g:ctrlp_root_markers')
132 let l:markers += g:ctrlp_root_markers 142 let l:markers += g:ctrlp_root_markers
133 endif 143 endif
134 while l:path != l:previous_path 144 while l:path != l:previous_path
135 for root in g:autotags_project_root 145 for root in g:autotags_project_root
136 if getftype(l:path . '/' . root) != "" 146 if getftype(l:path . '/' . root) != ""
137 return simplify(fnamemodify(l:path, ':p') . g:autotags_tagfile) 147 return simplify(fnamemodify(l:path, ':p'))
138 endif 148 endif
139 endfor 149 endfor
140 let l:previous_path = l:path 150 let l:previous_path = l:path
141 let l:path = fnamemodify(l:path, ':h') 151 let l:path = fnamemodify(l:path, ':h')
142 endwhile 152 endwhile
143 call s:throw("Can't figure out what tag file to use for: " . a:path) 153 call s:throw("Can't figure out what tag file to use for: " . a:path)
144 endfunction 154 endfunction
145 155
156 " Get the tag filename for a given project root.
157 function! s:get_tagfile(root_dir) abort
158 let l:tag_path = s:stripslash(a:root_dir) . '/' . g:autotags_tagfile
159 if g:autotags_cache_dir != ""
160 " Put the tag file in the cache dir instead of inside the
161 " projet root.
162 let l:tag_path = g:autotags_cache_dir . '/' .
163 \tr(l:tag_path, '\/:', '---')
164 let l:tag_path = substitute(l:tag_path, '/\-', '/', '')
165 endif
166 let l:tag_path = s:normalizepath(l:tag_path)
167 return l:tag_path
168 endfunction
169
146 " Setup autotags for the current buffer. 170 " Setup autotags for the current buffer.
147 function! s:setup_autotags() abort 171 function! s:setup_autotags() abort
148 if exists('b:autotags_file') && !g:autotags_debug 172 if exists('b:autotags_file') && !g:autotags_debug
149 " This buffer already has autotags support. 173 " This buffer already has autotags support.
150 return 174 return
151 endif 175 endif
152 176
153 " Try and find what tags file we should manage. 177 " Try and find what tags file we should manage.
154 call s:trace("Scanning buffer '" . bufname('%') . "' for autotags setup...") 178 call s:trace("Scanning buffer '" . bufname('%') . "' for autotags setup...")
155 try 179 try
156 let b:autotags_file = s:get_tagfile_for(expand('%:h')) 180 let b:autotags_root = s:get_project_root(expand('%:h'))
181 let b:autotags_file = s:get_tagfile(b:autotags_root)
157 catch /^autotags\:/ 182 catch /^autotags\:/
158 call s:trace("Can't figure out what tag file to use... no autotags support.") 183 call s:trace("Can't figure out what tag file to use... no autotags support.")
159 return 184 return
160 endtry 185 endtry
161 186
258 " is specified, it will go to the autotags-defined file. 283 " is specified, it will go to the autotags-defined file.
259 function! s:update_tags(write_mode, queue_mode, ...) abort 284 function! s:update_tags(write_mode, queue_mode, ...) abort
260 " Figure out where to save. 285 " Figure out where to save.
261 if a:0 == 1 286 if a:0 == 1
262 let l:tags_file = a:1 287 let l:tags_file = a:1
288 let l:proj_dir = fnamemodify(a:1, ':h')
263 else 289 else
264 let l:tags_file = b:autotags_file 290 let l:tags_file = b:autotags_file
291 let l:proj_dir = b:autotags_root
265 endif 292 endif
266 293
267 " Check that there's not already an update in progress. 294 " Check that there's not already an update in progress.
268 let l:lock_file = l:tags_file . '.lock' 295 let l:lock_file = l:tags_file . '.lock'
269 if filereadable(l:lock_file) 296 if filereadable(l:lock_file)
290 317
291 try 318 try
292 " Build the command line. 319 " Build the command line.
293 let l:cmd = s:get_execute_cmd() . s:runner_exe 320 let l:cmd = s:get_execute_cmd() . s:runner_exe
294 let l:cmd .= ' -e "' . g:autotags_executable . '"' 321 let l:cmd .= ' -e "' . g:autotags_executable . '"'
295 let l:cmd .= ' -t "' . fnamemodify(l:tags_file, ':t') . '"' 322 let l:cmd .= ' -t "' . l:tags_file . '"'
323 let l:cmd .= ' -p "' . l:proj_dir . '"'
296 if a:write_mode == 0 && filereadable(l:tags_file) 324 if a:write_mode == 0 && filereadable(l:tags_file)
297 " CTags specifies paths relative to the tags file with a `./` 325 let l:full_path = expand('%:p')
298 " prefix, so we need to specify the same prefix otherwise it will 326 let l:cmd .= ' -s "' . l:full_path . '"'
299 " think those are different files and we'll end up with duplicate
300 " entries.
301 let l:rel_path = s:normalizepath('./' . expand('%:.'))
302 let l:cmd .= ' -s "' . l:rel_path . '"'
303 endif 327 endif
304 for ign in split(&wildignore, ',') 328 for ign in split(&wildignore, ',')
305 let l:cmd .= ' -x ' . ign 329 let l:cmd .= ' -x ' . ign
306 endfor 330 endfor
307 for exc in g:autotags_exclude 331 for exc in g:autotags_exclude
313 if len(g:autotags_options_file) 337 if len(g:autotags_options_file)
314 let l:cmd .= ' -o "' . g:autotags_options_file . '"' 338 let l:cmd .= ' -o "' . g:autotags_options_file . '"'
315 endif 339 endif
316 if g:autotags_trace 340 if g:autotags_trace
317 if has('win32') 341 if has('win32')
318 let l:cmd .= ' -l "' . fnamemodify(l:tags_file, ':t') . '.log"' 342 let l:cmd .= ' -l "' . l:tags_file . '.log"'
319 else 343 else
320 let l:cmd .= ' > "' . fnamemodify(l:tags_file, ':t') . '.log" 2>&1' 344 let l:cmd .= ' > "' . l:tags_file . '.log" 2>&1'
321 endif 345 endif
322 else 346 else
323 if !has('win32') 347 if !has('win32')
324 let l:cmd .= ' > /dev/null 2>&1' 348 let l:cmd .= ' > /dev/null 2>&1'
325 endif 349 endif