ef8294a3e233f74e67f13ce096cd64021dc7d39c
[stack/conf/vim.git] / addons / TagHighlight / plugin / TagHighlight / module / languages.py
1 #!/usr/bin/env python
2 # Tag Highlighter:
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
12 #            of this software.
13
14 # ---------------------------------------------------------------------
15 import os
16 import glob
17
18 from .config import config
19 from .loaddata import LoadDataFile, LoadFile, GlobData
20 from .debug import Debug
21
22 class Languages():
23     registry = {}
24
25     def __init__(self, options):
26         self.options = options
27         self.kinds = None
28
29         language_list_entries = ['SkipList','Priority']
30
31         # Import language specific modules: this will make them be parsed
32         # and will add to the registry
33         self.defaults = LoadDataFile('language_defaults.txt', language_list_entries)
34
35         for language_file in GlobData('languages/*.txt'):
36             language_dict = LoadDataFile(language_file, language_list_entries)
37             language_dict['Filename'] = language_file
38             if 'ReservedKeywords' in language_dict:
39                 # This is some weird python magic that takes a list of
40                 # strings containing space-separated items and produces
41                 # a single list of those items.
42                 language_dict['ReservedKeywords'] = \
43                         [item for sublist in language_dict['ReservedKeywords'] for item in sublist.split(' ')]
44             else:
45                 language_dict['ReservedKeywords'] = []
46             language_dict = self.VerifyLanguage(language_dict)
47             self.registry[language_dict['FriendlyName']] = language_dict
48
49     def ReadConfigFile(self, filename):
50         result = {}
51         fh = open(filename, 'r')
52         list_entries = ['SkipList','Priority']
53         key = None
54         for line in fh:
55             if line.strip().endswith(':') and line[0] not in [' ','\t',':','#']:
56                 key = line.strip()[:-1]
57                 result[key] = []
58             elif key is not None and line.startswith('\t'):
59                 result[key] += [line.strip()]
60             elif ':' in line and line[0] not in [' ','\t',':','#']:
61                 # End of the previous list, so reset key
62                 key = None
63                 parts = line.strip().split(':',1)
64                 if parts[0] in list_entries:
65                     if ',' in parts[1]:
66                         result[parts[0]] = parts[1].split(',')
67                     else:
68                         result[parts[0]] = [parts[1]]
69                 else:
70                     result[parts[0]] = parts[1]
71         fh.close()
72         return result
73
74     def VerifyLanguage(self, language_dict):
75         required_keys = [
76                 'FriendlyName',
77                 'CTagsName',
78                 'PythonExtensionMatcher',
79                 'VimExtensionMatcher',
80                 'Suffix',
81                 'SkipList',
82                 'IsKeyword',
83                 'Priority',
84                 ]
85         for key in required_keys:
86             if key not in language_dict:
87                 if key in self.defaults:
88                     language_dict[key] = self.defaults[key]
89                 else:
90                     raise Exception("Language data from file {filename} is " \
91                             "missing required key {key} (no default " \
92                             "available).".format(filename=language_dict['Filename'],
93                                 key=key))
94         return language_dict
95
96     def GetAllLanguages(self):
97         return list(self.registry.keys())
98
99     def GetAllLanguageHandlers(self):
100         return list(self.registry.values())
101
102     def GetLanguageHandler(self, name):
103         return self.registry[name]
104
105     def GenerateExtensionTable(self):
106         results = {}
107         for handler in list(self.registry.values()):
108             extensions = handler.GetVimMatcher()
109             suffix = handler.GetSuffix()
110             results[extensions] = suffix
111         return results
112
113     def GenerateFullKindList(self):
114         self.LoadKindList()
115         kinds = set()
116         for language in list(self.kinds.keys()):
117             kinds |= set(self.kinds[language].values())
118         return sorted(list(kinds))
119
120     def GetKindList(self, language=None):
121         """Explicit list of kinds exported from ctags help."""
122         if self.kinds is None:
123             kind_import = LoadDataFile('kinds.txt')
124             # Generate the kind database with 'ctags_' prefix on the keys
125             self.kinds = {}
126             for key in kind_import:
127                 self.kinds[key] = {}
128                 for kind in kind_import[key]:
129                     self.kinds[key]['ctags_'+kind] = kind_import[key][kind]
130
131         if language is None:
132             return self.kinds
133         elif language in self.kinds:
134             return self.kinds[language]
135         else:
136             return None
137