parent
5c9608d300
commit
e2e6e28c07
|
@ -161,17 +161,17 @@ class Buffer(object):
|
|||
def _region_add(self, p1, p2, lines, act):
|
||||
move = DelMove(self, p1, p2)
|
||||
self.add_to_stack(move, act)
|
||||
for w in self.windows:
|
||||
w.region_added(p1, lines)
|
||||
for name in self.highlights:
|
||||
self.highlights[name].relex_add(self.lines, p1.y, p1.x, lines)
|
||||
for w in self.windows:
|
||||
w.region_added(p1, lines)
|
||||
def _region_del(self, p1, p2, lines, act):
|
||||
move = AddMove(self, p1, lines)
|
||||
self.add_to_stack(move, act)
|
||||
for w in self.windows:
|
||||
w.region_removed(p1, p2)
|
||||
for name in self.highlights:
|
||||
self.highlights[name].relex_del(self.lines, p1.y, p1.x, p2.y, p2.x)
|
||||
for w in self.windows:
|
||||
w.region_removed(p1, p2)
|
||||
|
||||
# internal validation
|
||||
def _validate_point(self, p):
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
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):
|
||||
self.adjust_name_map(p, len(newlines) - 1)
|
||||
self.rebuild_name_map(p.y, p.y + len(newlines))
|
||||
def region_removed(self, p1, p2):
|
||||
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
|
||||
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)
|
||||
|
||||
def build_name_map(self):
|
||||
self._init_name_map()
|
||||
self._build_name_map(0, len(self.mode.window.buffer.lines), 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
|
||||
|
||||
if y1 == 0:
|
||||
self._build_name_map(y1, y2, None, None, [])
|
||||
else:
|
||||
last, curr, stack = None, self.namelines[y1 - 1], []
|
||||
count = 0
|
||||
if curr:
|
||||
for part in curr.split('.'):
|
||||
stack.append([count, part])
|
||||
count += self.mode.tabwidth
|
||||
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]
|
||||
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]
|
102
edb.py
102
edb.py
|
@ -1,66 +1,59 @@
|
|||
import bdb, os, re, sys, time, traceback
|
||||
#! /usr/bin/env python
|
||||
|
||||
class Edb(bdb.Bdb):
|
||||
run_ = 0
|
||||
def interaction(self, frame, t):
|
||||
"""Another Python debugger."""
|
||||
|
||||
import os, pdb, sys, time, traceback
|
||||
|
||||
__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace",
|
||||
"post_mortem", "help"]
|
||||
|
||||
class Edb(pdb.Pdb):
|
||||
def cmdloop(self, intro=None):
|
||||
stop = False
|
||||
while not stop:
|
||||
sys.stdout.write(self.prompt)
|
||||
sys.stdout.flush()
|
||||
line = sys.stdin.readline()
|
||||
line = self.precmd(line)
|
||||
stop = self.onecmd(line)
|
||||
stop = self.postcmd(stop, line)
|
||||
self.postloop()
|
||||
|
||||
def columnize(self, list, displaywidth=80):
|
||||
pass
|
||||
def do_help(self, arg):
|
||||
pass
|
||||
def print_topics(self, header, cmds, cmdlen, maxcol):
|
||||
pass
|
||||
def user_call(self, frame, args):
|
||||
name = frame.f_code.co_name or "<unknown>"
|
||||
print "call", name, args
|
||||
sys.stdin.readline()
|
||||
self.set_continue() # continue
|
||||
|
||||
def user_line(self, frame):
|
||||
if self.run_:
|
||||
self.run_ = 0
|
||||
self.set_trace() # start tracing
|
||||
else:
|
||||
# arrived at breakpoint
|
||||
name = frame.f_code.co_name or "<unknown>"
|
||||
filename = self.canonic(frame.f_code.co_filename)
|
||||
print "break at", filename, frame.f_lineno, "in", name
|
||||
print "continue..."
|
||||
sys.stdin.readline()
|
||||
self.set_continue() # continue to next breakpoint
|
||||
# Simplified interface
|
||||
def run(statement, globals=None, locals=None):
|
||||
Edb().run(statement, globals, locals)
|
||||
def runeval(expression, globals=None, locals=None):
|
||||
return Edb().runeval(expression, globals, locals)
|
||||
def runctx(statement, globals, locals):
|
||||
run(statement, globals, locals)
|
||||
def runcall(*args, **kwds):
|
||||
return Edb().runcall(*args, **kwds)
|
||||
def set_trace():
|
||||
Edb().set_trace(sys._getframe().f_back)
|
||||
|
||||
def user_return(self, frame, value):
|
||||
name = frame.f_code.co_name or "<unknown>"
|
||||
print "return from", name, value
|
||||
print "continue..."
|
||||
sys.stdin.readline()
|
||||
self.set_continue() # continue
|
||||
|
||||
def user_exception(self, frame, exception):
|
||||
name = frame.f_code.co_name or "<unknown>"
|
||||
print "exception in", name, exception
|
||||
print "continue..."
|
||||
sys.stdin.readline()
|
||||
self.set_continue() # continue
|
||||
|
||||
def _runscript(self, filename):
|
||||
# Start with fresh empty copy of globals and locals and tell the script
|
||||
# that it's being run as __main__ to avoid scripts being able to access
|
||||
# the pdb.py namespace.
|
||||
globals_ = {"__name__" : "__main__"}
|
||||
locals_ = globals_
|
||||
|
||||
# When bdb sets tracing, a number of call and line events happens
|
||||
# BEFORE debugger even reaches user's code (and the exact sequence of
|
||||
# events depends on python version). So we take special measures to
|
||||
# avoid stopping before we reach the main script (see user_line and
|
||||
# user_call for details).
|
||||
self._wait_for_mainpyfile = 1
|
||||
self.mainpyfile = self.canonic(filename)
|
||||
self._user_requested_quit = 0
|
||||
statement = 'execfile( "%s")' % filename
|
||||
self.run(statement, globals=globals_, locals=locals_)
|
||||
# Post-Mortem interface
|
||||
def post_mortem(t):
|
||||
p = Edb()
|
||||
p.reset()
|
||||
while t.tb_next is not None:
|
||||
t = t.tb_next
|
||||
p.interaction(t.tb_frame, t)
|
||||
def pm():
|
||||
post_mortem(sys.last_traceback)
|
||||
|
||||
def main():
|
||||
if not sys.argv[1:]:
|
||||
print "usage: edb.py scriptfile [arg] ..."
|
||||
sys.exit(2)
|
||||
|
||||
mainpyfile = sys.argv[1] # Get script filename
|
||||
mainpyfile = sys.argv[1]
|
||||
if not os.path.exists(mainpyfile):
|
||||
print 'Error:', mainpyfile, 'does not exist'
|
||||
sys.exit(1)
|
||||
|
@ -84,13 +77,12 @@ def main():
|
|||
except:
|
||||
traceback.print_exc()
|
||||
print "Uncaught exception. Entering post mortem debugging"
|
||||
#print "Running 'cont' or 'step' will restart the program"
|
||||
print "Running 'cont' or 'step' will restart the program"
|
||||
t = sys.exc_info()[2]
|
||||
while t.tb_next is not None:
|
||||
t = t.tb_next
|
||||
edb.interaction(t.tb_frame,t)
|
||||
print "Post mortem debugger finished. The "+mainpyfile+" will be restarted"
|
||||
|
||||
# When invoked as main program, invoke the debugger on a script
|
||||
if __name__=='__main__':
|
||||
main()
|
||||
|
|
|
@ -86,6 +86,7 @@ class Fundamental(Handler):
|
|||
grammar = None
|
||||
lexer = None
|
||||
tabber = None
|
||||
context = None
|
||||
colors = {}
|
||||
config = {}
|
||||
actions = []
|
||||
|
@ -322,9 +323,7 @@ class Fundamental(Handler):
|
|||
self.window.set_error(err)
|
||||
|
||||
def region_added(self, p, newlines):
|
||||
if self.tabber is not None:
|
||||
self.tabber.region_added(p, newlines)
|
||||
if self.lexer:
|
||||
if self.lexer is not None:
|
||||
ydelta = len(newlines) - 1
|
||||
xdelta = len(newlines[-1])
|
||||
ghist = {}
|
||||
|
@ -345,10 +344,13 @@ class Fundamental(Handler):
|
|||
ghist.setdefault(name, {})
|
||||
ghist[name][newp] = self.ghist[name][gp]
|
||||
self.ghist = ghist
|
||||
def region_removed(self, p1, p2):
|
||||
if self.tabber is not None:
|
||||
self.tabber.region_removed(p1, p2)
|
||||
if self.lexer:
|
||||
self.tabber.region_added(p, newlines)
|
||||
if self.context is not None:
|
||||
self.context.region_added(p, newlines)
|
||||
|
||||
def region_removed(self, p1, p2):
|
||||
if self.lexer is not None:
|
||||
ydelta = p2.y - p1.y
|
||||
xdelta = p2.x - p1.x
|
||||
ghist = {}
|
||||
|
@ -371,4 +373,9 @@ class Fundamental(Handler):
|
|||
ghist.setdefault(name, {})
|
||||
ghist[name][newp] = self.ghist[name][gp]
|
||||
self.ghist = ghist
|
||||
if self.tabber is not None:
|
||||
self.tabber.region_removed(p1, p2)
|
||||
if self.context is not None:
|
||||
self.context.region_removed(p1, p2)
|
||||
|
||||
install = Fundamental.install
|
||||
|
|
12
mode/dir.py
12
mode/dir.py
|
@ -166,19 +166,19 @@ class Dir(mode.Fundamental):
|
|||
grammar = DirGrammar()
|
||||
colors = {
|
||||
'dir_blk.start': ('cyan', 'default', 'bold'),
|
||||
'dir_blk.name': ('cyan', 'default', 'bold'),
|
||||
'dir_blk.dir_name': ('cyan', 'default', 'bold'),
|
||||
'dir_chr.start': ('yellow', 'default', 'bold'),
|
||||
'dir_chr.name': ('yellow', 'default', 'bold'),
|
||||
'dir_chr.dir_name': ('yellow', 'default', 'bold'),
|
||||
'dir_dir.start': ('blue', 'default', 'bold'),
|
||||
'dir_dir.dir_name': ('blue', 'default', 'bold'),
|
||||
'dir_lnk.start': ('green', 'default', 'bold'),
|
||||
'dir_lnk.name': ('green', 'default', 'bold'),
|
||||
'dir_lnk.dir_name': ('green', 'default', 'bold'),
|
||||
'dir_fifo.start': ('red', 'default', 'bold'),
|
||||
'dir_fifo.name': ('red', 'default', 'bold'),
|
||||
'dir_fifo.dir_name': ('red', 'default', 'bold'),
|
||||
'dir_sock.start': ('red', 'default', 'bold'),
|
||||
'dir_sock.name': ('red', 'default', 'bold'),
|
||||
'dir_sock.dir_name': ('red', 'default', 'bold'),
|
||||
'dir_unk.start': ('magenta', 'default', 'bold'),
|
||||
'dir_unk.name': ('magenta', 'default', 'bold'),
|
||||
'dir_unk.dir_name': ('magenta', 'default', 'bold'),
|
||||
|
||||
'dir_perm.perm_setid': ('yellow', 'default', 'bold'),
|
||||
'dir_perm.perm_sticky': ('yellow', 'default', 'bold'),
|
||||
|
|
278
mode/python.py
278
mode/python.py
|
@ -1,5 +1,5 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import color, completer, default, mode, method, regex, tab
|
||||
import color, completer, context, default, mode, method, regex, tab
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
||||
|
@ -173,53 +173,6 @@ class PythonTabber(tab.StackTabber):
|
|||
self._append(token.string, currlvl + w)
|
||||
return currlvl
|
||||
|
||||
class PythonInitNames(method.Method):
|
||||
'''Jump to a function defined in this module'''
|
||||
def _execute(self, w, **vargs):
|
||||
w.mode.build_name_map()
|
||||
w.application.set_error("Initialized name maps")
|
||||
|
||||
class PythonGotoName(method.Method):
|
||||
'''Jump to a class or function defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonname", "Goto Name: ")]
|
||||
def _execute(self, w, **vargs):
|
||||
name = vargs['name']
|
||||
d = {}
|
||||
d.update(w.mode.get_classes())
|
||||
d.update(w.mode.get_functions())
|
||||
if name in d:
|
||||
w.goto(Point(0, d[name]))
|
||||
else:
|
||||
w.application.set_error("Function %r was not found" % name)
|
||||
class PythonGotoFunction(method.Method):
|
||||
'''Jump to a function defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonfunction", "Goto Function: ")]
|
||||
def _execute(self, w, **vargs):
|
||||
name = vargs['name']
|
||||
functions = w.mode.get_functions()
|
||||
if name in functions:
|
||||
w.goto(Point(0, functions[name]))
|
||||
else:
|
||||
w.application.set_error("Function %r was not found" % name)
|
||||
class PythonGotoClass(method.Method):
|
||||
'''Jump to a class defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonclass", "Goto Class: ")]
|
||||
def _execute(self, w, **vargs):
|
||||
name = vargs['name']
|
||||
classes = w.mode.get_classes()
|
||||
if name in classes:
|
||||
w.goto(Point(0, classes[name]))
|
||||
else:
|
||||
w.application.set_error("Class %r was not found" % name)
|
||||
|
||||
class PythonListNames(method.Method):
|
||||
'''Show the user all functions defined in this module'''
|
||||
def _execute(self, w, **vargs):
|
||||
names = w.mode.get_function_names()
|
||||
names.extend(w.mode.get_class_names())
|
||||
output = '\n'.join(sorted(names)) + "\n"
|
||||
w.application.data_buffer("*Python-List-Names*", output, switch_to=True)
|
||||
|
||||
class PythonCheckSyntax(method.Method):
|
||||
'''Check the syntax of the current python file'''
|
||||
def _execute(self, w, **vargs):
|
||||
|
@ -318,35 +271,151 @@ class PythonDictCleanup(method.Method):
|
|||
|
||||
class PythonInsertTripleSquotes(method.Method):
|
||||
'''Insert a triple-quoted string using single-quotes'''
|
||||
_q = "'''"
|
||||
def _execute(self, w, **vargs):
|
||||
w.insert_string_at_cursor("''''''")
|
||||
w.insert_string_at_cursor('%s%s' % (_q, _q))
|
||||
for i in range(0, 3):
|
||||
w.backward()
|
||||
|
||||
class PythonInsertTripleDquotes(method.Method):
|
||||
class PythonInsertTripleDquotes(PythonInsertTripleSquotes):
|
||||
'''Insert a triple-quoted string using double-quotes'''
|
||||
def _execute(self, w, **vargs):
|
||||
w.insert_string_at_cursor('""""""')
|
||||
for i in range(0, 3):
|
||||
w.backward()
|
||||
_q = '"""'
|
||||
|
||||
class PythonInitNames(method.Method):
|
||||
'''Jump to a function defined in this module'''
|
||||
def _execute(self, w, **vargs):
|
||||
w.mode.context.build_name_map()
|
||||
w.application.set_error("Initialized name maps")
|
||||
|
||||
class PythonGotoName(method.Method):
|
||||
'''Jump to a class or function defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonname", "Goto Name: ")]
|
||||
title = 'Name'
|
||||
def _get_dict(self, w):
|
||||
return w.mode.context.get_names()
|
||||
def _execute(self, w, **vargs):
|
||||
name = vargs['name']
|
||||
d = self._get_dict(w)
|
||||
if name in d:
|
||||
w.goto(Point(0, d[name]))
|
||||
else:
|
||||
w.application.set_error("%r %r was not found" % (title, name))
|
||||
class PythonGotoFunction(PythonGotoName):
|
||||
'''Jump to a function defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonfunction", "Goto Function: ")]
|
||||
title = 'Function'
|
||||
def _get_dict(self, w):
|
||||
return w.mode.context.get_functions()
|
||||
class PythonGotoClass(method.Method):
|
||||
'''Jump to a class defined in this module'''
|
||||
args = [method.Argument("name", type(""), "pythonclass", "Goto Class: ")]
|
||||
title = 'Class'
|
||||
def _get_dict(self, w):
|
||||
return w.mode.context.get_classes()
|
||||
|
||||
class PythonListNames(method.Method):
|
||||
'''Show the user all functions defined in this module'''
|
||||
def _execute(self, w, **vargs):
|
||||
names = w.mode.context.get_names()
|
||||
output = '\n'.join(sorted(names)) + "\n"
|
||||
w.application.data_buffer("*Python-List-Names*", output, switch_to=True)
|
||||
|
||||
class PythonFunctionCompleter(completer.Completer):
|
||||
def get_candidates(self, s, w=None):
|
||||
old_window = w.buffer.method.old_window
|
||||
functions = old_window.mode.get_functions()
|
||||
return [n for n in functions if n.startswith(s)]
|
||||
class PythonClassCompleter(completer.Completer):
|
||||
def get_candidates(self, s, w=None):
|
||||
old_window = w.buffer.method.old_window
|
||||
classes = old_window.mode.get_classes()
|
||||
return [n for n in classes if n.startswith(s)]
|
||||
class PythonNameCompleter(completer.Completer):
|
||||
def _get_dict(self, w):
|
||||
return w.buffer.method.old_window.mode.context.get_names()
|
||||
def get_candidates(self, s, w=None):
|
||||
old_window = w.buffer.method.old_window
|
||||
names = []
|
||||
names.extend(old_window.mode.get_classes())
|
||||
names.extend(old_window.mode.get_functions())
|
||||
return [n for n in names if n.startswith(s)]
|
||||
return [n for n in self._get_dict(w) if n.startswith(s)]
|
||||
class PythonFunctionCompleter(PythonNameCompleter):
|
||||
def _get_dict(self, w):
|
||||
return w.buffer.method.old_window.mode.context.get_functions()
|
||||
class PythonClassCompleter(completer.Completer):
|
||||
def _get_dict(self, w):
|
||||
return w.buffer.method.old_window.mode.context.get_classes()
|
||||
|
||||
class PythonContext(context.Context):
|
||||
def __init__(self, mode):
|
||||
self.mode = mode
|
||||
self.names = None
|
||||
self.namelines = None
|
||||
self.classes = None
|
||||
self.functions = None
|
||||
|
||||
# new object methods
|
||||
def get_functions(self):
|
||||
if self.functions is None:
|
||||
self.build_name_map()
|
||||
return self.functions
|
||||
def get_classes(self):
|
||||
if self.classes is None:
|
||||
self.build_name_map()
|
||||
return self.classes
|
||||
def get_function_list(self):
|
||||
return self._ordered_dict(self.get_functions())
|
||||
def get_class_list(self):
|
||||
return self._ordered_dict(self.get_classes())
|
||||
|
||||
# overridden object methods
|
||||
def _init_name_map(self):
|
||||
self.names = {}
|
||||
self.classes = {}
|
||||
self.functions = {}
|
||||
self.namelines = [None] * len(self.mode.window.buffer.lines)
|
||||
|
||||
def _build_name_map(self, y1, y2, last, curr, stack):
|
||||
blen = len(self.mode.window.buffer.lines)
|
||||
highlights = self.mode.window.get_highlighter()
|
||||
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
|
||||
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
|
||||
if curr:
|
||||
self.namelines[i] = curr
|
||||
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
|
||||
|
||||
class Python(mode.Fundamental):
|
||||
modename = 'Python'
|
||||
|
@ -382,6 +451,20 @@ class Python(mode.Fundamental):
|
|||
"pythonfunction": PythonFunctionCompleter(),
|
||||
"pythonclass": PythonClassCompleter(),
|
||||
}
|
||||
format = "%(flag)s %(bname)-18s (%(mname)s) %(cursor)s/%(mark)s %(perc)s [%(name)s]"
|
||||
def get_status_names(self):
|
||||
w = self.window
|
||||
c = w.logical_cursor()
|
||||
names = {
|
||||
'bname': w.buffer.name(),
|
||||
'mname': self.name(),
|
||||
'flag': self._get_flag(),
|
||||
'perc': self._get_perc(),
|
||||
'cursor': '(%d,%d)' % (c.y + 1, c.x + 1),
|
||||
'mark': self._get_mark(),
|
||||
'name': self.context.get_line_name(c.y),
|
||||
}
|
||||
return names
|
||||
def __init__(self, w):
|
||||
mode.Fundamental.__init__(self, w)
|
||||
self.add_bindings('close-paren', (')',))
|
||||
|
@ -394,59 +477,6 @@ class Python(mode.Fundamental):
|
|||
self.add_bindings('python-dict-cleanup', ('C-c h',))
|
||||
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
|
||||
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
|
||||
|
||||
self.classes = None
|
||||
self.functions = None
|
||||
def build_name_map(self):
|
||||
b = self.window.buffer
|
||||
scope_stack = []
|
||||
self.classes = {}
|
||||
self.functions = {}
|
||||
for i in range(0, len(b.lines)):
|
||||
if regex.whitespace.match(b.lines[i]):
|
||||
continue
|
||||
m = regex.python_indent.match(b.lines[i])
|
||||
assert m
|
||||
lvl = len(m.group(1))
|
||||
while scope_stack:
|
||||
if lvl <= scope_stack[-1][0]:
|
||||
scope_stack.pop(-1)
|
||||
else:
|
||||
break
|
||||
m = regex.python_scope.match(b.lines[i])
|
||||
if m:
|
||||
(ws, typ, name) = m.groups()
|
||||
lvl = len(ws)
|
||||
if typ == 'class':
|
||||
#raise Exception, repr(m.groups())
|
||||
d = self.classes
|
||||
else:
|
||||
d = self.functions
|
||||
if scope_stack:
|
||||
prefix = '.'.join([x[1] for x in scope_stack])
|
||||
d['%s.%s' % (prefix, name)] = i
|
||||
else:
|
||||
d[name] = i
|
||||
scope_stack.append((len(ws), name))
|
||||
def get_functions(self):
|
||||
if self.functions is None:
|
||||
self.build_name_map()
|
||||
return self.functions
|
||||
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
|
||||
def get_classes(self):
|
||||
if self.classes is None:
|
||||
self.build_name_map()
|
||||
return self.classes
|
||||
def get_class_names(self):
|
||||
classes = self.get_classes()
|
||||
pairs = [[classes[key], key] for key in classes]
|
||||
pairs.sort()
|
||||
names = [x[1] for x in pairs]
|
||||
return names
|
||||
self.context = PythonContext(self)
|
||||
|
||||
install = Python.install
|
||||
|
|
Loading…
Reference in New Issue