From: Robin Dunn Date: Sat, 9 Feb 2002 00:41:10 +0000 (+0000) Subject: New PyCrust source from Patrick's CVS X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/167a4bb9fdd5745810fbfb0ab420c207a99207bb New PyCrust source from Patrick's CVS git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14078 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/wxPython/lib/PyCrust/filling.py b/wxPython/wxPython/lib/PyCrust/filling.py index c49708c8d8..b7a29eda78 100644 --- a/wxPython/wxPython/lib/PyCrust/filling.py +++ b/wxPython/wxPython/lib/PyCrust/filling.py @@ -52,9 +52,9 @@ class FillingTree(wxTreeCtrl): objtype = type(object) if objtype is types.DictType: dict = object - elif (objtype in (types.ClassType, types.InstanceType, \ - types.ModuleType)) \ - or hasattr(object, '__class__'): + elif (objtype in (types.ClassType, \ + types.InstanceType, \ + types.ModuleType)): for key in introspect.getAttributeNames(object): # Believe it or not, some attributes can disappear, such as # the exc_traceback attribute of the sys module. So this is @@ -74,7 +74,7 @@ class FillingTree(wxTreeCtrl): if not children: return list = children.keys() - list.sort() + list.sort(lambda x, y: cmp(x.lower(), y.lower())) for item in list: itemtext = str(item) # Show string dictionary items with single quotes, except for @@ -315,4 +315,4 @@ class App(wxApp): - \ No newline at end of file + diff --git a/wxPython/wxPython/lib/PyCrust/introspect.py b/wxPython/wxPython/lib/PyCrust/introspect.py index 237ed198e5..7a09a40cd6 100644 --- a/wxPython/wxPython/lib/PyCrust/introspect.py +++ b/wxPython/wxPython/lib/PyCrust/introspect.py @@ -7,6 +7,7 @@ __version__ = "$Revision$"[11:-2] import inspect import string +import types def getAutoCompleteList(command='', locals=None, includeMagic=1, \ includeSingle=1, includeDouble=1): @@ -35,11 +36,13 @@ def getAttributeNames(object, includeMagic=1, includeSingle=1, includeDouble=1): for item in getAllAttributeNames(object): dict[item] = None attributes += dict.keys() - attributes.sort(lambda x, y: cmp(x.lower(), y.lower())) + attributes.sort(lambda x, y: cmp(x.upper(), y.upper())) if not includeSingle: attributes = filter(lambda item: item[0]!='_' or item[1]=='_', attributes) if not includeDouble: attributes = filter(lambda item: item[:2]!='__', attributes) + # Make sure we haven't picked up any bogus attributes somehow. + attributes = [attribute for attribute in attributes if hasattr(object, attribute)] return attributes def getAllAttributeNames(object): @@ -47,12 +50,22 @@ def getAllAttributeNames(object): Recursively walk through a class and all base classes. """ + # !!! + # !!! Do Not use hasattr() as a test anywhere in this function, + # !!! because it is unreliable with remote objects - xmlrpc, soap, etc. + # !!! attributes = [] # Wake up sleepy objects - a hack for ZODB objects in "ghost" state. wakeupcall = dir(object) del wakeupcall # Get attributes available through the normal convention. attributes += dir(object) + try: + keys = object.__dict__.keys() + except: + pass + else: + attributes += keys # For a class instance, get the attributes for the class. if hasattr(object, '__class__'): # Break a circular reference. This happens with extension classes. @@ -61,9 +74,18 @@ def getAllAttributeNames(object): else: attributes += getAllAttributeNames(object.__class__) # Also get attributes from any and all parent classes. - if hasattr(object, '__bases__'): - for base in object.__bases__: - attributes += getAllAttributeNames(base) + try: + bases = object.__bases__ + except: + pass + else: + if isinstance(bases, type(())): + for base in bases: + if type(base) is types.TypeType: + # Break a circular reference. Happens in Python 2.2. + pass + else: + attributes += getAllAttributeNames(base) return attributes def getCallTip(command='', locals=None): diff --git a/wxPython/wxPython/lib/PyCrust/shell.py b/wxPython/wxPython/lib/PyCrust/shell.py index 37f380fe14..245f80bc42 100644 --- a/wxPython/wxPython/lib/PyCrust/shell.py +++ b/wxPython/wxPython/lib/PyCrust/shell.py @@ -31,8 +31,7 @@ if wxPlatform == '__WXMSW__': } # Versions of wxPython prior to 2.3.2 had a sizing bug on Win platform. # The font was 2 points too large. So we need to reduce the font size. - if ((wxMAJOR_VERSION, wxMINOR_VERSION) == (2, 3) and wxRELEASE_NUMBER < 2) \ - or (wxMAJOR_VERSION <= 2 and wxMINOR_VERSION <= 2): + if (wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER) < (2, 3, 2): faces['size'] -= 2 faces['lnsize'] -= 2 else: # GTK @@ -72,8 +71,28 @@ class ShellFacade: self.__dict__[method] = getattr(other, method) d = self.__dict__ d['other'] = other - d['help'] = 'There is no help available, yet.' - + d['helpText'] = \ +""" +* Key bindings: +Home Go to the beginning of the command or line. +Shift+Home Select to the beginning of the command or line. +Shift+End Select to the end of the line. +End Go to the end of the line. +Ctrl+C Copy selected text, removing prompts. +Ctrl+Shift+C Copy selected text, retaining prompts. +Ctrl+X Cut selected text. +Ctrl+V Paste from clipboard. +Ctrl+Up Arrow Retrieve Previous History item. +Alt+P Retrieve Previous History item. +Ctrl+Down Arrow Retrieve Next History item. +Alt+N Retrieve Next History item. +F8 Command-completion of History item. + (Type a few characters of a previous command and then press F8.) +""" + + def help(self): + """Display some useful information about how to use the shell.""" + self.write(self.helpText) def __getattr__(self, name): if hasattr(self.other, name): @@ -138,10 +157,9 @@ class Shell(wxStyledTextCtrl): stdout=PseudoFileOut(self.writeOut), \ stderr=PseudoFileErr(self.writeErr), \ *args, **kwds) - # Keep track of the most recent prompt starting and ending positions. - self.promptPos = [0, 0] - # Keep track of the most recent non-continuation prompt. - self.prompt1Pos = [0, 0] + # Keep track of the last non-continuation prompt positions. + self.promptPosStart = 0 + self.promptPosEnd = 0 # Keep track of multi-line commands. self.more = 0 # Create the command history. Commands are added into the front of @@ -253,7 +271,7 @@ class Shell(wxStyledTextCtrl): """Configure font size, typeface and color for lexer.""" # Default style - self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) + self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d,back:%(backcol)s" % faces) self.StyleClearAll() @@ -287,7 +305,7 @@ class Shell(wxStyledTextCtrl): return key = event.KeyCode() currpos = self.GetCurrentPos() - stoppos = self.promptPos[1] + stoppos = self.promptPosEnd if key == ord('.'): # The dot or period key activates auto completion. # Get the command between the prompt and the cursor. @@ -317,7 +335,6 @@ class Shell(wxStyledTextCtrl): altDown = event.AltDown() shiftDown = event.ShiftDown() currpos = self.GetCurrentPos() - stoppos = self.promptPos[1] # Return is used to submit a command to the interpreter. if key == WXK_RETURN: if self.AutoCompActive(): self.AutoCompCancel() @@ -330,16 +347,20 @@ class Shell(wxStyledTextCtrl): elif controlDown and altDown: event.Skip() # Cut to the clipboard. - elif controlDown and key in (ord('X'), ord('x')): + elif (controlDown and key in (ord('X'), ord('x'))) \ + or (shiftDown and key == WXK_DELETE): self.Cut() # Copy to the clipboard. - elif controlDown and not shiftDown and key in (ord('C'), ord('c')): + elif controlDown and not shiftDown \ + and key in (ord('C'), ord('c'), WXK_INSERT): self.Copy() # Copy to the clipboard, including prompts. - elif controlDown and shiftDown and key in (ord('C'), ord('c')): + elif controlDown and shiftDown \ + and key in (ord('C'), ord('c'), WXK_INSERT): self.CopyWithPrompts() # Paste from the clipboard. - elif controlDown and key in (ord('V'), ord('v')): + elif (controlDown and key in (ord('V'), ord('v'), WXK_INSERT)) \ + or (shiftDown and key == WXK_INSERT): self.Paste() # Retrieve the previous command from the history buffer. elif (controlDown and key == WXK_UP) \ @@ -354,22 +375,23 @@ class Shell(wxStyledTextCtrl): self.OnHistorySearch() # Home needs to be aware of the prompt. elif key == WXK_HOME: - if currpos >= stoppos: + home = self.promptPosEnd + if currpos >= home: if event.ShiftDown(): # Select text from current position to end of prompt. - self.SetSelection(self.GetCurrentPos(), stoppos) + self.SetSelection(self.GetCurrentPos(), home) else: - self.SetCurrentPos(stoppos) - self.SetAnchor(stoppos) + self.SetCurrentPos(home) + self.SetAnchor(home) else: event.Skip() # Basic navigation keys should work anywhere. elif key in (WXK_END, WXK_LEFT, WXK_RIGHT, WXK_UP, WXK_DOWN, \ WXK_PRIOR, WXK_NEXT): event.Skip() - # Don't backspace over the latest prompt. + # Don't backspace over the latest non-continuation prompt. elif key == WXK_BACK: - if currpos > self.prompt1Pos[1]: + if currpos > self.promptPosEnd: event.Skip() # Only allow these keys after the latest prompt. elif key in (WXK_TAB, WXK_DELETE): @@ -459,23 +481,23 @@ class Shell(wxStyledTextCtrl): if thepos == endpos: self.interp.more = 0 if self.getCommand(): - command = self.GetTextRange(self.prompt1Pos[1], endpos) + command = self.GetTextRange(self.promptPosEnd, endpos) else: # This is a hack, now that we allow editing of previous # lines, which throws off our promptPos values. newend = endpos - len(self.getCommand(rstrip=0)) - command = self.GetTextRange(self.prompt1Pos[1], newend) + command = self.GetTextRange(self.promptPosEnd, newend) command = command.replace(os.linesep + sys.ps2, '\n') self.push(command) # Or replace the current command with the other command. - elif thepos < self.prompt1Pos[0]: + elif thepos < self.promptPosStart: theline = self.GetCurrentLine() command = self.getCommand(rstrip=0) # If the new line contains a command (even an invalid one). if command: command = self.getMultilineCommand() self.SetCurrentPos(endpos) - startpos = self.prompt1Pos[1] + startpos = self.promptPosEnd self.SetSelection(startpos, endpos) self.ReplaceSelection('') self.write(command) @@ -485,7 +507,7 @@ class Shell(wxStyledTextCtrl): self.SetCurrentPos(thepos) self.SetAnchor(thepos) # Or add a new line to the current single or multi-line command. - elif thepos > self.prompt1Pos[1]: + elif thepos > self.promptPosEnd: self.write(os.linesep) self.more = 1 self.prompt() @@ -601,12 +623,11 @@ class Shell(wxStyledTextCtrl): prompt = str(sys.ps1) pos = self.GetCurLine()[1] if pos > 0: self.write(os.linesep) - self.promptPos[0] = self.GetCurrentPos() - if not self.more: self.prompt1Pos[0] = self.GetCurrentPos() + if not self.more: + self.promptPosStart = self.GetCurrentPos() self.write(prompt) - self.promptPos[1] = self.GetCurrentPos() if not self.more: - self.prompt1Pos[1] = self.GetCurrentPos() + self.promptPosEnd = self.GetCurrentPos() # Keep the undo feature from undoing previous responses. self.EmptyUndoBuffer() # XXX Add some autoindent magic here if more. @@ -732,8 +753,8 @@ class Shell(wxStyledTextCtrl): def CanCut(self): """Return true if text is selected and can be cut.""" if self.GetSelectionStart() != self.GetSelectionEnd() \ - and self.GetSelectionStart() >= self.prompt1Pos[1] \ - and self.GetSelectionEnd() >= self.prompt1Pos[1]: + and self.GetSelectionStart() >= self.promptPosEnd \ + and self.GetSelectionEnd() >= self.promptPosEnd: return 1 else: return 0 @@ -751,7 +772,7 @@ class Shell(wxStyledTextCtrl): def CanEdit(self): """Return true if editing should succeed.""" - return self.GetCurrentPos() >= self.prompt1Pos[1] + return self.GetCurrentPos() >= self.promptPosEnd def Cut(self): """Remove selection and place it on the clipboard."""