Mercurial > vim-gutentags
annotate plugin/autotags.vim @ 16:c11616828595
Add an option to specify a `ctags` options file to be used.
Fixed some arguments being forgotten in the Windows script.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 21 Aug 2014 11:32:32 -0700 |
parents | b557282af215 |
children | d48b0e48283b |
rev | line source |
---|---|
0 | 1 " autotags.vim - Automatic ctags management for Vim |
2 " Maintainer: Ludovic Chabant <http://ludovic.chabant.com> | |
3 " Version: 0.0.1 | |
4 | |
5 " Globals {{{ | |
6 | |
7 if !exists('g:autotags_debug') | |
8 let g:autotags_debug = 0 | |
9 endif | |
10 | |
11 if (exists('g:loaded_autotags') || &cp) && !g:autotags_debug | |
12 finish | |
13 endif | |
14 if (exists('g:loaded_autotags') && g:autotags_debug) | |
15 echom "Reloaded autotags." | |
16 endif | |
17 let g:loaded_autotags = 1 | |
18 | |
19 if !exists('g:autotags_trace') | |
3 | 20 let g:autotags_trace = 0 |
0 | 21 endif |
22 | |
23 if !exists('g:autotags_fake') | |
24 let g:autotags_fake = 0 | |
25 endif | |
26 | |
27 if !exists('g:autotags_background_update') | |
28 let g:autotags_background_update = 1 | |
29 endif | |
30 | |
11
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
31 if !exists('g:autotags_pause_after_update') |
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
32 let g:autotags_pause_after_update = 0 |
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
33 endif |
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
34 |
0 | 35 if !exists('g:autotags_enabled') |
36 let g:autotags_enabled = 1 | |
37 endif | |
38 | |
39 if !exists('g:autotags_executable') | |
40 let g:autotags_executable = 'ctags' | |
41 endif | |
42 | |
43 if !exists('g:autotags_tagfile') | |
44 let g:autotags_tagfile = 'tags' | |
45 endif | |
46 | |
47 if !exists('g:autotags_project_root') | |
48 let g:autotags_project_root = [] | |
49 endif | |
50 let g:autotags_project_root += ['.git', '.hg', '.bzr', '_darcs'] | |
51 | |
16
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
52 if !exists('g:autotags_options_file') |
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
53 let g:autotags_options_file = '' |
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
54 endif |
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
55 |
3 | 56 if !exists('g:autotags_exclude') |
57 let g:autotags_exclude = [] | |
58 endif | |
59 | |
14
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
60 if !exists('g:autotags_generate_on_new') |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
61 let g:autotags_generate_on_new = 1 |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
62 endif |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
63 |
3 | 64 if !exists('g:autotags_generate_on_missing') |
65 let g:autotags_generate_on_missing = 1 | |
66 endif | |
67 | |
68 if !exists('g:autotags_generate_on_write') | |
69 let g:autotags_generate_on_write = 1 | |
70 endif | |
71 | |
72 if !exists('g:autotags_auto_set_tags') | |
73 let g:autotags_auto_set_tags = 1 | |
74 endif | |
75 | |
0 | 76 " }}} |
77 | |
78 " Utilities {{{ | |
79 | |
80 " Throw an exception message. | |
81 function! s:throw(message) | |
82 let v:errmsg = "autotags: " . a:message | |
83 throw v:errmsg | |
84 endfunction | |
85 | |
86 " Prints a message if debug tracing is enabled. | |
87 function! s:trace(message, ...) | |
88 if g:autotags_trace || (a:0 && a:1) | |
89 let l:message = "autotags: " . a:message | |
90 echom l:message | |
91 endif | |
92 endfunction | |
93 | |
94 " Strips the ending slash in a path. | |
95 function! s:stripslash(path) | |
96 return fnamemodify(a:path, ':s?[/\\]$??') | |
97 endfunction | |
98 | |
99 " Normalizes the slashes in a path. | |
100 function! s:normalizepath(path) | |
101 if exists('+shellslash') && &shellslash | |
102 return substitute(a:path, '\v/', '\\', 'g') | |
103 elseif has('win32') | |
104 return substitute(a:path, '\v/', '\\', 'g') | |
105 else | |
106 return a:path | |
107 endif | |
108 endfunction | |
109 | |
110 " Shell-slashes the path (opposite of `normalizepath`). | |
111 function! s:shellslash(path) | |
112 if exists('+shellslash') && !&shellslash | |
113 return substitute(a:path, '\v\\', '/', 'g') | |
114 else | |
115 return a:path | |
116 endif | |
117 endfunction | |
118 | |
119 " }}} | |
120 | |
121 " Autotags Setup {{{ | |
122 | |
14
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
123 let s:known_tagfiles = [] |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
124 |
0 | 125 " Finds the tag file path for the given current directory |
126 " (typically the directory of the file being edited) | |
127 function! s:get_tagfile_for(path) abort | |
128 let l:path = s:stripslash(a:path) | |
129 let l:previous_path = "" | |
5
12f4f50f4d3a
Use CtrlP root markers if they've been defined.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
130 let l:markers = g:autotags_project_root[:] |
12f4f50f4d3a
Use CtrlP root markers if they've been defined.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
131 if exists('g:ctrlp_root_markers') |
12f4f50f4d3a
Use CtrlP root markers if they've been defined.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
132 let l:markers += g:ctrlp_root_markers |
12f4f50f4d3a
Use CtrlP root markers if they've been defined.
Ludovic Chabant <ludovic@chabant.com>
parents:
3
diff
changeset
|
133 endif |
0 | 134 while l:path != l:previous_path |
135 for root in g:autotags_project_root | |
136 if getftype(l:path . '/' . root) != "" | |
137 return simplify(fnamemodify(l:path, ':p') . g:autotags_tagfile) | |
138 endif | |
139 endfor | |
140 let l:previous_path = l:path | |
141 let l:path = fnamemodify(l:path, ':h') | |
142 endwhile | |
143 call s:throw("Can't figure out what tag file to use for: " . a:path) | |
144 endfunction | |
145 | |
146 " Setup autotags for the current buffer. | |
147 function! s:setup_autotags() abort | |
3 | 148 if exists('b:autotags_file') && !g:autotags_debug |
149 " This buffer already has autotags support. | |
0 | 150 return |
151 endif | |
3 | 152 |
14
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
153 " Try and find what tags file we should manage. |
3 | 154 call s:trace("Scanning buffer '" . bufname('%') . "' for autotags setup...") |
0 | 155 try |
156 let b:autotags_file = s:get_tagfile_for(expand('%:h')) | |
157 catch /^autotags\:/ | |
3 | 158 call s:trace("Can't figure out what tag file to use... no autotags support.") |
0 | 159 return |
160 endtry | |
161 | |
3 | 162 " We know what tags file to manage! Now set things up. |
0 | 163 call s:trace("Setting autotags for buffer '" . bufname('%') . "' with tagfile: " . b:autotags_file) |
164 | |
3 | 165 " Set the tags file for Vim to use. |
166 if g:autotags_auto_set_tags | |
167 execute 'setlocal tags^=' . b:autotags_file | |
168 endif | |
169 | |
170 " Autocommands for updating the tags on save. | |
0 | 171 let l:bn = bufnr('%') |
172 execute 'augroup autotags_buffer_' . l:bn | |
173 execute ' autocmd!' | |
3 | 174 execute ' autocmd BufWritePost <buffer=' . l:bn . '> call s:write_triggered_update_tags()' |
0 | 175 execute 'augroup end' |
176 | |
3 | 177 " Miscellaneous commands. |
0 | 178 command! -buffer -bang AutotagsUpdate :call s:manual_update_tags(<bang>0) |
3 | 179 |
14
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
180 " Add this tags file to the known tags files if it wasn't there already. |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
181 let l:found = index(s:known_tagfiles, b:autotags_file) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
182 if l:found < 0 |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
183 call add(s:known_tagfiles, b:autotags_file) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
184 |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
185 " Generate this new file depending on settings and stuff. |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
186 if g:autotags_generate_on_missing && !filereadable(b:autotags_file) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
187 call s:trace("Generating missing tags file: " . b:autotags_file) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
188 call s:update_tags(1, 0) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
189 elseif g:autotags_generate_on_new |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
190 call s:trace("Generating tags file: " . b:autotags_file) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
191 call s:update_tags(1, 0) |
b8f23bf7b20f
Ability to (re)generate tags when opening a new project.
Ludovic Chabant <ludovic@chabant.com>
parents:
11
diff
changeset
|
192 endif |
3 | 193 endif |
0 | 194 endfunction |
195 | |
196 augroup autotags_detect | |
197 autocmd! | |
198 autocmd BufNewFile,BufReadPost * call s:setup_autotags() | |
199 autocmd VimEnter * if expand('<amatch>')==''|call s:setup_autotags()|endif | |
200 augroup end | |
201 | |
202 " }}} | |
203 | |
204 " Tags File Management {{{ | |
205 | |
206 let s:runner_exe = expand('<sfile>:h:h') . '/plat/unix/update_tags.sh' | |
207 if has('win32') | |
208 let s:runner_exe = expand('<sfile>:h:h') . '\plat\win32\update_tags.cmd' | |
209 endif | |
210 | |
211 let s:update_queue = [] | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
212 let s:maybe_in_progress = {} |
0 | 213 |
214 " Get how to execute an external command depending on debug settings. | |
215 function! s:get_execute_cmd() abort | |
216 if has('win32') | |
217 let l:cmd = '!start ' | |
218 if g:autotags_background_update | |
219 let l:cmd .= '/b ' | |
220 endif | |
221 return l:cmd | |
222 else | |
223 return '!' | |
224 endif | |
225 endfunction | |
226 | |
3 | 227 " Get the suffix for how to execute an external command. |
228 function! s:get_execute_cmd_suffix() abort | |
229 if has('win32') | |
230 return '' | |
231 else | |
232 return ' &' | |
233 endif | |
234 endfunction | |
235 | |
0 | 236 " (Re)Generate the tags file for the current buffer's file. |
237 function! s:manual_update_tags(bang) abort | |
238 call s:update_tags(a:bang, 0) | |
239 endfunction | |
240 | |
3 | 241 " (Re)Generate the tags file for a buffer that just go saved. |
242 function! s:write_triggered_update_tags() abort | |
243 if g:autotags_enabled && g:autotags_generate_on_write | |
244 call s:update_tags(0, 1) | |
245 endif | |
246 endfunction | |
247 | |
0 | 248 " Update the tags file for the current buffer's file. |
249 " write_mode: | |
250 " 0: update the tags file if it exists, generate it otherwise. | |
251 " 1: always generate (overwrite) the tags file. | |
252 " | |
253 " queue_mode: | |
254 " 0: if an update is already in progress, report it and abort. | |
255 " 1: if an update is already in progress, queue another one. | |
256 " | |
257 " An additional argument specifies where to write the tags file. If nothing | |
258 " is specified, it will go to the autotags-defined file. | |
259 function! s:update_tags(write_mode, queue_mode, ...) abort | |
260 " Figure out where to save. | |
261 if a:0 == 1 | |
262 let l:tags_file = a:1 | |
263 else | |
264 let l:tags_file = b:autotags_file | |
265 endif | |
266 | |
267 " Check that there's not already an update in progress. | |
268 let l:lock_file = l:tags_file . '.lock' | |
269 if filereadable(l:lock_file) | |
270 if a:queue_mode == 1 | |
271 let l:idx = index(s:update_queue, l:tags_file) | |
272 if l:idx < 0 | |
273 call add(s:update_queue, l:tags_file) | |
274 endif | |
275 call s:trace("Tag file '" . l:tags_file . "' is already being updated. Queuing it up...") | |
276 call s:trace("") | |
277 else | |
278 echom "autotags: The tags file is already being updated, please try again later." | |
279 echom "" | |
280 endif | |
281 return | |
282 endif | |
283 | |
284 " Switch to the project root to make the command line smaller, and make | |
285 " it possible to get the relative path of the filename to parse if we're | |
286 " doing an incremental update. | |
287 let l:prev_cwd = getcwd() | |
288 let l:work_dir = fnamemodify(l:tags_file, ':h') | |
289 execute "chdir " . l:work_dir | |
290 | |
291 try | |
292 " Build the command line. | |
293 let l:cmd = s:get_execute_cmd() . s:runner_exe | |
3 | 294 let l:cmd .= ' -e "' . g:autotags_executable . '"' |
295 let l:cmd .= ' -t "' . fnamemodify(l:tags_file, ':t') . '"' | |
0 | 296 if a:write_mode == 0 && filereadable(l:tags_file) |
297 " CTags specifies paths relative to the tags file with a `./` | |
298 " prefix, so we need to specify the same prefix otherwise it will | |
299 " think those are different files and we'll end up with duplicate | |
300 " entries. | |
301 let l:rel_path = s:normalizepath('./' . expand('%:.')) | |
3 | 302 let l:cmd .= ' -s "' . l:rel_path . '"' |
0 | 303 endif |
3 | 304 for ign in split(&wildignore, ',') |
305 let l:cmd .= ' -x ' . ign | |
306 endfor | |
307 for exc in g:autotags_exclude | |
308 let l:cmd .= ' -x ' . exc | |
309 endfor | |
11
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
310 if g:autotags_pause_after_update |
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
311 let l:cmd .= ' -p' |
478638833c3b
Fix Win32 update script, add option to pause it.
Ludovic Chabant <ludovic@chabant.com>
parents:
10
diff
changeset
|
312 endif |
16
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
313 if len(g:autotags_options_file) |
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
314 let l:cmd .= ' -o "' . g:autotags_options_file . '"' |
c11616828595
Add an option to specify a `ctags` options file to be used.
Ludovic Chabant <ludovic@chabant.com>
parents:
15
diff
changeset
|
315 endif |
0 | 316 if g:autotags_trace |
3 | 317 if has('win32') |
318 let l:cmd .= ' -l "' . fnamemodify(l:tags_file, ':t') . '.log"' | |
319 else | |
9
f0f1d20d6f5c
On Unix, either log to file or don't log at all.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
320 let l:cmd .= ' > "' . fnamemodify(l:tags_file, ':t') . '.log" 2>&1' |
f0f1d20d6f5c
On Unix, either log to file or don't log at all.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
321 endif |
f0f1d20d6f5c
On Unix, either log to file or don't log at all.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
322 else |
f0f1d20d6f5c
On Unix, either log to file or don't log at all.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
323 if !has('win32') |
f0f1d20d6f5c
On Unix, either log to file or don't log at all.
Ludovic Chabant <ludovic@chabant.com>
parents:
5
diff
changeset
|
324 let l:cmd .= ' > /dev/null 2>&1' |
3 | 325 endif |
0 | 326 endif |
3 | 327 let l:cmd .= s:get_execute_cmd_suffix() |
328 | |
0 | 329 call s:trace("Running: " . l:cmd) |
330 call s:trace("In: " . l:work_dir) | |
331 if !g:autotags_fake | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
332 " Run the background process. |
0 | 333 if !g:autotags_trace |
334 silent execute l:cmd | |
335 else | |
336 execute l:cmd | |
337 endif | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
338 |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
339 " Flag this tags file as being in progress |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
340 let l:full_tags_file = fnamemodify(l:tags_file, ':p') |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
341 let s:maybe_in_progress[l:full_tags_file] = localtime() |
0 | 342 else |
343 call s:trace("(fake... not actually running)") | |
344 endif | |
345 call s:trace("") | |
346 finally | |
347 " Restore the current directory... | |
348 execute "chdir " . l:prev_cwd | |
349 endtry | |
350 endfunction | |
351 | |
352 " }}} | |
353 | |
354 " Manual Tagfile Generation {{{ | |
355 | |
356 function! s:generate_tags(bang, ...) abort | |
357 call s:update_tags(1, 0, a:1) | |
358 endfunction | |
359 | |
360 command! -bang -nargs=1 -complete=file AutotagsGenerate :call s:generate_tags(<bang>0, <f-args>) | |
361 | |
362 " }}} | |
363 | |
3 | 364 " Toggles and Miscellaneous Commands {{{ |
0 | 365 |
366 command! AutotagsToggleEnabled :let g:autotags_enabled=!g:autotags_enabled | |
367 command! AutotagsToggleTrace :call autotags#trace() | |
368 command! AutotagsUnlock :call delete(b:autotags_file . '.lock') | |
369 | |
10
b853ad0e7afd
Only define `:AutotagsToggleFake` if debug mode is on.
Ludovic Chabant <ludovic@chabant.com>
parents:
9
diff
changeset
|
370 if g:autotags_debug |
b853ad0e7afd
Only define `:AutotagsToggleFake` if debug mode is on.
Ludovic Chabant <ludovic@chabant.com>
parents:
9
diff
changeset
|
371 command! AutotagsToggleFake :call autotags#fake() |
b853ad0e7afd
Only define `:AutotagsToggleFake` if debug mode is on.
Ludovic Chabant <ludovic@chabant.com>
parents:
9
diff
changeset
|
372 endif |
b853ad0e7afd
Only define `:AutotagsToggleFake` if debug mode is on.
Ludovic Chabant <ludovic@chabant.com>
parents:
9
diff
changeset
|
373 |
0 | 374 " }}} |
375 | |
376 " Autoload Functions {{{ | |
377 | |
378 function! autotags#rescan(...) | |
379 if exists('b:autotags_file') | |
380 unlet b:autotags_file | |
381 endif | |
382 if a:0 && a:1 | |
383 let l:trace_backup = g:autotags_trace | |
384 let l:autotags_trace = 1 | |
385 endif | |
386 call s:setup_autotags() | |
387 if a:0 && a:1 | |
388 let g:autotags_trace = l:trace_backup | |
389 endif | |
390 endfunction | |
391 | |
392 function! autotags#trace(...) | |
393 let g:autotags_trace = !g:autotags_trace | |
394 if a:0 > 0 | |
395 let g:autotags_trace = a:1 | |
396 endif | |
397 if g:autotags_trace | |
398 echom "autotags: Tracing is enabled." | |
399 else | |
400 echom "autotags: Tracing is disabled." | |
401 endif | |
402 echom "" | |
403 endfunction | |
404 | |
405 function! autotags#fake(...) | |
406 let g:autotags_fake = !g:autotags_fake | |
407 if a:0 > 0 | |
408 let g:autotags_fake = a:1 | |
409 endif | |
410 if g:autotags_fake | |
411 echom "autotags: Now faking autotags." | |
412 else | |
413 echom "autotags: Now running autotags for real." | |
414 endif | |
415 echom "" | |
416 endfunction | |
417 | |
3 | 418 function! autotags#inprogress() |
419 echom "autotags: generations in progress:" | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
420 for mip in keys(s:maybe_in_progress) |
3 | 421 echom mip |
422 endfor | |
423 echom "" | |
424 endfunction | |
425 | |
0 | 426 " }}} |
427 | |
3 | 428 " Statusline Functions {{{ |
429 | |
430 " Prints whether a tag file is being generated right now for the current | |
431 " buffer in the status line. | |
432 " | |
433 " Arguments can be passed: | |
434 " - args 1 and 2 are the prefix and suffix, respectively, of whatever output, | |
435 " if any, is going to be produced. | |
436 " (defaults to empty strings) | |
437 " - arg 3 is the text to be shown if tags are currently being generated. | |
438 " (defaults to 'TAGS') | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
439 |
3 | 440 function! autotags#statusline(...) abort |
441 if !exists('b:autotags_file') | |
442 " This buffer doesn't have autotags. | |
443 return '' | |
444 endif | |
445 | |
446 " Figure out what the user is customizing. | |
447 let l:gen_msg = 'TAGS' | |
448 if a:0 >= 0 | |
449 let l:gen_msg = a:1 | |
450 endif | |
451 | |
452 " To make this function as fast as possible, we first check whether the | |
453 " current buffer's tags file is 'maybe' being generated. This provides a | |
454 " nice and quick bail out for 99.9% of cases before we need to this the | |
455 " file-system to check the lock file. | |
456 let l:abs_tag_file = fnamemodify(b:autotags_file, ':p') | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
457 let l:timestamp = get(s:maybe_in_progress, l:abs_tag_file) |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
458 if l:timestamp == 0 |
3 | 459 return '' |
460 endif | |
15
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
461 " It's maybe generating! Check if the lock file is still there... but |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
462 " don't do it too soon after the script was originally launched, because |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
463 " there can be a race condition where we get here just before the script |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
464 " had a chance to write the lock file. |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
465 if (localtime() - l:timestamp) > 1 && |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
466 \!filereadable(l:abs_tag_file . '.lock') |
b557282af215
Fix race condition between the statusline and the lock file.
Ludovic Chabant <ludovic@chabant.com>
parents:
14
diff
changeset
|
467 call remove(s:maybe_in_progress, l:abs_tag_file) |
3 | 468 return '' |
469 endif | |
470 " It's still there! So probably `ctags` is still running... | |
471 " (although there's a chance it crashed, or the script had a problem, and | |
472 " the lock file has been left behind... we could try and run some | |
473 " additional checks here to see if it's legitimately running, and | |
474 " otherwise delete the lock file... maybe in the future...) | |
475 return l:gen_msg | |
476 endfunction | |
477 | |
478 " }}} | |
479 |