3 # Author: A. S. Budden <abudden _at_ gmail _dot_ com>
4 # Copyright: Copyright (C) 2009-2011 A. S. Budden
5 # Permission is hereby granted to use and distribute this code,
6 # with or without modifications, provided that this copyright
7 # notice is copied with it. Like anything else that's free,
8 # the TagHighlight plugin is provided *as is* and comes with no
9 # warranty of any kind, either expressed or implied. By using
10 # this plugin, you agree that in no event will the copyright
11 # holder be liable for any damages resulting from the use
14 # ---------------------------------------------------------------------
15 from __future__ import print_function
18 from .utilities import GenerateValidKeywordRange, IsValidKeyword
19 from .debug import Debug
21 vim_synkeyword_arguments = [
36 def CreateTypesFile(options, language, tags):
37 tag_types = list(tags.keys())
40 Debug("Writing types file", "Information")
42 language_handler = options['language_handler'].GetLanguageHandler(language)
44 if options['check_keywords']:
45 iskeyword = GenerateValidKeywordRange(language_handler['IsKeyword'])
46 Debug("Is Keyword is {0!r}".format(iskeyword), "Information")
52 typesUsedByLanguage = list(options['language_handler'].GetKindList(language).values())
53 # TODO: This may be included elsewhere, but we'll leave it in for now
54 #clear_string = 'silent! syn clear ' + " ".join(typesUsedByLanguage)
57 #vimtypes_entries.append(clear_string)
59 # Get the priority list from the language handler
60 priority = language_handler['Priority'][:]
61 # Reverse the priority such that highest priority
65 fullTypeList = list(reversed(sorted(tags.keys())))
66 # Reorder type list according to priority sort order
68 for thisType in priority:
69 if thisType in fullTypeList:
70 allTypes.append(thisType)
71 fullTypeList.remove(thisType)
72 # Add the ones not specified in priority
73 allTypes = fullTypeList + allTypes
75 Debug("Type priority list: " + repr(allTypes), "Information")
78 for pattern in options['skip_patterns']:
79 patternREs.append(re.compile(pattern))
81 for thisType in allTypes:
82 keystarter = 'syn keyword ' + thisType
83 keycommand = keystarter
84 for keyword in tags[thisType]:
86 if options['skip_reserved_keywords']:
87 if keyword in language_handler['ReservedKeywords']:
88 Debug('Skipping reserved word ' + keyword, 'Information')
91 for pattern in patternREs:
92 if pattern.search(keyword) != None:
98 if options['check_keywords']:
99 # In here we should check that the keyword only matches
100 # vim's \k parameter (which will be different for different
101 # languages). This is quite slow so is turned off by
102 # default; however, it is useful for some things where the
103 # default generated file contains a lot of rubbish. It may
104 # be worth optimising IsValidKeyword at some point.
105 if not IsValidKeyword(keyword, iskeyword):
107 if options['include_matches']:
109 patternCharacters = "/@#':"
110 charactersToEscape = '\\' + '~[]*.$^'
112 for patChar in patternCharacters:
113 if keyword.find(patChar) == -1:
114 escapedKeyword = keyword
115 for ch in charactersToEscape:
116 escapedKeyword = escapedKeyword.replace(ch, '\\' + ch)
117 if options['include_matches']:
118 matchEntries.add('syn match ' + thisType + ' ' + patChar + escapedKeyword + patChar)
123 Debug("Skipping keyword '" + keyword + "'", "Information")
128 if keyword.lower() in vim_synkeyword_arguments:
129 if not options['skip_vimkeywords']:
130 matchEntries.add('syn match ' + thisType + ' /' + keyword + '/')
133 temp = keycommand + " " + keyword
135 vimtypes_entries.append(keycommand)
136 keycommand = keystarter
137 keycommand = keycommand + " " + keyword
138 if keycommand != keystarter:
139 vimtypes_entries.append(keycommand)
142 matchEntries = sorted(list(matchEntries))
144 if (len(matchEntries) + len(vimtypes_entries)) == 0:
145 # All keywords have been filtered out, give up
148 vimtypes_entries.append('')
149 vimtypes_entries += matchEntries
151 if options['include_locals']:
152 LocalTagType = ',CTagsLocalVariable'
156 if options['types_file_name_override'] is not None and options['types_file_name_override'] != 'None':
157 type_file_name = options['types_file_name_override']
159 type_file_name = options['types_file_prefix'] + '_' + language_handler['Suffix'] + '.' + options['types_file_extension']
160 filename = os.path.join(options['types_file_location'], type_file_name)
161 Debug("Filename is {0}\n".format(filename), "Information")
164 # Have to open in binary mode as we want to write with Unix line endings
165 # The resulting file will then work with any Vim (Windows, Linux, Cygwin etc)
166 fh = open(filename, 'wb')
168 Debug("ERROR: Couldn't create {file}\n".format(file=outfile), "Error")
172 for line in vimtypes_entries:
174 fh.write(line.encode('ascii'))
175 except UnicodeDecodeError:
176 Debug("Error decoding line '{0!r}'".format(line), "Error")
177 fh.write('echoerr "Types generation error"\n'.encode('ascii'))
178 fh.write('\n'.encode('ascii'))
180 Debug("ERROR: Couldn't write {file} contents\n".format(file=outfile), "Error")