Commits

abudden committed c81cd4f

Moved bundle to top level. Can now clone git repository directly into bundle directory of vimfiles.

Comments (0)

Files changed (108)

autoload/TagHighlight/Debug.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    08/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLDebug') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLDebug = 1
+
+let TagHighlight#Debug#DebugLevels = [
+			\ "None",
+			\ "Critical",
+			\ "Error",
+			\ "Warning",
+			\ "Status",
+			\ "Information",
+			\ ]
+
+function! TagHighlight#Debug#GetDebugLevel()
+	try
+		let debug_level = TagHighlight#Option#GetOption('DebugLevel')
+	catch /Unrecognised option/
+		" Probably loading the option file, so no debug level available
+		" yet, so assume 'Information'
+		let debug_level = 'Information'
+	endtry
+	let debug_num = index(g:TagHighlight#Debug#DebugLevels, debug_level)
+	if debug_num != -1
+		return debug_num
+	else
+		return index(g:TagHighlight#Debug#DebugLevels, 'Error')
+	endif
+endfunction
+
+function! TagHighlight#Debug#GetDebugLevelName()
+	let debug_level_num = TagHighlight#Debug#GetDebugLevel()
+	return g:TagHighlight#Debug#DebugLevels[debug_level_num]
+endfunction
+
+function! TagHighlight#Debug#DebugLevelIncludes(level)
+	let level_index = index(g:TagHighlight#Debug#DebugLevels, a:level)
+	if level_index == -1
+		let level_index = index(g:TagHighlight#Debug#DebugLevels, 'Critical')
+	endif
+	if level_index <= TagHighlight#Debug#GetDebugLevel()
+		return 1
+	else
+		return 0
+	endif
+endfunction
+
+function! TagHighlight#Debug#DebugUpdateTypesFile(filename)
+	" Update the types file with debugging turned on
+	if a:filename ==? 'None'
+		" Force case to be correct
+		let debug_file = 'None'
+	else
+		let debug_file = a:filename
+	endif
+
+	let debug_options = ["DebugFile","DebugLevel"]
+
+	" Store the old debug options
+	for dbg_option in debug_options
+		let stored_option_name = 'Stored'.dbg_option
+		if has_key(g:TagHighlightSettings, dbg_option)
+			let g:TagHighlightSettings[stored_option_name] = g:TagHighlightSettings[dbg_option]
+		else
+			let g:TagHighlightSettings[stored_option_name] = 'None'
+		endif
+	endfor
+
+	let g:TagHighlightSettings['DebugFile'] = debug_file
+	let g:TagHighlightSettings['DebugLevel'] = 'Information'
+
+	call TagHLDebug("========================================================", "Information")
+	call TagHighlight#Generation#UpdateAndRead(0)
+
+	" Get rid of the 'stored' versions of the debug options
+	for dbg_option in debug_options
+		let stored_option_name = 'Stored'.dbg_option
+		if g:TagHighlightSettings[stored_option_name] == 'None'
+			unlet g:TagHighlightSettings[dbg_option]
+		else
+			let g:TagHighlightSettings[dbg_option] = g:TagHighlightSettings[stored_option_name]
+		endif
+		unlet g:TagHighlightSettings[stored_option_name]
+	endfor
+endfunction

autoload/TagHighlight/Find.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    08/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLFind') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLFind = 1
+
+" Tools for finding files.  When generating the tags and types file, we need
+" to decide where to place it.  If the user has configured the mode in which
+" everything is based on the current directory (which works well with the
+" project plugin), the current directory is what we use.  If the user wants to
+" search up for a tags file, we can look for an existing tags file and stop
+" when we find one, starting either from the current directory or source
+" directory.  If we don't, either use the current directory or the source file
+" directory (configuration).
+"
+" It should also be possible to place the tags file in a remote location and
+" use either the current directory, source directory or explicitly set
+" directory for the base of the scan.
+
+" Option structure:
+"
+" [gb]:TagHighlightSettings:
+"	DefaultDirModePriority:[Explicit,UpFromCurrent,UpFromFile,CurrentDirectory,FileDirectory]
+"	TagFileDirModePriority:["Default"] or as above
+"	TypesFileDirModePriority:As tag file
+"	ConfigFileDirModePriority:As tag file
+"	DefaultDirModeSearchWildcard:'' (look for tags file) or something specific (*.uvopt)?
+"	MaxDirSearchLevels: (integer)
+"
+" Explicit Locations:
+"
+"  [gb]:TagHighlightSettings:
+"    TagFileDirectory:str (NONE)
+"    TagFileName:str (tags)
+"    TypesFileDirectory:str (NONE)
+"    TypesPrefix:str (types)
+"    ProjectConfigFileName:str (taghl_config.txt)
+"    ProjectConfigFileDirectory:str (NONE)
+
+function! TagHighlight#Find#LocateFile(which, suffix)
+	call TagHLDebug("Locating file " . a:which . " with suffix " . a:suffix, 'Information')
+
+	" a:which is 'TAGS', 'TYPES', 'CONFIG'
+	let default_priority = TagHighlight#Option#GetOption('DefaultDirModePriority')
+	call TagHLDebug("Priority: " . string(default_priority), "Information")
+	let default_search_wildcards = TagHighlight#Option#GetOption('DefaultDirModeSearchWildcards')
+
+
+	let file = expand('<afile>')
+	if len(file) == 0
+		let file = expand('%')
+	endif
+
+	if a:which == 'TAGS'
+		" Suffix is ignored here
+		let filename = TagHighlight#Option#GetOption('TagFileName')
+		let search_priority = TagHighlight#Option#GetOption('TagFileDirModePriority')
+		let explicit_location = TagHighlight#Option#GetOption('TagFileDirectory')
+		let search_wildcards = TagHighlight#Option#GetOption('TagFileSearchWildcards')
+	elseif a:which == 'TYPES'
+		let filename = TagHighlight#Option#GetOption('TypesFilePrefix') . '_' .
+					\ a:suffix . "." .
+					\ TagHighlight#Option#GetOption('TypesFileExtension')
+		let search_priority = TagHighlight#Option#GetOption('TypesFileDirModePriority')
+		let explicit_location = TagHighlight#Option#GetOption('TypesFileDirectory')
+		let search_wildcards = TagHighlight#Option#GetOption('TypesFileSearchWildcards')
+	elseif a:which == 'CONFIG'
+		" Suffix is ignored here
+		let filename = TagHighlight#Option#GetOption('ProjectConfigFileName')
+		let search_priority = TagHighlight#Option#GetOption('ProjectConfigFileDirModePriority')
+		let explicit_location = TagHighlight#Option#GetOption('ProjectConfigFileDirectory')
+		let search_wildcards = TagHighlight#Option#GetOption('ProjectConfigFileSearchWildcards')
+	else
+		throw "Unrecognised file"
+	endif
+
+	if search_wildcards[0] == 'Default'
+		let search_wildcards = default_search_wildcards
+	endif
+
+	if search_priority[0] == 'Default'
+		let search_priority = default_priority
+	endif
+
+	" Ensure there's no trailing slash on 'explicit location'
+	if explicit_location[len(explicit_location)-1] == '/'
+		let explicit_location = explicit_location[:len(explicit_location)-2]
+	endif
+
+	" Result contains 'Found','FullPath','Directory','Filename','Exists']
+	let result = {}
+
+	for search_mode in search_priority
+		if search_mode == 'Explicit' && explicit_location != 'None'
+			" Use explicit location, overriding everything else
+			call TagHLDebug('Using explicit location', 'Information')
+			let result['Directory'] = explicit_location
+			let result['Filename'] = filename
+		elseif search_mode == 'UpFromCurrent'
+			" Start in the current directory and search up
+			let dir = fnamemodify('.',':p:h')
+			let result = s:ScanUp(dir, search_wildcards)
+			if has_key(result, 'Directory')
+				call TagHLDebug('Found location with UpFromCurrent', 'Information')
+				let result['Filename'] = filename
+			endif
+		elseif search_mode == 'UpFromFile'
+			" Start in the directory containing the current file and search up
+			let dir = fnamemodify(file,':p:h')
+			let result = s:ScanUp(dir, search_wildcards)
+			if has_key(result, 'Directory')
+				call TagHLDebug('Found location with UpFromFile', 'Information')
+				let result['Filename'] = filename
+			endif
+		elseif search_mode == 'CurrentDirectory'
+			call TagHLDebug('Using current directory', 'Information')
+			let result['Directory'] = fnamemodify('.',':p:h')
+			let result['Filename'] = filename
+		elseif search_mode == 'FileDirectory'
+			call TagHLDebug('Using file directory', 'Information')
+			let result['Directory'] = fnamemodify(file,':p:h')
+			let result['Filename'] = filename
+		endif
+		if has_key(result, 'Directory')
+			let result['FullPath'] = result['Directory'] . '/' . result['Filename']
+			let result['Found'] = 1
+			call TagHLDebug('Found file location', 'Information')
+			if filereadable(result['FullPath'])
+				call TagHLDebug('File exists', 'Information')
+				let result['Exists'] = 1
+			else
+				call TagHLDebug('File does not exist', 'Information')
+				let result['Exists'] = 0
+			endif
+			break
+		endif
+	endfor
+
+	if ! has_key(result, 'Directory')
+		call TagHLDebug("Couldn't find path", 'Warning')
+		let result = {'Found': 0, 'Exists': 0}
+	endif
+
+	return result
+endfunction
+
+function! s:ScanUp(dir, wildcards)
+	let result = {}
+	let max_levels = TagHighlight#Option#GetOption('MaxDirSearchLevels')
+	let levels = 0
+	let new_dir = a:dir
+	let dir = ''
+	let found = 0
+
+	call TagHLDebug("Searching up from " . a:dir . " for " . string(a:wildcards), 'Information')
+
+	" new_dir != dir check looks for the root directory
+	while new_dir != dir
+		let dir = new_dir
+		let new_dir = fnamemodify(dir, ':h')
+		
+		call TagHLDebug("Trying " . dir, "Information")
+		for wildcard in a:wildcards
+			let glob_pattern = dir
+			if glob_pattern[len(glob_pattern)-1] != '/'
+				let glob_pattern .= '/'
+			endif
+			let glob_pattern .= wildcard
+			let glob_result = split(glob(glob_pattern), "\n")
+			if len(glob_result) > 0
+				for r in glob_result
+					if filereadable(r)
+						let found = 1
+					endif
+				endfor
+				if found
+					call TagHLDebug("Found match: " . dir . " (" . glob_pattern . ")", "Information")
+					let result['Directory'] = dir
+					let found = 1
+					break
+				else
+					call TagHLDebug("Wildcard matches were not readable (directory?)", "Information")
+				endif
+			endif
+		endfor
+		if found
+			break
+		endif
+
+		" Check for recursion limit
+		let levels += 1
+		if (max_levels > 0) && (levels >= max_levels)
+			call TagHLDebug("Hit recursion limit", "Information")
+			break
+		endif
+	endwhile
+	if new_dir == dir
+		" Must have reached root directory
+		call TagHLDebug("Reached root directory and stopped", "Information")
+	endif
+	return result
+endfunction

autoload/TagHighlight/Generation.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    08/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLGeneration') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLGeneration = 1
+
+function! TagHighlight#Generation#UpdateTypesFile()
+	" Load the version information if we haven't already
+	call TagHighlight#Version#LoadVersionInfo()
+
+	" Debug information for configuration
+	if TagHighlight#Debug#DebugLevelIncludes('Information')
+		call TagHLDebug("Running UpdateTypesFile function at " . strftime("%Y%m%d-%H%M%S"), "Information")
+		call TagHLDebug("Current directory is " . getcwd(), "Information")
+		call TagHLDebug("Current file is " . expand('%:p'), "Information")
+		call TagHLDebug("Release Info:" . string(g:TagHighlightPrivate['PluginVersion']), "Information")
+		call TagHLDebug("Global options (g:TagHighlightSettings): " . string(g:TagHighlightSettings), "Information")
+		if exists('b:TagHighlightSettings')
+			call TagHLDebug("Buffer options (b:TagHighlightSettings): " . string(b:TagHighlightSettings), "Information")
+		else
+			call TagHLDebug("No buffer options set", "Information")
+		endif
+	endif
+
+	" Load the option file
+	let option_file_info = TagHighlight#Option#LoadOptionFileIfPresent()
+	" Debug information for configuration
+	if TagHighlight#Debug#DebugLevelIncludes('Information') && option_file_info['Exists']
+		call TagHLDebug("Project config file options: " . string(b:TagHighlightConfigFileOptions), "Information")
+	else
+		call TagHLDebug("Project config file does not exist", "Information")
+	endif
+	
+	" Call any PreUpdate hooks
+	let preupdate_hooks = TagHighlight#Option#GetOption('PreUpdateHooks')
+	for preupdate_hook in preupdate_hooks
+		call TagHLDebug("Calling pre-update hook " . preupdate_hook, "Information")
+		exe 'call' preupdate_hook . '()'
+	endfor
+	
+	" Most simple options are automatic.  The options below are
+	" handled manually.
+	
+	" Find the ctags path
+	let ctags_option = TagHighlight#Option#GetOption('CtagsExecutable')
+	if ctags_option == 'None'
+		" Option not set: search for 'ctags' in the path
+		call TagHLDebug("CtagsExecutable not set, searching for 'ctags' in path", "Information")
+		let b:TagHighlightSettings['CtagsExeFull'] = TagHighlight#RunPythonScript#FindExeInPath('ctags')
+	elseif ctags_option =~ '[\\/]'
+		" Option set and includes '/' or '\': must be explicit
+		" path to named executable: just pass to mktypes
+		call TagHLDebug("CtagsExecutable set with path delimiter, using as explicit path", "Information")
+		let b:TagHighlightSettings['CtagsExeFull'] = ctags_option
+	else
+		" Option set but doesn't include path separator: search
+		" in the path
+		call TagHLDebug("CtagsExecutable set without path delimiter, searching in path", "Information")
+		let b:TagHighlightSettings['CtagsExeFull'] = TagHighlight#RunPythonScript#FindExeInPath(ctags_option)
+	endif
+
+	let tag_file_info = TagHighlight#Find#LocateFile('TAGS', '')
+	if tag_file_info['Found'] == 1
+		let b:TagHighlightSettings['CtagsFileLocation'] = tag_file_info['Directory']
+	endif
+
+	let types_file_info = TagHighlight#Find#LocateFile('TYPES', '*')
+	if types_file_info['Found'] == 1
+		let b:TagHighlightSettings['TypesFileLocation'] = types_file_info['Directory']
+	endif
+
+	if TagHighlight#Option#GetOption('SourceDir') =~ 'None'
+		" The source directory has not been set.  If a project config file was
+		" found, use that directory.  If not, but a types file was found,
+		" use that directory.  If not, but a tag file was found, use that
+		" directory.  If not, use the current directory.
+		call TagHLDebug("No source dir set", "Information")
+		call TagHLDebug("Current directory is now " . getcwd(), "Information")
+		if ! TagHighlight#Option#GetOption('Recurse')
+			call TagHLDebug("Non-recursive mode, using file directory", "Information")
+			let file = expand('<afile>')
+			if len(file) == 0
+				let file = expand('%')
+			endif
+			call TagHLDebug("File is " . file . "(" . fnamemodify(file, ':p:h') . ")", "Information")
+			let b:TagHighlightSettings['SourceDir'] = fnamemodify(file, ':p:h')
+		elseif option_file_info['Found'] == 1 && option_file_info['Exists'] == 1
+			call TagHLDebug("Using project config file directory", "Information")
+			let b:TagHighlightSettings['SourceDir'] = option_file_info['Directory']
+		elseif types_file_info['Found'] == 1 && types_file_info['Exists'] == 1
+			call TagHLDebug("Using types file directory", "Information")
+			let b:TagHighlightSettings['SourceDir'] = types_file_info['Directory']
+		elseif tag_file_info['Found'] == 1 && tag_file_info['Exists'] == 1
+			call TagHLDebug("Using tags file directory", "Information")
+			let b:TagHighlightSettings['SourceDir'] = tag_file_info['Directory']
+		else
+			call TagHLDebug("Using current directory", "Information")
+			let b:TagHighlightSettings['SourceDir'] = '.'
+		endif
+	else
+		call TagHLDebug("Source dir set explicitly to " . TagHighlight#Option#GetOption("SourceDir"), "Information")
+	endif
+	
+	call TagHLDebug("Running generator with options:", "Information")
+	for var in ["g:TagHighlightSettings","b:TagHighlightConfigFileOptions","b:TagHighlightSettings"]
+		if exists(var)
+			call TagHLDebug(" - " . var . ": " . string(eval(var)), "Information")
+		else
+			call TagHLDebug(" - " . var . ": UNSET", "Information")
+		endif
+	endfor
+	let RunOptions = TagHighlight#Option#CopyOptions()
+	call TagHighlight#RunPythonScript#RunGenerator(RunOptions)
+
+	let postupdate_hooks = TagHighlight#Option#GetOption('PostUpdateHooks')
+	for postupdate_hook in postupdate_hooks
+		call TagHLDebug("Calling post-update hook " . postupdate_hook, "Information")
+		exe 'call' postupdate_hook . '()'
+	endfor
+
+	call TagHLDebug("UpdateTypesFile() complete, current directory is now " . getcwd(), "Information")
+endfunction
+
+function! TagHighlight#Generation#UpdateAndRead(skiptags)
+	let restore_options = 0
+	if exists('b:TagHighlightSettings')
+		let stored_options = deepcopy(b:TagHighlightSettings)
+		let restore_options = 1
+	else
+		let b:TagHighlightSettings = {}
+	endif
+
+	" Start with a copy of the settings so that we can tweak things
+	if a:skiptags
+		let b:TagHighlightSettings['DoNotGenerateTags'] = 1
+	endif
+	
+	call TagHighlight#Generation#UpdateTypesFile()
+	let SavedTabNr = tabpagenr()
+	let SavedWinNr = winnr()
+	tabdo windo call TagHighlight#ReadTypes#ReadTypesAutoDetect()
+	exe 'tabn' SavedTabNr
+	exe SavedWinNr . 'wincmd w'
+
+	unlet b:TagHighlightSettings
+	if restore_options
+		let b:TagHighlightSettings = deepcopy(stored_options)
+	endif
+endfunction

autoload/TagHighlight/Libraries.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    02/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLLibraries') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLLibraries = 1
+
+function! TagHighlight#Libraries#LoadLibraries()
+	if has_key(g:TagHighlightPrivate,'Libraries')
+		" Already loaded
+		return
+	endif
+	call TagHLDebug("Loading standard library information", "Information")
+
+	let g:TagHighlightPrivate['LibraryPath'] = g:TagHighlightPrivate['PluginPath'] . '/standard_libraries'
+	let g:TagHighlightPrivate['Libraries'] = {}
+	let library_config_files = split(glob(g:TagHighlightPrivate['LibraryPath'] . '/*/library_types.txt'), '\n')
+
+	let required_keys = ["LibraryName","TypesFiles","CheckMode","TypesSuffixes"]
+	for library_config in library_config_files
+		call TagHLDebug("Loading information for " . library_config, "Information")
+		let skip = 0
+		let library_details = TagHighlight#LoadDataFile#LoadFile(library_config)
+		for key in required_keys
+			if ! has_key(library_details, key)
+				call TagHLDebug("Could not load library from " . library_config, "Warning")
+				let skip = 1
+				break
+			endif
+		endfor
+		if skip
+			continue
+		endif
+		" Config looks valid; check fields that should be lists are:
+		let list_keys = ["TypesFiles","TypesSuffixes","MatchREs"]
+		for key in list_keys
+			if has_key(library_details,key) && type(library_details[key]) == type('')
+				let value = library_details[key]
+				unlet library_details[key]
+				let library_details[key] = [value]
+			endif
+		endfor
+		" Store the absolute path to the all types files
+		let library_details['TypesFileFullPaths'] = []
+		for types_file in library_details['TypesFiles']
+			let library_details['TypesFileFullPaths'] += [fnamemodify(library_config, ':p:h') . '/' . types_file]
+		endfor
+
+		" Handle some defaults
+		if ! has_key(library_details,'MatchREs')
+			" Default matcher will never match on any file
+			let library_details['MatchREs'] = ['.\%^']
+		endif
+		if ! has_key(library_details, 'CustomFunction')
+			" Default custom function will always return 'Skip'
+			let library_details['CustomFunction'] = 'TagHighlight#Libraries#NeverMatch'
+		endif
+		if ! has_key(library_details, 'MatchLines')
+			" Just use a suitable default value
+			let library_details['MatchLines'] = 30
+		endif
+		
+		call TagHLDebug("Loaded library: " . string(library_details), "Information")
+		let g:TagHighlightPrivate['Libraries'][library_details['LibraryName']] = library_details
+	endfor
+endfunction
+
+function! TagHighlight#Libraries#FindUserLibraries()
+	" Open any explicitly configured libraries
+	call TagHLDebug("Searching for user libraries", "Information")
+	let user_library_dir = TagHighlight#Option#GetOption('UserLibraryDir')
+	let user_libraries = TagHighlight#Option#GetOption('UserLibraries')
+
+	call TagHLDebug("Library Dir: " . user_library_dir, "Information")
+	call TagHLDebug("Library List: " . string(user_libraries), "Information")
+
+	let libraries_to_load = []
+
+	for library in user_libraries
+		" If it looks like an absolute path, just load it
+		if (library[1] == ':' || library['0'] == '/') && filereadable(library)
+			call TagHLDebug("User library is absolute path: " . library, "Information")
+			let libraries_to_load +=
+						\ [{
+						\     'Name': 'User Library',
+						\     'Filename': fnamemodify(library, ':t'),
+						\     'Path': fnamemodify(library, '%:p'),
+						\ }]
+		" Otherwise, try appending to the library dir
+		elseif filereadable(user_library_dir . '/' . library)
+			call TagHLDebug("User library is relative path: " . library, "Information")
+			let library_path = user_library_dir . '/' . library
+			let libraries_to_load +=
+						\ [{
+						\     'Name': 'User Library',
+						\     'Filename': fnamemodify(library_path, ':t'),
+						\     'Path': fnamemodify(library_path, '%:p'),
+						\ }]
+		else
+			TagHLDebug("Cannot load user library " . library, "Error")
+		endif
+	endfor
+	return libraries_to_load
+endfunction
+
+function! TagHighlight#Libraries#FindLibraryFiles(suffix)
+	" Should only actually read the libraries once
+	call TagHLDebug("Finding library files for current file with suffix " . a:suffix, "Information")
+	call TagHighlight#Libraries#LoadLibraries()
+
+	let libraries_to_load = []
+	let forced_standard_libraries = TagHighlight#Option#GetOption('ForcedStandardLibraries')
+
+	if TagHighlight#Option#GetOption('DisableStandardLibraries')
+		call TagHLDebug("Standard library loading disabled", "Information")
+		return []
+	endif
+
+	for library in values(g:TagHighlightPrivate['Libraries'])
+		call TagHLDebug("Checking " . library['LibraryName'], "Information")
+		let load = 0
+		if index(library['TypesSuffixes'], a:suffix) != -1
+			" Suffix is in the list of acceptable ones
+			if index(forced_standard_libraries, library['LibraryName']) != -1
+				call TagHLDebug("Library(".library['LibraryName']."): Forced", "Information")
+				let load = 1
+			elseif library['CheckMode'] == 'Always'
+				call TagHLDebug("Library(".library['LibraryName']."): Always", "Information")
+				let load = 1
+			elseif library['CheckMode'] == 'MatchStart'
+				call TagHLDebug("Library(".library['LibraryName']."): Checking MatchStart", "Information")
+				for matcher in library['MatchREs']
+					call cursor(1,1)
+					if search(matcher, 'nc',library['MatchLines'])
+						call TagHLDebug("Library(".library['LibraryName']."): Match!", "Information")
+						let load = 1
+						break
+					endif
+				endfor
+			elseif library['CheckMode'] == 'MatchEnd'
+				call TagHLDebug("Library(".library['LibraryName']."): Checking MatchEnd", "Information")
+				for matcher in library['MatchREs']
+					call cursor(1000000,1000000)
+					if search(matcher, 'ncb', library['MatchLines'])
+						call TagHLDebug("Library(".library['LibraryName']."): Match!", "Information")
+						let load = 1
+						break
+					endif
+				endfor
+			elseif library['CheckMode'] == 'Custom'
+				call TagHLDebug("Library(".library['LibraryName']."): Custom (".library['CustomFunction'].")", "Information")
+				" The hope is that this won't really ever be used, but
+				" call the function and check that it returns the right
+				" kind of thing (takes suffix as parameter)
+				exe 'let result = ' . library['CustomFunction'] . '(' . a:suffix . ')'
+				if result == 'Load'
+					call TagHLDebug("Custom result: Load", "Information")
+					let load = 1
+				elseif result == 'Skip'
+					call TagHLDebug("Custom result: Skip", "Information")
+					" Pass
+				else
+					call TagHLDebug("Misconfigured library: custom function has invalid return value", "Critical")
+				endif
+			endif
+		endif
+		if load
+			for full_path in library['TypesFileFullPaths']
+				let libraries_to_load += 
+							\ [{
+							\     'Name': library['LibraryName'],
+							\     'Filename': fnamemodify(full_path, ':t'),
+							\     'Path': full_path,
+							\ }]
+			endfor
+		else
+			call TagHLDebug("No match:" . library['LibraryName'], "Information")
+		endif
+	endfor
+
+	return libraries_to_load
+endfunction
+
+function! TagHighlight#Libraries#NeverMatch()
+	return 'Skip'
+endfunction

autoload/TagHighlight/LoadDataFile.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    02/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLLoadDataFile') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLLoadDataFile = 1
+
+function! TagHighlight#LoadDataFile#LoadDataFile(filename)
+	let filename = g:TagHighlightPrivate['PluginPath'] . '/data/' . a:filename
+	return TagHighlight#LoadDataFile#LoadFile(filename)
+endfunction
+
+function! TagHighlight#LoadDataFile#LoadFile(filename)
+	let result = {}
+	let entries = readfile(a:filename)
+	
+	let top_key = ''
+	for entry in entries
+		if entry[0] == '#'
+		elseif entry[0] =~ '\k'
+			" Keyword character, so not sub entry or comment
+			if entry[len(entry)-1:] == ":"
+				" Beginning of a field, but we don't know whether
+				" it's a list of a dict yet
+				let top_key = entry[:len(entry)-2]
+			elseif stridx(entry, ':') != -1
+				" This is key:value, so it's a simple dictionary entry
+				let parts = split(entry, ':')
+				" Rather coarse replacement of split(x,y,n)
+				if len(parts) > 2
+					let parts[1] = join(parts[1:], ':')
+				endif
+				if stridx(parts[1], ',') != -1
+					" This entry is a list
+					let result[parts[0]] = split(parts[1], ',')
+				else
+					let result[parts[0]] = parts[1]
+				endif
+				" Clear the top key as this isn't a multi-line entry
+				let top_key = ''
+			else
+				call TagHLDebug("  Unhandled line: '" . entry . "'", "Error")
+			endif
+		elseif entry[0] == "\t" && top_key != ''
+			" This is a continuation of a top level key
+			if stridx(entry, ':') != -1
+				" The key is a dictionary, check for mismatch:
+				if has_key(result, top_key)
+					if type(result[top_key]) != type({})
+						call TagHLDebug("Type mismatch on line '".entry."': expected key:value", "Error")
+					endif
+				else
+					let result[top_key] = {}
+				endif
+				" Handle the entry (without the preceding tab)
+				let parts = split(entry[1:], ':')
+				" Rather coarse replacement of split(x,y,n)
+				if len(parts) > 2
+					let parts[1] = join(parts[1:], ':')
+				endif
+				if stridx(parts[1], ',') != -1
+					" This entry is a list
+					let result[top_key][parts[0]] = split(parts[1], ',')
+				else
+					let result[top_key][parts[0]] = parts[1]
+				endif
+			else
+				" This is a list of strings, check for mismatch
+				if has_key(result, top_key)
+					if type(result[top_key]) != type([])
+						call TagHLDebug("Type mismatch on line '".entry."': didn't expect key:value", "Error")
+					endif
+				else
+					let result[top_key] = []
+				endif
+				" Add to the list (without the preceding tag)
+				let result[top_key] += [entry[1:]]
+			endif
+		else
+			" Probably a comment or blank line
+		endif
+	endfor
+	return result
+endfunction

autoload/TagHighlight/Option.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    05/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLOption') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLOption = 1
+
+let s:log_defaults = 1
+let g:TagHighlightOptionDefaults = {}
+
+function! TagHighlight#Option#LoadOptionFileIfPresent()
+	let option_file = TagHighlight#Find#LocateFile('CONFIG', '')
+
+	" Check whether we've found the option file
+	if ! option_file['Exists']
+		return
+	endif
+
+	" Got an option file, load it in:
+	let b:TagHighlightConfigFileOptions = TagHighlight#LoadDataFile#LoadFile(option_file['FullPath'])
+
+	return option_file
+endfunction
+
+function! TagHighlight#Option#LoadOptions()
+	if has_key(g:TagHighlightPrivate, 'PluginOptions')
+		return
+	endif
+
+	let g:TagHighlightPrivate['PluginOptions'] = []
+	let options = TagHighlight#LoadDataFile#LoadDataFile('options.txt')
+
+	for option_dest in keys(options)
+		if has_key(options[option_dest], 'VimOptionMap')
+			let option = deepcopy(options[option_dest])
+			let option['Destination'] = option_dest
+			let g:TagHighlightPrivate['PluginOptions'] += [option]
+		endif
+	endfor
+endfunction
+
+function! TagHighlight#Option#GetOption(name)
+	" Check we've loaded the options
+	call TagHighlight#Option#LoadOptions()
+
+	" Check this option exists
+	let found = 0
+	for option in g:TagHighlightPrivate['PluginOptions']
+		if option['VimOptionMap'] == a:name
+			let found = 1
+			break
+		endif
+	endfor
+	if ! found
+		throw "Unrecognised option:" .a:name
+	endif
+
+	" Option priority (highest first):
+	" * buffer dictionary,
+	" * config file dictionary
+	" * global dictionary,
+	for var in ["g:TagHighlightSettings","b:TagHighlightConfigFileOptions","b:TagHighlightSettings"]
+		if exists(var)
+			exe 'let present = has_key(' . var . ', a:name)'
+			if present
+				exe 'let opt = ' . var . '[a:name]'
+			endif
+		endif
+	endfor
+
+	if ! exists('opt')
+		" We haven't found it, return the default
+		" Special cases first
+		if a:name == "DefaultDirModePriority"
+			if TagHighlight#Option#GetOption("Recurse")
+				let opt = ["Explicit","UpFromFile","CurrentDirectory"]
+			else
+				let opt = ["FileDirectory"]
+			endif
+		else
+			" Normal case
+			let opt = option['Default']
+		endif
+	else
+	endif
+
+	if option['Type'] =~ 'list'
+		let result = []
+		if type(opt) == type('')
+			if opt == '[]' || opt == ''
+				let parsed_opt = []
+			else
+				let parsed_opt = [opt]
+			endif
+		else
+			let parsed_opt = opt
+		endif
+		for part in parsed_opt
+			if part =~ '^OPT(\k\+)$'
+				let value_name = part[4:len(part)-2]
+				let result += [TagHighlight#Option#GetOption(value_name)]
+			else
+				let result += [part]
+			endif
+		endfor
+	elseif option['Type'] == 'bool'
+		if opt =~ 'True' || opt == 1
+			let result = 1
+		elseif opt =~ 'False' || opt == 0
+			let result = 0
+		else
+			throw "Unrecognised bool value"
+		endif
+	elseif option['Type'] == 'string'
+		if opt =~ '^OPT(\k\+)$'
+			let value_name = opt[4:len(opt)-2]
+			let result = TagHighlight#Option#GetOption(value_name)
+		else
+			let result = opt
+		endif
+	elseif option['Type'] == 'dict'
+		" This is a complex one: just assume it's valid Vim script
+		if type(opt) == type([])
+			" Probably a multi-entry dict that has automatically been
+			" split: rejoin
+			let result = eval(join(opt, ', '))
+		else
+			let result = eval(opt)
+		endif
+	elseif option['Type'] == 'int'
+		let result = str2nr(opt)
+	endif
+	return result
+endfunction
+
+function! TagHighlight#Option#CopyOptions()
+	let result = {}
+	for var in ["g:TagHighlightSettings","b:TagHighlightConfigFileOptions","b:TagHighlightSettings"]
+		if exists(var)
+			for key in keys(eval(var))
+				if type(eval(var)[key]) == type([])
+					let result[key] = eval(var)[key][:]
+				elseif type(eval(var)[key]) == type({})
+					let result[key] = deepcopy(eval(var)[key])
+				else
+					let result[key] = eval(var)[key]
+				endif
+			endfor
+		endif
+	endfor
+	return result
+endfunction

autoload/TagHighlight/ReadTypes.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    02/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLReadTypes') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLReadTypes = 1
+
+function! TagHighlight#ReadTypes#ReadTypesAutoDetect()
+	let extension = expand('%:e')
+	if TagHighlight#Debug#DebugLevelIncludes('Information')
+		call TagHLDebug("Reading types for extension " . extension . " at " . strftime("%Y%m%d-%H%M%S"), "Information")
+	endif
+	for key in keys(g:TagHighlightPrivate['ExtensionLookup'])
+		let regex = '^'.key.'$'
+		if extension =~ regex
+			call TagHighlight#ReadTypes#ReadTypes(g:TagHighlightPrivate['ExtensionLookup'][key])
+		endif
+	endfor
+endfunction
+
+function! TagHighlight#ReadTypes#ReadTypes(suffix)
+	let savedView = winsaveview()
+
+	call TagHighlight#Option#LoadOptionFileIfPresent()
+
+	let file = expand('<afile>')
+	if len(file) == 0
+		let file = expand('%')
+	endif
+
+	call TagHLDebug("Reading types of suffix " . a:suffix . " for file " . file, "Information")
+
+	if TagHighlight#Option#GetOption('DisableTypeParsing') == 1
+		call TagHLDebug("Type file parsing disabled", 'Status')
+		return
+	endif
+
+	let fullname = expand(file . ':p')
+
+	let skiplist = TagHighlight#Option#GetOption('ParsingSkipList')
+	if len(skiplist) > 0
+		let basename = expand(file . ':p:t')
+		if index(skiplist, basename) != -1
+			call TagHLDebug("Skipping file due to basename match", 'Status')
+			return
+		endif
+		if index(skiplist, fullname) != -1
+			call TagHLDebug("Skipping file due to fullname match", 'Status')
+			return
+		endif
+	endif
+	"
+	" Call Pre Read hooks (if any)
+	let preread_hooks = TagHighlight#Option#GetOption('PreReadHooks')
+	for preread_hook in preread_hooks
+		call TagHLDebug("Calling pre-read hook " . preread_hook, 'Information')
+		exe 'call' preread_hook . '(fullname, a:suffix)'
+	endfor
+
+	call TagHLDebug("Searching for types file", 'Status')
+
+	" Clear any existing syntax entries
+	for group in g:TagHighlightPrivate['AllTypes']
+		exe 'syn clear' group
+	endfor
+
+	let b:TagHighlightLoadedLibraries = []
+	
+	let type_files = TagHighlight#ReadTypes#FindTypeFiles(a:suffix)
+	for fname in type_files
+		call TagHLDebug("Loading type highlighter file " . fname, 'Information')
+		exe 'so' fname
+		let b:TagHighlightLoadedLibraries +=
+					\ [{
+					\     'Name': 'Local',
+					\     'Filename': fnamemodify(fname, ':t'),
+					\     'Path': fnamemodify(fname, ':p'),
+					\ }]
+	endfor
+
+	" Load user libraries
+	let user_library_files = TagHighlight#Libraries#FindUserLibraries()
+	for lib in user_library_files
+		call TagHLDebug("Loading user library type highlighter file " . lib['Path'], 'Information')
+		exe 'so' lib['Path']
+		let b:TagHighlightLoadedLibraries += [lib]
+	endfor
+
+	" Now load any libraries that are relevant
+	let library_files = TagHighlight#Libraries#FindLibraryFiles(a:suffix)
+	for lib in library_files
+		call TagHLDebug("Loading standard library type highlighter file " . lib['Path'], 'Information')
+		exe 'so' lib['Path']
+		let b:TagHighlightLoadedLibraries += [lib]
+	endfor
+
+	" Handle any special cases
+	if has_key(g:TagHighlightPrivate['SpecialSyntaxHandlers'], a:suffix)
+		for handler in g:TagHighlightPrivate['SpecialSyntaxHandlers'][a:suffix]
+			call TagHLDebug("Calling special handler " . handler, 'Information')
+			exe 'call' handler . '()'
+		endfor
+	endif
+
+	" Call Post Read Hooks (if any)
+	let postread_hooks = TagHighlight#Option#GetOption('PostReadHooks')
+	for postread_hook in postread_hooks
+		call TagHLDebug("Calling post-read hook " . postread_hook, 'Information')
+		exe 'call' postread_hook . '(fullname, a:suffix)'
+	endfor
+
+	" Restore the view
+	call winrestview(savedView)
+endfunction
+
+function! TagHighlight#ReadTypes#FindTypeFiles(suffix)
+	let results = []
+	let search_result = TagHighlight#Find#LocateFile('TYPES', a:suffix)
+	if search_result['Found'] == 1 && search_result['Exists'] == 1
+		let results += [search_result['FullPath']]
+	endif
+	return results
+endfunction

autoload/TagHighlight/RunPythonScript.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    02/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLRunPythonScript') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLRunPythonScript = 1
+
+let s:python_variant = 'None'
+
+" A simply python script that will try to import the print function
+" and will fail gracefully if the python version is too old.  It's
+" unlikely that the sys.hexversion check will ever fail as if the version
+" is older than 2.6, the import_check will have failed.  I've left it in,
+" however, in case I ever need to depend on 2.7
+let s:version_and_future_check = 
+			\ "try:\n" .
+			\ "    import import_check\n" .
+			\ "    import vim\n" .
+			\ "    import sys\n" .
+			\ "    vim.command('''let g:taghl_python_version = '%s' ''' % sys.version)\n" .
+			\ "    if sys.hexversion < 0x02060000:\n" .
+			\ "        raise ValueError('Incorrect python version')\n" .
+			\ "    vim.command('let g:taghl_python_operational = 1')\n" .
+			\ "except:\n" .
+			\ "    pass\n"
+
+" This script is responsible for finding a means of running the python app.
+" If vim is compiled with python support (and we can run a simple test
+" command), use that method.  If not, but python is in the path, use it to
+" run the script.  If python is not in path, we'll have to rely on a compiled
+" executable version.
+
+function! s:GetPath()
+	if has("win32")
+		let path = substitute($PATH, '\\\?;', ',', 'g')
+	else
+		let path = substitute($PATH, ':', ',', 'g')
+	endif
+	return path
+endfunction
+
+function! s:RunShellCommand(args)
+	let syscmd = ""
+	for arg in a:args
+		if len(syscmd) > 0
+			let syscmd .= " "
+		endif
+		if stridx(arg, " ") != -1
+			let syscmd .= shellescape(arg)
+		else
+			let syscmd .= arg
+		endif
+	endfor
+	call TagHLDebug(syscmd, "Information")
+	let result = system(syscmd)
+	echo result
+	return result
+endfunction
+
+function! TagHighlight#RunPythonScript#RunGenerator(options)
+	" Will only actually load the options once
+	call TagHighlight#Option#LoadOptions()
+
+	" This will only search for python the first time or if
+	" the variant priority or forced variant preferences have
+	" changed.
+	call TagHighlight#RunPythonScript#FindPython()
+
+	call TagHLDebug("Using variant: " .s:python_variant, "Information")
+
+	if index(["if_pyth","if_pyth3"], s:python_variant) != -1
+		let PY = s:python_cmd[0]
+		exe PY 'from module.utilities import TagHighlightOptionDict' 
+		exe PY 'from module.worker import RunWithOptions'
+		exe PY 'options = TagHighlightOptionDict()'
+		let handled_options = []
+		" We're using the custom interpreter: create an options object
+		" All options supported by both Vim and the Python script must
+		" have VimOptionMap and CommandLineSwitches keys
+		for option in g:TagHighlightPrivate['PluginOptions']
+			if has_key(option, 'VimOptionMap') && 
+						\ has_key(option, 'CommandLineSwitches') &&
+						\ has_key(a:options, option['VimOptionMap'])
+				" We can handle this one automatically
+				let pyoption = 'options["'.option['Destination'].'"]'
+				if option['Type'] == 'bool'
+					let handled_options += [option['VimOptionMap']]
+					if a:options[option['VimOptionMap']]
+						exe PY pyoption '= True'
+					else
+						exe PY pyoption '= False'
+					endif
+				elseif option['Type'] == 'string'
+					let handled_options += [option['VimOptionMap']]
+					exe PY pyoption '= r"""'.a:options[option['VimOptionMap']].'"""'
+				elseif option['Type'] == 'int'
+					let handled_options += [option['VimOptionMap']]
+					exe PY pyoption '= ' . a:options[option['VimOptionMap']]
+				elseif option['Type'] == 'list'
+					let handled_options += [option['VimOptionMap']]
+					exe PY pyoption '= []'
+					for entry in a:options[option['VimOptionMap']]
+						exe PY pyoption '+= [r"""' . entry . '"""]'
+					endfor
+				endif
+			endif
+		endfor
+		for check_opt in keys(a:options)
+			if index(handled_options, check_opt) == -1
+				call TagHLDebug("Unhandled run option: " . check_opt, "Information")
+			endif
+		endfor
+		exe PY 'RunWithOptions(options)'
+	elseif index(["python","compiled"], s:python_variant) != -1
+		let args = s:python_cmd[:]
+		" We're calling the script externally, build a list of arguments
+		for option in g:TagHighlightPrivate['PluginOptions']
+			if has_key(option, 'VimOptionMap') && 
+						\ has_key(option, 'CommandLineSwitches') &&
+						\ has_key(a:options, option['VimOptionMap'])
+				if type(option['CommandLineSwitches']) == type([])
+					let switch = option['CommandLineSwitches'][0]
+				else
+					let switch = option['CommandLineSwitches']
+				endif
+				if switch[:1] == "--"
+					let as_one = 1
+				elseif switch[:0] == "-"
+					let as_one = 0
+				else
+					call TagHLDebug("Invalid configuration for option " . option['VimOptionMap'], "Error")
+				endif
+				" We can handle this one automatically
+				if option['Type'] == 'bool'
+					if ((a:options[option['VimOptionMap']] && option['Default'] == 'False')
+								\ || ( ! a:options[option['VimOptionMap']] && option['Default'] == 'True'))
+						let args += [switch]
+					endif
+				elseif option['Type'] == 'string'
+					if as_one == 1
+						let args += [switch . '=' . a:options[option['VimOptionMap']]]
+					else
+						let args += [switch, a:options[option['VimOptionMap']]]
+					endif
+				elseif option['Type'] == 'int'
+					if as_one == 1
+						let args += [switch . '=' . a:options[option['VimOptionMap']]]
+					else
+						let args += [switch, a:options[option['VimOptionMap']]]
+					endif
+				elseif option['Type'] == 'list'
+					for entry in a:options[option['VimOptionMap']]
+						if as_one == 1
+							let args += [switch . '=' . entry]
+						else
+							let args += [switch, entry]
+						endif
+					endfor
+				endif
+			endif
+		endfor
+		let sysoutput = s:RunShellCommand(args)
+	else
+		throw "Tag highlighter: invalid or not implemented python variant"
+	endif
+endfunction
+
+function! TagHighlight#RunPythonScript#FindExeInPath(file)
+	let full_file = a:file
+	if has("win32") || has("win32unix")
+		if a:file !~ '.exe$'
+			let full_file = a:file . '.exe.'
+		endif
+	endif
+	let short_file = fnamemodify(full_file, ':p:t')
+	let file_exe_list = split(globpath(s:GetPath(), short_file), '\n')
+	
+	if len(file_exe_list) > 0 && executable(file_exe_list[0])
+		let file_exe = file_exe_list[0]
+	else
+		return 'None'
+	endif
+	"let file_exe = substitute(file_exe, '\\', '/', 'g')
+	return file_exe
+endfunction
+
+function! TagHighlight#RunPythonScript#FindPython()
+	let forced_variant = TagHighlight#Option#GetOption('ForcedPythonVariant')
+	" Supported variants
+	let supported_variants = ['if_pyth3', 'if_pyth', 'python', 'compiled']
+	" Priority of those variants (default is that specified above)
+	let variant_priority = TagHighlight#Option#GetOption('PythonVariantPriority')
+
+	" If we've run before and nothing has changed, just return
+	if s:python_variant != 'None'
+		if forced_variant == s:stored_forced_variant
+					\ && s:stored_variant_priority == variant_priority
+					\ && s:python_path == TagHighlight#Option#GetOption("PathToPython")
+			return s:python_variant
+		endif
+	endif
+
+	let s:python_variant = 'None'
+	let s:python_version = 'Unknown'
+	let s:python_cmd = []
+	let s:python_path = ""
+
+	" Make sure that the user specified variant is supported
+	if index(supported_variants, forced_variant) == -1
+		let forced_variant = 'None'
+	endif
+
+	let s:stored_forced_variant = forced_variant
+	let s:stored_variant_priority = variant_priority
+
+	let add_to_py_path = substitute(g:TagHighlightPrivate['PluginPath'], '\\', '/','g')
+
+	" Make sure that all variants in the priority list are supported
+	call filter(variant_priority, 'index(supported_variants, v:val) != -1')
+
+	" Try each variant in the priority list until we find one that works
+	for variant in variant_priority
+		if forced_variant == variant || forced_variant == 'None'
+			if variant == 'if_pyth3' && has('python3')
+				" Check whether the python 3 interface works
+				let g:taghl_findpython_testvar = 0
+				try
+					py3 import sys
+					exe 'py3 sys.path = ["'.add_to_py_path.'"] + sys.path'
+					let g:taghl_python_operational = 0
+					exe 'py3' s:version_and_future_check
+					py3 import vim
+
+					if g:taghl_python_operational != 1
+						throw "Python doesn't seem to be working"
+					endif
+					let s:python_version = g:taghl_python_version
+					unlet g:taghl_python_operational
+					unlet g:taghl_python_version
+
+					" If we got this far, it should be working
+					let s:python_variant = 'if_pyth3'
+					let s:python_cmd = ['py3']
+				catch
+					call TagHLDebug("Cannot use python3 interface", "Status")
+				endtry
+			elseif variant == 'if_pyth' && has('python')
+				" Check whether the python 2 interface works
+				let g:taghl_findpython_testvar = 0
+				try
+					py import sys
+					exe 'py sys.path = ["'.add_to_py_path.'"] + sys.path'
+					let g:taghl_python_operational = 0
+					exe 'py' s:version_and_future_check
+					py import vim
+
+					if g:taghl_python_operational != 1
+						throw "Python doesn't seem to be working"
+					endif
+					let s:python_version = g:taghl_python_version
+					unlet g:taghl_python_operational
+					unlet g:taghl_python_version
+
+					" If we got this far, it should be working
+					let s:python_variant = 'if_pyth'
+					let s:python_cmd = ['py']
+				catch
+					call TagHLDebug("Cannot use python2 interface", "Status")
+				endtry
+			elseif variant == 'python'
+				" Try calling an external python
+				
+				" Has a specific path to python been set?
+				let python_path = TagHighlight#Option#GetOption('PathToPython')
+				if python_path != 'None' && executable(python_path)
+					" We've found python, it's probably usable
+					let s:python_variant = 'python'
+					let s:python_path = python_path
+					let s:python_cmd = [python_path, g:TagHighlightPrivate['PluginPath'] . '/TagHighlight.py']
+				else
+					" See if it's in the path
+					let python_path = TagHighlight#RunPythonScript#FindExeInPath('python')
+					if python_path != 'None'
+						let s:python_variant = 'python'
+						let s:python_path = python_path
+						let s:python_cmd = [python_path, g:TagHighlightPrivate['PluginPath'] . '/TagHighlight.py']
+					endif
+				endif
+
+				" Now run some simple test code to make sure it works correctly and
+				" is a reasonable version
+				let result = s:RunShellCommand([s:python_path, g:TagHighlightPrivate['PluginPath'] . '/version_check.py'])
+				let lines = split(result, '\n')
+				let s:python_version = lines[1]
+				if lines[0] != 'OK'
+					let s:python_variant = 'None'
+					let s:python_path = ''
+					let s:python_cmd = []
+				endif
+			elseif variant == 'compiled'
+				" See if there's a compiled executable version of the
+				" highlighter
+				if has("win32")
+					let compiled_highlighter = split(globpath(&rtp, "plugin/TagHighlight/Compiled/Win32/TagHighlight.exe"), "\n")
+					if len(compiled_highlighter) > 0  && executable(compiled_highlighter[0])
+						let s:python_variant = 'compiled'
+						let s:python_version = 'Compiled Highlighter'
+						let s:python_cmd = [compiled_highlighter[0]]
+					endif
+				elseif has("unix")
+					let compiled_highlighter = split(globpath(&rtp, "plugin/TagHighlight/Compiled/Linux/TagHighlight"), "\n")
+					if len(compiled_highlighter) > 0  && executable(compiled_highlighter[0])
+						let s:python_variant = 'compiled'
+						let s:python_version = 'Compiled Highlighter'
+						let s:python_cmd = [compiled_highlighter[0]]
+					endif
+				endif
+			endif
+		endif
+		
+		if s:python_variant != 'None'
+			" Found one!
+			break
+		endif
+	endfor
+
+	if s:python_variant != 'None'
+		call TagHLDebug("Python variant is " . s:python_variant, "Information")
+		call TagHLDebug("Python Command is " . join(s:python_cmd, " "), "Information")
+		call TagHLDebug("Python Path is " . s:python_path, "Information")
+		call TagHLDebug("Python version reported as: " . s:python_version,
+					\ 'Information')
+	else
+		throw "Tag highlighter: could not find python (2.6+) or the compiled version of the highlighter."
+	endif
+
+	return s:python_variant
+endfunction
+

autoload/TagHighlight/SpecialHandlers.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    02/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLSpecialHandlers') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLSpecialHandlers = 1
+
+function! TagHighlight#SpecialHandlers#CRainbowHandler()
+	call TagHLDebug("Language handler for rainbow.vim compatibility", "Information")
+	if exists("b:hlrainbow") && ! exists("g:nohlrainbow")
+		" Use a dictionary as a set (a unique item list)
+		let hl_dict = {}
+		for key in ["c","c++"]
+			if has_key(g:TagHighlightPrivate['Kinds'], key)
+				for kind in values(g:TagHighlightPrivate['Kinds'][key])
+					let hl_dict[kind] = ""
+				endfor
+			endif
+		endfor
+		let all_kinds = keys(hl_dict)
+		for cluster in ["cBracketGroup","cCppBracketGroup","cCurlyGroup","cParenGroup","cCppParenGroup"]
+			exe 'syn cluster' cluster 'add=' . join(all_kinds, ',')
+		endfor
+	endif
+endfunction
+
+function! TagHighlight#SpecialHandlers#JavaTopHandler()
+	call TagHLDebug("Language handler for javaTop compatibility", "Information")
+	if has_key(g:TagHighlightPrivate['Kinds'], 'java')
+		exe 'syn cluster javaTop add=' . join(values(g:TagHighlightPrivate['Kinds']['java']), ',')
+	endif
+endfunction

autoload/TagHighlight/Version.vim

+" Tag Highlighter:
+"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
+"   Date:    05/08/2011
+" Copyright: Copyright (C) 2009-2011 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,
+"            the TagHighlight plugin is provided *as is* and comes with no
+"            warranty of any kind, either expressed or implied. By using
+"            this plugin, you agree that in no event will the copyright
+"            holder be liable for any damages resulting from the use
+"            of this software.
+
+" ---------------------------------------------------------------------
+try
+	if &cp || (exists('g:loaded_TagHLVersion') && (g:plugin_development_mode != 1))
+		throw "Already loaded"
+	endif
+catch
+	finish
+endtry
+let g:loaded_TagHLVersion = 1
+
+function! TagHighlight#Version#LoadVersionInfo()
+	if has_key(g:TagHighlightPrivate, 'PluginVersion')
+		return
+	endif
+
+	let g:TagHighlightPrivate['PluginVersion'] = {}
+	
+	let last_release_info = TagHighlight#LoadDataFile#LoadDataFile('release.txt')
+	let g:TagHighlightPrivate['PluginVersion']['LastRelease'] = last_release_info['release']
+
+	try
+		let release_version_info = TagHighlight#LoadDataFile#LoadDataFile('version_info.txt')
+		let g:TagHighlightPrivate['PluginVersion']['VersionInfo'] = release_version_info
+	catch /^Vim\%((\a\+)\)\=:E484/
+		" Not a release version
+		let g:TagHighlightPrivate['PluginVersion']['VersionInfo'] =
+					\ {
+					\    'release_clean': 'N/A',
+					\    'release_date': 'N/A',
+					\    'release_revno': 'N/A',
+					\    'release_revid': 'N/A'
+					\ }
+	endtry
+endfunction

bundle/TagHighlight/autoload/TagHighlight/Debug.vim

-" Tag Highlighter:
-"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
-"   Date:    08/08/2011
-" Copyright: Copyright (C) 2009-2011 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,
-"            the TagHighlight plugin is provided *as is* and comes with no
-"            warranty of any kind, either expressed or implied. By using
-"            this plugin, you agree that in no event will the copyright
-"            holder be liable for any damages resulting from the use
-"            of this software.
-
-" ---------------------------------------------------------------------
-try
-	if &cp || (exists('g:loaded_TagHLDebug') && (g:plugin_development_mode != 1))
-		throw "Already loaded"
-	endif
-catch
-	finish
-endtry
-let g:loaded_TagHLDebug = 1
-
-let TagHighlight#Debug#DebugLevels = [
-			\ "None",
-			\ "Critical",
-			\ "Error",
-			\ "Warning",
-			\ "Status",
-			\ "Information",
-			\ ]
-
-function! TagHighlight#Debug#GetDebugLevel()
-	try
-		let debug_level = TagHighlight#Option#GetOption('DebugLevel')
-	catch /Unrecognised option/
-		" Probably loading the option file, so no debug level available
-		" yet, so assume 'Information'
-		let debug_level = 'Information'
-	endtry
-	let debug_num = index(g:TagHighlight#Debug#DebugLevels, debug_level)
-	if debug_num != -1
-		return debug_num
-	else
-		return index(g:TagHighlight#Debug#DebugLevels, 'Error')
-	endif
-endfunction
-
-function! TagHighlight#Debug#GetDebugLevelName()
-	let debug_level_num = TagHighlight#Debug#GetDebugLevel()
-	return g:TagHighlight#Debug#DebugLevels[debug_level_num]
-endfunction
-
-function! TagHighlight#Debug#DebugLevelIncludes(level)
-	let level_index = index(g:TagHighlight#Debug#DebugLevels, a:level)
-	if level_index == -1
-		let level_index = index(g:TagHighlight#Debug#DebugLevels, 'Critical')
-	endif
-	if level_index <= TagHighlight#Debug#GetDebugLevel()
-		return 1
-	else
-		return 0
-	endif
-endfunction
-
-function! TagHighlight#Debug#DebugUpdateTypesFile(filename)
-	" Update the types file with debugging turned on
-	if a:filename ==? 'None'
-		" Force case to be correct
-		let debug_file = 'None'
-	else
-		let debug_file = a:filename
-	endif
-
-	let debug_options = ["DebugFile","DebugLevel"]
-
-	" Store the old debug options
-	for dbg_option in debug_options
-		let stored_option_name = 'Stored'.dbg_option
-		if has_key(g:TagHighlightSettings, dbg_option)
-			let g:TagHighlightSettings[stored_option_name] = g:TagHighlightSettings[dbg_option]
-		else
-			let g:TagHighlightSettings[stored_option_name] = 'None'
-		endif
-	endfor
-
-	let g:TagHighlightSettings['DebugFile'] = debug_file
-	let g:TagHighlightSettings['DebugLevel'] = 'Information'
-
-	call TagHLDebug("========================================================", "Information")
-	call TagHighlight#Generation#UpdateAndRead(0)
-
-	" Get rid of the 'stored' versions of the debug options
-	for dbg_option in debug_options
-		let stored_option_name = 'Stored'.dbg_option
-		if g:TagHighlightSettings[stored_option_name] == 'None'
-			unlet g:TagHighlightSettings[dbg_option]
-		else
-			let g:TagHighlightSettings[dbg_option] = g:TagHighlightSettings[stored_option_name]
-		endif
-		unlet g:TagHighlightSettings[stored_option_name]
-	endfor
-endfunction

bundle/TagHighlight/autoload/TagHighlight/Find.vim

-" Tag Highlighter:
-"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
-"   Date:    08/08/2011
-" Copyright: Copyright (C) 2009-2011 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,
-"            the TagHighlight plugin is provided *as is* and comes with no
-"            warranty of any kind, either expressed or implied. By using
-"            this plugin, you agree that in no event will the copyright
-"            holder be liable for any damages resulting from the use
-"            of this software.
-
-" ---------------------------------------------------------------------
-try
-	if &cp || (exists('g:loaded_TagHLFind') && (g:plugin_development_mode != 1))
-		throw "Already loaded"
-	endif
-catch
-	finish
-endtry
-let g:loaded_TagHLFind = 1
-
-" Tools for finding files.  When generating the tags and types file, we need
-" to decide where to place it.  If the user has configured the mode in which
-" everything is based on the current directory (which works well with the
-" project plugin), the current directory is what we use.  If the user wants to
-" search up for a tags file, we can look for an existing tags file and stop
-" when we find one, starting either from the current directory or source
-" directory.  If we don't, either use the current directory or the source file
-" directory (configuration).
-"
-" It should also be possible to place the tags file in a remote location and
-" use either the current directory, source directory or explicitly set
-" directory for the base of the scan.
-
-" Option structure:
-"
-" [gb]:TagHighlightSettings:
-"	DefaultDirModePriority:[Explicit,UpFromCurrent,UpFromFile,CurrentDirectory,FileDirectory]
-"	TagFileDirModePriority:["Default"] or as above
-"	TypesFileDirModePriority:As tag file
-"	ConfigFileDirModePriority:As tag file
-"	DefaultDirModeSearchWildcard:'' (look for tags file) or something specific (*.uvopt)?
-"	MaxDirSearchLevels: (integer)
-"
-" Explicit Locations:
-"
-"  [gb]:TagHighlightSettings:
-"    TagFileDirectory:str (NONE)
-"    TagFileName:str (tags)
-"    TypesFileDirectory:str (NONE)
-"    TypesPrefix:str (types)
-"    ProjectConfigFileName:str (taghl_config.txt)
-"    ProjectConfigFileDirectory:str (NONE)
-
-function! TagHighlight#Find#LocateFile(which, suffix)
-	call TagHLDebug("Locating file " . a:which . " with suffix " . a:suffix, 'Information')
-
-	" a:which is 'TAGS', 'TYPES', 'CONFIG'
-	let default_priority = TagHighlight#Option#GetOption('DefaultDirModePriority')
-	call TagHLDebug("Priority: " . string(default_priority), "Information")
-	let default_search_wildcards = TagHighlight#Option#GetOption('DefaultDirModeSearchWildcards')
-
-
-	let file = expand('<afile>')
-	if len(file) == 0
-		let file = expand('%')
-	endif
-
-	if a:which == 'TAGS'
-		" Suffix is ignored here
-		let filename = TagHighlight#Option#GetOption('TagFileName')
-		let search_priority = TagHighlight#Option#GetOption('TagFileDirModePriority')
-		let explicit_location = TagHighlight#Option#GetOption('TagFileDirectory')
-		let search_wildcards = TagHighlight#Option#GetOption('TagFileSearchWildcards')
-	elseif a:which == 'TYPES'
-		let filename = TagHighlight#Option#GetOption('TypesFilePrefix') . '_' .
-					\ a:suffix . "." .
-					\ TagHighlight#Option#GetOption('TypesFileExtension')
-		let search_priority = TagHighlight#Option#GetOption('TypesFileDirModePriority')
-		let explicit_location = TagHighlight#Option#GetOption('TypesFileDirectory')
-		let search_wildcards = TagHighlight#Option#GetOption('TypesFileSearchWildcards')
-	elseif a:which == 'CONFIG'
-		" Suffix is ignored here
-		let filename = TagHighlight#Option#GetOption('ProjectConfigFileName')
-		let search_priority = TagHighlight#Option#GetOption('ProjectConfigFileDirModePriority')
-		let explicit_location = TagHighlight#Option#GetOption('ProjectConfigFileDirectory')
-		let search_wildcards = TagHighlight#Option#GetOption('ProjectConfigFileSearchWildcards')
-	else
-		throw "Unrecognised file"
-	endif
-
-	if search_wildcards[0] == 'Default'
-		let search_wildcards = default_search_wildcards
-	endif
-
-	if search_priority[0] == 'Default'
-		let search_priority = default_priority
-	endif
-
-	" Ensure there's no trailing slash on 'explicit location'
-	if explicit_location[len(explicit_location)-1] == '/'
-		let explicit_location = explicit_location[:len(explicit_location)-2]
-	endif
-
-	" Result contains 'Found','FullPath','Directory','Filename','Exists']
-	let result = {}
-
-	for search_mode in search_priority
-		if search_mode == 'Explicit' && explicit_location != 'None'
-			" Use explicit location, overriding everything else
-			call TagHLDebug('Using explicit location', 'Information')
-			let result['Directory'] = explicit_location
-			let result['Filename'] = filename
-		elseif search_mode == 'UpFromCurrent'
-			" Start in the current directory and search up
-			let dir = fnamemodify('.',':p:h')
-			let result = s:ScanUp(dir, search_wildcards)
-			if has_key(result, 'Directory')
-				call TagHLDebug('Found location with UpFromCurrent', 'Information')
-				let result['Filename'] = filename
-			endif
-		elseif search_mode == 'UpFromFile'
-			" Start in the directory containing the current file and search up
-			let dir = fnamemodify(file,':p:h')
-			let result = s:ScanUp(dir, search_wildcards)
-			if has_key(result, 'Directory')
-				call TagHLDebug('Found location with UpFromFile', 'Information')
-				let result['Filename'] = filename
-			endif
-		elseif search_mode == 'CurrentDirectory'
-			call TagHLDebug('Using current directory', 'Information')
-			let result['Directory'] = fnamemodify('.',':p:h')
-			let result['Filename'] = filename
-		elseif search_mode == 'FileDirectory'
-			call TagHLDebug('Using file directory', 'Information')
-			let result['Directory'] = fnamemodify(file,':p:h')
-			let result['Filename'] = filename
-		endif
-		if has_key(result, 'Directory')
-			let result['FullPath'] = result['Directory'] . '/' . result['Filename']
-			let result['Found'] = 1
-			call TagHLDebug('Found file location', 'Information')
-			if filereadable(result['FullPath'])
-				call TagHLDebug('File exists', 'Information')
-				let result['Exists'] = 1
-			else
-				call TagHLDebug('File does not exist', 'Information')
-				let result['Exists'] = 0
-			endif
-			break
-		endif
-	endfor
-
-	if ! has_key(result, 'Directory')
-		call TagHLDebug("Couldn't find path", 'Warning')
-		let result = {'Found': 0, 'Exists': 0}
-	endif
-
-	return result
-endfunction
-
-function! s:ScanUp(dir, wildcards)
-	let result = {}
-	let max_levels = TagHighlight#Option#GetOption('MaxDirSearchLevels')
-	let levels = 0
-	let new_dir = a:dir
-	let dir = ''
-	let found = 0
-
-	call TagHLDebug("Searching up from " . a:dir . " for " . string(a:wildcards), 'Information')
-
-	" new_dir != dir check looks for the root directory
-	while new_dir != dir
-		let dir = new_dir
-		let new_dir = fnamemodify(dir, ':h')
-		
-		call TagHLDebug("Trying " . dir, "Information")
-		for wildcard in a:wildcards
-			let glob_pattern = dir
-			if glob_pattern[len(glob_pattern)-1] != '/'
-				let glob_pattern .= '/'
-			endif
-			let glob_pattern .= wildcard
-			let glob_result = split(glob(glob_pattern), "\n")
-			if len(glob_result) > 0
-				for r in glob_result
-					if filereadable(r)
-						let found = 1
-					endif
-				endfor
-				if found
-					call TagHLDebug("Found match: " . dir . " (" . glob_pattern . ")", "Information")
-					let result['Directory'] = dir
-					let found = 1
-					break
-				else
-					call TagHLDebug("Wildcard matches were not readable (directory?)", "Information")
-				endif
-			endif
-		endfor
-		if found
-			break
-		endif
-
-		" Check for recursion limit
-		let levels += 1
-		if (max_levels > 0) && (levels >= max_levels)
-			call TagHLDebug("Hit recursion limit", "Information")
-			break
-		endif
-	endwhile
-	if new_dir == dir
-		" Must have reached root directory
-		call TagHLDebug("Reached root directory and stopped", "Information")
-	endif
-	return result
-endfunction

bundle/TagHighlight/autoload/TagHighlight/Generation.vim

-" Tag Highlighter:
-"   Author:  A. S. Budden <abudden _at_ gmail _dot_ com>
-"   Date:    08/08/2011
-" Copyright: Copyright (C) 2009-2011 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,
-"            the TagHighlight plugin is provided *as is* and comes with no