comparison autoload/gutentags/ctags.vim @ 202:b50b6d0f82dd

Refactor for Vim8/Neovim job support. - Refactor all modules' `generate` methods to use a vaguely generic job API wrapper that works for both Vim8 and Neovim jobs. - Make the `statusline` method use new `User` autocommands driven by the job-started/ended callbacks. - Remove all the lock-file-related stuff. - Better error/warning messages. - Move a few things around.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 31 Mar 2018 18:42:54 -0700
parents f7a417234dea
children f2fd7d5835d9
comparison
equal deleted inserted replaced
201:b41385032f86 202:b50b6d0f82dd
64 endif 64 endif
65 let s:did_check_exe = 1 65 let s:did_check_exe = 1
66 endif 66 endif
67 endfunction 67 endfunction
68 68
69 function! gutentags#ctags#generate(proj_dir, tags_file, write_mode) abort 69 function! gutentags#ctags#generate(proj_dir, tags_file, gen_opts) abort
70 let l:write_mode = a:gen_opts['write_mode']
71
70 let l:tags_file_exists = filereadable(a:tags_file) 72 let l:tags_file_exists = filereadable(a:tags_file)
71 let l:tags_file_relative = fnamemodify(a:tags_file, ':.') 73 let l:tags_file_relative = fnamemodify(a:tags_file, ':.')
72 let l:tags_file_is_local = len(l:tags_file_relative) < len(a:tags_file) 74 let l:tags_file_is_local = len(l:tags_file_relative) < len(a:tags_file)
73 75
74 if l:tags_file_exists && g:gutentags_ctags_check_tagfile 76 if l:tags_file_exists && g:gutentags_ctags_check_tagfile
75 let l:first_lines = readfile(a:tags_file, '', 1) 77 let l:first_lines = readfile(a:tags_file, '', 1)
76 if len(l:first_lines) == 0 || stridx(l:first_lines[0], '!_TAG_') != 0 78 if len(l:first_lines) == 0 || stridx(l:first_lines[0], '!_TAG_') != 0
77 call gutentags#throwerr( 79 call gutentags#throw(
78 \"File ".a:tags_file." doesn't appear to be ". 80 \"File ".a:tags_file." doesn't appear to be ".
79 \"a ctags file. Please delete it and run ". 81 \"a ctags file. Please delete it and run ".
80 \":GutentagsUpdate!.") 82 \":GutentagsUpdate!.")
81 return 83 return
82 endif 84 endif
99 let l:actual_proj_dir = a:proj_dir 101 let l:actual_proj_dir = a:proj_dir
100 let l:actual_tags_file = a:tags_file 102 let l:actual_tags_file = a:tags_file
101 endif 103 endif
102 104
103 " Build the command line. 105 " Build the command line.
104 let l:cmd = gutentags#get_execute_cmd() . s:runner_exe 106 let l:cmd = [s:runner_exe]
105 let l:cmd .= ' -e "' . s:get_ctags_executable(a:proj_dir) . '"' 107 let l:cmd += ['-e', '"' . s:get_ctags_executable(a:proj_dir) . '"']
106 let l:cmd .= ' -t "' . l:actual_tags_file . '"' 108 let l:cmd += ['-t', '"' . l:actual_tags_file . '"']
107 let l:cmd .= ' -p "' . l:actual_proj_dir . '"' 109 let l:cmd += ['-p', '"' . l:actual_proj_dir . '"']
108 if a:write_mode == 0 && l:tags_file_exists 110 if l:write_mode == 0 && l:tags_file_exists
109 let l:cur_file_path = expand('%:p') 111 let l:cur_file_path = expand('%:p')
110 if empty(g:gutentags_cache_dir) && l:tags_file_is_local 112 if empty(g:gutentags_cache_dir) && l:tags_file_is_local
111 let l:cur_file_path = fnamemodify(l:cur_file_path, ':.') 113 let l:cur_file_path = fnamemodify(l:cur_file_path, ':.')
112 endif 114 endif
113 let l:cmd .= ' -s "' . l:cur_file_path . '"' 115 let l:cmd += ['-s', '"' . l:cur_file_path . '"']
114 else 116 else
115 let l:file_list_cmd = gutentags#get_project_file_list_cmd(l:actual_proj_dir) 117 let l:file_list_cmd = gutentags#get_project_file_list_cmd(l:actual_proj_dir)
116 if !empty(l:file_list_cmd) 118 if !empty(l:file_list_cmd)
117 if match(l:file_list_cmd, '///') > 0 119 if match(l:file_list_cmd, '///') > 0
118 let l:suffopts = split(l:file_list_cmd, '///') 120 let l:suffopts = split(l:file_list_cmd, '///')
119 let l:suffoptstr = l:suffopts[1] 121 let l:suffoptstr = l:suffopts[1]
120 let l:file_list_cmd = l:suffopts[0] 122 let l:file_list_cmd = l:suffopts[0]
121 if l:suffoptstr == 'absolute' 123 if l:suffoptstr == 'absolute'
122 let l:cmd .= ' -A' 124 let l:cmd += ['-A']
123 endif 125 endif
124 endif 126 endif
125 let l:cmd .= ' -L ' . '"' . l:file_list_cmd. '"' 127 let l:cmd += ['-L', '"' . l:file_list_cmd. '"']
126 endif 128 endif
127 endif 129 endif
128 if empty(get(l:, 'file_list_cmd', '')) 130 if empty(get(l:, 'file_list_cmd', ''))
129 " Pass the Gutentags recursive options file before the project 131 " Pass the Gutentags recursive options file before the project
130 " options file, so that users can override --recursive. 132 " options file, so that users can override --recursive.
131 " Omit --recursive if this project uses a file list command. 133 " Omit --recursive if this project uses a file list command.
132 let l:cmd .= ' -o "' . gutentags#get_res_file('ctags_recursive.options') . '"' 134 let l:cmd += ['-o', '"' . gutentags#get_res_file('ctags_recursive.options') . '"']
133 endif 135 endif
134 if !empty(g:gutentags_ctags_extra_args) 136 if !empty(g:gutentags_ctags_extra_args)
135 let l:cmd .= ' -O '.shellescape(join(g:gutentags_ctags_extra_args)) 137 let l:cmd += ['-O', shellescape(join(g:gutentags_ctags_extra_args))]
136 endif 138 endif
137 if !empty(g:gutentags_ctags_post_process_cmd) 139 if !empty(g:gutentags_ctags_post_process_cmd)
138 let l:cmd .= ' -P '.shellescape(g:gutentags_ctags_post_process_cmd) 140 let l:cmd += ['-P', shellescape(g:gutentags_ctags_post_process_cmd)]
139 endif 141 endif
140 let l:proj_options_file = a:proj_dir . '/' . 142 let l:proj_options_file = a:proj_dir . '/' .
141 \g:gutentags_ctags_options_file 143 \g:gutentags_ctags_options_file
142 if filereadable(l:proj_options_file) 144 if filereadable(l:proj_options_file)
143 let l:proj_options_file = s:process_options_file( 145 let l:proj_options_file = s:process_options_file(
144 \a:proj_dir, l:proj_options_file) 146 \a:proj_dir, l:proj_options_file)
145 let l:cmd .= ' -o "' . l:proj_options_file . '"' 147 let l:cmd += ['-o', '"' . l:proj_options_file . '"']
146 endif 148 endif
147 if g:gutentags_ctags_exclude_wildignore 149 if g:gutentags_ctags_exclude_wildignore
148 for ign in split(&wildignore, ',') 150 for ign in split(&wildignore, ',')
149 let l:cmd .= ' -x ' . shellescape(ign, 1) 151 let l:cmd += ['-x', shellescape(ign, 1)]
150 endfor 152 endfor
151 endif 153 endif
152 for exc in g:gutentags_ctags_exclude 154 for exc in g:gutentags_ctags_exclude
153 let l:cmd .= ' -x ' . '"' . exc . '"' 155 let l:cmd += ['-x', '"' . exc . '"']
154 endfor 156 endfor
155 if g:gutentags_pause_after_update 157 if g:gutentags_pause_after_update
156 let l:cmd .= ' -c' 158 let l:cmd += ['-c']
157 endif 159 endif
158 if g:gutentags_trace 160 if g:gutentags_trace
159 if has('win32') 161 let l:cmd += ['-l', '"' . l:actual_tags_file . '.log"']
160 let l:cmd .= ' -l "' . l:actual_tags_file . '.log"' 162 endif
161 else 163 let l:cmd = gutentags#make_args(l:cmd)
162 let l:cmd .= ' ' . printf(s:unix_redir, '"' . l:actual_tags_file . '.log"') 164
163 endif 165 call gutentags#trace("Running: " . string(l:cmd))
164 else
165 if !has('win32')
166 let l:cmd .= ' ' . printf(s:unix_redir, '/dev/null')
167 endif
168 endif
169 let l:cmd .= gutentags#get_execute_cmd_suffix()
170
171 call gutentags#trace("Running: " . l:cmd)
172 call gutentags#trace("In: " . getcwd()) 166 call gutentags#trace("In: " . getcwd())
173 if !g:gutentags_fake 167 if !g:gutentags_fake
174 " Run the background process. 168 let l:job_opts = gutentags#build_default_job_options('ctags')
175 if !g:gutentags_trace 169 let l:job = gutentags#start_job(l:cmd, l:job_opts)
176 silent execute l:cmd 170 call gutentags#add_job('ctags', a:tags_file, l:job)
177 else
178 execute l:cmd
179 endif
180
181 " Flag this tags file as being in progress
182 call gutentags#add_progress('ctags', a:tags_file)
183 else 171 else
184 call gutentags#trace("(fake... not actually running)") 172 call gutentags#trace("(fake... not actually running)")
185 endif 173 endif
186 call gutentags#trace("") 174 endfunction
175
176 function! gutentags#ctags#on_job_exit(job, exit_val) abort
177 call gutentags#remove_job_by_data('ctags', a:job)
178
179 if a:exit_val != 0
180 call gutentags#warning("gutentags: ctags job failed, returned: ".
181 \string(a:exit_val))
182 endif
187 endfunction 183 endfunction
188 184
189 " }}} 185 " }}}
190 186
191 " Utilities {{{ 187 " Utilities {{{