parent
dc625d6eb5
commit
25cd253693
23
context.py
23
context.py
|
@ -20,35 +20,32 @@ class Context(object):
|
||||||
for i in reversed(range(p.y + 1, len(self.mode.window.buffer.lines))):
|
for i in reversed(range(p.y + 1, len(self.mode.window.buffer.lines))):
|
||||||
self.namelines[i] = self.namelines[i - delta]
|
self.namelines[i] = self.namelines[i - delta]
|
||||||
for i in range(p.y, p.y + delta):
|
for i in range(p.y, p.y + delta):
|
||||||
self.namelines[i] = None
|
self.namelines[i] = (None, None)
|
||||||
else:
|
else:
|
||||||
for i in range(p.y + 1, len(self.mode.window.buffer.lines)):
|
for i in range(p.y + 1, len(self.mode.window.buffer.lines)):
|
||||||
self.namelines[i + delta] = self.namelines[i]
|
self.namelines[i + delta] = self.namelines[i]
|
||||||
|
|
||||||
def _init_name_map(self):
|
def _init_name_map(self):
|
||||||
self.names = {}
|
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):
|
def build_name_map(self):
|
||||||
self._init_name_map()
|
self._init_name_map()
|
||||||
self._build_name_map(0, len(self.mode.window.buffer.lines), None, None, [])
|
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):
|
def rebuild_name_map(self, y1, y2):
|
||||||
for y in range(y1, y2):
|
for y in range(y1, y2):
|
||||||
name = self.namelines[y]
|
(name, info) = self.namelines[y]
|
||||||
if name:
|
self._del_name(y, 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
|
|
||||||
|
|
||||||
if y1 == 0:
|
if y1 == 0:
|
||||||
self._build_name_map(y1, y2, None, None, [])
|
self._build_name_map(y1, y2, None, None, [])
|
||||||
else:
|
else:
|
||||||
last, curr, stack = None, self.namelines[y1 - 1], []
|
last, curr, stack = None, self.namelines[y1 - 1][0], []
|
||||||
count = 0
|
count = 0
|
||||||
if curr:
|
if curr:
|
||||||
for part in curr.split('.'):
|
for part in curr.split('.'):
|
||||||
|
@ -63,7 +60,7 @@ class Context(object):
|
||||||
if self.namelines is None:
|
if self.namelines is None:
|
||||||
self.build_name_map()
|
self.build_name_map()
|
||||||
if y < len(self.namelines):
|
if y < len(self.namelines):
|
||||||
return self.namelines[y]
|
return self.namelines[y][0]
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
def get_names(self):
|
def get_names(self):
|
||||||
|
|
195
mode/perl.py
195
mode/perl.py
|
@ -286,7 +286,7 @@ class PerlGotoFunction(Method):
|
||||||
args = [Argument("name", type(""), "perlfunction", "Goto Function: ")]
|
args = [Argument("name", type(""), "perlfunction", "Goto Function: ")]
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
name = vargs['name']
|
name = vargs['name']
|
||||||
functions = w.mode.get_functions()
|
functions = w.mode.context.get_names()
|
||||||
if name in functions:
|
if name in functions:
|
||||||
w.goto(Point(0, functions[name]))
|
w.goto(Point(0, functions[name]))
|
||||||
else:
|
else:
|
||||||
|
@ -295,7 +295,7 @@ class PerlGotoFunction(Method):
|
||||||
class PerlListFunctions(Method):
|
class PerlListFunctions(Method):
|
||||||
'''Show the user all functions defined in this module'''
|
'''Show the user all functions defined in this module'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
names = w.mode.get_function_names()
|
names = w.mode.context.get_name_list()
|
||||||
output = "\n".join(names) + "\n"
|
output = "\n".join(names) + "\n"
|
||||||
w.application.data_buffer("*Perl-List-Functions*", output, switch_to=True)
|
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'''
|
'''Show the user what function they are in'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
cursor = w.logical_cursor()
|
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:
|
if name is None:
|
||||||
w.application.set_error("None");
|
w.application.set_error("None");
|
||||||
else:
|
else:
|
||||||
functions = w.mode.get_functions()
|
functions = w.mode.context.get_names()
|
||||||
i = functions[name] + 1
|
i = functions[name] + 1
|
||||||
w.application.set_error("line %d: %s" % (i, name))
|
w.application.set_error("line %d: %s" % (i, name))
|
||||||
|
|
||||||
|
@ -389,91 +389,6 @@ class PerlHashCleanup(Method):
|
||||||
w.kill(start_p, end_p)
|
w.kill(start_p, end_p)
|
||||||
w.insert_string(start_p, data)
|
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):
|
class PerlWrapParagraph(method.WrapParagraph):
|
||||||
'''Wrap Comments and POD'''
|
'''Wrap Comments and POD'''
|
||||||
# enumerations for line types
|
# enumerations for line types
|
||||||
|
@ -575,7 +490,7 @@ class PerlWrapParagraph(method.WrapParagraph):
|
||||||
class PerlFunctionCompleter(completer.Completer):
|
class PerlFunctionCompleter(completer.Completer):
|
||||||
def get_candidates(self, s, w=None):
|
def get_candidates(self, s, w=None):
|
||||||
old_window = w.buffer.method.old_window
|
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)]
|
return [n for n in functions if n.startswith(s)]
|
||||||
|
|
||||||
class PerlContext(context.Context):
|
class PerlContext(context.Context):
|
||||||
|
@ -585,56 +500,26 @@ class PerlContext(context.Context):
|
||||||
i = y1
|
i = y1
|
||||||
while i < y2:
|
while i < y2:
|
||||||
g = highlights.tokens[i]
|
g = highlights.tokens[i]
|
||||||
if (len(g) == 1 and g[0].name == 'eol' or
|
if (not stack and len(g) > 2 and g[0].name == 'perl_keyword' and
|
||||||
len(g) == 2 and g[0].name == 'null' and g[1].name == 'eol'):
|
g[0].string == 'sub' and g[2].name == 'sub'):
|
||||||
if last is None:
|
curr = g[2].string
|
||||||
last = i
|
self.names[curr] = i
|
||||||
i += 1
|
|
||||||
if i == y2 and y2 < blen:
|
|
||||||
y2 += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
if g[0].name == 'null':
|
if i == y2 - 1 and curr != self.namelines[i][0] and y2 < blen:
|
||||||
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
|
|
||||||
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:
|
|
||||||
y2 += 1
|
y2 += 1
|
||||||
if curr:
|
if curr:
|
||||||
self.namelines[i] = curr
|
self.namelines[i] = (curr, tuple(stack))
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
if last is not None and y2 < len(self.namelines):
|
m = self.mode
|
||||||
if self.namelines[y2]:
|
for t in g:
|
||||||
n = len(self.namelines[y2].split('.'))
|
if t.name in m.opentokens and t.string in m.opentags:
|
||||||
curr = '.'.join([x[1] for x in stack[:n]])
|
stack.append(t.string)
|
||||||
if curr:
|
elif t.name in m.closetokens and t.string in m.closetags:
|
||||||
for k in range(last, y2):
|
assert stack[-1] == m.closetags[t.string]
|
||||||
self.namelines[k] = curr
|
stack.pop(-1)
|
||||||
|
if not stack:
|
||||||
|
curr = None
|
||||||
|
|
||||||
class Perl(mode.Fundamental):
|
class Perl(mode.Fundamental):
|
||||||
modename = 'Perl'
|
modename = 'Perl'
|
||||||
|
@ -775,47 +660,15 @@ class Perl(mode.Fundamental):
|
||||||
self.add_bindings('close-paren', (')'))
|
self.add_bindings('close-paren', (')'))
|
||||||
self.add_bindings('close-bracket', (']'))
|
self.add_bindings('close-bracket', (']'))
|
||||||
self.add_bindings('close-brace', ('}'))
|
self.add_bindings('close-brace', ('}'))
|
||||||
|
self.context = PerlContext(self)
|
||||||
self.functions = None
|
self.functions = None
|
||||||
self.funclines = 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):
|
def get_functions(self):
|
||||||
if self.functions is None:
|
return self.context.get_names()
|
||||||
self.build_function_map()
|
|
||||||
return self.functions
|
|
||||||
def get_function_names(self):
|
def get_function_names(self):
|
||||||
functions = self.get_functions()
|
return self.context.get_name_list()
|
||||||
pairs = [[functions[key], key] for key in functions]
|
|
||||||
pairs.sort()
|
|
||||||
names = [x[1] for x in pairs]
|
|
||||||
return names
|
|
||||||
def get_line_function(self, y):
|
def get_line_function(self, y):
|
||||||
if self.funclines is None:
|
return self.context.get_line_name(y)
|
||||||
self.build_function_map()
|
|
||||||
if y < len(self.funclines):
|
|
||||||
return self.funclines[y]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
install = Perl.install
|
install = Perl.install
|
||||||
|
|
|
@ -358,8 +358,16 @@ class PythonContext(context.Context):
|
||||||
self.names = {}
|
self.names = {}
|
||||||
self.classes = {}
|
self.classes = {}
|
||||||
self.functions = {}
|
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):
|
def _build_name_map(self, y1, y2, last, curr, stack):
|
||||||
blen = len(self.mode.window.buffer.lines)
|
blen = len(self.mode.window.buffer.lines)
|
||||||
highlights = self.mode.window.get_highlighter()
|
highlights = self.mode.window.get_highlighter()
|
||||||
|
@ -386,7 +394,7 @@ class PythonContext(context.Context):
|
||||||
curr = '.'.join([x[1] for x in stack])
|
curr = '.'.join([x[1] for x in stack])
|
||||||
if curr:
|
if curr:
|
||||||
for k in range(last, i):
|
for k in range(last, i):
|
||||||
self.namelines[k] = curr
|
self.namelines[k] = (curr, None)
|
||||||
last = None
|
last = None
|
||||||
|
|
||||||
if len(g[j:]) > 3:
|
if len(g[j:]) > 3:
|
||||||
|
@ -403,19 +411,19 @@ class PythonContext(context.Context):
|
||||||
else:
|
else:
|
||||||
curr = '.'.join([x[1] for x in stack])
|
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
|
y2 += 1
|
||||||
if curr:
|
if curr:
|
||||||
self.namelines[i] = curr
|
self.namelines[i] = (curr, None)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
if last is not None and y2 < len(self.namelines):
|
if last is not None and y2 < len(self.namelines):
|
||||||
if self.namelines[y2]:
|
if self.namelines[y2][0]:
|
||||||
n = len(self.namelines[y2].split('.'))
|
n = len(self.namelines[y2][0].split('.'))
|
||||||
curr = '.'.join([x[1] for x in stack[:n]])
|
curr = '.'.join([x[1] for x in stack[:n]])
|
||||||
if curr:
|
if curr:
|
||||||
for k in range(last, y2):
|
for k in range(last, y2):
|
||||||
self.namelines[k] = curr
|
self.namelines[k] = (curr, None)
|
||||||
|
|
||||||
class Python(mode.Fundamental):
|
class Python(mode.Fundamental):
|
||||||
modename = 'Python'
|
modename = 'Python'
|
||||||
|
|
Loading…
Reference in New Issue