Skip to content

Commit 1194a6b

Browse files
committed
:TagsByFileType to create filetype specific tagsfiles from global tagsfile
1 parent 4df41ad commit 1194a6b

File tree

4 files changed

+79
-8
lines changed

4 files changed

+79
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ By default all tags are stored in a global tags file. When the tags file grows b
6868

6969
To avoid this problem you can set `g:easytags_by_filetype` to the path of an existing directory. The easytags plug-in will create separate tags files for each file type in the configured directory. These tags files are automatically registered by the easytags plug-in when the file type of a buffer is set.
7070

71+
Note that if you already have a global tags file you can create file type specific tags files from the global tags file using the command `:TagsByFileType`.
72+
7173
### The `g:easytags_always_enabled` option
7274

7375
By default the plug-in automatically generates and highlights tags when you stop typing for a few seconds (this works using the [CursorHold](http://vimdoc.sourceforge.net/htmldoc/autocmd.html#CursorHold) automatic command). This means that when you edit a file, the dynamic highlighting won't appear until you pause for a moment. If you don't like this you can configure the plug-in to always enable dynamic highlighting:

autoload/xolox/easytags.vim

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ function! xolox#easytags#autoload() " {{{2
6464
endfunction
6565

6666
function! xolox#easytags#update(silent, filter_tags, filenames) " {{{2
67+
" TODO Use save_by_filetype() when --force-language is not in effect!
6768
try
6869
let s:cached_filenames = {}
6970
let starttime = xolox#misc#timer#start()
@@ -209,7 +210,6 @@ function! s:filter_merge_tags(filter_tags, tagsfile, output) " {{{3
209210
call filter(entries, join(filters, ' && '))
210211
endif
211212
let num_filtered = num_old_entries - len(entries)
212-
call map(entries, 'join(v:val, "\t")')
213213
call extend(entries, a:output)
214214
if !xolox#easytags#write_tagsfile(a:tagsfile, headers, entries)
215215
let msg = "Failed to write filtered tags file %s!"
@@ -219,14 +219,19 @@ function! s:filter_merge_tags(filter_tags, tagsfile, output) " {{{3
219219
endfunction
220220

221221
function! s:find_tagged_files(new_entries) " {{{3
222+
" FIXME Don't parse tags files in multiple places!
222223
let tagged_files = {}
223-
for line in a:new_entries
224-
" Never corrupt the tags file by merging an invalid line
225-
" (probably an error message) with the existing tags!
226-
if match(line, '^[^\t]\+\t[^\t]\+\t.\+$') == -1
227-
throw "Exuberant Ctags returned invalid data: " . strtrans(line)
224+
for entry in a:new_entries
225+
if type(entry) == type([])
226+
let filename = entry[1]
227+
else
228+
if match(entry, '^[^\t]\+\t[^\t]\+\t.\+$') == -1
229+
" Never corrupt the tags file by merging an invalid line
230+
" (probably an error message) with the existing tags!
231+
throw "Exuberant Ctags returned invalid data: " . strtrans(entry)
232+
endif
233+
let filename = matchstr(entry, '^[^\t]\+\t\zs[^\t]\+')
228234
endif
229-
let filename = matchstr(line, '^[^\t]\+\t\zs[^\t]\+')
230235
if !has_key(tagged_files, filename)
231236
let filename = s:canonicalize(filename)
232237
let tagged_files[filename] = 1
@@ -285,6 +290,60 @@ function! xolox#easytags#highlight() " {{{2
285290
endtry
286291
endfunction
287292

293+
function! xolox#easytags#by_filetype(undo) " {{{2
294+
try
295+
let s:cached_filenames = {}
296+
if empty(g:easytags_by_filetype)
297+
throw "Please set g:easytags_by_filetype before running :TagsByFileType!"
298+
endif
299+
let global_tagsfile = expand(g:easytags_file)
300+
let disabled_tagsfile = global_tagsfile . '.disabled'
301+
if !a:undo
302+
let [headers, entries] = xolox#easytags#read_tagsfile(global_tagsfile)
303+
call s:save_by_filetype(headers, entries)
304+
call rename(global_tagsfile, disabled_tagsfile)
305+
let msg = "Finished copying tags from %s to %s! Note that your old tags file has been renamed to %s instead of deleting it, should you want to restore it."
306+
call xolox#misc#msg#info(msg, g:easytags_file, g:easytags_by_filetype, disabled_tagsfile)
307+
else
308+
let headers = []
309+
let all_entries = []
310+
for tagsfile in split(glob(g:easytags_by_filetype . '/*'), '\n')
311+
let [headers, entries] = xolox#easytags#read_tagsfile(tagsfile)
312+
call extend(all_entries, entries)
313+
endfor
314+
call xolox#easytags#write_tagsfile(global_tagsfile, headers, all_entries)
315+
call xolox#misc#msg#info("Finished copying tags from %s to %s!", g:easytags_by_filetype, g:easytags_file)
316+
endif
317+
catch
318+
call xolox#misc#msg#warn("%s: %s (at %s)", s:script, v:exception, v:throwpoint)
319+
finally
320+
unlet s:cached_filenames
321+
endtry
322+
endfunction
323+
324+
function! s:save_by_filetype(headers, entries)
325+
let filetypes = {}
326+
for entry in a:entries
327+
let ctags_ft = matchstr(entry[2], '\tlanguage:\zs\S\+')
328+
if !empty(ctags_ft)
329+
let vim_ft = xolox#easytags#to_vim_ft(ctags_ft)
330+
if !has_key(filetypes, vim_ft)
331+
let filetypes[vim_ft] = []
332+
endif
333+
call add(filetypes[vim_ft], entry)
334+
endif
335+
endfor
336+
let directory = xolox#misc#path#absolute(g:easytags_by_filetype)
337+
for vim_ft in keys(filetypes)
338+
let tagsfile = xolox#misc#path#merge(directory, vim_ft)
339+
if !filereadable(tagsfile)
340+
call xolox#easytags#write_tagsfile(tagsfile, a:headers, filetypes[vim_ft])
341+
else
342+
call s:filter_merge_tags(0, tagsfile, filetypes[vim_ft])
343+
endif
344+
endfor
345+
endfunction
346+
288347
" Public supporting functions (might be useful to others). {{{1
289348

290349
function! xolox#easytags#supported_filetypes() " {{{2
@@ -343,6 +402,7 @@ function! xolox#easytags#write_tagsfile(tagsfile, headers, entries) " {{{2
343402
let sort_order = 2
344403
endif
345404
endfor
405+
call map(a:entries, 's:join_entry(v:val)')
346406
if sort_order == 1
347407
call sort(a:entries)
348408
else
@@ -364,6 +424,10 @@ function! xolox#easytags#write_tagsfile(tagsfile, headers, entries) " {{{2
364424
return writefile(lines, a:tagsfile) == 0
365425
endfunction
366426

427+
function! s:join_entry(value)
428+
return type(a:value) == type([]) ? join(a:value, "\t") : a:value
429+
endfunction
430+
367431
function! xolox#easytags#file_has_tags(filename) " {{{2
368432
call s:cache_tagged_files()
369433
return has_key(s:tagged_files, s:resolve(a:filename))

doc/easytags.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ existing directory. The easytags plug-in will create separate tags files for
143143
each file type in the configured directory. These tags files are automatically
144144
registered by the easytags plug-in when the file type of a buffer is set.
145145

146+
Note that if you already have a global tags file you can create file type
147+
specific tags files from the global tags file using the command
148+
':TagsByFileType'.
149+
146150
-------------------------------------------------------------------------------
147151
The *g:easytags_always_enabled* option
148152

plugin/easytags.vim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
" URL: http://peterodding.com/code/vim/easytags/
55
" Requires: Exuberant Ctags (http://ctags.sf.net)
66
" License: MIT
7-
" Version: 2.3
7+
" Version: 2.3.1
88

99
" Support for automatic update using the GLVS plug-in.
1010
" GetLatestVimScripts: 3114 1 :AutoInstall: easytags.zip
@@ -145,6 +145,7 @@ call xolox#easytags#register(1)
145145

146146
command! -bar -bang -nargs=* -complete=file UpdateTags call xolox#easytags#update(0, <q-bang> == '!', [<f-args>])
147147
command! -bar HighlightTags call xolox#easytags#highlight()
148+
command! -bang TagsByFileType call xolox#easytags#by_filetype(<q-bang> == '!')
148149

149150
" Automatic commands. {{{1
150151

0 commit comments

Comments
 (0)