Commits

abudden  committed a326f4d

Addition of LanguageDetectionMethods option to allow loading of types when FileType or Syntax are set (thanks to Hong Xu for the suggestion). This also involved addition of syntax and filetype definitions to all languages and fixes #271. Prevent Vim from repeatedly loading autocmds in plugin development mode.

  • Participants
  • Parent commits acddc24

Comments (0)

Files changed (13)

File autoload/TagHighlight/Generation.vim

 	call TagHighlight#Generation#UpdateTypesFile()
 	let SavedTabNr = tabpagenr()
 	let SavedWinNr = winnr()
-	tabdo windo call TagHighlight#ReadTypes#ReadTypesAutoDetect()
+	tabdo windo call TagHighlight#ReadTypes#ReadTypesByOption()
 	exe 'tabn' SavedTabNr
 	exe SavedWinNr . 'wincmd w'
 

File autoload/TagHighlight/ReadTypes.vim

 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])
+let s:all_ft_methods = ['Extension', 'Syntax', 'FileType']
+
+function! TagHighlight#ReadTypes#ReadTypesByOption()
+	let ft_methods = TagHighlight#Option#GetOption('LanguageDetectionMethods')
+	for method in ft_methods
+		if index(s:all_ft_methods, method) == -1
+			echoerr "Invalid detection method: " . method . ": valid values are " .
+						\ string(s:all_ft_methods)
+		endif
+		if eval('TagHighlight#ReadTypes#ReadTypesBy'.method.'()') == 1
+			call TagHLDebug("Success with method " . method, "Information")
+			break
+		else
+			call TagHLDebug("Could not find types with method " . method, "Information")
 		endif
 	endfor
 endfunction
 
-function! TagHighlight#ReadTypes#ReadTypes(suffix)
+function! TagHighlight#ReadTypes#ReadTypesByExtension()
+	if ! s:MethodListed('Extension')
+		call TagHLDebug("Read Types by Extension not specified", "Information")
+		return 0
+	endif
+
+	let file = expand('<afile>')
+	if len(file) == 0
+		let file = expand('%')
+	endif
+	let extension = fnamemodify(file, ':e')
+
+	return s:ReadTypesImplementation('ExtensionLookup', extension, 's:ExtensionCheck')
+endfunction
+
+function! TagHighlight#ReadTypes#ReadTypesBySyntax()
+	if ! s:MethodListed('Syntax')
+		call TagHLDebug("Read Types by Syntax not specified", "Information")
+		return 0
+	endif
+
+	let result = 0
+	let syn = expand('<amatch>')
+	if len(syn) == 0
+		let syn = &syntax
+	endif
+
+	return s:ReadTypesImplementation('SyntaxLookup', syn, 's:InListCheck')
+endfunction
+
+function! TagHighlight#ReadTypes#ReadTypesByFileType()
+	if ! s:MethodListed('FileType')
+		call TagHLDebug("Read Types by FileType not specified", "Information")
+		return 0
+	endif
+
+	let result = 0
+	let ft = expand('<amatch>')
+	if len(ft) == 0
+		let ft = &filetype
+	endif
+
+	return s:ReadTypesImplementation('FileTypeLookup', ft, 's:InListCheck')
+endfunction
+function! s:ExtensionCheck(this, expected)
+	let regex = '^'.a:expected.'$'
+	if a:this =~ regex
+		return 1
+	endif
+	return 0
+endfunction
+
+function! s:InListCheck(this, expected)
+	let split_list = split(a:expected, ",")
+	if index(split_list, a:this) != -1
+		return 1
+	endif
+	return 0
+endfunction
+
+function! s:MethodListed(method)
+	let ft_methods = TagHighlight#Option#GetOption('LanguageDetectionMethods')
+	if index(ft_methods, a:method) != -1
+		return 1
+	endif
+	return 0
+endfunction
+
+function! s:ReadTypesImplementation(lookup, reference, check_function)
+	let result = 0
+	if TagHighlight#Debug#DebugLevelIncludes('Information')
+		call TagHLDebug("Reading types with " . a:lookup . " at " . strftime("%Y%m%d-%H%M%S"), "Information")
+	endif
+	for key in keys(g:TagHighlightPrivate[a:lookup])
+		if eval(a:check_function . '(a:reference, key)') == 1
+			call s:ReadTypes(g:TagHighlightPrivate[a:lookup][key])
+			let result = 1
+		endif
+	endfor
+	return result
+endfunction
+
+function! s:ReadTypes(suffix)
 	let savedView = winsaveview()
 
 	call TagHighlight#Option#LoadOptionFileIfPresent()
 
 	" Restore the view
 	call winrestview(savedView)
+	call TagHLDebug("ReadTypes complete", "Information")
 endfunction
 
 function! TagHighlight#ReadTypes#FindTypeFiles(suffix)

File doc/TagHighlight.txt

 		SourceDir                        Link:|TagHL-SourceDir|
 		   Explicit location of the source code that you want to scan.
 
+	When to read the generated types file
+
+		LanguageDetectionMethods         Link:|TagHL-LanguageDetectionMethods|
+			How to identify programming language and which |autocmd|s to run.
+
 	What to include in the generated types file
 
 		IncludeLocals                    Link:|TagHL-IncludeLocals|
 		Option Type: Boolean
 		Default: False
 
+	LanguageDetectionMethods             *TagHL-LanguageDetectionMethods*
+		This option can be used to configure which methods are used for
+		detecting the language of a file in order to read the appropriate
+		highlight definition file.  There are three methods that are
+		available:
+
+			Extension: Look at the extension of the current file and check
+					   for matches with the VimExtensionMatcher in the
+					   language definition files.
+
+			Syntax: Look at syntax that has been selected by Vim and check for
+			        matches with the VimSyntaxes list in the language
+			        definition files.
+
+			FileType: Look at the file type that has been selected by Vim and
+			          check for matches with the VimFileTypes list in the
+			          language definition files.
+
+		When calling the either of the core commands (|:ReadTypes| and
+		|:UpdateTypesFile|), they are checked in the order specified in the
+		option.  In addition, there are |autocommand|s defined that will load
+		the definitions when reading or creating a new file (Extension match),
+		setting the |'syntax'| (Syntax match) or setting the |'filetype'|
+		(FileType match).  In each case, the |autocommand|s do nothing unless
+		the match type is listed in this option.
+
+		Option Type: List
+		Default: ['Extension']
+
 	Languages                            *TagHL-Languages*
 		By default, when |:UpdateTypesFile| is run, any files that ctags
 		recognises will be scanned for tags and types highlighters will be
 		CTagsName - Whatever ctags refers to the language as.
 
 		PythonExtensionMatcher - A python regular expression that matches
-					 the extensions of files that are written
-					 in this language.
+					             the extensions of files that are written
+					             in this language.
 
 		VimExtensionMatcher - The Vim regular expression version of
-				  PythonExtensionMatcher.
+				              PythonExtensionMatcher.
+
+		VimFileTypes - A list of Vim file types (the output of the Vim command
+		               ":set ft?") that are relevant for this language.
+
+		VimSyntaxes - A list of Vim syntax names (the output of the Vim
+		              command ":set syntax?") that are relevant for this
+		              language.
 
 		Suffix - Whatever you would like the generated files to be named,
-			 e.g. for C code, the suffix is c and the generated files
-			 are by default called types_c.taghl.
+			     e.g. for C code, the suffix is c and the generated files
+			     are by default called types_c.taghl.
 
 	5. Optionally, add other fields as required:
 
 ==============================================================================
 6. TagHighlight History                *TagHighlight-history*               {{{1
 
+2.x.x:  xxxx xxxxxx 2011   : Addition of LanguageDetectionMethods option to
+                             allow loading of types when FileType or Syntax
+                             are set (thanks to Hong Xu for the suggestion).
+                             This also involved addition of syntax and
+							 filetype definitions to all languages.  Prevent
+							 Vim from repeatedly loading autocmds in plugin
+							 development mode.
+
 2.1.0:  22nd August 2011   : First public release of TagHighlight.  Many
                              thanks to Aleksey Baibarin, Marcus Martin,
 							 Mishail, Prasun Ratn and Yongwei Wu for the help

File plugin/TagHighlight.vim

 	" This loads the language data files.
 	let language_files = split(glob(g:TagHighlightPrivate['PluginPath'] . '/data/languages/*.txt'), '\n')
 	let g:TagHighlightPrivate['ExtensionLookup'] = {}
+	let g:TagHighlightPrivate['FileTypeLookup'] = {}
+	let g:TagHighlightPrivate['SyntaxLookup'] = {}
 	let g:TagHighlightPrivate['SpecialSyntaxHandlers'] = {}
 	for language_file in language_files
 		let entries = TagHighlight#LoadDataFile#LoadFile(language_file)
-		if has_key(entries, 'VimExtensionMatcher') && has_key(entries, 'Suffix')
+		if has_key(entries, 'Suffix') && has_key(entries, 'VimExtensionMatcher') 
+					\ && has_key(entries, 'VimFileTypes') && has_key(entries, 'VimSyntaxes')
 			let g:TagHighlightPrivate['ExtensionLookup'][entries['VimExtensionMatcher']] = entries['Suffix']
+
+			if type(entries['VimFileTypes']) == type([])
+				let ftkey = join(entries['VimFileTypes'], ",")
+			else
+				let ftkey = entries['VimFileTypes']
+			endif
+			let g:TagHighlightPrivate['FileTypeLookup'][ftkey] = entries['Suffix']
+
+			if type(entries['VimSyntaxes']) == type([])
+				let stkey = join(entries['VimSyntaxes'], ",")
+			else
+				let stkey = entries['VimSyntaxes']
+			endif
+			let g:TagHighlightPrivate['SyntaxLookup'][stkey] = entries['Suffix']
 		else
 			echoerr "Could not load language from file " . language_file
 		endif
 	exe 'hi default link' simplename 'Keyword'
 endfor
 
-autocmd BufRead,BufNewFile * call TagHighlight#ReadTypes#ReadTypesAutoDetect()
-command! ReadTypes call TagHighlight#ReadTypes#ReadTypesAutoDetect()
+if ! has_key(g:TagHighlightPrivate, 'AutoCommandsLoaded')
+	let g:TagHighlightPrivate['AutoCommandsLoaded'] = 1
+	autocmd BufRead,BufNewFile * call TagHighlight#ReadTypes#ReadTypesByExtension()
+	autocmd Syntax * call TagHighlight#ReadTypes#ReadTypesBySyntax()
+	autocmd FileType * call TagHighlight#ReadTypes#ReadTypesByFileType()
+endif
+command! ReadTypes call TagHighlight#ReadTypes#ReadTypesByOption()

File plugin/TagHighlight/data/languages/c.txt

 CTagsName:c
 PythonExtensionMatcher:(c|cc|cpp|h|hpp|cxx|hxx)
 VimExtensionMatcher:\(c\|cc\|cpp\|h\|hpp\|cxx\|hxx\)
+VimSyntaxes:c,cpp
+VimFileTypes:c,cpp
 Suffix:c
 SkipList:p
 SpecialSyntaxHandlers:TagHighlight#SpecialHandlers#CRainbowHandler

File plugin/TagHighlight/data/languages/csharp.txt

 PythonExtensionMatcher:cs
 VimExtensionMatcher:cs
 Suffix:cs
+VimSyntaxes:cs
+VimFileTypes:cs
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/java.txt

 VimExtensionMatcher:java
 Suffix:java
 SpecialSyntaxHandlers:TagHighlight#SpecialHandlers#JavaTopHandler
+VimSyntaxes:java
+VimFileTypes:java
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/perl.txt

 PythonExtensionMatcher:p[lm]
 VimExtensionMatcher:p[lm]
 Suffix:pl
+VimFileTypes:perl
+VimSyntaxes:perl
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/php.txt

 PythonExtensionMatcher:php
 VimExtensionMatcher:php
 Suffix:php
+VimFileTypes:php
+VimSyntaxes:php
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/python.txt

 PythonExtensionMatcher:pyw?
 VimExtensionMatcher:pyw\?
 Suffix:py
+VimSyntaxes:python
+VimFileTypes:python
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/ruby.txt

 PythonExtensionMatcher:rb
 VimExtensionMatcher:rb
 Suffix:ruby
+VimSyntaxes:ruby
+VimFileTypes:ruby
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/languages/vhdl.txt

 PythonExtensionMatcher:vhdl?
 VimExtensionMatcher:vhdl\?
 Suffix:vhdl
+VimFileTypes:vhdl
+VimSyntaxes:vhdl
 
 # vim: ff=unix:noet

File plugin/TagHighlight/data/options.txt

 # Vim-only options: #
 #####################
 
+language_detection_method:
+	VimOptionMap:LanguageDetectionMethods
+	Type:list
+	Default:Extension
+	Help:Specify methods to use for determining language for the file when reading highlight definitions.
+
 disable_type_parsing:
 	VimOptionMap:DisableTypeParsing
 	Type:bool