import os import regex from method import Method from method.shell import Interact from mode import Fundamental from tab import StackTabber from lex import Grammar, PatternRule, RegionRule from mode.python import StringGrammar2 class LispGrammar(Grammar): rules = [ PatternRule('comment', ';.*$'), PatternRule('delimiter', "[()']"), PatternRule('keyword', r'(?:or|not|list|let\*|let|lambda|if|cons|c[ad]+r|apply|and)(?![^\"\' \t()])'), PatternRule('lisp_word', r"[^\"' \t()]+"), RegionRule('string', '"', StringGrammar2, '"'), PatternRule('spaces', ' +'), PatternRule('eol', r'\n'), ] class LispTabber(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 None: level = self.get_curr_level() + self.mode.tabwidth elif rtoken.string not in ('(', 'define', 'lambda'): rtoken = self.get_next_right_token(y, i + 1) if rtoken is None or rtoken.string != '(': level = self.get_curr_level() + self.mode.tabwidth else: level = rtoken.x else: level = self.get_curr_level() + self.mode.tabwidth self._append(token.string, level) return currlvl class ClispStart(Interact): args = [] reuse = True def _execute(self, w, **vargs): Interact._execute(self, w, bname='*Clisp*', cmd='clisp') class ClispLoadFile(Interact): args = [] reuse = True def _execute(self, w, **vargs): Interact._execute(self, w, bname='*Clisp*', cmd='clisp') b = w.application.get_buffer_by_name('*Clisp*') path = os.path.realpath(w.buffer.path) b.pipe_write('(load "%s")\n' % path) class Lisp(Fundamental): name = 'Lisp' extensions = ['.lisp'] tabwidth = 2 tabbercls = LispTabber grammar = LispGrammar commentc = ';' opentokens = ('delimiter',) opentags = {'(': ')'} closetokens = ('delimiter',) closetags = {')': '('} actions = [ClispStart, ClispLoadFile] _bindings = { 'close-paren': (')',), } commentc = ';' install = Lisp.install