pmacs3/mode/lisp.py

74 lines
2.3 KiB
Python

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