diff -r 000000000000 -r ca70ae20a155 src/extras/pyrepl/cmdrepl.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/extras/pyrepl/cmdrepl.py Tue Feb 16 10:07:05 2010 +0530 @@ -0,0 +1,118 @@ +# Copyright 2000-2004 Michael Hudson mwh@python.net +# +# All Rights Reserved +# +# Portions Copyright (c) 2005 Nokia Corporation +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose is hereby granted without fee, +# provided that the above copyright notice appear in all copies and +# that both that copyright notice and this permission notice appear in +# supporting documentation. +# +# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, +# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Wedge pyrepl behaviour into cmd.Cmd-derived classes. + +replize, when given a subclass of cmd.Cmd, returns a class that +behaves almost identically to the supplied class, except that it uses +pyrepl instead if raw_input. + +It was designed to let you do this: + +>>> import pdb +>>> from pyrepl import replize +>>> pdb.Pdb = replize(pdb.Pdb) + +which is in fact done by the `pythoni' script that comes with +pyrepl.""" + +from __future__ import nested_scopes + +from pyrepl import completing_reader as cr, reader, completer +from pyrepl.completing_reader import CompletingReader as CR +import cmd + +class CmdReader(CR): + def collect_keymap(self): + return super(CmdReader, self).collect_keymap() + ( + ("\\M-\\n", "invalid-key"), + ("\\n", "accept")) + + CR_init = CR.__init__ + def __init__(self, completions, console): + self.CR_init(console) + self.completions = completions + + def get_completions(self, stem): + if len(stem) != self.pos: + return [] + return cr.uniqify([s for s in self.completions + if s.startswith(stem)]) + +def replize(klass, console, history_across_invocations=1): + + """Return a subclass of the cmd.Cmd-derived klass that uses + pyrepl instead of readline. + + Raises a ValueError if klass does not derive from cmd.Cmd. + + The optional history_across_invocations parameter (default 1) + controls whether instances of the returned class share + histories.""" + + completions = [s[3:] + for s in completer.get_class_members(klass) + if s.startswith("do_")] + + if not issubclass(klass, cmd.Cmd): + raise Exception +# if klass.cmdloop.im_class is not cmd.Cmd: +# print "this may not work" + + class CmdRepl(klass): + k_init = klass.__init__ + + if history_across_invocations: + _CmdRepl__history = [] + def __init__(self, *args, **kw): + self.k_init(*args, **kw) + self.__reader = CmdReader(completions,console) + self.__reader.history = CmdRepl._CmdRepl__history + self.__reader.historyi = len(CmdRepl._CmdRepl__history) + else: + def __init__(self, *args, **kw): + self.k_init(*args, **kw) + self.__reader = CmdReader(completions,console) + + def cmdloop(self, intro=None): + self.preloop() + if intro is not None: + self.intro = intro + if self.intro: + print self.intro + stop = None + while not stop: + if self.cmdqueue: + line = self.cmdqueue[0] + del self.cmdqueue[0] + else: + try: + self.__reader.ps1 = self.prompt + line = self.__reader.readline() + except EOFError: + line = "EOF" + line = self.precmd(line) + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + self.postloop() + + CmdRepl.__name__ = "replize(%s.%s)"%(klass.__module__, klass.__name__) + return CmdRepl +