adding more powerful support for single-statement control structures to support scala's lack of semicolons

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2010-08-12 00:01:47 -04:00
parent dd3151d354
commit c494da8b44
2 changed files with 41 additions and 4 deletions

View File

@ -64,7 +64,21 @@ class ScalaTabber(StackTabber2):
is_ignored_tokens = set(('spaces', 'eol', 'comment', 'comment.start', is_ignored_tokens = set(('spaces', 'eol', 'comment', 'comment.start',
'comment.data', 'comment.null', 'comment.end')) 'comment.data', 'comment.null', 'comment.end'))
is_indent_tokens = set(('spaces',)) is_indent_tokens = set(('spaces',))
def is_base(self, y): return y == 0 def _is_base(self, y):
# the first line is always safe
if y == 0: return True
# if there are no tokens we don't really have any info
tokens = self._get_tokens(y)
if not tokens: return False
# if it looks like a top-level class, object or function, then say ok
t = tokens[0]
if t.fqmatchs('scala.reserved', ('class', 'object', 'def')):
return True
# the default is to assume no
return False
class Scala(Fundamental): class Scala(Fundamental):
name = 'Scala' name = 'Scala'

29
tab.py
View File

@ -247,6 +247,8 @@ class StackTabber2(Tabber):
close_tokens = {'delimiter': set(['}', ')', ']'])} close_tokens = {'delimiter': set(['}', ')', ']'])}
open_scope_tokens = {'delimiter': set(['{'])} open_scope_tokens = {'delimiter': set(['{'])}
close_scope_tokens = {'delimiter': set(['}'])} close_scope_tokens = {'delimiter': set(['}'])}
open_test_tokens = {'delimiter': set(['('])}
close_test_tokens = {'delimiter': set([')'])}
control_tokens = {'keyword': set(['if', 'else', 'while', 'do', 'for'])} control_tokens = {'keyword': set(['if', 'else', 'while', 'do', 'for'])}
end_at_eof = True end_at_eof = True
end_at_tokens = {} end_at_tokens = {}
@ -383,6 +385,17 @@ class StackTabber2(Tabber):
if i == 0: if i == 0:
self._save_curr_level() self._save_curr_level()
# if we need to end at eof and we're at the EOF and we have a control
# token, then we need to pop it.
if self.end_at_eof and i == end - start and self._match('control'):
self.stack.pop()
# 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.
if self._match('in-control') and \
t.string in self.close_test_tokens.get(t.name, set()):
self.stack[-1].name = 'control'
# if we don't want implicit continuation, return. # if we don't want implicit continuation, return.
if self.end_at_eof: if self.end_at_eof:
return return
@ -408,9 +421,18 @@ class StackTabber2(Tabber):
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, set())
def _handle_open_token(self, y, tokens, start, end, i, t): def _handle_open_token(self, y, tokens, start, end, i, t):
if i == 0 and self.stack and self.stack[-1].name == 'continue': if self.stack:
self.stack.pop() if i == 0 and self._match('continue'):
self.stack.pop()
# if we have seen a control token, and we are starting a test, then
# need to note that we've entered the test stanza.
if self._match('pre-control') and \
t.string in self.open_test_tokens.get(t.name, set()):
self.stack[-1].name = 'in-control'
if t.string in self.open_scope_tokens.get(t.name, set()): if t.string in self.open_scope_tokens.get(t.name, set()):
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, set()):
@ -472,4 +494,5 @@ class StackTabber2(Tabber):
if i == start: if i == start:
self._save_curr_level() self._save_curr_level()
self._pop_while('continue'); self._pop_while('continue');
self._append_unless('control', name, self._get_next_level(), y) #self._append_unless('control', name, self._get_next_level(), y)
self._append_unless('pre-control', name, self._get_next_level(), y)