import commands, os.path, sets, string, sys, traceback
import color, completer, default, mode, method, regex, tab
from point import Point
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
from mode.python import StringGrammar

class LispGrammar(Grammar):
    rules = [
        PatternRule(r'comment', r';.*$'),
        PatternRule(r'delimiter', r'[()]'),
        RegionRule(r'string', r'"', StringGrammar, r'"'),
        PatternRule(r'spaces', r' +'),
        PatternRule(r'eol', r'\n'),
    ]

class LispTabber(tab.StackTabber):
    wsre = regex.whitespace
    wst  = ('spaces', 'null', 'eol',)
    sre  = regex.space
    st   = ('spaces', 'null',)
    def _handle_open_token(self, currlvl, y, i):
        token  = self.get_token(y, i)
        rtoken = self.get_next_right_token(y, i)
        if rtoken is not None and rtoken.string != '(':
            rtoken = self.get_next_right_token(y, i + 1)
        if rtoken is None:
            level = self.get_curr_level() + self.mode.tabwidth
        else:
            level = rtoken.x
        self._append(token.string, level)
        return currlvl

class Lisp(mode.Fundamental):
    modename    = 'Lisp'
    tabwidth    = 2
    tabbercls   = LispTabber
    grammar     = LispGrammar
    opentokens  = ('delimiter',)
    opentags    = {'(': ')'}
    closetokens = ('delimiter',)
    closetags   = {')': '('}
    def __init__(self, w):
        mode.Fundamental.__init__(self, w)
        self.add_bindings('close-paren', (')',))
        self.add_bindings('close-brace', ('}',))
        self.add_bindings('close-bracket', (']',))

install = Lisp.install