import commands, os.path, sets, string, sys, traceback
import color, completer, default, mode2, method, regex, tab2
from point2 import Point
from lex3 import Grammar, PatternRule, RegionRule, OverridePatternRule
import mode.lisp

class SchemeGrammar(Grammar):
    rules = [
        PatternRule(r'comment', r';.*$'),
        PatternRule(r'delimiter', r'[()]'),
        RegionRule(r'string', r'"', mode.lisp.StringGrammar, r'"'),
        PatternRule(r'spaces', r' +'),
        PatternRule(r'eol', r'\n'),
        PatternRule(r'abbrev', r"'|`|,\@|,"),

        # from r5rs
        PatternRule(r'keyword', r'(?:=>|unquote-splicing|unquote|syntax-rules|set!|quote|quasiquote|or|map|loop|letrec-syntax|letrec|let-syntax|let\*|let|lambda|if|for-each|else|dynamic-wind|do|delay|define-syntax|define-macro|define|cond|case|call-with-output-file|call-with-input-file|call-with-current-continuation|begin|and)(?![^\n )])'),

        PatternRule(r'boolean', r'#[tf]'),
        PatternRule(r'char', r'#\\space|#\\newline|#\\.'),
        PatternRule(r'number', '[+-]?[0-9][^ ()\n]+'),
        PatternRule(r'number', '#[bodx][ie]?[^ ()\n]+'),
        PatternRule(r'number', '#[ie][bodx]?[^ ()\n]+'),

        PatternRule(r'variable', r'[a-zA-Z!$%&*/:<=>?\^_~][-a-zA-Z0-9!$%&*/:<=>?^_~+.@]*|\+|-|\.\.\.'),
    ]

class Scheme(mode2.Fundamental):
    tabwidth    = 2
    tabbercls   = mode.lisp.LispTabber
    grammar     = SchemeGrammar
    opentokens  = ('delimiter',)
    opentags    = {'(': ')'}
    closetokens = ('delimiter',)
    closetags   = {')': '('}
    colors      = {
        'comment': ('red', 'default'),

        'keyword': ('cyan', 'default'),
        'builtin': ('cyan', 'default'),

        'string.start':   ('green', 'default'),
        'string.null':    ('green', 'default'),
        'string.octal':   ('magenta', 'default'),
        'string.escaped': ('magenta', 'default'),
        'string.end':     ('green', 'default'),
        'char':           ('green', 'default'),
        'boolean': ('magenta', 'default'),
        'number':  ('default', 'default'),
    }
    def __init__(self, w):
        mode2.Fundamental.__init__(self, w)
        # tag matching
        self.add_bindings('close-paren', (')',))
        self.add_bindings('close-brace', ('}',))
        self.add_bindings('close-bracket', (']',))
        ## add scheme-specific methods
        #self.add_action_and_bindings(SchemeCheckSyntax(), ('C-c s',))
    def name(self):
        return "Scheme"