import commands, os.path, string, sys, traceback import color, completer, default, mode, regex, tab from point import Point from lex import Grammar, PatternRule, RegionRule, OverridePatternRule from lex import NocasePatternRule, PatternMatchRule from method.shell import Interact class AtomGrammar(Grammar): rules = [ NocasePatternRule(r'escaped', r'\\(?:[bdefnrstv\\"\']|\^[a-z]|\d{1,3})'), NocasePatternRule(r'data', r"[^\\']+"), ] class StringGrammar(Grammar): rules = [ NocasePatternRule(r'escaped', r'\\(?:[bdefnrstv\\"\']|\^[a-z]|\d{1,3})'), NocasePatternRule(r'data', r'[^\\"]+'), ] chr1 = '[a-z]' chr2 = '[a-zA-Z0-9_@]' atom = chr1 + chr2 + '*' class ErlangGrammar(Grammar): rules = [ PatternRule('eol', r'\n'), PatternRule('comment', '%.*$'), PatternRule('erl_attribute', '-' + atom), RegionRule('erl_attribute', "-'", AtomGrammar ,"'"), PatternRule('erl_reserved', "(?:xor|when|try|rem|receive|query|orelse|or|of|not|let|if|fun|end|div|cond|catch|case|bxor|bsr|bsl|bor|bnot|begin|band|andalso|and|after)(?!" + chr2 + ")"), PatternRule('erl_arity', atom + '/(?:0|[1-9][0-9]*)'), PatternMatchRule('x', '('+atom+')( *)(\()', 'erl_function', 'spaces', 'delimiter'), PatternMatchRule('x', '('+atom+')(:)', 'erl_namespace', 'delimiter'), PatternRule('erl_builtin', "(?:whereis|unregister|unlink|tuple_to_list|tuple_size|trunc|tl|time|throw|term_to_binary|term_to_binary|statistics|split_binary|spawn_opt|spawn_opt|spawn_opt|spawn_opt|spawn_monitor|spawn_monitor|spawn_link|spawn_link|spawn_link|spawn_link|spawn|spawn|spawn|spawn|size|setelement|self|round|registered|register|put|purge_module|process_info|process_info|process_flag|process_flag|processes|pre_loaded|port_control|port_connect|port_command|port_close|pid_to_list|open_port|now|nodes|nodes|node|node|monitor_node|module_loaded|make_ref|load_module|list_to_tuple|list_to_pid|list_to_integer|list_to_float|list_to_existing_atom|list_to_bitstring|list_to_binary|list_to_atom|link|length|is_tuple|is_reference|is_record|is_record|is_process_alive|is_port|is_pid|is_number|is_list|is_integer|is_function|is_function|is_float|is_boolean|is_bitstring|is_binary|is_atom|is_alive|iolist_to_binary|iolist_size|iolist|iodata|integer_to_list|hd|halt|halt|group_leader|group_leader|get_keys|get|get|garbage_collect|garbage_collect|float_to_list|float|ext_binary|exit|exit|erase|erase|ence|element|disconnect_node|delete_module|date|concat_binary|check_process_code|byte_size|bitstring_to_list|bit_size|binary_to_term|binary_to_list|binary_to_list|atom_to_list|atom_to_list|apply|apply|apply|abs)(?!" + chr2 + ")"), RegionRule('erl_atom', "'", AtomGrammar, "'"), RegionRule('string', '"', StringGrammar, '"'), PatternRule('erl_atom', atom), PatternRule('erl_variable', r"[A-Z_]" + chr2 + "*"), PatternRule('delimiter', r'->|<<|>>|\(|\)|{|}|\[|\]|\.|;|,|\|'), PatternRule('operator', r'\+\+|--|==|/=|=<|<|>=|>|=:=|=/=>|-|\+|\*|/|:|#|!]'), NocasePatternRule('number', r'\$.|[+-]?\d+#[a-z0-9]+|[+-]?\d+\.\d+|[+-]?\.\d+|[+-]?\d+'), ] class ErlangTabber(tab.StackTabber): enterlvl = ('after', 'begin', 'case', 'catch', 'fun', 'if', 'query', 'receive') def _handle_close_token(self, currlvl, y, i): self._opt_pop(*self.enterlvl) return tab.StackTabber._handle_close_token(self, currlvl, y, i) def _handle_other_token(self, currlvl, y, i): token = self.get_token(y, i) rtoken = self.get_next_right_token(y, i) ltoken = self.get_next_left_token(y, i) if token.name == 'eol': pass elif token.name == 'string.start': self._append('string', None) elif token.name == 'string.end': self._opt_pop('string') elif token.name == 'delimiter': if token.string == '->': if rtoken is None or rtoken.name == 'comment': level = self.get_curr_level() + self.mode.tabwidth else: level = rtoken.x self._append(token.string, level) elif token.string == '.': self.markers = [] elif token.string == ';': self._pop() elif token.name == 'erl_reserved': if token.string in self.enterlvl: if rtoken is None or rtoken.name == 'comment': level = self.get_curr_level() + self.mode.tabwidth else: level = rtoken.x self._append(token.string, level) elif token.string == 'of': self._opt_pop('case') elif token.string == 'end': self._opt_pop('->') self._pop_unless('->') currlvl = self.get_curr_level() return currlvl class ErlStart(Interact): args = [] reuse = True def _execute(self, w, **vargs): Interact._execute(self, w, bname='*Erl*', cmd='erl') class Erlang(mode.Fundamental): name = 'Erlang' extensions = ['.erl'] tabwidth = 4 tabbercls = ErlangTabber grammar = ErlangGrammar commentc = '%' opentokens = ('delimiter',) opentags = {'(': ')', '[': ']', '{': '}'} closetokens = ('delimiter',) closetags = {')': '(', ']': '[', '}': '{'} colors = { 'erl_attribute': ('cyan', 'default', 'bold'), 'erl_reserved': ('cyan', 'default', 'bold'), 'erl_arity': ('magenta', 'default', 'bold'), 'erl_namespace': ('magenta', 'default', 'bold'), 'erl_function': ('blue', 'default', 'bold'), 'erl_builtin': ('magenta', 'default', 'bold'), 'erl_variable': ('yellow', 'default', 'bold'), 'erl_operator': ('default', 'default', 'bold'), 'erl_atom': ('magenta', 'default', 'bold'), 'erl_atom.start': ('magenta', 'default', 'bold'), 'erl_atom.null': ('magenta', 'default', 'bold'), 'erl_atom.data': ('magenta', 'default', 'bold'), 'erl_atom.end': ('magenta', 'default', 'bold'), } actions = [ ErlStart, ] _bindings = { 'close-paren': (')',), 'close-brace': ('}',), 'close-bracket': (']',), } install = Erlang.install