92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
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, None)] * delta)
|
|
l = len(self.mode.window.buffer.lines)
|
|
for i in reversed(range(p.y + 1, l)):
|
|
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]
|