2007-03-06 10:05:38 -05:00
|
|
|
import tab, point
|
|
|
|
|
|
|
|
class ShTabber(tab.TokenStackTabber):
|
|
|
|
close_tags = {'}': '{',
|
|
|
|
')': '(',
|
|
|
|
']': '[',
|
|
|
|
'done': 'do',
|
|
|
|
'fi': 'then',
|
|
|
|
'esac': 'case'}
|
|
|
|
|
|
|
|
def stack_append_const(self, c):
|
|
|
|
self.stack_append((c, self.tab_stack[-1][1] + 4))
|
|
|
|
def stack_append_unique_const(self, c):
|
|
|
|
if self.tab_stack[-1][0] != c:
|
|
|
|
self.stack_append((c, self.tab_stack[-1][1] + 4))
|
|
|
|
def stack_pop_const(self, *c_args):
|
|
|
|
if self.tab_stack[-1][0] in c_args:
|
|
|
|
self.stack_pop()
|
|
|
|
def stack_pop_all_const(self, *c_args):
|
|
|
|
while self.tab_stack[-1][0] in c_args:
|
|
|
|
self.stack_pop()
|
|
|
|
|
|
|
|
def handle_token(self, prev_token, token, next_token, y=None):
|
|
|
|
buffer = self.mode.window.buffer
|
|
|
|
name = token.name
|
|
|
|
s = token.string
|
|
|
|
|
|
|
|
if next_token is None and name != "continuation":
|
|
|
|
self.stack_pop_all_const(self, "continued")
|
|
|
|
|
|
|
|
if name == 'reserved' or name == "keyword" or name == "delimiter":
|
|
|
|
if s == ")" and self.tab_stack[-1][0] == "case":
|
|
|
|
pass
|
|
|
|
elif s == "then" or s == "do" or s == "(" or s == "[" or s == "case" or s == "{":
|
|
|
|
if next_token is None:
|
|
|
|
self.stack_append((s, self.tab_stack[-1][1] + 4))
|
|
|
|
else:
|
|
|
|
p = buffer.get_offset_point(next_token.start)
|
|
|
|
self.stack_append((s, p.x))
|
|
|
|
elif s == "else":
|
2007-06-13 22:38:46 -04:00
|
|
|
assert self.tab_stack[-1][0] == "then", "bbbsssxxx: %s" % self.tab_stack[-1][0]
|
2007-03-06 10:05:38 -05:00
|
|
|
d = self.tab_stack[-1][1] - self.tab_stack[-2][1]
|
|
|
|
self.line_depth -= d
|
|
|
|
elif s in self.close_tags:
|
|
|
|
if self.tab_stack[-1][0] == self.close_tags[s]:
|
|
|
|
self.stack_pop()
|
|
|
|
if prev_token is None:
|
|
|
|
self.line_depth = self.tab_stack[-1][1]
|
|
|
|
elif self.errors is False:
|
|
|
|
err = "tag mismatch, line %d: expected %r, got %r" % \
|
|
|
|
(self.y, self.tab_stack[-1][0], s)
|
|
|
|
self.mode.window.application.set_error(err)
|
|
|
|
self.errors = True
|
|
|
|
elif name == "continuation":
|
|
|
|
self.stack_append_unique_const("continued")
|