more bug fixes

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-10-03 03:57:32 +00:00
parent db2675aac5
commit 5e8ad6f831
3 changed files with 127 additions and 87 deletions

View File

@ -3,6 +3,7 @@ import buffer, color, commands, completer, context, default, method, mode, regex
from point import Point from point import Point
from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule from lex import Grammar, PatternRule, ContextPatternRule, RegionRule, OverridePatternRule, PatternGroupRule
from method import Argument, Method, WrapParagraph from method import Argument, Method, WrapParagraph
from tab import StackTabber, StackTabber2
class PodGrammar(Grammar): class PodGrammar(Grammar):
rules = [ rules = [
@ -37,8 +38,28 @@ class StrictStringGrammar(Grammar):
class StringGrammar(Grammar): class StringGrammar(Grammar):
rules = _make_string_rules('"') rules = _make_string_rules('"')
class MatchGrammar(Grammar): class EvalGrammar(Grammar):
rules = _make_string_rules('`')
class TranslateGrammar1(Grammar):
rules = [PatternRule(r'data', r"(?:\\.|[^\\/])")]
class TranslateGrammar2(Grammar):
rules = [PatternRule(r'data', r"(?:\\.|[^\\#])")]
class TranslateGrammarX(Grammar):
rules = [PatternRule(r'data', r"(?:\\.|[^\\%(delim)s])")]
class MatchGrammar1(Grammar):
rules = _make_string_rules('/') rules = _make_string_rules('/')
class MatchGrammar2(Grammar):
rules = _make_string_rules('#')
class MatchGrammar3(Grammar):
rules = _make_string_rules(')')
class MatchGrammar4(Grammar):
rules = _make_string_rules(']')
class MatchGrammar5(Grammar):
rules = _make_string_rules('}')
class MatchGrammar6(Grammar):
rules = _make_string_rules('>')
class QuotedGrammar1(Grammar): class QuotedGrammar1(Grammar):
rules = _make_string_rules(')') rules = _make_string_rules(')')
@ -67,7 +88,7 @@ class PerlGrammar(Grammar):
PatternRule(r'comment', r'#.*$'), PatternRule(r'comment', r'#.*$'),
RegionRule(r'perl_string', r'"', StringGrammar, r'"'), RegionRule(r'perl_string', r'"', StringGrammar, r'"'),
RegionRule(r'perl_string', r"'", StrictStringGrammar, r"'"), RegionRule(r'perl_string', r"'", StrictStringGrammar, r"'"),
RegionRule(r'evalstring', r"`", StringGrammar, r"`"), RegionRule(r'evalstring', r"`", EvalGrammar, r"`"),
PatternRule(r'number', r'0?\.[0-9]+|[0-9]+(?:\.[0-9]+)?'), PatternRule(r'number', r'0?\.[0-9]+|[0-9]+(?:\.[0-9]+)?'),
PatternRule(r'perl_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'perl_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_]+(?=})'),
@ -84,30 +105,32 @@ class PerlGrammar(Grammar):
PatternRule(r'deref', r"[@%\$&\*](?={)"), PatternRule(r'deref', r"[@%\$&\*](?={)"),
# match regexes; paired delimiters # match regexes; paired delimiters
RegionRule(r'match', r'm *(?P<delim>\()', StringGrammar, r'\)[a-z]*'), RegionRule(r'match', r'm *(?P<delim>\()', MatchGrammar3, r'\)[a-z]*'),
RegionRule(r'match', r'm *(?P<delim>\[)', StringGrammar, r'\][a-z]*'), RegionRule(r'match', r'm *(?P<delim>\[)', MatchGrammar4, r'\][a-z]*'),
RegionRule(r'match', r'm *(?P<delim>\{)', StringGrammar, r'\}[a-z]*'), RegionRule(r'match', r'm *(?P<delim>\{)', MatchGrammar5, r'\}[a-z]*'),
RegionRule(r'match', r'm *(?P<delim>\<)', StringGrammar, r'\>[a-z]*'), RegionRule(r'match', r'm *(?P<delim>\<)', MatchGrammar6, r'\>[a-z]*'),
# match regexes # match regexes
RegionRule(r'match', r'(?:(?<==~)|(?<=!~)|(?<=\()|(?<=split)|(?<=if)|(?<=unless)|(?<=while)|(?<=until)) *(?P<delim>/)', StringGrammar, r'/[a-z]*'), RegionRule(r'match', r'(?:(?<==~)|(?<=!~)|(?<=\()|(?<=split)|(?<=if)|(?<=unless)|(?<=while)|(?<=until)) *(?P<delim>/)', MatchGrammar1, r'/[a-z]*'),
RegionRule(r'match', r'm *(?P<delim>/)', MatchGrammar, r'/[a-z]*'), RegionRule(r'match', r'm *(?P<delim>/)', MatchGrammar1, r'/[a-z]*'),
RegionRule(r'match', r'm *(?P<delim>[^ #a-zA-Z0-9_])', StringGrammar, r'%(delim)s[a-z]*'), RegionRule(r'match', r'm *(?P<delim>[^ #a-zA-Z0-9_])', StringGrammar, r'%(delim)s[a-z]*'),
RegionRule(r'match', r'm(?P<delim>#)', StringGrammar, r'#[a-z]*'), RegionRule(r'match', r'm(?P<delim>#)', MatchGrammar2, r'#[a-z]*'),
# match regexes; paired delimiters # match regexes; paired delimiters
RegionRule(r'replace', r's *(?P<delim>\()', StringGrammar, r'\) *\(', StringGrammar, r'\)[a-z]*'), RegionRule(r'replace', r's *(?P<delim>\()', MatchGrammar3, r'\) *\(', MatchGrammar3, r'\)[a-z]*'),
RegionRule(r'replace', r's *(?P<delim>\[)', StringGrammar, r'\] *\[', StringGrammar, r'\][a-z]*'), RegionRule(r'replace', r's *(?P<delim>\[)', MatchGrammar4, r'\] *\[', MatchGrammar4, r'\][a-z]*'),
RegionRule(r'replace', r's *(?P<delim>\{)', StringGrammar, r'\} *\{', StringGrammar, r'\}[a-z]*'), RegionRule(r'replace', r's *(?P<delim>\{)', MatchGrammar5, r'\} *\{', MatchGrammar5, r'\}[a-z]*'),
RegionRule(r'replace', r's *(?P<delim>\<)', StringGrammar, r'\> *\<', StringGrammar, r'\>[a-z]*'), RegionRule(r'replace', r's *(?P<delim>\<)', MatchGrammar6, r'\> *\<', MatchGrammar6, r'\>[a-z]*'),
# replace regexes # replace regexes
RegionRule(r'replace', r's *(?P<delim>/)', MatchGrammar1, r'/', MatchGrammar1, r'/[a-z]*'),
RegionRule(r'replace', r's *(?P<delim>[^ a-zA-Z0-9_])', StringGrammar, r'%(delim)s', StringGrammar, r'%(delim)s[a-z]*'), RegionRule(r'replace', r's *(?P<delim>[^ a-zA-Z0-9_])', StringGrammar, r'%(delim)s', StringGrammar, r'%(delim)s[a-z]*'),
RegionRule(r'replace', r's(?P<delim>#)', StringGrammar, r'#', StringGrammar, r'#[a-z]*'), RegionRule(r'replace', r's(?P<delim>#)', MatchGrammar2, r'#', MatchGrammar2, r'#[a-z]*'),
# translate operator # translate operator
RegionRule(r'translate', r'(?:y|tr) *(?P<delim>[^ a-zA-Z0-9_])', Grammar, r'%(delim)s', Grammar, r'%(delim)s[a-z]*'), RegionRule(r'translate', r'(?:y|tr) *(?P<delim>/)', TranslateGrammar1, r'/', TranslateGrammar1, r'/[a-z]*'),
RegionRule(r'translate', r'(?:y|tr)#', Grammar, r'#', Grammar, r'#[a-z]*'), RegionRule(r'translate', r'(?:y|tr)#', TranslateGrammar2, r'#', TranslateGrammar2, r'#[a-z]*'),
RegionRule(r'translate', r'(?:y|tr) *(?P<delim>[^ a-zA-Z0-9_])', TranslateGrammarX, r'%(delim)s', TranslateGrammarX, r'%(delim)s[a-z]*'),
# some more basic stuff # some more basic stuff
PatternRule(r'package', r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"), PatternRule(r'package', r"(?<=package )(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*"),
@ -151,73 +174,84 @@ class PerlGrammar(Grammar):
PatternRule(r"eol", r"\n$"), PatternRule(r"eol", r"\n$"),
] ]
class PerlTabber(tab.StackTabber): class PerlTabber2(StackTabber2):
def is_base(self, y): open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}}
if y == 0: close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}}
return True end_at_eof = False
highlighter = self.mode.window.buffer.highlights[self.mode.name()] end_at_tokens = {'delimiter': {';': 1}}
if not highlighter.tokens[y]: nocontinue_tokens = {'delimiter': {';': 1}}
return False start_free_tokens = {'string.start': 1, 'pod.start': 1, 'heredoc.start': 1,
t = highlighter.tokens[y][0] 'evaldoc.start': 1}
return t.name == 'perl_keyword' and t.string == 'sub' end_free_tokens = {'string.end': 1, 'pod.end': 1, 'heredoc.end': 1,
def _handle_open_token(self, currlvl, y, i): 'evaldoc.start': 1}
currlvl = tab.StackTabber._handle_open_token(self, currlvl, y, i)
return currlvl #class PerlTabber(StackTabber):
def _handle_close_token(self, currlvl, y, i): # def is_base(self, y):
w = self.mode.tabwidth # if y == 0:
self._opt_pop('cont') # return True
currlvl = tab.StackTabber._handle_close_token(self, currlvl, y, i) # highlighter = self.mode.window.buffer.highlights[self.mode.name()]
token = self.get_token(y, i) # if not highlighter.tokens[y]:
if self.is_rightmost_token(y, i): # return False
if token.string == '}': # t = highlighter.tokens[y][0]
self._opt_pop('cont') # return t.name == 'perl_keyword' and t.string == 'sub'
else: # def _handle_open_token(self, currlvl, y, i):
self._opt_append('cont', currlvl + w) # currlvl = StackTabber._handle_open_token(self, currlvl, y, i)
return currlvl # return currlvl
def _handle_other_token(self, currlvl, y, i): # def _handle_close_token(self, currlvl, y, i):
w = self.mode.tabwidth # w = self.mode.tabwidth
token = self.get_token(y, i) # self._opt_pop('cont')
fqname = token.fqname() # currlvl = StackTabber._handle_close_token(self, currlvl, y, i)
if fqname == 'delimiter' and token.string == ';': # token = self.get_token(y, i)
self._opt_pop('cont') # if self.is_rightmost_token(y, i):
elif fqname == 'heredoc.start': # if token.string == '}':
self._opt_append('heredoc', None) # self._opt_pop('cont')
elif fqname == 'heredoc.end': # else:
self._opt_pop('heredoc') # self._opt_append('cont', currlvl + w)
self._opt_pop('cont') # return currlvl
elif fqname == 'quoted.start': # def _handle_other_token(self, currlvl, y, i):
self._opt_append('quoted', currlvl + w) # w = self.mode.tabwidth
elif fqname == 'quoted.end': # token = self.get_token(y, i)
self._opt_pop('cont') # fqname = token.fqname()
self._opt_pop('quoted') # if fqname == 'delimiter' and token.string == ';':
elif fqname == 'evaldoc.start': # self._opt_pop('cont')
self._opt_append('evaldoc', None) # elif fqname == 'heredoc.start':
elif fqname == 'evaldoc.end': # self._opt_append('heredoc', None)
self._opt_pop('evaldoc') # elif fqname == 'heredoc.end':
self._opt_pop('cont') # self._opt_pop('heredoc')
elif fqname == 'pod.start': # self._opt_pop('cont')
self._opt_append('pod', None) # elif fqname == 'quoted.start':
elif fqname == 'pod.end': # self._opt_append('quoted', currlvl + w)
self._opt_pop('pod') # elif fqname == 'quoted.end':
currlvl = 0 # self._opt_pop('cont')
elif fqname == 'perl_string.start': # self._opt_pop('quoted')
self._opt_append('string', None) # elif fqname == 'evaldoc.start':
elif fqname == 'perl_string.end': # self._opt_append('evaldoc', None)
self._opt_pop('string') # elif fqname == 'evaldoc.end':
if self.is_rightmost_token(y, i): # self._opt_pop('evaldoc')
self._opt_append('cont', currlvl + w) # self._opt_pop('cont')
if self.is_rightmost_token(y, i): # elif fqname == 'pod.start':
if(not fqname.startswith('pod') and # self._opt_append('pod', None)
not fqname.startswith('heredoc') and # elif fqname == 'pod.end':
not fqname.startswith('perl_string') and # self._opt_pop('pod')
not fqname.startswith('endblock') and # currlvl = 0
fqname != 'eol' and # elif fqname == 'perl_string.start':
fqname != 'comment' and # self._opt_append('string', None)
fqname != 'spaces' and # elif fqname == 'perl_string.end':
fqname != 'null' and # self._opt_pop('string')
token.string not in ('}', ';', '(', '{', '[', ',')): # if self.is_rightmost_token(y, i):
self._opt_append('cont', currlvl + w) # self._opt_append('cont', currlvl + w)
return currlvl # if self.is_rightmost_token(y, i):
# if(not fqname.startswith('pod') and
# not fqname.startswith('heredoc') and
# not fqname.startswith('perl_string') and
# not fqname.startswith('endblock') and
# fqname != 'eol' and
# fqname != 'comment' and
# fqname != 'spaces' and
# fqname != 'null' and
# token.string not in ('}', ';', '(', '{', '[', ',')):
# self._opt_append('cont', currlvl + w)
# return currlvl
class PerlSetLib(Method): class PerlSetLib(Method):
'''Set the path(s) to find perl modules''' '''Set the path(s) to find perl modules'''
@ -640,7 +674,8 @@ class Perl(mode.Fundamental):
modename = 'Perl' modename = 'Perl'
extensions = ['.pl', '.pm'] extensions = ['.pl', '.pm']
detection = ['perl'] detection = ['perl']
tabbercls = PerlTabber #tabbercls = PerlTabber
tabbercls = PerlTabber2
grammar = PerlGrammar grammar = PerlGrammar
opentokens = ('delimiter',) opentokens = ('delimiter',)
opentags = {'(': ')', '[': ']', '{': '}'} opentags = {'(': ')', '[': ']', '{': '}'}

View File

@ -1,6 +1,6 @@
import commands import commands
import color, mode, tab import color, mode, tab
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule from lex import Grammar, PatternRule, RegionRule, PatternGroupRule, OverridePatternRule
from method import Method from method import Method
class StringGrammar1(Grammar): class StringGrammar1(Grammar):
@ -88,6 +88,10 @@ class TestGrammar(Grammar):
class ShGrammar(Grammar): class ShGrammar(Grammar):
rules = [ rules = [
PatternGroupRule(r'vardecl', r'spaces', r'^ +', r'variable', r'[a-zA-Z_][a-zA-Z0-9_]*', r'delimiter', r'='),
PatternGroupRule(r'vardecl', r'sh_builtin', r'export', r'spaces', r' +', r'variable', r'[a-zA-Z_][a-zA-Z0-9_]*', r'delimiter', r'='),
PatternRule(r'variable', r"^[a-zA-Z_][a-zA-Z0-9_]*(?==)"),
PatternRule(r'spaces', r' +'), PatternRule(r'spaces', r' +'),
RegionRule(r'heredoc', r"<<[<\\]?(?P<heredoc>[a-zA-Z_][a-zA-Z0-9_]*)", None, "\n", HereGrammar, r'^%(heredoc)s$'), RegionRule(r'heredoc', r"<<[<\\]?(?P<heredoc>[a-zA-Z_][a-zA-Z0-9_]*)", None, "\n", HereGrammar, r'^%(heredoc)s$'),
RegionRule(r'heredoc', r"<<-(?P<heredoc>[a-zA-Z_][a-zA-Z0-9_]*)", None, "\n", HereGrammar, r'^ *%(heredoc)s$'), RegionRule(r'heredoc', r"<<-(?P<heredoc>[a-zA-Z_][a-zA-Z0-9_]*)", None, "\n", HereGrammar, r'^ *%(heredoc)s$'),
@ -195,10 +199,12 @@ class Sh(mode.Fundamental):
'eval.start': ('cyan', 'default', 'bold'), 'eval.start': ('cyan', 'default', 'bold'),
'eval.variable': ('yellow', 'default', 'bold'), 'eval.variable': ('yellow', 'default', 'bold'),
'eval.data': ('cyan', 'default', 'bold'),
'eval.null': ('cyan', 'default', 'bold'), 'eval.null': ('cyan', 'default', 'bold'),
'eval.end': ('cyan', 'default', 'bold'), 'eval.end': ('cyan', 'default', 'bold'),
'neval.start': ('yellow', 'default', 'bold'), 'neval.start': ('yellow', 'default', 'bold'),
'neval.variable': ('yellow', 'default', 'bold'), 'neval.variable': ('yellow', 'default', 'bold'),
'neval.data': ('cyan', 'default', 'bold'),
'neval.null': ('cyan', 'default', 'bold'), 'neval.null': ('cyan', 'default', 'bold'),
'neval.end': ('yellow', 'default', 'bold'), 'neval.end': ('yellow', 'default', 'bold'),
} }

3
tab.py
View File

@ -231,7 +231,6 @@ class Marker2(object):
def __repr__(self): def __repr__(self):
return '<Marker2(%r, %r, %r)>' % (self.name, self.type_, self.level) return '<Marker2(%r, %r, %r)>' % (self.name, self.type_, self.level)
#class StackTabber2(tab.StackTabber):
class StackTabber2(Tabber): class StackTabber2(Tabber):
open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}} open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}}
close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}} close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}}
@ -404,7 +403,7 @@ class StackTabber2(Tabber):
# add implicit continuation # add implicit continuation
top = self._peek() top = self._peek()
if top and top.name in self.scope_tokens.get(top.type_, {}): if i + start == end and top and top.name in self.scope_tokens.get(top.type_, {}):
if self.continue_tokens: if self.continue_tokens:
if s in self.continue_tokens.get(name, {}): if s in self.continue_tokens.get(name, {}):
self._append_unless('continue', name, self._get_next_level()) self._append_unless('continue', name, self._get_next_level())