dynamically-parsed nested regions seem to work!!!! holy shit!!!
--HG-- branch : pmacs2
This commit is contained in:
parent
e691606a33
commit
81b84b24e1
|
@ -579,18 +579,6 @@ class Application(object):
|
||||||
x += slot.width
|
x += slot.width
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
def _get_token_color(self, w, token):
|
|
||||||
fqlist = token.fqlist()
|
|
||||||
c = w.mode.default_color
|
|
||||||
for j in range(0, len(fqlist)):
|
|
||||||
name = '.'.join(fqlist[j:])
|
|
||||||
if name in w.mode.colors:
|
|
||||||
c = w.mode.colors[name]
|
|
||||||
break
|
|
||||||
if DARK_BACKGROUND:
|
|
||||||
c |= curses.A_BOLD
|
|
||||||
return c
|
|
||||||
|
|
||||||
def _draw_slot_lit(self, i):
|
def _draw_slot_lit(self, i):
|
||||||
slot = self.bufferlist.slots[i]
|
slot = self.bufferlist.slots[i]
|
||||||
w = slot.window
|
w = slot.window
|
||||||
|
@ -617,12 +605,10 @@ class Application(object):
|
||||||
x_offset = max(token.x - x, 0)
|
x_offset = max(token.x - x, 0)
|
||||||
assert x_offset <= slot.width, '%d <= %d' % (x_offset, slot.width)
|
assert x_offset <= slot.width, '%d <= %d' % (x_offset, slot.width)
|
||||||
|
|
||||||
c = self._get_token_color(w, token)
|
|
||||||
#s = token.string[s_offset:]
|
|
||||||
s = tstring[s_offset:]
|
s = tstring[s_offset:]
|
||||||
token_done = x_offset + len(s) <= slot.width
|
token_done = x_offset + len(s) <= slot.width
|
||||||
token_wrap = x_offset + len(s) > slot.width
|
token_wrap = x_offset + len(s) > slot.width
|
||||||
self.win.addstr(slot.offset + count, x_offset, s[:slot.width - x_offset], c)
|
self.win.addstr(slot.offset + count, x_offset, s[:slot.width - x_offset], token.color)
|
||||||
|
|
||||||
if token_wrap:
|
if token_wrap:
|
||||||
self.win.addch(slot.offset + count, slot.width, '\\', redattr)
|
self.win.addch(slot.offset + count, slot.width, '\\', redattr)
|
||||||
|
|
|
@ -7,11 +7,13 @@ sub foo {
|
||||||
unless 9 && 3;
|
unless 9 && 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#@@:heredoc:mode_sql.SqlGrammar
|
#@@:heredoc:mode_sql.Sql
|
||||||
my $s = <<EOT;
|
my $s = <<EOT;
|
||||||
drop table foog;
|
drop table foog;
|
||||||
|
select cast(plunk as timestamp) from blarg join plarg using(id_what) where x = 3;
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
|
#@@:string:mode_sql.Sql
|
||||||
my $foo = {
|
my $foo = {
|
||||||
'drop table ',
|
'drop table ',
|
||||||
'bar',
|
'bar',
|
||||||
|
|
86
lex3.py
86
lex3.py
|
@ -1,18 +1,18 @@
|
||||||
import re
|
import curses, re
|
||||||
import regex, util
|
import regex, util
|
||||||
from point2 import Point
|
from point2 import Point
|
||||||
|
|
||||||
class Token(object):
|
class Token(object):
|
||||||
def __init__(self, name, rule, y, x, s, parent=None, matchd={}, link=None):
|
def __init__(self, name, rule, y, x, s, color=None, parent=None, matchd={}, link=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.rule = rule
|
self.rule = rule
|
||||||
self.y = y
|
self.y = y
|
||||||
self.x = x
|
self.x = x
|
||||||
self.string = s
|
self.string = s
|
||||||
self.parent = parent
|
self.color = color
|
||||||
self.matchd = matchd
|
self.parent = parent
|
||||||
self.link = link
|
self.matchd = matchd
|
||||||
#self.loverride = None
|
self.link = link
|
||||||
assert parent is None or hasattr(parent, 'name'), 'oh no %r' % parent
|
assert parent is None or hasattr(parent, 'name'), 'oh no %r' % parent
|
||||||
def parents(self):
|
def parents(self):
|
||||||
if self.parent is not None:
|
if self.parent is not None:
|
||||||
|
@ -43,7 +43,7 @@ class Token(object):
|
||||||
return '.'.join(names)
|
return '.'.join(names)
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return Token(self.name, self.rule, self.y, self.x, self.string,
|
return Token(self.name, self.rule, self.y, self.x, self.string,
|
||||||
self.parent, self.matchd)
|
self.color, self.parent, self.matchd, self.link)
|
||||||
def add_to_string(self, s):
|
def add_to_string(self, s):
|
||||||
self.string += s
|
self.string += s
|
||||||
def end_x(self):
|
def end_x(self):
|
||||||
|
@ -72,7 +72,8 @@ class Rule:
|
||||||
def lex(self, lexer, parent, match):
|
def lex(self, lexer, parent, match):
|
||||||
raise Exception, "not implemented"
|
raise Exception, "not implemented"
|
||||||
def make_token(self, lexer, s, name, parent=None, matchd={}, link=None):
|
def make_token(self, lexer, s, name, parent=None, matchd={}, link=None):
|
||||||
t = Token(name, self, lexer.y, lexer.x, s, parent, matchd, link)
|
t = Token(name, self, lexer.y, lexer.x, s, None, parent, matchd, link)
|
||||||
|
t.color = lexer.get_color(t)
|
||||||
lexer.x += len(s)
|
lexer.x += len(s)
|
||||||
return t
|
return t
|
||||||
def get_line(self, lexer):
|
def get_line(self, lexer):
|
||||||
|
@ -92,6 +93,8 @@ class PatternRule(Rule):
|
||||||
class NocasePatternRule(PatternRule):
|
class NocasePatternRule(PatternRule):
|
||||||
reflags = re.IGNORECASE
|
reflags = re.IGNORECASE
|
||||||
|
|
||||||
|
class OverrideError(Exception):
|
||||||
|
pass
|
||||||
class OverridePatternRule(PatternRule):
|
class OverridePatternRule(PatternRule):
|
||||||
def lex(self, lexer, parent, m):
|
def lex(self, lexer, parent, m):
|
||||||
if m:
|
if m:
|
||||||
|
@ -99,13 +102,16 @@ class OverridePatternRule(PatternRule):
|
||||||
if lexer.action == 'lex':
|
if lexer.action == 'lex':
|
||||||
a = lexer.mode.window.application
|
a = lexer.mode.window.application
|
||||||
try:
|
try:
|
||||||
names = d['grammar'].split('.')
|
names = d['mode'].split('.')
|
||||||
grammar = a.globals()[names.pop(0)]
|
modecls = a.globals()[names.pop(0)]
|
||||||
for name in names:
|
for name in names:
|
||||||
grammar = getattr(grammar, name)
|
modecls = getattr(modecls, name)
|
||||||
lexer.mode.gstack['%s.start' % d['token']] = grammar
|
mode = modecls(None)
|
||||||
except Exception:
|
if hasattr(mode, 'grammar') and hasattr(mode, 'colors'):
|
||||||
#raise
|
lexer.mode.gstack['%s.start' % d['token']] = mode
|
||||||
|
else:
|
||||||
|
raise OverrideError, "argh: %r" % mode
|
||||||
|
except (KeyError, AttributeError, OverrideError):
|
||||||
pass
|
pass
|
||||||
yield self.make_token(lexer, m.group(0), self.name, parent, d)
|
yield self.make_token(lexer, m.group(0), self.name, parent, d)
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
@ -211,14 +217,18 @@ class RegionRule(Rule):
|
||||||
fqname = toresume[0].fqname()
|
fqname = toresume[0].fqname()
|
||||||
p = Point(toresume[0].x, toresume[0].y)
|
p = Point(toresume[0].x, toresume[0].y)
|
||||||
if fqname in lexer.mode.ghist and p in lexer.mode.ghist[fqname]:
|
if fqname in lexer.mode.ghist and p in lexer.mode.ghist[fqname]:
|
||||||
grammar = lexer.mode.ghist[fqname][p]
|
mode = lexer.mode.ghist[fqname][p]
|
||||||
|
grammar = mode.grammar
|
||||||
elif fqname in lexer.mode.gstack:
|
elif fqname in lexer.mode.gstack:
|
||||||
grammar = lexer.mode.gstack[fqname]
|
mode = lexer.mode.gstack[fqname]
|
||||||
|
grammar = mode.grammar
|
||||||
lexer.mode.ghist.setdefault(fqname, {})
|
lexer.mode.ghist.setdefault(fqname, {})
|
||||||
lexer.mode.ghist[fqname][p] = grammar
|
lexer.mode.ghist[fqname][p] = mode
|
||||||
del lexer.mode.gstack[fqname]
|
del lexer.mode.gstack[fqname]
|
||||||
else:
|
else:
|
||||||
|
mode = lexer.mode
|
||||||
grammar = self.pairs[i][0]
|
grammar = self.pairs[i][0]
|
||||||
|
lexer.mstack.append(mode)
|
||||||
|
|
||||||
if self.pairs[i][1]:
|
if self.pairs[i][1]:
|
||||||
stopre = re.compile(self.pairs[i][1] % matchd, self.reflags)
|
stopre = re.compile(self.pairs[i][1] % matchd, self.reflags)
|
||||||
|
@ -242,6 +252,8 @@ class RegionRule(Rule):
|
||||||
matchd.update(tok.matchd)
|
matchd.update(tok.matchd)
|
||||||
else:
|
else:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
# this should have already gotten done by _lex
|
||||||
|
#lexer.mstack.pop(-1)
|
||||||
i += 1
|
i += 1
|
||||||
# assuming we make it through all our grammars, and find the end-token,
|
# assuming we make it through all our grammars, and find the end-token,
|
||||||
# then we need to signal that we are done.
|
# then we need to signal that we are done.
|
||||||
|
@ -286,6 +298,7 @@ class RegionRule(Rule):
|
||||||
null_t = None
|
null_t = None
|
||||||
# ok, now return the stop-token, and signal that we are
|
# ok, now return the stop-token, and signal that we are
|
||||||
# done and no more input is to be consumed
|
# done and no more input is to be consumed
|
||||||
|
lexer.mstack.pop(-1)
|
||||||
yield self.make_token(lexer, m.group(0), stopname,
|
yield self.make_token(lexer, m.group(0), stopname,
|
||||||
parent, m.groupdict(), stopname)
|
parent, m.groupdict(), stopname)
|
||||||
done = True
|
done = True
|
||||||
|
@ -311,7 +324,8 @@ class RegionRule(Rule):
|
||||||
# we didn't find a match on a rule, so add this character to
|
# we didn't find a match on a rule, so add this character to
|
||||||
# the current null token (creating a new one if necessary);
|
# the current null token (creating a new one if necessary);
|
||||||
if not null_t:
|
if not null_t:
|
||||||
null_t = Token('null', None, lexer.y, lexer.x, '', parent)
|
null_t = Token('null', None, lexer.y, lexer.x, '', None, parent)
|
||||||
|
null_t.color = lexer.get_color(null_t)
|
||||||
null_t.add_to_string(line[lexer.x])
|
null_t.add_to_string(line[lexer.x])
|
||||||
lexer.x += 1
|
lexer.x += 1
|
||||||
|
|
||||||
|
@ -334,6 +348,7 @@ grammar = Grammar()
|
||||||
class Lexer:
|
class Lexer:
|
||||||
def __init__(self, mode, grammar):
|
def __init__(self, mode, grammar):
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
self.mstack = []
|
||||||
self.grammar = grammar
|
self.grammar = grammar
|
||||||
self.y = 0
|
self.y = 0
|
||||||
self.x = 0
|
self.x = 0
|
||||||
|
@ -346,6 +361,7 @@ class Lexer:
|
||||||
self.y = y
|
self.y = y
|
||||||
self.x = x
|
self.x = x
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
|
self.mstack = []
|
||||||
self.mode.ghist = {}
|
self.mode.ghist = {}
|
||||||
self.mode.gstack = {}
|
self.mode.gstack = {}
|
||||||
for t in self._lex():
|
for t in self._lex():
|
||||||
|
@ -357,8 +373,8 @@ class Lexer:
|
||||||
self.y = y
|
self.y = y
|
||||||
self.x = x
|
self.x = x
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
self.tokens = []
|
self.mstack = []
|
||||||
toresume = token.parents()
|
toresume = token.parents()
|
||||||
|
|
||||||
i = 1
|
i = 1
|
||||||
while i < len(toresume):
|
while i < len(toresume):
|
||||||
|
@ -398,7 +414,8 @@ class Lexer:
|
||||||
if not m:
|
if not m:
|
||||||
if self.x < len(line):
|
if self.x < len(line):
|
||||||
if null_t is None:
|
if null_t is None:
|
||||||
null_t = Token('null', None, self.y, self.x, '', parent)
|
null_t = Token('null', None, self.y, self.x, '', None, parent)
|
||||||
|
null_t.color = self.get_color(null_t)
|
||||||
null_t.add_to_string(line[self.x])
|
null_t.add_to_string(line[self.x])
|
||||||
self.x += 1
|
self.x += 1
|
||||||
if null_t:
|
if null_t:
|
||||||
|
@ -406,3 +423,20 @@ class Lexer:
|
||||||
self.y += 1
|
self.y += 1
|
||||||
self.x = 0
|
self.x = 0
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
|
def get_color(self, token):
|
||||||
|
fqlist = token.fqlist()
|
||||||
|
if self.mstack:
|
||||||
|
mode = self.mstack[-1]
|
||||||
|
else:
|
||||||
|
mode = self.mode
|
||||||
|
c = mode.default_color
|
||||||
|
for j in range(0, len(fqlist)):
|
||||||
|
name = '.'.join(fqlist[j:])
|
||||||
|
if name in mode.colors:
|
||||||
|
c = mode.colors[name]
|
||||||
|
break
|
||||||
|
#if DARK_BACKGROUND:
|
||||||
|
if True:
|
||||||
|
c |= curses.A_BOLD
|
||||||
|
return c
|
||||||
|
|
12
mode2.py
12
mode2.py
|
@ -17,25 +17,37 @@ class Handler(object):
|
||||||
|
|
||||||
# handle adding and removing actions
|
# handle adding and removing actions
|
||||||
def add_action(self, action):
|
def add_action(self, action):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
if action.name in self.window.application.methods:
|
if action.name in self.window.application.methods:
|
||||||
return
|
return
|
||||||
if action.name in self.window.application.methods:
|
if action.name in self.window.application.methods:
|
||||||
raise Exception, "Action %r already found" % action.name
|
raise Exception, "Action %r already found" % action.name
|
||||||
self.window.application.methods[action.name] = action
|
self.window.application.methods[action.name] = action
|
||||||
def del_action(self, name):
|
def del_action(self, name):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
for binding in self.bindings.keys():
|
for binding in self.bindings.keys():
|
||||||
if self.bindings[binding] == name:
|
if self.bindings[binding] == name:
|
||||||
del self.bindings[binding]
|
del self.bindings[binding]
|
||||||
def add_binding(self, name, sequence):
|
def add_binding(self, name, sequence):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
if name not in self.window.application.methods:
|
if name not in self.window.application.methods:
|
||||||
raise Exception, "No action called %r found" % name
|
raise Exception, "No action called %r found" % name
|
||||||
self.bindings[sequence] = name
|
self.bindings[sequence] = name
|
||||||
def add_bindings(self, name, sequences):
|
def add_bindings(self, name, sequences):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
for sequence in sequences:
|
for sequence in sequences:
|
||||||
self.add_binding(name, sequence)
|
self.add_binding(name, sequence)
|
||||||
def del_binding(self, sequence):
|
def del_binding(self, sequence):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
del self.bindings[sequence]
|
del self.bindings[sequence]
|
||||||
def add_action_and_bindings(self, action, sequences):
|
def add_action_and_bindings(self, action, sequences):
|
||||||
|
if self.window is None:
|
||||||
|
return
|
||||||
self.add_action(action)
|
self.add_action(action)
|
||||||
for sequence in sequences:
|
for sequence in sequences:
|
||||||
self.add_binding(action.name, sequence)
|
self.add_binding(action.name, sequence)
|
||||||
|
|
|
@ -35,7 +35,7 @@ class PerlGrammar(Grammar):
|
||||||
RegionRule(r'endblock', r"^__END__|__DATA__ *$", Grammar, r''),
|
RegionRule(r'endblock', r"^__END__|__DATA__ *$", Grammar, r''),
|
||||||
RegionRule(r'pod', r'^=[a-zA-Z0-9_]+', PodGrammar, r'^=cut'),
|
RegionRule(r'pod', r'^=[a-zA-Z0-9_]+', PodGrammar, r'^=cut'),
|
||||||
|
|
||||||
OverridePatternRule(r'comment', r'#@@:(?P<token>[.a-zA-Z0-9_]+):(?P<grammar>[.a-zA-Z0-9_]+) *$'),
|
OverridePatternRule(r'comment', r'#@@:(?P<token>[.a-zA-Z0-9_]+):(?P<mode>[.a-zA-Z0-9_]+) *$'),
|
||||||
PatternRule(r'comment', r'#.*$'),
|
PatternRule(r'comment', r'#.*$'),
|
||||||
RegionRule(r'string', r'"', StringGrammar, r'"'),
|
RegionRule(r'string', r'"', StringGrammar, r'"'),
|
||||||
RegionRule(r'string', r"'", Grammar, r"'"),
|
RegionRule(r'string', r"'", Grammar, r"'"),
|
||||||
|
@ -165,6 +165,7 @@ class Perl(mode2.Fundamental):
|
||||||
opentags = {'(': ')', '[': ']', '{': '}'}
|
opentags = {'(': ')', '[': ']', '{': '}'}
|
||||||
closetokens = ('delimiter',)
|
closetokens = ('delimiter',)
|
||||||
closetags = {')': '(', ']': '[', '}': '{'}
|
closetags = {')': '(', ']': '[', '}': '{'}
|
||||||
|
|
||||||
def __init__(self, w):
|
def __init__(self, w):
|
||||||
mode2.Fundamental.__init__(self, w)
|
mode2.Fundamental.__init__(self, w)
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ class Perl(mode2.Fundamental):
|
||||||
'use': color.build('cyan', 'default'),
|
'use': color.build('cyan', 'default'),
|
||||||
'require': color.build('cyan', 'default'),
|
'require': color.build('cyan', 'default'),
|
||||||
'method': color.build('cyan', 'default'),
|
'method': color.build('cyan', 'default'),
|
||||||
|
|
||||||
# heredoc/evaldoc
|
# heredoc/evaldoc
|
||||||
'heredoc.start': color.build('green', 'default'),
|
'heredoc.start': color.build('green', 'default'),
|
||||||
'heredoc.null': color.build('green', 'default'),
|
'heredoc.null': color.build('green', 'default'),
|
||||||
|
|
Loading…
Reference in New Issue