📄 shell.py
字号:
(name, argspec, tip) = self.interp.getCallTip(command)
if tip:
dispatcher.send(signal='Shell.calltip', sender=self, calltip=tip)
if not self.autoCallTip and not forceCallTip:
return
if argspec and insertcalltip and self.callTipInsert:
startpos = self.GetCurrentPos()
self.write(argspec + ')')
endpos = self.GetCurrentPos()
self.SetSelection(endpos, startpos)
if tip:
curpos = self.GetCurrentPos()
tippos = curpos - (len(name) + 1)
fallback = curpos - self.GetColumn(curpos)
# In case there isn't enough room, only go back to the
# fallback.
tippos = max(tippos, fallback)
self.CallTipShow(tippos, tip)
def OnCallTipAutoCompleteManually (self, shiftDown):
"""AutoComplete and Calltips manually."""
if self.AutoCompActive():
self.AutoCompCancel()
currpos = self.GetCurrentPos()
stoppos = self.promptPosEnd
cpos = currpos
#go back until '.' is found
pointavailpos = -1
while cpos >= stoppos:
if self.GetCharAt(cpos) == ord ('.'):
pointavailpos = cpos
break
cpos -= 1
#word from non whitespace until '.'
if pointavailpos != -1:
#look backward for first whitespace char
textbehind = self.GetTextRange (pointavailpos + 1, currpos)
pointavailpos += 1
if not shiftDown:
#call AutoComplete
stoppos = self.promptPosEnd
textbefore = self.GetTextRange(stoppos, pointavailpos)
self.autoCompleteShow(textbefore, len (textbehind))
else:
#call CallTips
cpos = pointavailpos
begpos = -1
while cpos > stoppos:
if chr(self.GetCharAt(cpos)).isspace():
begpos = cpos
break
cpos -= 1
if begpos == -1:
begpos = cpos
ctips = self.GetTextRange (begpos, currpos)
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(),
True)
def writeOut(self, text):
"""Replacement for stdout."""
self.write(text)
def writeErr(self, text):
"""Replacement for stderr."""
self.write(text)
def redirectStdin(self, redirect=True):
"""If redirect is true then sys.stdin will come from the shell."""
if redirect:
sys.stdin = self.reader
else:
sys.stdin = self.stdin
def redirectStdout(self, redirect=True):
"""If redirect is true then sys.stdout will go to the shell."""
if redirect:
sys.stdout = PseudoFileOut(self.writeOut)
else:
sys.stdout = self.stdout
def redirectStderr(self, redirect=True):
"""If redirect is true then sys.stderr will go to the shell."""
if redirect:
sys.stderr = PseudoFileErr(self.writeErr)
else:
sys.stderr = self.stderr
def CanCut(self):
"""Return true if text is selected and can be cut."""
if self.GetSelectionStart() != self.GetSelectionEnd() \
and self.GetSelectionStart() >= self.promptPosEnd \
and self.GetSelectionEnd() >= self.promptPosEnd:
return True
else:
return False
def CanPaste(self):
"""Return true if a paste should succeed."""
if self.CanEdit() and editwindow.EditWindow.CanPaste(self):
return True
else:
return False
def CanEdit(self):
"""Return true if editing should succeed."""
if self.GetSelectionStart() != self.GetSelectionEnd():
if self.GetSelectionStart() >= self.promptPosEnd \
and self.GetSelectionEnd() >= self.promptPosEnd:
return True
else:
return False
else:
return self.GetCurrentPos() >= self.promptPosEnd
def Cut(self):
"""Remove selection and place it on the clipboard."""
if self.CanCut() and self.CanCopy():
if self.AutoCompActive():
self.AutoCompCancel()
if self.CallTipActive():
self.CallTipCancel()
self.Copy()
self.ReplaceSelection('')
def Copy(self):
"""Copy selection and place it on the clipboard."""
if self.CanCopy():
ps1 = str(sys.ps1)
ps2 = str(sys.ps2)
command = self.GetSelectedText()
command = command.replace(os.linesep + ps2, os.linesep)
command = command.replace(os.linesep + ps1, os.linesep)
command = self.lstripPrompt(text=command)
data = wx.TextDataObject(command)
self._clip(data)
def CopyWithPrompts(self):
"""Copy selection, including prompts, and place it on the clipboard."""
if self.CanCopy():
command = self.GetSelectedText()
data = wx.TextDataObject(command)
self._clip(data)
def CopyWithPromptsPrefixed(self):
"""Copy selection, including prompts prefixed with four
spaces, and place it on the clipboard."""
if self.CanCopy():
command = self.GetSelectedText()
spaces = ' ' * 4
command = spaces + command.replace(os.linesep,
os.linesep + spaces)
data = wx.TextDataObject(command)
self._clip(data)
def _clip(self, data):
if wx.TheClipboard.Open():
wx.TheClipboard.UsePrimarySelection(False)
wx.TheClipboard.SetData(data)
wx.TheClipboard.Flush()
wx.TheClipboard.Close()
def Paste(self):
"""Replace selection with clipboard contents."""
if self.CanPaste() and wx.TheClipboard.Open():
ps2 = str(sys.ps2)
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
data = wx.TextDataObject()
if wx.TheClipboard.GetData(data):
self.ReplaceSelection('')
command = data.GetText()
command = command.rstrip()
command = self.fixLineEndings(command)
command = self.lstripPrompt(text=command)
command = command.replace(os.linesep + ps2, '\n')
command = command.replace(os.linesep, '\n')
command = command.replace('\n', os.linesep + ps2)
self.write(command)
wx.TheClipboard.Close()
def PasteAndRun(self):
"""Replace selection with clipboard contents, run commands."""
text = ''
if wx.TheClipboard.Open():
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)):
data = wx.TextDataObject()
if wx.TheClipboard.GetData(data):
text = data.GetText()
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."""
try:
self.SetWrapMode(wrap)
except AttributeError:
return 'Wrapping is not available in this version.'
def zoom(self, points=0):
"""Set the zoom level.
This number of points is added to the size of all fonts. It
may be positive to magnify or negative to reduce."""
self.SetZoom(points)
def LoadSettings(self, config):
self.autoComplete = config.ReadBool('Options/AutoComplete', True)
self.autoCompleteIncludeMagic = config.ReadBool('Options/AutoCompleteIncludeMagic', True)
self.autoCompleteIncludeSingle = config.ReadBool('Options/AutoCompleteIncludeSingle', True)
self.autoCompleteIncludeDouble = config.ReadBool('Options/AutoCompleteIncludeDouble', True)
self.autoCallTip = config.ReadBool('Options/AutoCallTip', True)
self.callTipInsert = config.ReadBool('Options/CallTipInsert', True)
self.SetWrapMode(config.ReadBool('View/WrapMode', True))
useAA = config.ReadBool('Options/UseAntiAliasing', self.GetUseAntiAliasing())
self.SetUseAntiAliasing(useAA)
self.lineNumbers = config.ReadBool('View/ShowLineNumbers', True)
self.setDisplayLineNumbers (self.lineNumbers)
zoom = config.ReadInt('View/Zoom/Shell', -99)
if zoom != -99:
self.SetZoom(zoom)
def SaveSettings(self, config):
config.WriteBool('Options/AutoComplete', self.autoComplete)
config.WriteBool('Options/AutoCompleteIncludeMagic', self.autoCompleteIncludeMagic)
config.WriteBool('Options/AutoCompleteIncludeSingle', self.autoCompleteIncludeSingle)
config.WriteBool('Options/AutoCompleteIncludeDouble', self.autoCompleteIncludeDouble)
config.WriteBool('Options/AutoCallTip', self.autoCallTip)
config.WriteBool('Options/CallTipInsert', self.callTipInsert)
config.WriteBool('Options/UseAntiAliasing', self.GetUseAntiAliasing())
config.WriteBool('View/WrapMode', self.GetWrapMode())
config.WriteBool('View/ShowLineNumbers', self.lineNumbers)
config.WriteInt('View/Zoom/Shell', self.GetZoom())
## NOTE: The DnD of file names is disabled until I can figure out how
## best to still allow DnD of text.
## #seb : File drag and drop
## class FileDropTarget(wx.FileDropTarget):
## def __init__(self, obj):
## wx.FileDropTarget.__init__(self)
## self.obj = obj
## def OnDropFiles(self, x, y, filenames):
## if len(filenames) == 1:
## txt = 'r\"%s\"' % filenames[0]
## else:
## txt = '( '
## for f in filenames:
## txt += 'r\"%s\" , ' % f
## txt += ')'
## self.obj.AppendText(txt)
## pos = self.obj.GetCurrentPos()
## self.obj.SetCurrentPos( pos )
## self.obj.SetSelection( pos, pos )
## class TextAndFileDropTarget(wx.DropTarget):
## def __init__(self, shell):
## wx.DropTarget.__init__(self)
## self.shell = shell
## self.compdo = wx.DataObjectComposite()
## self.textdo = wx.TextDataObject()
## self.filedo = wx.FileDataObject()
## self.compdo.Add(self.textdo)
## self.compdo.Add(self.filedo, True)
## self.SetDataObject(self.compdo)
## def OnDrop(self, x, y):
## return True
## def OnData(self, x, y, result):
## self.GetData()
## if self.textdo.GetTextLength() > 1:
## text = self.textdo.GetText()
## # *** Do somethign with the dragged text here...
## self.textdo.SetText('')
## else:
## filenames = str(self.filename.GetFilenames())
## if len(filenames) == 1:
## txt = 'r\"%s\"' % filenames[0]
## else:
## txt = '( '
## for f in filenames:
## txt += 'r\"%s\" , ' % f
## txt += ')'
## self.shell.AppendText(txt)
## pos = self.shell.GetCurrentPos()
## self.shell.SetCurrentPos( pos )
## self.shell.SetSelection( pos, pos )
## return result
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -