X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/02b800ce7c2bb1c1f08075f22be2e7412124b47f..9d5244b1eeb78a5b9be933045edb949f319e26e9:/wxPython/wx/py/shell.py?ds=sidebyside diff --git a/wxPython/wx/py/shell.py b/wxPython/wx/py/shell.py index da3f2751d2..fe60b38221 100644 --- a/wxPython/wx/py/shell.py +++ b/wxPython/wx/py/shell.py @@ -95,22 +95,27 @@ class ShellFrame(frame.Frame, frame.ShellFrameMixin): dialog.Destroy() + def OnHelp(self, event): + """Show a help dialog.""" + frame.ShellFrameMixin.OnHelp(self, event) + + def LoadSettings(self): if self.config is not None: frame.ShellFrameMixin.LoadSettings(self) frame.Frame.LoadSettings(self, self.config) self.shell.LoadSettings(self.config) - def SaveSettings(self): + def SaveSettings(self, force=False): if self.config is not None: frame.ShellFrameMixin.SaveSettings(self) - if self.autoSaveSettings: + if self.autoSaveSettings or force: frame.Frame.SaveSettings(self, self.config) self.shell.SaveSettings(self.config) def DoSaveSettings(self): if self.config is not None: - self.SaveSettings() + self.SaveSettings(force=True) self.config.Flush() @@ -142,10 +147,9 @@ Ctrl+[ Decrease font size. Ctrl+= Default font size. Ctrl-Space Show Auto Completion. Ctrl-Alt-Space Show Call Tip. -Alt+Shift+C Clear Screen. Shift+Enter Complete Text from History. -Ctrl+F Search (backwards) TODO: regexp-wholeWords-... -Ctrl+G Search next +Ctrl+F Search +F3 Search next Ctrl+H "hide" lines containing selection / "unhide" F12 on/off "free-edit" mode """ @@ -164,6 +168,7 @@ class ShellFacade: d = self.__dict__ d['other'] = other d['helpText'] = HELP_TEXT + d['this'] = other.this def help(self): """Display some useful information about how to use the shell.""" @@ -316,6 +321,11 @@ class Shell(editwindow.EditWindow): wx.CallAfter(self.ScrollToLine, 0) + def clearHistory(self): + self.history = [] + self.historyIndex = -1 + dispatcher.send(signal="Shell.clearHistory") + def destroy(self): del self.interp @@ -344,7 +354,7 @@ class Shell(editwindow.EditWindow): def setBuiltinKeywords(self): """Create pseudo keywords as part of builtins. - This sets `close`, `exit` and `quit` to a helpful string. + This sets "close", "exit" and "quit" to a helpful string. """ import __builtin__ __builtin__.close = __builtin__.exit = __builtin__.quit = \ @@ -407,11 +417,11 @@ Platform: %s""" % \ # commands/responses. if not self.CanEdit(): return - key = event.KeyCode() + key = event.GetKeyCode() currpos = self.GetCurrentPos() stoppos = self.promptPosEnd # Return (Enter) needs to be ignored in this handler. - if key == wx.WXK_RETURN: + if key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: pass elif key in self.autoCompleteKeys: # Usually the dot (period) key activates auto completion. @@ -442,11 +452,12 @@ Platform: %s""" % \ def OnKeyDown(self, event): """Key down event handler.""" - key = event.KeyCode() + key = event.GetKeyCode() # If the auto-complete window is up let it do its thing. if self.AutoCompActive(): event.Skip() return + # Prevent modification of previously submitted # commands/responses. controlDown = event.ControlDown() @@ -456,7 +467,7 @@ Platform: %s""" % \ endpos = self.GetTextLength() selecting = self.GetSelectionStart() != self.GetSelectionEnd() - if controlDown and key in (ord('H'), ord('h')): + if controlDown and shiftDown and key in (ord('F'), ord('f')): li = self.GetCurrentLine() m = self.MarkerGet(li) if m & 1<<0: @@ -506,55 +517,71 @@ Platform: %s""" % \ # Return (Enter) is used to submit a command to the # interpreter. - if (not controlDown and not shiftDown and not altDown) and key == wx.WXK_RETURN: + if (not controlDown and not shiftDown and not altDown) and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: if self.CallTipActive(): self.CallTipCancel() self.processLine() - #Complete Text (from already typed words) - elif shiftDown and key == wx.WXK_RETURN: + + # Complete Text (from already typed words) + elif shiftDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: self.OnShowCompHistory() - # Ctrl+Return (Cntrl+Enter) is used to insert a line break. - elif controlDown and key == wx.WXK_RETURN: + + # Ctrl+Return (Ctrl+Enter) is used to insert a line break. + elif controlDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: if self.CallTipActive(): self.CallTipCancel() if currpos == endpos: self.processLine() else: self.insertLineBreak() + # Let Ctrl-Alt-* get handled normally. elif controlDown and altDown: event.Skip() + # Clear the current, unexecuted command. elif key == wx.WXK_ESCAPE: if self.CallTipActive(): event.Skip() else: self.clearCommand() + + # Clear the current command + elif key == wx.WXK_BACK and controlDown and shiftDown: + self.clearCommand() + # Increase font size. - elif controlDown and key in (ord(']'),): + elif controlDown and key in (ord(']'), wx.WXK_NUMPAD_ADD): dispatcher.send(signal='FontIncrease') + # Decrease font size. - elif controlDown and key in (ord('['),): + elif controlDown and key in (ord('['), wx.WXK_NUMPAD_SUBTRACT): dispatcher.send(signal='FontDecrease') + # Default font size. - elif controlDown and key in (ord('='),): + elif controlDown and key in (ord('='), wx.WXK_NUMPAD_DIVIDE): dispatcher.send(signal='FontDefault') + # Cut to the clipboard. elif (controlDown and key in (ord('X'), ord('x'))) \ - or (shiftDown and key == wx.WXK_DELETE): + or (shiftDown and key == wx.WXK_DELETE): self.Cut() + # Copy to the clipboard. elif controlDown and not shiftDown \ - and key in (ord('C'), ord('c'), wx.WXK_INSERT): + and key in (ord('C'), ord('c'), wx.WXK_INSERT): self.Copy() + # Copy to the clipboard, including prompts. elif controlDown and shiftDown \ - and key in (ord('C'), ord('c'), wx.WXK_INSERT): + and key in (ord('C'), ord('c'), wx.WXK_INSERT): self.CopyWithPrompts() + # Copy to the clipboard, including prefixed prompts. elif altDown and not controlDown \ - and key in (ord('C'), ord('c'), wx.WXK_INSERT): + and key in (ord('C'), ord('c'), wx.WXK_INSERT): self.CopyWithPromptsPrefixed() + # Home needs to be aware of the prompt. elif key == wx.WXK_HOME: home = self.promptPosEnd @@ -565,6 +592,7 @@ Platform: %s""" % \ self.EnsureCaretVisible() else: event.Skip() + # # The following handlers modify text, so we need to see if # there is a selection that includes text prior to the prompt. @@ -572,61 +600,78 @@ Platform: %s""" % \ # Don't modify a selection with text prior to the prompt. elif selecting and key not in NAVKEYS and not self.CanEdit(): pass + # Paste from the clipboard. elif (controlDown and not shiftDown and key in (ord('V'), ord('v'))) \ or (shiftDown and not controlDown and key == wx.WXK_INSERT): self.Paste() + + # manually invoke AutoComplete and Calltips elif controlDown and key == wx.WXK_SPACE: - """AutoComplete and Calltips manually.""" - self.OnCallTipAutoCompleteManually (shiftDown) + self.OnCallTipAutoCompleteManually(shiftDown) + # Paste from the clipboard, run commands. elif controlDown and shiftDown and key in (ord('V'), ord('v')): self.PasteAndRun() + # Replace with the previous command from the history buffer. elif (controlDown and key == wx.WXK_UP) \ or (altDown and key in (ord('P'), ord('p'))): self.OnHistoryReplace(step=+1) + # Replace with the next command from the history buffer. elif (controlDown and key == wx.WXK_DOWN) \ or (altDown and key in (ord('N'), ord('n'))): self.OnHistoryReplace(step=-1) + # Insert the previous command from the history buffer. elif (shiftDown and key == wx.WXK_UP) and self.CanEdit(): self.OnHistoryInsert(step=+1) + # Insert the next command from the history buffer. elif (shiftDown and key == wx.WXK_DOWN) and self.CanEdit(): self.OnHistoryInsert(step=-1) + # Search up the history for the text in front of the cursor. elif key == wx.WXK_F8: self.OnHistorySearch() + # Don't backspace over the latest non-continuation prompt. elif key == wx.WXK_BACK: if selecting and self.CanEdit(): event.Skip() elif currpos > self.promptPosEnd: event.Skip() + # Only allow these keys after the latest prompt. elif key in (wx.WXK_TAB, wx.WXK_DELETE): if self.CanEdit(): event.Skip() + # Don't toggle between insert mode and overwrite mode. elif key == wx.WXK_INSERT: pass + # Don't allow line deletion. elif controlDown and key in (ord('L'), ord('l')): pass + # Don't allow line transposition. elif controlDown and key in (ord('T'), ord('t')): pass + # Basic navigation keys should work anywhere. elif key in NAVKEYS: event.Skip() + # Protect the readonly portion of the shell. elif not self.CanEdit(): pass + else: event.Skip() + def OnShowCompHistory(self): """Show possible autocompletion Words from already typed words.""" @@ -878,6 +923,7 @@ Platform: %s""" % \ if command != '' \ and (len(self.history) == 0 or command != self.history[0]): self.history.insert(0, command) + dispatcher.send(signal="Shell.addHistory", command=command) def write(self, text): """Display text in the shell. @@ -1087,8 +1133,8 @@ Platform: %s""" % \ ctindex = ctips.find ('(') if ctindex != -1 and not self.CallTipActive(): #insert calltip, if current pos is '(', otherwise show it only - self.autoCallTipShow(ctips[:ctindex + 1], \ - self.GetCharAt(currpos - 1) == ord('(') and self.GetCurrentPos() == self.GetTextLength(),\ + self.autoCallTipShow(ctips[:ctindex + 1], + self.GetCharAt(currpos - 1) == ord('(') and self.GetCurrentPos() == self.GetTextLength(), True) @@ -1213,52 +1259,64 @@ Platform: %s""" % \ self.write(command) wx.TheClipboard.Close() + def PasteAndRun(self): """Replace selection with clipboard contents, run commands.""" + text = '' if wx.TheClipboard.Open(): - ps1 = str(sys.ps1) - ps2 = str(sys.ps2) if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)): data = wx.TextDataObject() if wx.TheClipboard.GetData(data): - endpos = self.GetTextLength() - self.SetCurrentPos(endpos) - startpos = self.promptPosEnd - self.SetSelection(startpos, endpos) - self.ReplaceSelection('') text = data.GetText() - text = text.lstrip() - text = self.fixLineEndings(text) - text = self.lstripPrompt(text) - text = text.replace(os.linesep + ps1, '\n') - text = text.replace(os.linesep + ps2, '\n') - text = text.replace(os.linesep, '\n') - lines = text.split('\n') - commands = [] - command = '' - for line in lines: - if line.strip() == ps2.strip(): - # If we are pasting from something like a - # web page that drops the trailing space - # from the ps2 prompt of a blank line. - line = '' - if line.strip() != '' and line.lstrip() == line: - # New command. - if command: - # Add the previous command to the list. - commands.append(command) - # Start a new command, which may be multiline. - command = line - else: - # Multiline command. Add to the command. - command += '\n' - command += line - commands.append(command) - for command in commands: - command = command.replace('\n', os.linesep + ps2) - self.write(command) - self.processLine() wx.TheClipboard.Close() + if text: + self.Execute(text) + + + def Execute(self, text): + """Replace selection with text and run commands.""" + ps1 = str(sys.ps1) + ps2 = str(sys.ps2) + endpos = self.GetTextLength() + self.SetCurrentPos(endpos) + startpos = self.promptPosEnd + self.SetSelection(startpos, endpos) + self.ReplaceSelection('') + text = text.lstrip() + text = self.fixLineEndings(text) + text = self.lstripPrompt(text) + text = text.replace(os.linesep + ps1, '\n') + text = text.replace(os.linesep + ps2, '\n') + text = text.replace(os.linesep, '\n') + lines = text.split('\n') + commands = [] + command = '' + for line in lines: + if line.strip() == ps2.strip(): + # If we are pasting from something like a + # web page that drops the trailing space + # from the ps2 prompt of a blank line. + line = '' + lstrip = line.lstrip() + if line.strip() != '' and lstrip == line and \ + lstrip[:4] not in ['else','elif'] and \ + lstrip[:6] != 'except': + # New command. + if command: + # Add the previous command to the list. + commands.append(command) + # Start a new command, which may be multiline. + command = line + else: + # Multiline command. Add to the command. + command += '\n' + command += line + commands.append(command) + for command in commands: + command = command.replace('\n', os.linesep + ps2) + self.write(command) + self.processLine() + def wrap(self, wrap=True): """Sets whether text is word wrapped."""