from mode import Fundamental from lex import Grammar, PatternRule, RegionRule, NocaseKeywordRule from tab import StackTabber import regex directives = '''abbreviate array attribute btrace class constant default dictionary end endif etrace extend fake_action global ifdef ifndef iftrue iffalse ifv3 ifv5 import include link listsymbols listdict listverbs lowstring ltrace message nearby nobtrace noetrace noltrace notrace object property release replace serial statusline stub switches system_file trace verb zcharacter'''.split() defines = '''array attribute class constant fake_action global lowstring nearby object property'''.split() attributes = '''absent animate clothing concealed container door edible enterable female general light lockable locked male moved neuter on open openable pluralname proper scenery scored static supporter switchable talkable transparent visited workflag worn'''.split() properties = '''n_to s_to e_to w_to ne_to se_to nw_to sw_to u_to d_to in_to out_to add_to_scope after article articles before cant_go capacity daemon describe description door_dir door_to each_turn found_in grammar initial inside_description invent life list_together name number orders parse_name plural react_after react_before short_name time_left time_out when_closed when_open when_on when_off with_key'''.split() keywords = '''box break class continue do else font off font on for give has hasnt if inversion jump move new_line notin objectloop ofclass print print_ret private quit read remove restore return rfalse rtrue save spaces string style bold style fixed style reverse style roman style underline switch to until while with'''.split() class StringGrammar(Grammar): rules = [ PatternRule('escaped', r'\\.'), PatternRule('data', r'[^\\"]+'), ] class NameGrammar(Grammar): rules = [ PatternRule('escaped', r'\\.'), PatternRule('data', r"[^\\']+"), ] class Inform6Grammar(Grammar): rules = [ PatternRule('comment', '!.*$'), PatternRule('inform6.char', "'.(?://.+)'"), RegionRule('inform6.name', "'", NameGrammar, "'"), RegionRule('inform6.string', '"', StringGrammar, '"'), NocaseKeywordRule('inform6.directive', directives), NocaseKeywordRule('inform6.define', defines), NocaseKeywordRule('inform6.attribute', attributes), NocaseKeywordRule('inform6.property', properties), NocaseKeywordRule('inform6.keyword', keywords), PatternRule('inform6.number', '\$\$[01]+'), PatternRule('inform6.number', '\$[0-9a-fA-F]+'), PatternRule('inform6.number', '[0-9]+'), PatternRule('inform6.label', '\.[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('inform6.identifier', '[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('inform6.word', '[a-zA-Z_]+'), PatternRule('delimiter', r'[\(\)\{\}\[\];]'), PatternRule('spaces', ' +'), PatternRule('eol', '\n'), PatternRule('continuation', r'\\\n$'), ] class Inform6Tabber(StackTabber): def is_base(self, y): if y == 0: return True h = self.mode.window.buffer.highlights[self.mode.name] if not h.tokens[y]: return False t = h.tokens[y][0] if t.name != 'inform6.directive': return False return t.string.lower() in ('constant', 'include', 'object') def _handle_open_token(self, currlvl, y, i): t = self.get_token(y, i) l = self.get_curr_level() + self.mode.tabwidth self._append(t.string, l, y) return currlvl def _handle_other_token(self, currlvl, y, i): w = self.mode.tabwidth t = self.get_token(y, i) s = t.string.lower() n = t.fqname() if n == 'inform6.directive': if s == 'object': self._append('object', currlvl + w, y) if n == 'inform6.keyword': if s in ('with', 'has'): if self._peek_name() == 'keyword': self._pop() currlvl -= w self._append('keyword', currlvl + w, y) elif n == 'delimiter': self._opt_pop('keyword') self._opt_pop('object') return currlvl class Inform6(Fundamental): name = 'inform6' extensions = ['.inf'] tabbercls = Inform6Tabber grammar = Inform6Grammar commentc = '!' opentokens = ('delimiter',) opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} colors = { 'inform6.label': ('magenta', 'default', 'bold'), 'inform6.define': ('magenta', 'default', 'bold'), 'inform6.directive': ('blue', 'default', 'bold'), 'inform6.keyword': ('blue', 'default', 'bold'), 'inform6.attribute': ('cyan', 'default', 'bold'), 'inform6.property': ('cyan', 'default', 'bold'), 'inform6.string.start': ('green', 'default', 'bold'), 'inform6.string.escaped': ('magenta', 'default', 'bold'), 'inform6.string.data': ('green', 'default', 'bold'), 'inform6.string.end': ('green', 'default', 'bold'), 'inform6.name.start': ('green', 'default', 'bold'), 'inform6.name.escaped': ('magenta', 'default', 'bold'), 'inform6.name.data': ('green', 'default', 'bold'), 'inform6.name.end': ('green', 'default', 'bold'), } _bindings = { 'close-paren': (')',), 'close-brace': ('}',), 'close-bracket': (']',), } install = Inform6.install