diff --git a/application.py b/application.py index db13aeb..1cd2b06 100755 --- a/application.py +++ b/application.py @@ -447,10 +447,10 @@ class Application(object): if self.mini_active: b = self.mini_buffer w = b.windows[0] - (cx, cy) = w.logical_cursor().xy() - if cy >= len(b.lines): + p = w.logical_cursor() + if p.y >= len(b.lines): return - (vy, vx) = (self.y - 1, cx + len(self.mini_prompt)) + (vy, vx) = (self.y - 1, min(p.x + len(self.mini_prompt), self.x - 2)) #self.win.move(self.y-1, cx + len(self.mini_prompt)) else: slot = self.bufferlist.slots[self.active_slot] @@ -475,7 +475,11 @@ class Application(object): #self.win.move(slot.offset + count, p.x - x) if vy is None or vx is None: return - self.win.move(vy, vx) + try: + self.win.move(vy, vx) + except: + raise Exception, "(%d,%d==%r) was illegal (%d,%d)" % \ + (vx, vy, p, self.x, self.y) # sub-drawing methods def draw_slots(self): @@ -490,8 +494,14 @@ class Application(object): char = junk & 255 #attr = color.build(fg, bg, curses.A_REVERSE) attr = color.build(fg, bg) - self.win.addch(sy, sx, char, attr) + try: + self.win.addch(sy, sx, char, attr) + except: + raise Exception, "(%d, %d, %r, %r) v. (%d, %d)" % \ + (sy, sx, fg, bg, self.y, self.x) + def highlight_chars(self, sy, sx1, sx2, fg='default', bg='default'): + assert sx2 < self.x, "%d < %d" % (sx2, self.x) for x in range(sx1, sx2): self.highlight_char(sy, x, fg, bg) @@ -516,13 +526,17 @@ class Application(object): (x, y) = w.first.xy() px = p1.x while count < slot.height: - if p1.y == y and px >= x and px < x + slot.width: - if px + slot.width > p2.x: - self.highlight_chars(slot.offset + count, px - x, p2.x -x, fg, bg) + if p1.y == y and px >= x and px - x < slot.width: + if slot.width > p2.x - x: + #assert p2.x-x < self.x, \ + # "%d-%d < %d" % (p2.x, x, self.x) + self.highlight_chars(slot.offset + count, px-x, p2.x-x, fg, bg) break else: - self.highlight_chars(slot.offset + count, px - x, px + slot.width -x-1, fg, bg) - px += slot.width + #assert px - x < self.x, \ + # "%d+%d-%d-1 < %d" % (px, slot.width, x, self.x) + self.highlight_chars(slot.offset + count, px-x, slot.width, fg, bg) + px += slot.width - px + x if x + slot.width >= len(w.buffer.lines[y]): x = 0 y += 1 diff --git a/lex2.py b/lex2.py index 7de1702..3bccf6e 100755 --- a/lex2.py +++ b/lex2.py @@ -63,14 +63,20 @@ class Rule: raise Exception, "%s rule cannot match!" % self.name def make_token(self, lexer, s, name, parent=None, matchd={}): return Token(name, self, lexer.y, lexer.x, s, parent, matchd) + def _set_group(self, group): + if group is None: + self.group = self.name + else: + self.group = group class ConstantRule(Rule): - def __init__(self, name, constant): + def __init__(self, name, constant, group=None): assert valid_name_re.match(name), 'invalid name %r' % name assert name not in reserved_names, "reserved rule name: %r" % name self.name = name self.constant = constant - self.lenth = len(self.constant) + self.length = len(self.constant) + self._set_group(group) def match(self, lexer, parent): if lexer.lines[lexer.y][lexer.x:].startswith(self.constant): token = self.make_token(lexer, self.constant, self.name, parent) @@ -81,12 +87,13 @@ class ConstantRule(Rule): return False class PatternRule(Rule): - def __init__(self, name, pattern): + def __init__(self, name, pattern, group=None): assert valid_name_re.match(name), 'invalid name %r' % name assert name not in reserved_names, "reserved rule name: %r" % name self.name = name self.pattern = pattern self._compile() + self._set_group(group) def _compile(self): self.re = re.compile(self.pattern) def _match(self, lexer, parent, m): @@ -107,13 +114,14 @@ class NocasePatternRule(PatternRule): self.re = re.compile(self.pattern, re.IGNORECASE) class ContextPatternRule(PatternRule): - def __init__(self, name, pattern, fallback): + def __init__(self, name, pattern, fallback, group=None): assert valid_name_re.match(name), 'invalid name %r' % name assert name not in reserved_names, "reserved rule name: %r" % name self.name = name self.pattern = pattern self.fallback = fallback self.fallback_re = re.compile(fallback) + self._set_group(group) def match(self, lexer, parent): try: r = re.compile(self.pattern % parent.matchd) @@ -127,7 +135,7 @@ class ContextPatternRule(PatternRule): return False class RegionRule(Rule): - def __init__(self, name, start, grammar, end): + def __init__(self, name, start, grammar, end, group=None): assert valid_name_re.match(name), 'invalid name %r' % name assert name not in reserved_names, "reserved rule name: %r" % name self.name = name @@ -135,6 +143,7 @@ class RegionRule(Rule): self.grammar = grammar self.end = end self.start_re = self._compile_start() + self._set_group(group) def _compile_start(self): return re.compile(self.start) @@ -270,7 +279,7 @@ class NocaseRegionRule(RegionRule): return re.compile(self.end % d, re.IGNORECASE) class DualRegionRule(Rule): - def __init__(self, name, start, grammar1, middle, grammar2, end): + def __init__(self, name, start, grammar1, middle, grammar2, end, group=None): assert valid_name_re.match(name), 'invalid name %r' % name assert name not in reserved_names, "reserved rule name: %r" % name self.name = name @@ -280,6 +289,7 @@ class DualRegionRule(Rule): self.grammar2 = grammar2 self.end = end self.start_re = re.compile(start) + self._set_group(group) def _add_from_regex(self, name, lexer, parent, m, matchd={}): s = m.group(0) token = self.make_token(lexer, s, name, parent, matchd) @@ -480,6 +490,30 @@ class Grammar: if hasattr(rule, 'grammar') and rule.grammar is None: rule.grammar = self +grammars = {} +grammars['null'] = Grammar() +crash = False + +def add(name, grammar): + global crash, grammars + if crash and name in grammars: + raise Exception, "oh no! already have a grammar for %r" %name + else: + grammars[name] = grammar + + +def get(name): + global crash, grammars + try: + return grammars[name] + except KeyError: + if crash: + raise + elif name == 'null': + return Grammar() + else: + return get('null') + class Lexer: def __init__(self, name, grammar): self.name = name @@ -542,3 +576,4 @@ class Lexer: return self.tokens.pop(0) else: raise StopIteration + diff --git a/mode_bds.py b/mode_bds.py index 1b65080..c77d437 100644 --- a/mode_bds.py +++ b/mode_bds.py @@ -1,39 +1,33 @@ -import color, mode2 +import color, lex2, mode2 from lex2 import Grammar, PatternRule, RegionRule -class OpenTagGrammar(Grammar): - rules = [ - RegionRule(name=r'string', start=r'(?P["\'])', grammar=Grammar(), end=r'%(tag)s'), - PatternRule(name=r'namespace', pattern=r'[a-zA-Z_]+:'), - PatternRule(name=r'attrname', pattern=r'[^ =>\n]+(?==)'), - PatternRule(name=r'name', pattern=r'[^ =>\n]+'), - ] - class StringGrammar(Grammar): rules = [ - PatternRule(name=r'octal', pattern=r'\\[0-7]{3}'), - PatternRule(name=r'escaped', pattern=r'\\.'), + PatternRule(r'octal', r'\\[0-7]{3}'), + PatternRule(r'escaped', r'\\.'), ] +lex2.add('xml-string', StringGrammar) class BDSGrammar(Grammar): rules = [ - RegionRule(name=r'comment', start=r''), - RegionRule(name=r'opentag', start=r'<', grammar=OpenTagGrammar(), end=r'/?>'), - PatternRule(name=r'closetag', pattern=r'< */ *[ =>\n]+ *>'), - PatternRule(name=r'delimiter', pattern=r'[\[\]\{\}\(\),\?:]'), - PatternRule(name=r'derived', pattern=r'(?:FM|CD|FS|FM|TA)[0-9]{3}-[0-9]{3}-[0-9]{3}'), - PatternRule(name=r'question', pattern=r'GQ[0-9]{3}-[0-9]{3}-[0-9]{3}:MQ[0-9]{3}-[0-9]{3}-[0-9]{3}'), - PatternRule(name=r'bdsfunc', pattern=r'[A-Z_][A-Z0-9_]+(?= *\()'), - PatternRule(name=r'perlfunc', pattern=r'[a-zA-Z_][a-zA-Z0-9_]+(?= *\()'), - PatternRule(name=r'misquoted', pattern=r"'[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3}(?::[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3})?'"), - PatternRule(name=r'misquoted', pattern=r'"[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3}(?::[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3})?"'), - RegionRule(name=r'string', start='"', grammar=StringGrammar(), end='"'), - RegionRule(name=r'string', start="'", grammar=Grammar(), end="'"), - PatternRule(name=r'operator', pattern=r'(?:>=|<=|>|<|==|&&|\|\||eq|ne)'), + RegionRule(r'comment', r''), + RegionRule(r'opentag', r'<', lex2.get('xml-opentag'), r'/?>'), + PatternRule(r'closetag', r'< */ *[ =>\n]+ *>'), + PatternRule(r'delimiter', r'[\[\]\{\}\(\),\?:]'), + PatternRule(r'derived', r'(?:FM|CD|FS|FM|TA)[0-9]{3}-[0-9]{3}-[0-9]{3}'), + PatternRule(r'question', r'GQ[0-9]{3}-[0-9]{3}-[0-9]{3}:MQ[0-9]{3}-[0-9]{3}-[0-9]{3}'), + PatternRule(r'bdsfunc', r'[A-Z_][A-Z0-9_]+(?= *\()'), + PatternRule(r'perlfunc', r'[a-zA-Z_][a-zA-Z0-9_]+(?= *\()'), + PatternRule(r'misquoted', r"'[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3}(?::[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3})?'"), + PatternRule(r'misquoted', r'"[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3}(?::[A-Z]{2}[0-9]{3}-[0-9]{3}-[0-9]{3})?"'), + RegionRule(r'string', '"', lex2.get('perl-string'), '"'), + RegionRule(r'string', "'", lex2.get('null'), "'"), + PatternRule(r'operator', r'(?:>=|<=|>|<|==|&&|\|\||eq|ne)'), ] +lex2.add('bds', BDSGrammar) class BDS(mode2.Fundamental): - grammar = BDSGrammar + grammar = lex2.get('bds') opentoken = 'delimiter' opentags = {'(': ')', '[': ']', '{': '}'} closetoken = 'delimiter' diff --git a/mode_perl.py b/mode_perl.py index 2296f7b..f7bead5 100644 --- a/mode_perl.py +++ b/mode_perl.py @@ -6,98 +6,97 @@ from method import Argument, Method class PodGrammar(Grammar): rules = [ - PatternRule(name=r'entry', pattern=r'(?<=^=head[1-4]) +.*$'), - PatternRule(name=r'entry', pattern=r'(?<=^=over) +.*$'), - PatternRule(name=r'entry', pattern=r'(?<=^=item) +.*$'), - PatternRule(name=r'entry', pattern=r'(?:(?<=^=begin)|(?<=^=end)) +.*$'), - PatternRule(name=r'entry', pattern=r'(?<=^=encoding) +.*$'), + PatternRule(r'entry', r'(?<=^=head[1-4]) +.*$'), + PatternRule(r'entry', r'(?<=^=over) +.*$'), + PatternRule(r'entry', r'(?<=^=item) +.*$'), + PatternRule(r'entry', r'(?:(?<=^=begin)|(?<=^=end)) +.*$'), + PatternRule(r'entry', r'(?<=^=encoding) +.*$'), ] +lex2.add('perl-pod', PodGrammar) class StringGrammar(Grammar): rules = [ - PatternRule(name=r'octal', pattern=r'\\[0-7]{3}'), - PatternRule(name=r'escaped', pattern=r'\\.'), - PatternRule(name=r'deref', pattern=r"\$+[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*(?:->{\$?(?:[a-zA-Z_][a-zA-Z_0-9]*|'(?:\\.|[^'\\])*'|\"(\\.|[^\\\"])*\")}|->\[\$?[0-9a-zA-Z_]+\])+"), - PatternRule(name=r'length', pattern=r"\$#[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), - ContextPatternRule(name=r'scalar', pattern=r"\$[^A-Za-z0-9 %(delim)s](?![A-Za-z0-9_])", fallback=r"\$[^A-Za-z0-9 ](?![A-Za-z0-9_])"), - PatternRule(name=r'scalar', pattern=r"\$\$*[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), - PatternRule(name=r'cast', pattern=r"[\$\@\%\&]{.*?}"), - PatternRule(name=r'array', pattern=r"@\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'octal', r'\\[0-7]{3}'), + PatternRule(r'escaped', r'\\.'), + PatternRule(r'deref', r"\$+[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*(?:->{\$?(?:[a-zA-Z_][a-zA-Z_0-9]*|'(?:\\.|[^'\\])*'|\"(\\.|[^\\\"])*\")}|->\[\$?[0-9a-zA-Z_]+\])+"), + PatternRule(r'length', r"\$#[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), + ContextPatternRule(r'scalar', r"\$[^A-Za-z0-9 %(delim)s](?![A-Za-z0-9_])", r"\$[^A-Za-z0-9 ](?![A-Za-z0-9_])"), + PatternRule(r'scalar', r"\$\$*[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'cast', r"[\$\@\%\&]{.*?}"), + PatternRule(r'array', r"@\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), ] - -g = Grammar() -pg = PodGrammar() -sg = StringGrammar() +lex2.add('perl-string', StringGrammar) class PerlGrammar(Grammar): rules = [ - RegionRule(name=r'heredoc1', start=r"<<(?P[a-zA-Z0-9_]+) *;", grammar=sg, end=r'^%(heredoc)s$'), - RegionRule(name=r'heredoc1', start=r'<< *"(?P[a-zA-Z0-9_]+)" *;', grammar=sg, end=r'^%(heredoc)s$'), - RegionRule(name=r'heredoc2', start=r"<< *'(?P[a-zA-Z0-9_]+)' *;", grammar=g, end=r'^%(heredoc)s$'), - RegionRule(name=r'eval_heredoc', start=r"<< *`(?P[a-zA-Z0-9_]+)` *;", grammar=sg, end=r'^%(heredoc)s$'), + RegionRule(r'heredoc1', r"<<(?P[a-zA-Z0-9_]+) *;", lex2.get('perl-string'), r'^%(heredoc)s$'), + RegionRule(r'heredoc1', r'<< *"(?P[a-zA-Z0-9_]+)" *;', lex2.get('perl-string'), r'^%(heredoc)s$'), + RegionRule(r'heredoc2', r"<< *'(?P[a-zA-Z0-9_]+)' *;", lex2.get('null'), r'^%(heredoc)s$'), + RegionRule(r'eval_heredoc', r"<< *`(?P[a-zA-Z0-9_]+)` *;", lex2.get('perl-string'), r'^%(heredoc)s$'), - RegionRule(name=r'endblock', start=r"^__END__|__DATA__ *$", grammar=g, end=r''), - RegionRule(name=r'pod', start=r'^=[a-zA-Z0-9_]+', grammar=pg, end=r'^=cut'), + RegionRule(r'endblock', r"^__END__|__DATA__ *$", lex2.get('null'), r''), + RegionRule(r'pod', r'^=[a-zA-Z0-9_]+', lex2.get('perl-pod'), r'^=cut'), - PatternRule(name=r'comment', pattern=r'#.*$'), - RegionRule(name=r'string1', start=r'"', grammar=sg, end=r'"'), - RegionRule(name=r'string2', start=r"'", grammar=g, end=r"'"), - RegionRule(name=r'evalstring', start=r"`", grammar=sg, end=r"`"), - PatternRule(name=r'number', pattern=r'0?\.[0-9]+|[0-9]+(?:\.[0-9]+)?'), - PatternRule(name=r'keyword', pattern=r"(?)(?:STDIN|STDERR|STDOUT|continue|do|else|elsif|eval|foreach|for|if|last|my|next|our|package|require|return|sub|undef|unless|until|use|while)(?![a-zA-Z0-9_])"), - PatternRule(name=r'hash_key', pattern=r'(?<={)[A-Za-z0-9_]+(?=})'), - PatternRule(name=r'hash_key', pattern=r'[A-Za-z0-9_]+(?= *=>)'), - PatternRule(name=r'length', pattern=r"\$#[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), - PatternRule(name=r'cast', pattern=r'[\$\@\%\^\&](?= *{)'), - PatternRule(name=r'scalar', pattern=r"\$[][> *\()"), - PatternRule(name=r'scalar', pattern=r"\$\$*[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), - PatternRule(name=r'array', pattern=r"@\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), - PatternRule(name=r'hash', pattern=r"%\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), - PatternRule(name=r'deref', pattern=r"[@%\$&\*](?={)"), + PatternRule(r'comment', r'#.*$'), + RegionRule(r'string1', r'"', lex2.get('perl-string'), r'"'), + RegionRule(r'string2', r"'", lex2.get('null'), r"'"), + RegionRule(r'evalstring', r"`", lex2.get('perl-string'), r"`"), + PatternRule(r'number', r'0?\.[0-9]+|[0-9]+(?:\.[0-9]+)?'), + PatternRule(r'keyword', r"(?)(?:STDIN|STDERR|STDOUT|continue|do|else|elsif|eval|foreach|for|if|last|my|next|our|package|require|return|sub|undef|unless|until|use|while)(?![a-zA-Z0-9_])"), + PatternRule(r'hash_key', r'(?<={)[A-Za-z0-9_]+(?=})'), + PatternRule(r'hash_key', r'[A-Za-z0-9_]+(?= *=>)'), + PatternRule(r'length', r"\$#[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'cast', r'[\$\@\%\^\&](?= *{)'), + PatternRule(r'scalar', r"\$[][> *\()"), + PatternRule(r'scalar', r"\$\$*[A-Za-z0-9_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'array', r"@\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'hash', r"%\$*[A-Za-z_](?:[A-Za-z0-9_]|::)*"), + PatternRule(r'deref', r"[@%\$&\*](?={)"), # match regexes - RegionRule(name=r'match', start=r'(?:(?<==~)|(?<=!~)|(?<=\()|(?<=split)) *(?P/)', grammar=sg, end=r'/[a-z]*'), - RegionRule(name=r'match', start=r'm *(?P[^ #a-zA-Z0-9_])', grammar=sg, end=r'%(delim)s[a-z]*'), - RegionRule(name=r'match', start=r'm(?P#)', grammar=sg, end=r'#[a-z]*'), + RegionRule(r'match', r'(?:(?<==~)|(?<=!~)|(?<=\()|(?<=split)) *(?P/)', lex2.get('perl-string'), r'/[a-z]*'), + RegionRule(r'match', r'm *(?P[^ #a-zA-Z0-9_])', lex2.get('perl-string'), r'%(delim)s[a-z]*'), + RegionRule(r'match', r'm(?P#)', lex2.get('perl-string'), r'#[a-z]*'), # replace regexes - DualRegionRule(name=r'replace', start=r's *(?P[^ a-zA-Z0-9_])', grammar1=sg, middle=r'%(delim)s', grammar2=sg, end=r'%(delim)s[a-z]*'), - DualRegionRule(name=r'replace', start=r's(?P#)', grammar1=sg, middle=r'#', grammar2=sg, end=r'#[a-z]*'), + DualRegionRule(r'replace', r's *(?P[^ a-zA-Z0-9_])', lex2.get('perl-string'), r'%(delim)s', lex2.get('perl-string'), r'%(delim)s[a-z]*'), + DualRegionRule(r'replace', r's(?P#)', lex2.get('perl-string'), r'#', lex2.get('perl-string'), r'#[a-z]*'), # translate operator - DualRegionRule(name=r'translate', start=r'(?:y|tr) *(?P[^ a-zA-Z0-9_])', grammar1=g, middle=r'%(delim)s', grammar2=g, end=r'%(delim)s[a-z]*'), - DualRegionRule(name=r'translate', start=r'(?:y|tr)#', grammar1=g, middle=r'#', grammar2=g, end=r'#[a-z]*'), + DualRegionRule(r'translate', r'(?:y|tr) *(?P[^ a-zA-Z0-9_])', lex2.get('null'), r'%(delim)s', lex2.get('null'), r'%(delim)s[a-z]*'), + DualRegionRule(r'translate', r'(?:y|tr)#', lex2.get('null'), r'#', lex2.get('null'), r'#[a-z]*'), # some more basic stuff - PatternRule(name=r'package', pattern=r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'sub', pattern=r"(?<=sub )[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'use', pattern=r"(?<=use )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'require', pattern=r"(?<=require )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'label', pattern=r'[a-zA-Z_][a-zA-Z0-9_]*:(?!:)'), - PatternRule(name=r'method', pattern=r"(?<=->)[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'function', pattern=r"&\$*(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), - PatternRule(name=r'builtin', pattern=r"(?)&?(?:write|warn|wantarray|waitpid|wait|vec|values|utime|use|untie|unshift|unpack|unlink|undef|umask|ucfirst|uc|truncate|times|time|tied|tie|telldir|tell|syswrite|system|sysseek|sysread|sysopen|syscall|symlink|substr|sub|study|stat|srand|sqrt|sprintf|split|splice|sort|socketpair|socket|sleep|sin|shutdown|shmwrite|shmread|shmget|shmctl|shift|setsockopt|setservent|setpwent|setprotoent|setpriority|setpgrp|setnetent|sethostent|setgrent|send|semop|semget|semctl|select|seekdir|seek|scalar|rmdir|rindex|rewinddir|reverse|return|reset|require|rename|ref|redo|recv|readpipe|readlink|readline|readdir|read|rand|quotemeta|push|prototype|printf|print|pos|pop|pipe|package|pack|our|ord|opendir|open|oct|no|next|my|msgsnd|msgrcv|msgget|msgctl|mkdir|map|lstat|log|lock|localtime|local|listen|link|length|lcfirst|lc|last|kill|keys|join|ioctl|int|index|import|hex|grep|goto|gmtime|glob|getsockopt|getsockname|getservent|getservbyport|getservbyname|getpwuid|getpwnam|getpwent|getprotoent|getprotobynumber|getprotobyname|getpriority|getppid|getpgrp|getpeername|getnetent|getnetbyname|getnetbyaddr|getlogin|gethostent|gethostbyname|gethostbyaddr|getgrnam|getgrgid|getgrent|getc|formline|format|fork|flock|fileno|fcntl|exp|exit|exists|exec|eval|eof|endservent|endpwent|endprotoent|endnetent|endhostent|endgrent|each|dump|do|die|delete|defined|dbmopen|dbmclose|crypt|cos|continue|connect|closedir|close|chroot|chr|chown|chop|chomp|chmod|chdir|caller|bless|binmode|bind|atan2|alarm|accept|abs)(?![a-zA-Z0-9_])"), + PatternRule(r'package', r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'sub', r"(?<=sub )[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'use', r"(?<=use )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'require', r"(?<=require )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'label', r'[a-zA-Z_][a-zA-Z0-9_]*:(?!:)'), + PatternRule(r'method', r"(?<=->)[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'function', r"&\$*(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), + PatternRule(r'builtin', r"(?)&?(?:write|warn|wantarray|waitpid|wait|vec|values|utime|use|untie|unshift|unpack|unlink|undef|umask|ucfirst|uc|truncate|times|time|tied|tie|telldir|tell|syswrite|system|sysseek|sysread|sysopen|syscall|symlink|substr|sub|study|stat|srand|sqrt|sprintf|split|splice|sort|socketpair|socket|sleep|sin|shutdown|shmwrite|shmread|shmget|shmctl|shift|setsockopt|setservent|setpwent|setprotoent|setpriority|setpgrp|setnetent|sethostent|setgrent|send|semop|semget|semctl|select|seekdir|seek|scalar|rmdir|rindex|rewinddir|reverse|return|reset|require|rename|ref|redo|recv|readpipe|readlink|readline|readdir|read|rand|quotemeta|push|prototype|printf|print|pos|pop|pipe|package|pack|our|ord|opendir|open|oct|no|next|my|msgsnd|msgrcv|msgget|msgctl|mkdir|map|lstat|log|lock|localtime|local|listen|link|length|lcfirst|lc|last|kill|keys|join|ioctl|int|index|import|hex|grep|goto|gmtime|glob|getsockopt|getsockname|getservent|getservbyport|getservbyname|getpwuid|getpwnam|getpwent|getprotoent|getprotobynumber|getprotobyname|getpriority|getppid|getpgrp|getpeername|getnetent|getnetbyname|getnetbyaddr|getlogin|gethostent|gethostbyname|gethostbyaddr|getgrnam|getgrgid|getgrent|getc|formline|format|fork|flock|fileno|fcntl|exp|exit|exists|exec|eval|eof|endservent|endpwent|endprotoent|endnetent|endhostent|endgrent|each|dump|do|die|delete|defined|dbmopen|dbmclose|crypt|cos|continue|connect|closedir|close|chroot|chr|chown|chop|chomp|chmod|chdir|caller|bless|binmode|bind|atan2|alarm|accept|abs)(?![a-zA-Z0-9_])"), # quote operator - RegionRule(name=r'quoted', start=r'q[rqwx]? *\(', grammar=g, end=r'\)'), - RegionRule(name=r'quoted', start=r'q[rqwx]? *{', grammar=g, end=r'}'), - RegionRule(name=r'quoted', start=r'q[rqwx]? *<', grammar=g, end=r'>'), - RegionRule(name=r'quoted', start=r'q[rqwx]? *\[', grammar=g, end=r'\]'), - RegionRule(name=r'quoted', start=r'q[rqwx]? *(?P[^ #])', grammar=g, end=r'%(delim)s'), - RegionRule(name=r'quoted', start=r'q[rqwx]?#', grammar=g, end=r'#'), + RegionRule(r'quoted', r'q[rqwx]? *\(', lex2.get('null'), r'\)'), + RegionRule(r'quoted', r'q[rqwx]? *{', lex2.get('null'), r'}'), + RegionRule(r'quoted', r'q[rqwx]? *<', lex2.get('null'), r'>'), + RegionRule(r'quoted', r'q[rqwx]? *\[', lex2.get('null'), r'\]'), + RegionRule(r'quoted', r'q[rqwx]? *(?P[^ #])', lex2.get('null'), r'%(delim)s'), + RegionRule(r'quoted', r'q[rqwx]?#', lex2.get('null'), r'#'), - PatternRule(name=r'function', pattern=r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*(?= *\()"), - PatternRule(name=r'class', pattern=r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*(?=->)"), + PatternRule(r'function', r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*(?= *\()"), + PatternRule(r'class', r"(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*(?=->)"), # some basic stuff - PatternRule(name=r'delimiter', pattern=r"[,;=\?(){}\[\]]|->|=>|(?>=|<<=|\*\*="), - PatternRule(name=r'operator', pattern=r"\+\+|\+|<=>|<>|<<|<=|<|-|>>|>=|>|\*\*|\*|&&|&|\|\||\||/|\^|==|//|~|=~|!~|!=|%|!|\.|x(?![a-zA-Z_])"), - PatternRule(name=r'operator2', pattern=r"(?:xor|or|not|ne|lt|le|gt|ge|eq|cmp|and)(?![a-zA-Z_])"), - PatternRule(name=r'bareword', pattern=r'(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*') + PatternRule(r'delimiter', r"[,;=\?(){}\[\]]|->|=>|(?>=|<<=|\*\*="), + PatternRule(r'operator', r"\+\+|\+|<=>|<>|<<|<=|<|-|>>|>=|>|\*\*|\*|&&|&|\|\||\||/|\^|==|//|~|=~|!~|!=|%|!|\.|x(?![a-zA-Z_])"), + PatternRule(r'operator2', r"(?:xor|or|not|ne|lt|le|gt|ge|eq|cmp|and)(?![a-zA-Z_])"), + PatternRule(r'bareword', r'(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*') ] +lex2.add('perl', PerlGrammar) class PerlTabber(tab2.StackTabber): def is_base(self, y): @@ -166,7 +165,7 @@ class PerlTabber(tab2.StackTabber): class Perl(mode2.Fundamental): tabbercls = PerlTabber - grammar = PerlGrammar() + grammar = lex2.get('perl') opentoken = 'delimiter' opentags = {'(': ')', '[': ']', '{': '}'} closetoken = 'delimiter' diff --git a/mode_python.py b/mode_python.py index aa86543..48ec51c 100644 --- a/mode_python.py +++ b/mode_python.py @@ -6,35 +6,37 @@ from lex2 import Grammar, PatternRule, RegionRule class StringGrammar(Grammar): rules = [ - PatternRule(name=r'octal', pattern=r'\\[0-7]{3}'), - PatternRule(name=r'escaped', pattern=r'\\.'), + PatternRule(r'octal', r'\\[0-7]{3}'), + PatternRule(r'escaped', r'\\.'), ] +lex2.grammars['string-py'] = StringGrammar class PythonGrammar(Grammar): rules = [ - PatternRule(name=r'functionname', pattern=r'(?<=def )[a-zA-Z_][a-zA-Z0-9_]*'), - PatternRule(name=r'classname', pattern=r'(?<=class )[a-zA-Z_][a-zA-Z0-9_]*'), - PatternRule(name=r'reserved', pattern=r'(?:True|None|False|Exception|self)(?![a-zA-Z0-9_])'), - PatternRule(name=r'keyword', pattern=r'(?:yield|while|try|return|raise|print|pass|or|not|lambda|is|in|import|if|global|from|for|finally|exec|except|else|elif|del|def|continue|class|break|assert|as|and)(?![a-zA-Z0-9_])'), - PatternRule(name=r"builtin", pattern=r'(?>=|<<=|\*\*='), - PatternRule(name=r"operator", pattern=r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"), - PatternRule(name=r"integer", pattern=r"(?>=|<<=|\*\*='), + PatternRule(r"operator", r"\+|<>|<<|<=|<|-|>>|>=|>|\*\*|&|\*|\||/|\^|==|//|~|!=|%"), + PatternRule(r"integer", r"(? 0 and line[start - 1] in word_chars: - start -= 1 - if start == end: - w.application.set_error('walrus 3') - return - word = line[start:end] - - candidates = [] - seen = sets.Set() - for p in w.mode.ctagger.packages.iterkeys(): - if p.startswith(word): - if p in seen: - continue - candidates.append(p) - seen.add(p) - for e in w.mode.ctagger.entries.itervalues(): - if e.symbol.startswith(word): - if e.symbol in seen: - continue - candidates.append(e.symbol) - seen.add(e.symbol) - if len(candidates) == 0: - w.application.set_error('No match: %r' % word) - return - elif len(candidates) == 1: - newword = candidates[0] - if word == newword: - w.application.set_error('Already completed!') - return - else: - w.application.set_error('Unique match!') - else: - newword = completer.find_common_string(candidates) - w.application.set_error('Ambiguous match: %r' % (candidates)) - b.delete_string(Point(start, cursor.y), Point(end, cursor.y)) - b.insert_string(Point(start, cursor.y), newword) +#class PythonUpdateTags(method.Method): +# '''Update the CTag data associated with a python buffer''' +# args = [method.Argument("lib", prompt="Module Base: ", datatype='path', +# default=default.build_constant("."))] +# def _execute(self, w, **vargs): +# w.mode.ctagger = ctag_python.PythonCTagger() +# w.mode.ctagger.process_paths([vargs['lib']]) +# w.application.set_error('Tag data updated') +# +#class PythonTagComplete(method.Method): +# '''Complete a symbol using tag data''' +# def _execute(self, w, **vargs): +# if not w.mode.ctagger.packages: +# w.application.methods['python-update-tags'].execute(w) +# return +# +# cursor = w.logical_cursor() +# b = w.buffer +# line = b.lines[cursor.y] +# end = cursor.x +# start = cursor.x +# +# word_chars = string.letters + string.digits + '_' +# if start == 0: +# w.application.set_error('walrus 1') +# return +# +# c = line[start - 1] +# if c == '(': +# w.application.set_error('goldfinch 1') +# return +# elif c not in word_chars: +# w.application.set_error('walrus 2') +# return +# +# while start > 0 and line[start - 1] in word_chars: +# start -= 1 +# if start == end: +# w.application.set_error('walrus 3') +# return +# word = line[start:end] +# +# candidates = [] +# seen = sets.Set() +# for p in w.mode.ctagger.packages.iterkeys(): +# if p.startswith(word): +# if p in seen: +# continue +# candidates.append(p) +# seen.add(p) +# for e in w.mode.ctagger.entries.itervalues(): +# if e.symbol.startswith(word): +# if e.symbol in seen: +# continue +# candidates.append(e.symbol) +# seen.add(e.symbol) +# if len(candidates) == 0: +# w.application.set_error('No match: %r' % word) +# return +# elif len(candidates) == 1: +# newword = candidates[0] +# if word == newword: +# w.application.set_error('Already completed!') +# return +# else: +# w.application.set_error('Unique match!') +# else: +# newword = completer.find_common_string(candidates) +# w.application.set_error('Ambiguous match: %r' % (candidates)) +# b.delete_string(Point(start, cursor.y), Point(end, cursor.y)) +# b.insert_string(Point(start, cursor.y), newword) class PythonDictCleanup(method.Method): '''Align assignment blocks and literal dictionaries''' diff --git a/mode_xml.py b/mode_xml.py index 60072e7..ffd25b6 100644 --- a/mode_xml.py +++ b/mode_xml.py @@ -1,28 +1,29 @@ -import color, mode2 +import color, lex2, mode2 from lex2 import Grammar, PatternRule, RegionRule class OpenTagGrammar(Grammar): rules = [ - RegionRule(name=r'string', start=r'(?P["\'])', grammar=Grammar(), end=r'%(tag)s'), - PatternRule(name=r'namespace', pattern=r'[a-zA-Z_]+:'), - PatternRule(name=r'attrname', pattern=r'[^ =>\n]+(?==)'), - PatternRule(name=r'name', pattern=r'[^ =>\n]+'), + RegionRule(r'string', r'"', lex2.grammars['null'], r'"'), + RegionRule(r'string', r"'", lex2.grammars['null'], r"'"), + PatternRule(r'namespace', r'[a-zA-Z_]+:'), + PatternRule(r'attrname', r'[^ =>\n]+(?==)'), + PatternRule(r'name', r'[^ =>\n]+'), ] +lex2.grammars['xml-opentag'] = OpenTagGrammar + class XMLGrammar(Grammar): rules = [ - RegionRule(name=r'comment', start=r''), - RegionRule(name=r'opentag', start=r'<', grammar=OpenTagGrammar(), end=r'/?>'), - PatternRule(name=r'closetag', pattern=r'< */ *[ =>\n]+ *>'), + RegionRule(r'comment', r''), + RegionRule(r'opentag', r'<', lex2.grammars['xml-opentag'], r'/?>'), + PatternRule(r'closetag', r'< */ *[ =>\n]+ *>'), ] +lex2.grammars['xml'] = XMLGrammar class XML(mode2.Fundamental): - grammar = XMLGrammar + grammar = lex2.grammars['xml'] def __init__(self, w): mode2.Fundamental.__init__(self, w) - #self.add_bindings('close-paren', (')',)) - #self.add_bindings('close-brace', ('}',)) - #self.add_bindings('close-bracket', (']',)) self.colors = { 'comment.start': color.build('red', 'default'), 'comment.null': color.build('red', 'default'), diff --git a/search.py b/search.py index 5da9ae2..8cd9ba5 100644 --- a/search.py +++ b/search.py @@ -16,8 +16,14 @@ def find_ranges(s, w, start=None, end=None): (x2, y2) = (len(w.buffer.lines[-1]) - 1, len(w.buffer.lines) - 1) else: (x2, y2) = end.xy() + #if x2 == 0: + # y2 -= 1 + # x2 = len(w.buffer.lines[-1]) - 1 + #else: + # x2 -= 1 ranges = [] + #while y <= y2: while y <= y2: if y == y2: limit = x2