2 " Author: A. S. Budden <abudden _at_ gmail _dot_ com>
3 " Copyright: Copyright (C) 2009-2011 A. S. Budden
4 " Permission is hereby granted to use and distribute this code,
5 " with or without modifications, provided that this copyright
6 " notice is copied with it. Like anything else that's free,
7 " the TagHighlight plugin is provided *as is* and comes with no
8 " warranty of any kind, either expressed or implied. By using
9 " this plugin, you agree that in no event will the copyright
10 " holder be liable for any damages resulting from the use
13 " ---------------------------------------------------------------------
15 if &cp || v:version < 700 || (exists('g:loaded_TagHLLibraries') && (g:plugin_development_mode != 1))
16 throw "Already loaded"
21 let g:loaded_TagHLLibraries = 1
23 function! TagHighlight#Libraries#LoadLibraries()
24 if has_key(g:TagHighlightPrivate,'Libraries')
28 call TagHLDebug("Loading standard library information", "Information")
30 let g:TagHighlightPrivate['LibraryPath'] = g:TagHighlightPrivate['PluginPath'] . '/standard_libraries'
31 let g:TagHighlightPrivate['Libraries'] = {}
32 let library_config_files = split(glob(g:TagHighlightPrivate['LibraryPath'] . '/*/library_types.txt'), '\n')
34 let required_keys = ["LibraryName","TypesFiles","CheckMode","TypesSuffixes"]
35 for library_config in library_config_files
36 call TagHLDebug("Loading information for " . library_config, "Information")
38 let library_details = TagHighlight#LoadDataFile#LoadFile(library_config)
39 for key in required_keys
40 if ! has_key(library_details, key)
41 call TagHLDebug("Could not load library from " . library_config, "Warning")
49 " Config looks valid; check fields that should be lists are:
50 let list_keys = ["TypesFiles","TypesSuffixes","MatchREs"]
52 if has_key(library_details,key) && type(library_details[key]) == type('')
53 let value = library_details[key]
54 unlet library_details[key]
55 let library_details[key] = [value]
58 " Store the absolute path to the all types files
59 let library_details['TypesFileFullPaths'] = []
60 for types_file in library_details['TypesFiles']
61 let library_details['TypesFileFullPaths'] += [fnamemodify(library_config, ':p:h') . '/' . types_file]
64 " Handle some defaults
65 if ! has_key(library_details,'MatchREs')
66 " Default matcher will never match on any file
67 let library_details['MatchREs'] = ['.\%^']
69 if ! has_key(library_details, 'CustomFunction')
70 " Default custom function will always return 'Skip'
71 let library_details['CustomFunction'] = 'TagHighlight#Libraries#NeverMatch'
73 if ! has_key(library_details, 'MatchLines')
74 " Just use a suitable default value
75 let library_details['MatchLines'] = 30
78 call TagHLDebug("Loaded library: " . string(library_details), "Information")
79 let g:TagHighlightPrivate['Libraries'][library_details['LibraryName']] = library_details
83 function! TagHighlight#Libraries#FindUserLibraries()
84 " Open any explicitly configured libraries
85 call TagHLDebug("Searching for user libraries", "Information")
86 let user_library_dir = TagHighlight#Option#GetOption('UserLibraryDir')
87 let user_libraries = TagHighlight#Option#GetOption('UserLibraries')
89 call TagHLDebug("Library Dir: " . user_library_dir, "Information")
90 call TagHLDebug("Library List: " . string(user_libraries), "Information")
92 let libraries_to_load = []
94 for library in user_libraries
95 " If it looks like an absolute path, just load it
96 if (library[1] == ':' || library['0'] == '/') && filereadable(library)
97 call TagHLDebug("User library is absolute path: " . library, "Information")
98 let libraries_to_load +=
100 \ 'Name': 'User Library',
101 \ 'Filename': fnamemodify(library, ':t'),
102 \ 'Path': fnamemodify(library, '%:p'),
104 " Otherwise, try appending to the library dir
105 elseif filereadable(user_library_dir . '/' . library)
106 call TagHLDebug("User library is relative path: " . library, "Information")
107 let library_path = user_library_dir . '/' . library
108 let libraries_to_load +=
110 \ 'Name': 'User Library',
111 \ 'Filename': fnamemodify(library_path, ':t'),
112 \ 'Path': fnamemodify(library_path, '%:p'),
115 call TagHLDebug("Cannot load user library " . library, "Error")
118 return libraries_to_load
121 function! TagHighlight#Libraries#FindLibraryFiles(suffix)
122 " Should only actually read the libraries once
123 call TagHLDebug("Finding library files for current file with suffix " . a:suffix, "Information")
124 call TagHighlight#Libraries#LoadLibraries()
126 let libraries_to_load = []
127 let forced_standard_libraries = TagHighlight#Option#GetOption('ForcedStandardLibraries')
129 if TagHighlight#Option#GetOption('DisableStandardLibraries')
130 call TagHLDebug("Standard library loading disabled", "Information")
134 for library in values(g:TagHighlightPrivate['Libraries'])
135 call TagHLDebug("Checking " . library['LibraryName'], "Information")
137 if index(library['TypesSuffixes'], a:suffix) != -1
138 " Suffix is in the list of acceptable ones
139 if index(forced_standard_libraries, library['LibraryName']) != -1
140 call TagHLDebug("Library(".library['LibraryName']."): Forced", "Information")
142 elseif library['CheckMode'] == 'Always'
143 call TagHLDebug("Library(".library['LibraryName']."): Always", "Information")
145 elseif library['CheckMode'] == 'MatchStart'
146 call TagHLDebug("Library(".library['LibraryName']."): Checking MatchStart", "Information")
147 for matcher in library['MatchREs']
149 if search(matcher, 'nc',library['MatchLines'])
150 call TagHLDebug("Library(".library['LibraryName']."): Match!", "Information")
155 elseif library['CheckMode'] == 'MatchEnd'
156 call TagHLDebug("Library(".library['LibraryName']."): Checking MatchEnd", "Information")
157 for matcher in library['MatchREs']
158 call cursor(1000000,1000000)
159 if search(matcher, 'ncb', library['MatchLines'])
160 call TagHLDebug("Library(".library['LibraryName']."): Match!", "Information")
165 elseif library['CheckMode'] == 'Custom'
166 call TagHLDebug("Library(".library['LibraryName']."): Custom (".library['CustomFunction'].")", "Information")
167 " The hope is that this won't really ever be used, but
168 " call the function and check that it returns the right
169 " kind of thing (takes suffix as parameter)
170 exe 'let result = ' . library['CustomFunction'] . '(' . a:suffix . ')'
172 call TagHLDebug("Custom result: Load", "Information")
174 elseif result == 'Skip'
175 call TagHLDebug("Custom result: Skip", "Information")
178 call TagHLDebug("Misconfigured library: custom function has invalid return value", "Critical")
183 for full_path in library['TypesFileFullPaths']
184 let libraries_to_load +=
186 \ 'Name': library['LibraryName'],
187 \ 'Filename': fnamemodify(full_path, ':t'),
192 call TagHLDebug("No match:" . library['LibraryName'], "Information")
196 return libraries_to_load
199 function! TagHighlight#Libraries#NeverMatch()