From 1194a6b8a2e21db24fe051c0679d17b8a6878ebf Mon Sep 17 00:00:00 2001 From: Peter Odding Date: Mon, 13 Jun 2011 18:18:49 +0200 Subject: :TagsByFileType to create filetype specific tagsfiles from global tagsfile --- README.md | 2 ++ autoload/xolox/easytags.vim | 78 +++++++++++++++++++++++++++++++++++++++++---- doc/easytags.txt | 4 +++ plugin/easytags.vim | 3 +- 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7eaf494..924384c 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ By default all tags are stored in a global tags file. When the tags file grows b 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. +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`. + ### The `g:easytags_always_enabled` option 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: diff --git a/autoload/xolox/easytags.vim b/autoload/xolox/easytags.vim index c78b261..b879458 100644 --- a/autoload/xolox/easytags.vim +++ b/autoload/xolox/easytags.vim @@ -64,6 +64,7 @@ function! xolox#easytags#autoload() " {{{2 endfunction function! xolox#easytags#update(silent, filter_tags, filenames) " {{{2 + " TODO Use save_by_filetype() when --force-language is not in effect! try let s:cached_filenames = {} let starttime = xolox#misc#timer#start() @@ -209,7 +210,6 @@ function! s:filter_merge_tags(filter_tags, tagsfile, output) " {{{3 call filter(entries, join(filters, ' && ')) endif let num_filtered = num_old_entries - len(entries) - call map(entries, 'join(v:val, "\t")') call extend(entries, a:output) if !xolox#easytags#write_tagsfile(a:tagsfile, headers, entries) let msg = "Failed to write filtered tags file %s!" @@ -219,14 +219,19 @@ function! s:filter_merge_tags(filter_tags, tagsfile, output) " {{{3 endfunction function! s:find_tagged_files(new_entries) " {{{3 + " FIXME Don't parse tags files in multiple places! let tagged_files = {} - for line in a:new_entries - " Never corrupt the tags file by merging an invalid line - " (probably an error message) with the existing tags! - if match(line, '^[^\t]\+\t[^\t]\+\t.\+$') == -1 - throw "Exuberant Ctags returned invalid data: " . strtrans(line) + for entry in a:new_entries + if type(entry) == type([]) + let filename = entry[1] + else + if match(entry, '^[^\t]\+\t[^\t]\+\t.\+$') == -1 + " Never corrupt the tags file by merging an invalid line + " (probably an error message) with the existing tags! + throw "Exuberant Ctags returned invalid data: " . strtrans(entry) + endif + let filename = matchstr(entry, '^[^\t]\+\t\zs[^\t]\+') endif - let filename = matchstr(line, '^[^\t]\+\t\zs[^\t]\+') if !has_key(tagged_files, filename) let filename = s:canonicalize(filename) let tagged_files[filename] = 1 @@ -285,6 +290,60 @@ function! xolox#easytags#highlight() " {{{2 endtry endfunction +function! xolox#easytags#by_filetype(undo) " {{{2 + try + let s:cached_filenames = {} + if empty(g:easytags_by_filetype) + throw "Please set g:easytags_by_filetype before running :TagsByFileType!" + endif + let global_tagsfile = expand(g:easytags_file) + let disabled_tagsfile = global_tagsfile . '.disabled' + if !a:undo + let [headers, entries] = xolox#easytags#read_tagsfile(global_tagsfile) + call s:save_by_filetype(headers, entries) + call rename(global_tagsfile, disabled_tagsfile) + 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." + call xolox#misc#msg#info(msg, g:easytags_file, g:easytags_by_filetype, disabled_tagsfile) + else + let headers = [] + let all_entries = [] + for tagsfile in split(glob(g:easytags_by_filetype . '/*'), '\n') + let [headers, entries] = xolox#easytags#read_tagsfile(tagsfile) + call extend(all_entries, entries) + endfor + call xolox#easytags#write_tagsfile(global_tagsfile, headers, all_entries) + call xolox#misc#msg#info("Finished copying tags from %s to %s!", g:easytags_by_filetype, g:easytags_file) + endif + catch + call xolox#misc#msg#warn("%s: %s (at %s)", s:script, v:exception, v:throwpoint) + finally + unlet s:cached_filenames + endtry +endfunction + +function! s:save_by_filetype(headers, entries) + let filetypes = {} + for entry in a:entries + let ctags_ft = matchstr(entry[2], '\tlanguage:\zs\S\+') + if !empty(ctags_ft) + let vim_ft = xolox#easytags#to_vim_ft(ctags_ft) + if !has_key(filetypes, vim_ft) + let filetypes[vim_ft] = [] + endif + call add(filetypes[vim_ft], entry) + endif + endfor + let directory = xolox#misc#path#absolute(g:easytags_by_filetype) + for vim_ft in keys(filetypes) + let tagsfile = xolox#misc#path#merge(directory, vim_ft) + if !filereadable(tagsfile) + call xolox#easytags#write_tagsfile(tagsfile, a:headers, filetypes[vim_ft]) + else + call s:filter_merge_tags(0, tagsfile, filetypes[vim_ft]) + endif + endfor +endfunction + " Public supporting functions (might be useful to others). {{{1 function! xolox#easytags#supported_filetypes() " {{{2 @@ -343,6 +402,7 @@ function! xolox#easytags#write_tagsfile(tagsfile, headers, entries) " {{{2 let sort_order = 2 endif endfor + call map(a:entries, 's:join_entry(v:val)') if sort_order == 1 call sort(a:entries) else @@ -364,6 +424,10 @@ function! xolox#easytags#write_tagsfile(tagsfile, headers, entries) " {{{2 return writefile(lines, a:tagsfile) == 0 endfunction +function! s:join_entry(value) + return type(a:value) == type([]) ? join(a:value, "\t") : a:value +endfunction + function! xolox#easytags#file_has_tags(filename) " {{{2 call s:cache_tagged_files() return has_key(s:tagged_files, s:resolve(a:filename)) diff --git a/doc/easytags.txt b/doc/easytags.txt index 4a6a394..1765f28 100644 --- a/doc/easytags.txt +++ b/doc/easytags.txt @@ -143,6 +143,10 @@ 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. +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'. + ------------------------------------------------------------------------------- The *g:easytags_always_enabled* option diff --git a/plugin/easytags.vim b/plugin/easytags.vim index 61fe3ed..9697967 100644 --- a/plugin/easytags.vim +++ b/plugin/easytags.vim @@ -4,7 +4,7 @@ " URL: http://peterodding.com/code/vim/easytags/ " Requires: Exuberant Ctags (http://ctags.sf.net) " License: MIT -" Version: 2.3 +" Version: 2.3.1 " Support for automatic update using the GLVS plug-in. " GetLatestVimScripts: 3114 1 :AutoInstall: easytags.zip @@ -145,6 +145,7 @@ call xolox#easytags#register(1) command! -bar -bang -nargs=* -complete=file UpdateTags call xolox#easytags#update(0, == '!', []) command! -bar HighlightTags call xolox#easytags#highlight() +command! -bang TagsByFileType call xolox#easytags#by_filetype( == '!') " Automatic commands. {{{1 -- cgit v1.2.3