class Context(object): """This object stores and updates contextual metadata about the buffer.""" def __init__(self, mode): self.mode = mode self.names = None self.namelines = None def region_added(self, p, newlines): if self.names: self.adjust_name_map(p, len(newlines) - 1) self.rebuild_name_map(p.y, p.y + len(newlines)) def region_removed(self, p1, p2): if self.names: self.adjust_name_map(p2, p1.y - p2.y) self.rebuild_name_map(p1.y, p1.y + 1) def adjust_name_map(self, p, delta): if delta == 0: return elif delta > 0: self.namelines.extend([None] * delta) for i in reversed(range(p.y + 1, len(self.mode.window.buffer.lines))): self.namelines[i] = self.namelines[i - delta] for i in range(p.y, p.y + delta): self.namelines[i] = (None, None) else: for i in range(p.y + 1, len(self.mode.window.buffer.lines)): self.namelines[i + delta] = self.namelines[i] def _init_name_map(self): self.names = {} self.namelines = [(None, None)] * len(self.mode.window.buffer.lines) def build_name_map(self): self._init_name_map() self._build_name_map(0, len(self.mode.window.buffer.lines), None, None, []) def _del_name(self, y, name): if name and name in self.names: del self.names[name] self.namelines[y] = (None, None) def _regen_curr(self, y): return self.namelines[y - 1][0] def _regen_last(self, y): return None def _regen_stack(self, y): assert y > 0 stack = [] curr = self.namelines[y - 1][0] count = 0 if curr: for part in curr.split('.'): stack.append([count, part]) count += self.mode.tabwidth return stack def rebuild_name_map(self, y1, y2): for y in range(y1, y2): (name, info) = self.namelines[y] self._del_name(y, name) if y1 == 0: self._build_name_map(y1, y2, None, None, []) else: last = self._regen_last(y1) curr = self._regen_curr(y1) stack = self._regen_stack(y1) self._build_name_map(y1, y2, last, curr, stack) def _build_name_map(self, y1, y2, last, curr, stack): raise Exception, 'unimplemented' def get_line_name(self, y): if self.namelines is None: self.build_name_map() if y < len(self.namelines): return self.namelines[y][0] else: return None def get_names(self): if self.names is None: self.build_name_map() return self.names def get_name_list(self): return self._ordered_dict(self.get_names()) def _ordered_dict(self, d): pairs = [[d[key], key] for key in d] pairs.sort() return [x[1] for x in pairs]