src/extras/pyrepl/cmdrepl.py
author Vijayan <ts.vijayan@nokia.com>
Tue, 16 Feb 2010 10:07:05 +0530
changeset 0 ca70ae20a155
permissions -rw-r--r--
Base Python2.0 code
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     1
#   Copyright 2000-2004 Michael Hudson mwh@python.net
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     2
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     3
#                        All Rights Reserved
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     4
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     5
# Portions Copyright (c) 2005 Nokia Corporation 
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     6
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     7
# Permission to use, copy, modify, and distribute this software and
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     8
# its documentation for any purpose is hereby granted without fee,
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
     9
# provided that the above copyright notice appear in all copies and
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    10
# that both that copyright notice and this permission notice appear in
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    11
# supporting documentation.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    12
#
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    13
# THE AUTHOR MICHAEL HUDSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    14
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    15
# AND FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    16
# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    17
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    18
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    19
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    20
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    21
"""Wedge pyrepl behaviour into cmd.Cmd-derived classes.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    22
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    23
replize, when given a subclass of cmd.Cmd, returns a class that
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    24
behaves almost identically to the supplied class, except that it uses
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    25
pyrepl instead if raw_input.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    26
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    27
It was designed to let you do this:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    28
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    29
>>> import pdb
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    30
>>> from pyrepl import replize
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    31
>>> pdb.Pdb = replize(pdb.Pdb)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    32
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    33
which is in fact done by the `pythoni' script that comes with
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    34
pyrepl."""
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    35
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    36
from __future__ import nested_scopes
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    37
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    38
from pyrepl import completing_reader as cr, reader, completer
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    39
from pyrepl.completing_reader import CompletingReader as CR
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    40
import cmd
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    41
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    42
class CmdReader(CR):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    43
    def collect_keymap(self):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    44
        return super(CmdReader, self).collect_keymap() + (
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    45
            ("\\M-\\n", "invalid-key"),
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    46
            ("\\n", "accept"))
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    47
    
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    48
    CR_init = CR.__init__
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    49
    def __init__(self, completions, console):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    50
        self.CR_init(console)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    51
        self.completions = completions
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    52
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    53
    def get_completions(self, stem):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    54
        if len(stem) != self.pos:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    55
            return []
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    56
        return cr.uniqify([s for s in self.completions
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    57
                           if s.startswith(stem)])
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    58
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    59
def replize(klass, console, history_across_invocations=1):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    60
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    61
    """Return a subclass of the cmd.Cmd-derived klass that uses
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    62
    pyrepl instead of readline.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    63
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    64
    Raises a ValueError if klass does not derive from cmd.Cmd.
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    65
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    66
    The optional history_across_invocations parameter (default 1)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    67
    controls whether instances of the returned class share
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    68
    histories."""
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    69
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    70
    completions = [s[3:]
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    71
                   for s in completer.get_class_members(klass)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    72
                   if s.startswith("do_")]
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    73
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    74
    if not issubclass(klass, cmd.Cmd):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    75
        raise Exception
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    76
#    if klass.cmdloop.im_class is not cmd.Cmd:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    77
#        print "this may not work"
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    78
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    79
    class CmdRepl(klass):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    80
        k_init = klass.__init__
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    81
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    82
        if history_across_invocations:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    83
            _CmdRepl__history = []
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    84
            def __init__(self, *args, **kw):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    85
                self.k_init(*args, **kw)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    86
                self.__reader = CmdReader(completions,console)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    87
                self.__reader.history = CmdRepl._CmdRepl__history
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    88
                self.__reader.historyi = len(CmdRepl._CmdRepl__history)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    89
        else:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    90
            def __init__(self, *args, **kw):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    91
                self.k_init(*args, **kw)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    92
                self.__reader = CmdReader(completions,console)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    93
        
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    94
        def cmdloop(self, intro=None):
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    95
            self.preloop()
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    96
            if intro is not None:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    97
                self.intro = intro
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    98
            if self.intro:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
    99
                print self.intro
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   100
            stop = None
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   101
            while not stop:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   102
                if self.cmdqueue:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   103
                    line = self.cmdqueue[0]
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   104
                    del self.cmdqueue[0]
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   105
                else:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   106
                    try:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   107
                        self.__reader.ps1 = self.prompt
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   108
                        line = self.__reader.readline()
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   109
                    except EOFError:
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   110
                        line = "EOF"
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   111
                line = self.precmd(line)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   112
                stop = self.onecmd(line)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   113
                stop = self.postcmd(stop, line)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   114
            self.postloop()
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   115
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   116
    CmdRepl.__name__ = "replize(%s.%s)"%(klass.__module__, klass.__name__)
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   117
    return CmdRepl
ca70ae20a155 Base Python2.0 code
Vijayan <ts.vijayan@nokia.com>
parents:
diff changeset
   118