import subprocess, 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 from etags import TagManager 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 ErlangTagManager(TagManager): lang = 'Erlang' exts = set(('.erl',)) class Erlang(mode.Fundamental): name = 'Erlang' extensions = ['.erl'] tabwidth = 4 tabbercls = ErlangTabber tagcls = ErlangTagManager 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