perl/python context improvements

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-05-12 15:34:06 +00:00
parent dc625d6eb5
commit 25cd253693
3 changed files with 50 additions and 192 deletions

View File

@ -20,35 +20,32 @@ class Context(object):
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
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] * len(self.mode.window.buffer.lines)
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 rebuild_name_map(self, y1, y2):
for y in range(y1, y2):
name = self.namelines[y]
if name:
if name in self.names:
del self.names[name]
if name in self.classes:
del self.classes[name]
if name in self.functions:
del self.functions[name]
self.namelines[y] = None
(name, info) = self.namelines[y]
self._del_name(y, name)
if y1 == 0:
self._build_name_map(y1, y2, None, None, [])
else:
last, curr, stack = None, self.namelines[y1 - 1], []
last, curr, stack = None, self.namelines[y1 - 1][0], []
count = 0
if curr:
for part in curr.split('.'):
@ -63,7 +60,7 @@ class Context(object):
if self.namelines is None:
self.build_name_map()
if y < len(self.namelines):
return self.namelines[y]
return self.namelines[y][0]
else:
return None
def get_names(self):

View File

@ -286,7 +286,7 @@ class PerlGotoFunction(Method):
args = [Argument("name", type(""), "perlfunction", "Goto Function: ")]
def _execute(self, w, **vargs):
name = vargs['name']
functions = w.mode.get_functions()
functions = w.mode.context.get_names()
if name in functions:
w.goto(Point(0, functions[name]))
else:
@ -295,7 +295,7 @@ class PerlGotoFunction(Method):
class PerlListFunctions(Method):
'''Show the user all functions defined in this module'''
def _execute(self, w, **vargs):
names = w.mode.get_function_names()
names = w.mode.context.get_name_list()
output = "\n".join(names) + "\n"
w.application.data_buffer("*Perl-List-Functions*", output, switch_to=True)
@ -303,11 +303,11 @@ class PerlWhichFunction(Method):
'''Show the user what function they are in'''
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
name = w.mode.get_line_function(cursor.y)
name = w.mode.context.get_line_name(cursor.y)
if name is None:
w.application.set_error("None");
else:
functions = w.mode.get_functions()
functions = w.mode.context.get_names()
i = functions[name] + 1
w.application.set_error("line %d: %s" % (i, name))
@ -389,91 +389,6 @@ class PerlHashCleanup(Method):
w.kill(start_p, end_p)
w.insert_string(start_p, data)
class PerlHashCleanup2(Method):
#_hash_parts = (
# (TokenMatch('null', None),),
# (TokenMatch('hash_key', None), TokenMatch('string.start', None)),
# (TokenMatch('null', None),),
# (TokenMatch('delimiter', '=>'),),
# (TokenMatch('null', None),),
#)
def _hash_matchXXX(self, group, line):
i = 0
j = 0
stages = []
while tok_i < len(group):
token = group[i]
name = token.fqname()
data = token.string
k = len(stages)
if k < len(self._hash_parts):
for (name2, data2) in self._hash_parts[k]:
if (name2 is None or name == name2 and
data2 is None or data == data2):
stages.append(line[j:token.x])
j = token.x
else:
stages.append(line[j:])
return stages
i += 1
return None
def _assign_match(self, group):
return None
def _execute(self, w, **vargs):
cursor = w.logical_cursor()
tokens = w.buffer.highlights[w.mode.name()].tokens
if self._hash_match(tokens[cursor.y]):
token_groups = self._parse_hash(w, **vargs)
elif self._assign_match(tokens[cursor.y]):
token_groups = self._parse_assign(w, **vargs)
else:
w.set_error("Not a hash line")
return
ys = token_groups.keys()
ys.sort()
segment_groups = []
for y in ys:
line = w.buffer.lines[y]
segments = []
i = 0
for token in token_groups[y]:
segments.append(line[i:token.x])
i = token.x
segments.append(line[i:])
segment_groups.append(segments)
output = "Lines %d through %d\n%r" % (ys[0] + 1, ys[-1] + 1, segment_groups)
w.application.data_buffer("hash-dump", output, switch_to=True)
def _parse_hash(self, w, **vargs):
cursor = w.logical_cursor()
tokens = w.buffer.highlights[w.mode.name()].tokens
lines = {cursor.y: self._hash_match(tokens[cursor.y])}
y1 = cursor.y
while y1 > 0:
match = self._hash_match(tokens[y1 - 1])
if not match:
break
lines[y1 - 1] = match
y1 -= 1
y2 = cursor.y
while y2 < len(tokens) - 1:
match = self._hash_match(tokens[y2 + 1])
if not match:
break
lines[y2 + 1] = match
y2 += 1
return lines
def _parse_assign(self, w, **vargs):
pass
class PerlWrapParagraph(method.WrapParagraph):
'''Wrap Comments and POD'''
# enumerations for line types
@ -575,7 +490,7 @@ class PerlWrapParagraph(method.WrapParagraph):
class PerlFunctionCompleter(completer.Completer):
def get_candidates(self, s, w=None):
old_window = w.buffer.method.old_window
functions = old_window.mode.get_functions()
functions = old_window.mode.context.get_names()
return [n for n in functions if n.startswith(s)]
class PerlContext(context.Context):
@ -585,56 +500,26 @@ class PerlContext(context.Context):
i = y1
while i < y2:
g = highlights.tokens[i]
if (len(g) == 1 and g[0].name == 'eol' or
len(g) == 2 and g[0].name == 'null' and g[1].name == 'eol'):
if last is None:
last = i
i += 1
if i == y2 and y2 < blen:
y2 += 1
continue
if g[0].name == 'null':
j, lvl = 1, len(g[0].string)
else:
j, lvl = 0, 0
while stack and lvl <= stack[-1][0]:
stack.pop(-1)
if last is not None:
curr = '.'.join([x[1] for x in stack])
if curr:
for k in range(last, i):
self.namelines[k] = curr
last = None
if len(g[j:]) > 3:
d, found = None, False
if g[j].name == 'python_keyword' and g[j].string == 'class':
d, found = self.classes, True
elif g[j].name == 'python_keyword' and g[j].string == 'def':
d, found = self.functions, True
if found:
stack.append([lvl, g[j+2].string])
curr = '.'.join([x[1] for x in stack])
d[curr] = i
if (not stack and len(g) > 2 and g[0].name == 'perl_keyword' and
g[0].string == 'sub' and g[2].name == 'sub'):
curr = g[2].string
self.names[curr] = i
else:
curr = '.'.join([x[1] for x in stack])
if i == y2 - 1 and curr != self.namelines[i] and y2 < blen:
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
y2 += 1
if curr:
self.namelines[i] = curr
self.namelines[i] = (curr, tuple(stack))
i += 1
if last is not None and y2 < len(self.namelines):
if self.namelines[y2]:
n = len(self.namelines[y2].split('.'))
curr = '.'.join([x[1] for x in stack[:n]])
if curr:
for k in range(last, y2):
self.namelines[k] = curr
m = self.mode
for t in g:
if t.name in m.opentokens and t.string in m.opentags:
stack.append(t.string)
elif t.name in m.closetokens and t.string in m.closetags:
assert stack[-1] == m.closetags[t.string]
stack.pop(-1)
if not stack:
curr = None
class Perl(mode.Fundamental):
modename = 'Perl'
@ -775,47 +660,15 @@ class Perl(mode.Fundamental):
self.add_bindings('close-paren', (')'))
self.add_bindings('close-bracket', (']'))
self.add_bindings('close-brace', ('}'))
self.context = PerlContext(self)
self.functions = None
self.funclines = None
def build_function_map(self):
self.functions = {}
self.funclines = []
highlights = self.window.get_highlighter()
curr, stack = None, []
for group in highlights.tokens:
self.funclines.append(curr)
for t in group:
if not curr and t.name == 'sub':
curr = t.string
stack = []
self.functions[curr] = t.y
elif t.name == 'delimiter':
if t.string == '{':
stack.append(None)
elif t.string == '}':
stack.pop()
if not stack:
curr = None
if curr:
self.funclines[-1] = curr
def get_functions(self):
if self.functions is None:
self.build_function_map()
return self.functions
return self.context.get_names()
def get_function_names(self):
functions = self.get_functions()
pairs = [[functions[key], key] for key in functions]
pairs.sort()
names = [x[1] for x in pairs]
return names
return self.context.get_name_list()
def get_line_function(self, y):
if self.funclines is None:
self.build_function_map()
if y < len(self.funclines):
return self.funclines[y]
else:
return None
return self.context.get_line_name(y)
install = Perl.install

View File

@ -358,8 +358,16 @@ class PythonContext(context.Context):
self.names = {}
self.classes = {}
self.functions = {}
self.namelines = [None] * len(self.mode.window.buffer.lines)
self.namelines = [(None, None)] * len(self.mode.window.buffer.lines)
def _del_name(self, y, name):
if name:
if name in self.names:
del self.names[name]
if name in self.classes:
del self.classes[name]
if name in self.functions:
del self.functions[name]
self.namelines[y] = (None, None)
def _build_name_map(self, y1, y2, last, curr, stack):
blen = len(self.mode.window.buffer.lines)
highlights = self.mode.window.get_highlighter()
@ -386,7 +394,7 @@ class PythonContext(context.Context):
curr = '.'.join([x[1] for x in stack])
if curr:
for k in range(last, i):
self.namelines[k] = curr
self.namelines[k] = (curr, None)
last = None
if len(g[j:]) > 3:
@ -403,19 +411,19 @@ class PythonContext(context.Context):
else:
curr = '.'.join([x[1] for x in stack])
if i == y2 - 1 and curr != self.namelines[i] and y2 < blen:
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
y2 += 1
if curr:
self.namelines[i] = curr
self.namelines[i] = (curr, None)
i += 1
if last is not None and y2 < len(self.namelines):
if self.namelines[y2]:
n = len(self.namelines[y2].split('.'))
if self.namelines[y2][0]:
n = len(self.namelines[y2][0].split('.'))
curr = '.'.join([x[1] for x in stack[:n]])
if curr:
for k in range(last, y2):
self.namelines[k] = curr
self.namelines[k] = (curr, None)
class Python(mode.Fundamental):
modename = 'Python'