fix some bugs and make scala mode better

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2010-09-23 23:35:19 -04:00
parent 77d6d64602
commit 8f82922870
3 changed files with 87 additions and 34 deletions

View File

@ -661,11 +661,13 @@ class Application(object):
# create directories under the application path # create directories under the application path
def mkdirs(self, *parts): def mkdirs(self, *parts):
path = self.getpath() path = os.path.join(self.getpath(), *parts)
for part in parts: if not os.path.exists(path):
path = os.path.join(path, part) os.makedirs(path)
if not os.path.exists(path): #for part in parts:
os.mkdir(path) # path = os.path.join(path, part)
# if not os.path.exists(path):
# os.mkdir(path)
# load user configuration NOW # load user configuration NOW
def loadrc(self): def loadrc(self):

View File

@ -7,6 +7,7 @@ from method.shell import Interact
from method import Method, arg from method import Method, arg
import default import default
import urllib2 import urllib2
import os
chr1 = '[a-zA-Z_]' chr1 = '[a-zA-Z_]'
chr2 = '[a-zA-Z_0-9]' chr2 = '[a-zA-Z_0-9]'
@ -29,6 +30,11 @@ class ScalaGrammar(Grammar):
PatternRule('scala.comment', '//.*$'), PatternRule('scala.comment', '//.*$'),
RegionRule('scala.comment', r'/\*', NestedCommentGrammar, r'\*/'), RegionRule('scala.comment', r'/\*', NestedCommentGrammar, r'\*/'),
PatternMatchRule('x', r'(?<=[a-zA-Z0-9_ ])(:)([a-zA-Z0-9_]+)',
'delimiter', 'scala.type'),
PatternMatchRule('x', r'(?<=[a-zA-Z0-9_ ])(:)( +)([a-zA-Z0-9_]+)',
'delimiter', 'spaces', 'scala.type'),
PatternRule('delimiter', r'(?:;|{|}|\[|\]|\(|\)|,|\.|<(?![a-zA-Z_])|>|:|/|\+|-|\*|=)'), PatternRule('delimiter', r'(?:;|{|}|\[|\]|\(|\)|,|\.|<(?![a-zA-Z_])|>|:|/|\+|-|\*|=)'),
RegionRule('scala.inline', r'(?:^| )(?=<[a-zA-Z_])', XMLGrammar, '^[ \t]*$'), RegionRule('scala.inline', r'(?:^| )(?=<[a-zA-Z_])', XMLGrammar, '^[ \t]*$'),
@ -36,10 +42,14 @@ class ScalaGrammar(Grammar):
PatternRule('eol', r'\n'), PatternRule('eol', r'\n'),
PatternRule('scala.def', '(?<=(?<![a-zA-Z0-9_])def )[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('scala.def', '(?<=(?<![a-zA-Z0-9_])def )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.class', '(?<=(?<![a-zA-Z0-9_])class )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.class', '(?<=(?<![a-zA-Z0-9_])object )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.reserved', '(?:yield|with|while|var|val|type|true|try|trait|throw|this|super|sealed|return|protected|private|package|override|object|null|new|match|lazy|import|implicit|if|forSome|for|finally|final|false|extends|else|do|def|class|catch|case|abstract)(?!%s)' % word), PatternRule('scala.class', '(?<=(?<![a-zA-Z0-9_])class )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.object', '(?<=(?<![a-zA-Z0-9_])object )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.trait', '(?<=(?<![a-zA-Z0-9_])trait )[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.pseudo', '(?:true|null|false)'),
PatternRule('scala.reserved', '(?:yield|with|while|var|val|until|type|true|try|trait|throw|this|super|sealed|return|protected|private|package|override|object|null|new|match|lazy|import|implicit|if|forSome|for|finally|final|false|extends|else|do|def|class|catch|case|abstract)(?!%s)' % word),
PatternRule('scala.integer', '-?(?:0|[1-9])[0-9]*[Ll]?'), PatternRule('scala.integer', '-?(?:0|[1-9])[0-9]*[Ll]?'),
PatternRule('scala.integer', '-?0x[0-9A-Fa-f]+[Ll]?'), PatternRule('scala.integer', '-?0x[0-9A-Fa-f]+[Ll]?'),
@ -47,15 +57,12 @@ class ScalaGrammar(Grammar):
PatternRule('scala.float', r'-?[0-9]+\.[0-9]*'), # FIXME PatternRule('scala.float', r'-?[0-9]+\.[0-9]*'), # FIXME
PatternRule('scala.bool', '(?:true|false)(?![a-zA-Z0-9_])'),
PatternRule('scala.char', r"'(?:[^'\\]|\\u[0-9A-Fa-f]{4}|\\[0-7]{1,3}|\\[btnfr\"'\\])'"), PatternRule('scala.char', r"'(?:[^'\\]|\\u[0-9A-Fa-f]{4}|\\[0-7]{1,3}|\\[btnfr\"'\\])'"),
RegionRule('scala.string', '"', StringGrammar, '"'), RegionRule('scala.string', '"', StringGrammar, '"'),
PatternRule('scala.symbol', "'[a-zA-Z_][a-zA-Z0-9_]*"), PatternRule('scala.symbol', "'[a-zA-Z_][a-zA-Z0-9_]*"),
PatternRule('scala.annotation', '@[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('scala.annotation', '@[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.bareword', '[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule('scala.bareword', '[a-zA-Z_][a-zA-Z0-9_]*'),
PatternRule('scala.null', 'null'),
] ]
class ScalaTabber(StackTabber2): class ScalaTabber(StackTabber2):
@ -119,6 +126,37 @@ class ScalaDocLookup(Method):
w.set_error('looking up %s...' % name) w.set_error('looking up %s...' % name)
# white is for delimiters, operators, numbers
default = ('default', 'default')
# magenta is for keywords/builtins
lo_magenta = ('magenta202', 'default')
hi_magenta = ('magenta414', 'default')
# red is for comments
lo_red = ('red300', 'default')
hi_red = ('red511', 'default')
# orange is for macro definitions, headers and constants
hi_orange = ('yellow531', 'default')
lo_orange = ('yellow520', 'default')
# yellow is for parts of macros
hi_yellow = ('yellow551', 'default')
lo_yellow = ('yellow330', 'default')
# green is for strings and characters
lo_green = ('green030', 'default')
hi_green = ('green050', 'default')
# cyan is for types
lo_cyan = ('cyan033', 'default')
hi_cyan = ('cyan155', 'default')
# blue is definitions, functions and some macros
lo_blue = ('blue113', 'default')
hi_blue = ('blue225', 'default')
class Scala(Fundamental): class Scala(Fundamental):
name = 'Scala' name = 'Scala'
extensions = ['.scala'] extensions = ['.scala']
@ -136,16 +174,25 @@ class Scala(Fundamental):
} }
colors = { colors = {
'scala.annotation': ('magenta', 'default'), 'scala.annotation': lo_green,
'scala.bool': ('magenta', 'default'), 'scala.pseudo': hi_magenta,
'scala.null': ('magenta', 'default'),
'scala.integer': ('default', 'default'), 'scala.reserved': hi_cyan,
'scala.float': ('default', 'default'),
'scala.bareword': ('default', 'default'),
'scala.class': ('yellow', 'default'), 'scala.integer': default,
'scala.def': ('blue', 'default'), 'scala.float': default,
'scala.bareword': default,
'scala.symbol': hi_orange,
'scala.class': hi_yellow,
'scala.object': hi_yellow,
'scala.trait': hi_yellow,
'scala.type': hi_magenta,
'scala.def': hi_blue,
'scala.def': hi_blue,
} }
_bindings = { _bindings = {

34
tab.py
View File

@ -1,6 +1,8 @@
import regex import regex
from point import Point from point import Point
empty = set()
class Marker(object): class Marker(object):
def __init__(self, name, level, y): def __init__(self, name, level, y):
self.name = name self.name = name
@ -364,15 +366,15 @@ class StackTabber2(Tabber):
return t.name in self.is_ignored_tokens return t.name in self.is_ignored_tokens
def _is_close_token(self, t): def _is_close_token(self, t):
return t.string in self.close_tokens.get(t.name, set()) return t.string in self.close_tokens.get(t.name, empty)
def _handle_close_token(self, y, tokens, start, end, i, t): def _handle_close_token(self, y, tokens, start, end, i, t):
while True: while True:
if not self.stack: if not self.stack:
raise Exception, "unmatched %r, line %d" % (t.string, y) raise Exception, "unmatched %r, line %d" % (t.string, y)
marker = self.stack[-1] marker = self.stack[-1]
if marker.name in ('control', 'continue'): if marker.name in ('control', 'continue', 'pre-control'):
self.stack.pop() self.stack.pop()
elif marker.name in self.open_tokens[marker.type_]: elif marker.name in self.open_tokens.get(marker.type_, empty):
s = self.open_tokens[marker.type_][marker.name] s = self.open_tokens[marker.type_][marker.name]
if s in (None, t.string): if s in (None, t.string):
self.stack.pop() self.stack.pop()
@ -381,7 +383,7 @@ class StackTabber2(Tabber):
msg = "mismatched %r, line %d (expected %r)" msg = "mismatched %r, line %d (expected %r)"
raise Exception, msg % (t.string, y, s) raise Exception, msg % (t.string, y, s)
else: else:
raise Exception, "what? %r" % marker.name raise Exception, "what? %r (%r)" % (marker, t)
if i == 0: if i == 0:
self._save_curr_level() self._save_curr_level()
@ -393,7 +395,7 @@ class StackTabber2(Tabber):
# if we are in a control test and this closes the test, then we need to # if we are in a control test and this closes the test, then we need to
# mark that we're out of the control test. # mark that we're out of the control test.
if self._match('in-control') and \ if self._match('in-control') and \
t.string in self.close_test_tokens.get(t.name, set()): t.string in self.close_test_tokens.get(t.name, empty):
self.stack[-1].name = 'control' self.stack[-1].name = 'control'
# if we don't want implicit continuation, return. # if we don't want implicit continuation, return.
@ -402,7 +404,7 @@ class StackTabber2(Tabber):
# ok, if we are closing a block then this will end a "single-statement" # ok, if we are closing a block then this will end a "single-statement"
# block. e.g. else switch() { ... } # block. e.g. else switch() { ... }
if t.string in self.close_scope_tokens.get(t.fqname(), set()): if t.string in self.close_scope_tokens.get(t.fqname(), empty):
self._pop('control') self._pop('control')
# if we do want implicit continuation, see if we need it. # if we do want implicit continuation, see if we need it.
@ -410,32 +412,34 @@ class StackTabber2(Tabber):
top = self._peek() top = self._peek()
atscope = True atscope = True
if top: if top:
d = self.open_scope_tokens.get(top.type_, set()) d = self.open_scope_tokens.get(top.type_, empty)
atscope = top.name in d atscope = top.name in d
if (atscope and i + start == end): if (atscope and i + start == end):
d = self.nocontinue_tokens.get(name) d = self.nocontinue_tokens.get(name)
if d is None or d != 1 and s not in d: if d is None or d != 1 and s not in d:
if s not in self.close_scope_tokens.get(name, set()): if s not in self.close_scope_tokens.get(name, empty):
nextlvl = self._get_next_level() nextlvl = self._get_next_level()
self._append_unless('continue', name, nextlvl, y) self._append_unless('continue', name, nextlvl, y)
def _is_open_token(self, t): def _is_open_token(self, t):
return t.string in self.open_tokens.get(t.name, set()) return t.string in self.open_tokens.get(t.name, empty)
def _handle_open_token(self, y, tokens, start, end, i, t): def _handle_open_token(self, y, tokens, start, end, i, t):
if self.stack: if self.stack:
if i == 0 and self._match('continue'): if i == 0 and self._match('continue'):
self.stack.pop() self.stack.pop()
# if we have seen a control token, and we are starting a test, then # if we have seen a control token, and we are starting a test, then
# need to note that we've entered the test stanza. # need to note that we've entered the test stanza.
if self._match('pre-control') and \ if self._match('pre-control'):
t.string in self.open_test_tokens.get(t.name, set()): if t.string in self.open_test_tokens.get(t.name, empty):
self.stack[-1].name = 'in-control' self.stack[-1].name = 'in-control'
else:
self.stack.pop()
if t.string in self.open_scope_tokens.get(t.name, set()): if t.string in self.open_scope_tokens.get(t.name, empty):
self._pop('continue', 'control') self._pop('continue', 'control')
if i == 0 and t.string in self.open_scope_tokens.get(t.name, set()): if i == 0 and t.string in self.open_scope_tokens.get(t.name, empty):
self._save_curr_level() self._save_curr_level()
if i == end - start or self.fixed_indent: if i == end - start or self.fixed_indent: