Commits

abudden committed 4f1c65b

Added support for ctags variants that are not strictly ctags-compatible.

This can be specified in two ways: CtagsVariant allows pre-defined variants
to be supported directly in the code. CtagsArguments allows complete control
over the arguments to be passed to ctags in order to support more obscure
variants.

Comments (0)

Files changed (4)

doc/TagHighlight.txt

 		CtagsExecutable                  Link:|TagHL-CtagsExecutable|
 		   Specify the name of (or full path to) exuberant ctags.
 
+		CtagsVariant                     Link:|TagHL-CtagsVariant|
+		   Use a variant of ctags other than exuberant.
+
+		CtagsArguments                   Link:|TagHL-CtagsArguments|
+		   Specify an explicit list of arguments to pass to ctags.
+
 	Locations of Files (normal):
 
 		DefaultDirModeSearchWildcards    Link:|TagHL-DirModeSearchWildcards|
 
 2.4.4 Option Details                     *TagHighlight-option-details*      {{{3
 
+	CtagsArguments                       *TagHL-CtagsArguments*
+		This option allows advanced users to specify an explicit list of
+		arguments to pass to ctags.  In most cases, you won't want to use
+		this, but if |TagHL-CtagsExecutable| is pointing to a non-recognised
+		version of ctags, you may need to specify custom arguments in order to
+		get it to work with |TagHighlight|.  Before using this, consider the
+		option |TagHL-CtagsVariant|.  If you do use CtagsArguments, please get
+		in touch and let me know why: I might be able to create a new
+		CtagsVariant to do whatever you need.
+
+		Option Type: List
+		Default: [] (empty list)
+
 	CtagsExeFull                         *TagHL-CtagsExeFull*
 		Used internally to tell the python part of the application where ctags
 		is.  Do not use this option as it will be automatically overwritten.
 
 		See also |TagHL-TagFileName|.
 
+	CtagsVariant                         *TagHL-CtagsVariant*
+		Some variants of ctags expect different arguments to exuberant ctags.
+		This option allows you to tell |TagHighlight| to provide the arguments
+		in a different form.  Currently supported values for this option are
+		"exuberant" for the standard implementation and "jsctags" for jsctags.
+		Note that if you're using this option, you probably also want to set
+		|TagHL-CtagsExecutable| to something other than "ctags".
+
+		Option Type: String
+		Default: "exuberant"
+
 	DebugFile                            *TagHL-DebugFile*
 		If set to something other than "None" (the default), write debugging
 		messages to a file.
                              Javascript (thanks to Piotr Yordanov).
                              Transferred source repository from git to
                              mercurial (will maintain git mirror on github).
+                             Added support for custom ctags argument lists
+                             (option CtagsArguments) in order to allow use
+                             with versions of ctags (like jsctags) that don't
+                             accept the same arguments as exuberant ctags
+                             (thanks to Piotr Yordanov for the suggestion and
+                             help getting jsctags working).  Also added
+                             support for CtagsVariant arguments to simplify
+                             this process for known variants.  Support for
+                             jsctags is still fairly flaky as jsctags seems to
+                             fail very easily (and I've only used it for
+                             generating tags for its own source code!).
 
 2.1.5: 20th February 2012  : Added support for Scala (thanks to Lee Gauthier).
 

plugin/TagHighlight/data/options.txt

 	Type:string
 	Default:ctags
 	Help:CTAGS Executable Directory
+
+ctags_arguments:
+	CommandLineSwitches:--add-ctags-argument
+	VimOptionMap:CtagsArguments
+	Type:list
+	Default:[
+	Help:Explicit list of arguments to parse to ctags (for use with non-recognised ctags implementations).
+
+ctags_variant:
+	CommandLineSwitches:--ctags-variant
+	VimOptionMap:CtagsVariant
+	Type:string
+	Default:exuberant
+	Help:Tells TagHighlight which variant of ctags is being used: some have different requirements for their arguments.
  
 include_docs:
 	CommandLineSwitches:--include-docs

plugin/TagHighlight/module/ctags_interface.py

 #!/usr/bin/env python
 # Tag Highlighter:
 #   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
-# Copyright: Copyright (C) 2009-2011 A. S. Budden
+# Copyright: Copyright (C) 2009-2012 A. S. Budden
 #            Permission is hereby granted to use and distribute this code,
 #            with or without modifications, provided that this copyright
 #            notice is copied with it. Like anything else that's free,
 import os
 import re
 import glob
-from .utilities import DictDict
+from .utilities import DictDict, rglob
 from .languages import Languages
 from .debug import Debug
 
     (\t|$)            # It must be followed either by a tab or by the end of the line
     .*                # If it is followed by a tab, soak up the rest of the line; replace with the syntax keyword line
 ''', re.VERBOSE)
+
 field_const = re.compile(r'\bconst\b')
 
 def GenerateTags(options):
     Debug("Generating Tags", "Information")
 
-    args = GetCommandArgs(options)
+    # Change the working directory to the source root
+    # now so that argument globs work correctly.
+    os.chdir(options['source_root'])
 
-    os.chdir(options['source_root'])
+    if 'ctags_arguments' in options:
+        args = options['ctags_arguments']
+    else:
+        if 'ctags_variant' in options:
+            variant = options['ctags_variant']
+        else:
+            variant = 'exuberant'
+        args = ctags_variant_args[variant](options)
 
     ctags_cmd = [options['ctags_exe_full']] + args
 
 
     return ctags_entries
 
-def GetCommandArgs(options):
+def ExuberantGetCommandArgs(options):
     args = []
 
     ctags_languages = [l['CTagsName'] for l in options['language_handler'].GetAllLanguageHandlers()]
 
     return args
 
+def JSCtagsGetCommandArgs(options):
+    args = []
+    if options['ctags_file']:
+        args += ['-f', os.path.join(options['ctags_file_dir'], options['ctags_file'])]
+    # jsctags isn't very ctags-compatible: if you give it a directory
+    # and expect it to recurse, it fails on the first non-javascript
+    # file.  Therefore, we have to assume all javascript files have .js
+    # extensions and we have to find them ourselves.  This may well fail
+    # on Windows if there are a lot of them due to the limited command
+    # length on Windows.
+    if options['recurse']:
+        args += rglob('.', '*.js')
+    else:
+        args += glob.glob('*.js')
+    return args
+
+ctags_variant_args = {
+        'exuberant': ExuberantGetCommandArgs,
+        'jsctags': JSCtagsGetCommandArgs,
+        }
+
 key_regexp = re.compile('^(?P<keyword>.*?)\t(?P<remainder>.*\t(?P<kind>[a-zA-Z])(?:\t|$).*)')
 
 def ctags_key(ctags_line):

plugin/TagHighlight/module/utilities.py

 #!/usr/bin/env python
 # Tag Highlighter:
 #   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
-# Copyright: Copyright (C) 2009-2011 A. S. Budden
+# Copyright: Copyright (C) 2009-2012 A. S. Budden
 #            Permission is hereby granted to use and distribute this code,
 #            with or without modifications, provided that this copyright
 #            notice is copied with it. Like anything else that's free,
             return False
     return True
 
+def rglob(path, pattern):
+    # Tweaked version of the stackoverflow answer:
+    # http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python#2186565
+    import os, fnmatch
+    matches = []
+    for root, dirnames, filenames in os.walk(path):
+        matches += [os.path.join(root, i) for i in fnmatch.filter(filenames, pattern)]
+    return matches
 
 if __name__ == "__main__":
     import pprint