parent
5c9608d300
commit
e2e6e28c07
|
@ -161,17 +161,17 @@ class Buffer(object):
|
||||||
def _region_add(self, p1, p2, lines, act):
|
def _region_add(self, p1, p2, lines, act):
|
||||||
move = DelMove(self, p1, p2)
|
move = DelMove(self, p1, p2)
|
||||||
self.add_to_stack(move, act)
|
self.add_to_stack(move, act)
|
||||||
for w in self.windows:
|
|
||||||
w.region_added(p1, lines)
|
|
||||||
for name in self.highlights:
|
for name in self.highlights:
|
||||||
self.highlights[name].relex_add(self.lines, p1.y, p1.x, lines)
|
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):
|
def _region_del(self, p1, p2, lines, act):
|
||||||
move = AddMove(self, p1, lines)
|
move = AddMove(self, p1, lines)
|
||||||
self.add_to_stack(move, act)
|
self.add_to_stack(move, act)
|
||||||
for w in self.windows:
|
|
||||||
w.region_removed(p1, p2)
|
|
||||||
for name in self.highlights:
|
for name in self.highlights:
|
||||||
self.highlights[name].relex_del(self.lines, p1.y, p1.x, p2.y, p2.x)
|
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
|
# internal validation
|
||||||
def _validate_point(self, p):
|
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]
|
104
edb.py
104
edb.py
|
@ -1,66 +1,59 @@
|
||||||
import bdb, os, re, sys, time, traceback
|
#! /usr/bin/env python
|
||||||
|
|
||||||
class Edb(bdb.Bdb):
|
"""Another Python debugger."""
|
||||||
run_ = 0
|
|
||||||
def interaction(self, frame, t):
|
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
|
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):
|
# Simplified interface
|
||||||
if self.run_:
|
def run(statement, globals=None, locals=None):
|
||||||
self.run_ = 0
|
Edb().run(statement, globals, locals)
|
||||||
self.set_trace() # start tracing
|
def runeval(expression, globals=None, locals=None):
|
||||||
else:
|
return Edb().runeval(expression, globals, locals)
|
||||||
# arrived at breakpoint
|
def runctx(statement, globals, locals):
|
||||||
name = frame.f_code.co_name or "<unknown>"
|
run(statement, globals, locals)
|
||||||
filename = self.canonic(frame.f_code.co_filename)
|
def runcall(*args, **kwds):
|
||||||
print "break at", filename, frame.f_lineno, "in", name
|
return Edb().runcall(*args, **kwds)
|
||||||
print "continue..."
|
def set_trace():
|
||||||
sys.stdin.readline()
|
Edb().set_trace(sys._getframe().f_back)
|
||||||
self.set_continue() # continue to next breakpoint
|
|
||||||
|
|
||||||
def user_return(self, frame, value):
|
# Post-Mortem interface
|
||||||
name = frame.f_code.co_name or "<unknown>"
|
def post_mortem(t):
|
||||||
print "return from", name, value
|
p = Edb()
|
||||||
print "continue..."
|
p.reset()
|
||||||
sys.stdin.readline()
|
while t.tb_next is not None:
|
||||||
self.set_continue() # continue
|
t = t.tb_next
|
||||||
|
p.interaction(t.tb_frame, t)
|
||||||
def user_exception(self, frame, exception):
|
def pm():
|
||||||
name = frame.f_code.co_name or "<unknown>"
|
post_mortem(sys.last_traceback)
|
||||||
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_)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if not sys.argv[1:]:
|
if not sys.argv[1:]:
|
||||||
print "usage: edb.py scriptfile [arg] ..."
|
print "usage: edb.py scriptfile [arg] ..."
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
mainpyfile = sys.argv[1] # Get script filename
|
mainpyfile = sys.argv[1]
|
||||||
if not os.path.exists(mainpyfile):
|
if not os.path.exists(mainpyfile):
|
||||||
print 'Error:', mainpyfile, 'does not exist'
|
print 'Error:', mainpyfile, 'does not exist'
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -79,18 +72,17 @@ def main():
|
||||||
print "The program finished and will be restarted"
|
print "The program finished and will be restarted"
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
# In most cases SystemExit does not warrant a post-mortem session.
|
# In most cases SystemExit does not warrant a post-mortem session.
|
||||||
print "The program exited via sys.exit(). Exit status:",
|
print "The program exited via sys.exit(). Exit status: ",
|
||||||
print sys.exc_info()[1]
|
print sys.exc_info()[1]
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
print "Uncaught exception. Entering post mortem debugging"
|
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]
|
t = sys.exc_info()[2]
|
||||||
while t.tb_next is not None:
|
while t.tb_next is not None:
|
||||||
t = t.tb_next
|
t = t.tb_next
|
||||||
edb.interaction(t.tb_frame,t)
|
edb.interaction(t.tb_frame,t)
|
||||||
print "Post mortem debugger finished. The "+mainpyfile+" will be restarted"
|
print "Post mortem debugger finished. The "+mainpyfile+" will be restarted"
|
||||||
|
|
||||||
# When invoked as main program, invoke the debugger on a script
|
|
||||||
if __name__=='__main__':
|
if __name__=='__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -86,6 +86,7 @@ class Fundamental(Handler):
|
||||||
grammar = None
|
grammar = None
|
||||||
lexer = None
|
lexer = None
|
||||||
tabber = None
|
tabber = None
|
||||||
|
context = None
|
||||||
colors = {}
|
colors = {}
|
||||||
config = {}
|
config = {}
|
||||||
actions = []
|
actions = []
|
||||||
|
@ -322,9 +323,7 @@ class Fundamental(Handler):
|
||||||
self.window.set_error(err)
|
self.window.set_error(err)
|
||||||
|
|
||||||
def region_added(self, p, newlines):
|
def region_added(self, p, newlines):
|
||||||
if self.tabber is not None:
|
if self.lexer is not None:
|
||||||
self.tabber.region_added(p, newlines)
|
|
||||||
if self.lexer:
|
|
||||||
ydelta = len(newlines) - 1
|
ydelta = len(newlines) - 1
|
||||||
xdelta = len(newlines[-1])
|
xdelta = len(newlines[-1])
|
||||||
ghist = {}
|
ghist = {}
|
||||||
|
@ -345,10 +344,13 @@ class Fundamental(Handler):
|
||||||
ghist.setdefault(name, {})
|
ghist.setdefault(name, {})
|
||||||
ghist[name][newp] = self.ghist[name][gp]
|
ghist[name][newp] = self.ghist[name][gp]
|
||||||
self.ghist = ghist
|
self.ghist = ghist
|
||||||
def region_removed(self, p1, p2):
|
|
||||||
if self.tabber is not None:
|
if self.tabber is not None:
|
||||||
self.tabber.region_removed(p1, p2)
|
self.tabber.region_added(p, newlines)
|
||||||
if self.lexer:
|
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
|
ydelta = p2.y - p1.y
|
||||||
xdelta = p2.x - p1.x
|
xdelta = p2.x - p1.x
|
||||||
ghist = {}
|
ghist = {}
|
||||||
|
@ -371,4 +373,9 @@ class Fundamental(Handler):
|
||||||
ghist.setdefault(name, {})
|
ghist.setdefault(name, {})
|
||||||
ghist[name][newp] = self.ghist[name][gp]
|
ghist[name][newp] = self.ghist[name][gp]
|
||||||
self.ghist = ghist
|
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
|
install = Fundamental.install
|
||||||
|
|
28
mode/dir.py
28
mode/dir.py
|
@ -165,20 +165,20 @@ class Dir(mode.Fundamental):
|
||||||
modename = 'Dir'
|
modename = 'Dir'
|
||||||
grammar = DirGrammar()
|
grammar = DirGrammar()
|
||||||
colors = {
|
colors = {
|
||||||
'dir_blk.start': ('cyan', 'default', 'bold'),
|
'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.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.start': ('blue', 'default', 'bold'),
|
||||||
'dir_dir.dir_name': ('blue', 'default', 'bold'),
|
'dir_dir.dir_name': ('blue', 'default', 'bold'),
|
||||||
'dir_lnk.start': ('green', '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.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.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.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_setid': ('yellow', 'default', 'bold'),
|
||||||
'dir_perm.perm_sticky': ('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 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 point import Point
|
||||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||||
|
|
||||||
|
@ -173,53 +173,6 @@ class PythonTabber(tab.StackTabber):
|
||||||
self._append(token.string, currlvl + w)
|
self._append(token.string, currlvl + w)
|
||||||
return currlvl
|
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):
|
class PythonCheckSyntax(method.Method):
|
||||||
'''Check the syntax of the current python file'''
|
'''Check the syntax of the current python file'''
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
|
@ -318,35 +271,151 @@ class PythonDictCleanup(method.Method):
|
||||||
|
|
||||||
class PythonInsertTripleSquotes(method.Method):
|
class PythonInsertTripleSquotes(method.Method):
|
||||||
'''Insert a triple-quoted string using single-quotes'''
|
'''Insert a triple-quoted string using single-quotes'''
|
||||||
|
_q = "'''"
|
||||||
def _execute(self, w, **vargs):
|
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):
|
for i in range(0, 3):
|
||||||
w.backward()
|
w.backward()
|
||||||
|
class PythonInsertTripleDquotes(PythonInsertTripleSquotes):
|
||||||
class PythonInsertTripleDquotes(method.Method):
|
|
||||||
'''Insert a triple-quoted string using double-quotes'''
|
'''Insert a triple-quoted string using double-quotes'''
|
||||||
def _execute(self, w, **vargs):
|
_q = '"""'
|
||||||
w.insert_string_at_cursor('""""""')
|
|
||||||
for i in range(0, 3):
|
class PythonInitNames(method.Method):
|
||||||
w.backward()
|
'''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):
|
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):
|
def get_candidates(self, s, w=None):
|
||||||
old_window = w.buffer.method.old_window
|
return [n for n in self._get_dict(w) if n.startswith(s)]
|
||||||
names = []
|
class PythonFunctionCompleter(PythonNameCompleter):
|
||||||
names.extend(old_window.mode.get_classes())
|
def _get_dict(self, w):
|
||||||
names.extend(old_window.mode.get_functions())
|
return w.buffer.method.old_window.mode.context.get_functions()
|
||||||
return [n for n in names if n.startswith(s)]
|
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):
|
class Python(mode.Fundamental):
|
||||||
modename = 'Python'
|
modename = 'Python'
|
||||||
|
@ -382,6 +451,20 @@ class Python(mode.Fundamental):
|
||||||
"pythonfunction": PythonFunctionCompleter(),
|
"pythonfunction": PythonFunctionCompleter(),
|
||||||
"pythonclass": PythonClassCompleter(),
|
"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):
|
def __init__(self, w):
|
||||||
mode.Fundamental.__init__(self, w)
|
mode.Fundamental.__init__(self, w)
|
||||||
self.add_bindings('close-paren', (')',))
|
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-dict-cleanup', ('C-c h',))
|
||||||
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
|
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
|
||||||
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
|
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
|
||||||
|
self.context = PythonContext(self)
|
||||||
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
|
|
||||||
|
|
||||||
install = Python.install
|
install = Python.install
|
||||||
|
|
Loading…
Reference in New Issue