pmacs3/mode/erlang.py

111 lines
5.8 KiB
Python

import commands, os.path, string, sys, traceback
import color, completer, default, mode, method, regex, tab
from point import Point
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule, NocasePatternRule
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'[^\\"]+'),
]
class ErlangGrammar(Grammar):
rules = [
PatternRule(r'eol', r'\n'),
PatternRule(r'comment', r'%.*$'),
PatternRule(r'erl_attribute', r'-[a-z][a-zA-Z0-9_@]+'),
PatternRule(r'erl_reserved', r"(?: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)(?![a-zA-Z0-9_'])"),
PatternRule(r'erl_arity', r'[a-z][a-zA-Z0-9_@]*/(?:0|[1-9][0-9]*)'),
PatternRule(r'erl_function', r'[a-z][a-zA-Z0-9_@]*(?= *\()'),
PatternRule(r'erl_namespace', r'[a-z][a-zA-Z0-9_@]*(?=:)'),
PatternRule(r'erl_builtin', r"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"),
RegionRule(r'erl_atom', r"'", AtomGrammar, r"'"),
RegionRule(r'string', r'"', StringGrammar, r'"'),
PatternRule(r'erl_atom', r"[a-z][a-zA-Z0-9_@]*"),
PatternRule(r'erl_variable', r"[A-Z_][a-zA-Z0-9_@]*"),
PatternRule(r'delimiter', r'->|<<|>>|\(|\)|{|}|\[|\]|\.|;|,|\|'),
PatternRule(r'operator', r'\+\+|--|==|/=|=<|<|>=|>|=:=|=/=>|-|\+|\*|/|:|#|!]'),
NocasePatternRule(r'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 Erlang(mode.Fundamental):
modename = '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.end': ('magenta', 'default', 'bold'),
}
_bindings = {
'close-paren': (')',),
'close-brace': ('}',),
'close-bracket': (']',),
}
install = Erlang.install