import regex, util from point2 import Point class Marker: def __init__(self, name, level): self.name = name self.level = level def __repr__(self): return '' % (self.name, self.level) class Tabber: def __init__(self, m): self.mode = m self.lines = {} def is_leftmost_token(self, y, i): tokens = self.get_tokens(y) assert i >= 0 and i < len(tokens) for j in range(0, i): m = regex.whitespace.match(tokens[j].string) if not m: return False return True def is_rightmost_token(self, y, i): tokens = self.get_tokens(y) assert i >= 0 and i < len(tokens) for j in range(i, len(tokens)): m = regex.whitespace.match(highlighter.tokens[y][j].string) if not m: return False return True def is_only_token(self, y, i): tokens = self.get_tokens(y) assert i >= 0 and i < len(tokens) for j in range(0, len(tokens)): if j == i: continue m = regex.whitespace.match(highlighter.tokens[y][j].string) if not m: return False return True def region_added(self, p, newlines): self.lines = {} def region_removed(self, p1, p2): self.lines = {} def is_base(self, y): return True def get_level(self, y): if y in self.lines: return self.lines[y] else: self._calc_level(y) return self.lines.get(y) def _calc_level(self, y): pass def get_level(markers): if markers: return markers[-1].level else: return 0 class StackTabber(Tabber): def __init__(self, m): self.mode = m self.lines = {} self.record = {} self.markers = [] def get_curr_level(self): if self.markers: return self.markers[-1].level else: return 0 def get_tokens(self, y): return self.mode.window.buffer.highlights[self.mode.name()].tokens[y] def region_added(self, p, newlines): self.lines = {} self.record = {} self.markers = [] def region_removed(self, p1, p2): self.lines = {} self.record = {} self.markers = [] def is_base(self, y): return y == 0 def _calc_level(self, y): highlighter = self.mode.window.buffer.highlights[self.mode.name()] target = y # first we need to step back to find the last place where we have tab # stops figured out, or a suitable place to start while not self.is_base(y) and y > 0: y -= 1 # ok now, let's do this shit self.markers = [] currlvl = 0 while y <= target: currlvl = self.get_curr_level() tokens = self.get_tokens(y) for i in range(0, len(tokens)): currlvl = self._handle_token(currlvl, y, i) self.lines[y] = currlvl self.record[y] = tuple(self.markers) y += 1 def _handle_token(self, currlvl, y, i): highlighter = self.mode.window.buffer.highlights[self.mode.name()] token = highlighter.tokens[y][i] s = token.string if token.name == 'delimiter': if s in self.mode.closetags: if not self.markers: raise Exception, "unmatched closing token %r" % s nam = self.markers[-1].name if s == self.mode.opentags[nam]: del self.markers[-1] if self.is_leftmost_token(y, i): currlvl = self.get_curr_level() else: raise Exception, "mismatched closing tag %r vs %r" % (nam, s) elif s in self.mode.opentags: level = self.get_curr_level() + 1 self.markers.append(Marker(s, level)) return currlvl