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()
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
"""
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."""
self.Bind(wx.EVT_CHAR, self.OnChar)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+ # Assign handler for the context menu
+ self.Bind(wx.EVT_CONTEXT_MENU, self.OnContextMenu)
+ self.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI)
+
+ # Assign handlers for edit events
+ self.Bind(wx.EVT_MENU, lambda evt: self.Cut(), id=wx.ID_CUT)
+ self.Bind(wx.EVT_MENU, lambda evt: self.Copy(), id=wx.ID_COPY)
+ self.Bind(wx.EVT_MENU, lambda evt: self.CopyWithPrompts(), id=frame.ID_COPY_PLUS)
+ self.Bind(wx.EVT_MENU, lambda evt: self.Paste(), id=wx.ID_PASTE)
+ self.Bind(wx.EVT_MENU, lambda evt: self.PasteAndRun(), id=frame.ID_PASTE_PLUS)
+ self.Bind(wx.EVT_MENU, lambda evt: self.SelectAll(), id=wx.ID_SELECTALL)
+ self.Bind(wx.EVT_MENU, lambda evt: self.Clear(), id=wx.ID_CLEAR)
+ self.Bind(wx.EVT_MENU, lambda evt: self.Undo(), id=wx.ID_UNDO)
+ self.Bind(wx.EVT_MENU, lambda evt: self.Redo(), id=wx.ID_REDO)
+
+
# Assign handler for idle time.
self.waiting = False
self.Bind(wx.EVT_IDLE, self.OnIdle)
wx.CallAfter(self.ScrollToLine, 0)
+ def clearHistory(self):
+ self.history = []
+ self.historyIndex = -1
+ dispatcher.send(signal="Shell.clearHistory")
+
def destroy(self):
del self.interp
def showIntro(self, text=''):
"""Display introductory text in the shell."""
if text:
- if not text.endswith(os.linesep):
- text += os.linesep
self.write(text)
try:
- self.write(self.interp.introText)
+ if self.interp.introText:
+ if text and not text.endswith(os.linesep):
+ self.write(os.linesep)
+ self.write(self.interp.introText)
except AttributeError:
pass
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 = \
# 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.
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 (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:
+ elif shiftDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]:
self.OnShowCompHistory()
# Ctrl+Return (Ctrl+Enter) is used to insert a line break.
- elif controlDown and key == wx.WXK_RETURN:
+ elif controlDown and key in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]:
if self.CallTipActive():
self.CallTipCancel()
if currpos == endpos:
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(']'), wx.WXK_NUMPAD_ADD):
dispatcher.send(signal='FontIncrease')
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.
config.WriteBool('View/ShowLineNumbers', self.lineNumbers)
config.WriteInt('View/Zoom/Shell', self.GetZoom())
+ def GetContextMenu(self):
+ """
+ Create and return a context menu for the shell.
+ This is used instead of the scintilla default menu
+ in order to correctly respect our immutable buffer.
+ """
+ menu = wx.Menu()
+ menu.Append(wx.ID_UNDO, "Undo")
+ menu.Append(wx.ID_REDO, "Redo")
+
+ menu.AppendSeparator()
+
+ menu.Append(wx.ID_CUT, "Cut")
+ menu.Append(wx.ID_COPY, "Copy")
+ menu.Append(frame.ID_COPY_PLUS, "Copy Plus")
+ menu.Append(wx.ID_PASTE, "Paste")
+ menu.Append(frame.ID_PASTE_PLUS, "Paste Plus")
+ menu.Append(wx.ID_CLEAR, "Clear")
+
+ menu.AppendSeparator()
+
+ menu.Append(wx.ID_SELECTALL, "Select All")
+ return menu
+
+ def OnContextMenu(self, evt):
+ menu = self.GetContextMenu()
+ self.PopupMenu(menu)
+
+ def OnUpdateUI(self, evt):
+ id = evt.Id
+ if id in (wx.ID_CUT, wx.ID_CLEAR):
+ evt.Enable(self.CanCut())
+ elif id in (wx.ID_COPY, frame.ID_COPY_PLUS):
+ evt.Enable(self.CanCopy())
+ elif id in (wx.ID_PASTE, frame.ID_PASTE_PLUS):
+ evt.Enable(self.CanPaste())
+ elif id == wx.ID_UNDO:
+ evt.Enable(self.CanUndo())
+ elif id == wx.ID_REDO:
+ evt.Enable(self.CanRedo())
+
+
## NOTE: The DnD of file names is disabled until I can figure out how