diff --git a/tab2.py b/tab2.py new file mode 100644 index 0000000..aa7ebdc --- /dev/null +++ b/tab2.py @@ -0,0 +1,131 @@ +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