]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxPython/lib/pyshell.py
58dd3601ff3d4875738677bb68a44e79f89c0d64
1 #----------------------------------------------------------------------
2 # Name: wxPython.lib.pyshell
3 # Purpose: A Python Interactive Interpreter running in a wxStyledTextCtrl
10 # Copyright: (c) 2000 by Total Control Software
11 # Licence: wxWindows license
12 #----------------------------------------------------------------------
15 PyShellWindow is a class that provides an Interactive Interpreter running
16 inside a wxStyledTextCtrl, similar to the Python shell windows found in
19 There is still much to be done to improve this class, such as line
20 buffering/recall, autoindent, calltips, autocomplete, etc... But
26 from wxPython
.wx
import *
27 from wxPython
.stc
import *
29 import sys
, string
, keyword
30 from code
import InteractiveInterpreter
32 #----------------------------------------------------------------------
33 # default styles, etc. to use for the STC
35 if wxPlatform
== '__WXMSW__':
41 _default_properties
= {
45 'stdout' : 'fore:#0000FF',
46 'stderr' : 'fore:#007f00',
47 'trace' : 'fore:#FF0000',
49 'default' : 'size:%d' % _defaultSize
,
50 'bracegood' : 'fore:#FFFFFF,back:#0000FF,bold',
51 'bracebad' : 'fore:#000000,back:#FF0000,bold',
53 # properties for the various Python lexer styles
54 'comment' : 'fore:#007F00',
55 'number' : 'fore:#007F7F',
56 'string' : 'fore:#7F007F,italic',
57 'char' : 'fore:#7F007F,italic',
58 'keyword' : 'fore:#00007F,bold',
59 'triple' : 'fore:#7F0000',
60 'tripledouble': 'fore:#7F0000',
61 'class' : 'fore:#0000FF,bold,underline',
62 'def' : 'fore:#007F7F,bold',
74 #----------------------------------------------------------------------
76 class PyShellWindow(wxStyledTextCtrl
, InteractiveInterpreter
):
77 def __init__(self
, parent
, ID
, pos
=wxDefaultPosition
,
78 size
=wxDefaultSize
, style
=0,
79 locals=None, properties
=None, banner
=None):
80 wxStyledTextCtrl
.__init
__(self
, parent
, ID
, pos
, size
, style
)
81 InteractiveInterpreter
.__init
__(self
, locals)
83 self
.lastPromptPos
= 0
85 # the line cache is used to cycle through previous commands
87 self
.lastUsedLine
= self
.curLine
= 0
89 # set defaults and then deal with any user defined properties
91 self
.props
.update(_default_properties
)
93 self
.props
.update(properties
)
94 self
.UpdateProperties()
96 # copyright/banner message
98 self
.write("Python %s on %s\n%s\n(%s)\n" %
99 (sys
.version
, sys
.platform
, sys
.copyright
,
100 self
.__class
__.__name
__))
102 self
.write("%s\n" % banner
)
104 # write the initial prompt
108 EVT_KEY_DOWN(self
, self
.OnKey
)
109 EVT_STC_UPDATEUI(self
, ID
, self
.OnUpdateUI
)
110 EVT_STC_STYLENEEDED(self
, ID
, self
.OnStyle
)
113 def GetLocals(self
): return self
.locals
114 def SetLocals(self
, locals): self
.locals = locals
116 def GetProperties(self
): return self
.props
117 def SetProperties(self
, properties
):
118 self
.props
.update(properties
)
119 self
.UpdateProperties()
122 def UpdateProperties(self
):
124 Reset the editor and other settings based on the contents of the
125 current properties dictionary.
129 self
.SetEdgeMode(wxSTC_EDGE_LINE
)
130 self
.SetEdgeColumn(80)
133 # set the selection margin and window margin
134 self
.SetMarginWidth(1, p
['selMargin'])
135 self
.SetMargins(p
['marginWidth'], p
['marginWidth'])
138 self
.StyleSetSpec(wxSTC_STYLE_DEFAULT
, p
['default'])
140 self
.StyleSetSpec(_stdout_style
, p
['stdout'])
141 self
.StyleSetSpec(_stderr_style
, p
['stderr'])
142 self
.StyleSetSpec(_trace_style
, p
['trace'])
144 self
.StyleSetSpec(wxSTC_STYLE_BRACELIGHT
, p
['bracegood'])
145 self
.StyleSetSpec(wxSTC_STYLE_BRACEBAD
, p
['bracebad'])
146 self
.StyleSetSpec(SCE_P_COMMENTLINE
, p
['comment'])
147 self
.StyleSetSpec(SCE_P_NUMBER
, p
['number'])
148 self
.StyleSetSpec(SCE_P_STRING
, p
['string'])
149 self
.StyleSetSpec(SCE_P_CHARACTER
, p
['char'])
150 self
.StyleSetSpec(SCE_P_WORD
, p
['keyword'])
151 self
.StyleSetSpec(SCE_P_TRIPLE
, p
['triple'])
152 self
.StyleSetSpec(SCE_P_TRIPLEDOUBLE
, p
['tripledouble'])
153 self
.StyleSetSpec(SCE_P_CLASSNAME
, p
['class'])
154 self
.StyleSetSpec(SCE_P_DEFNAME
, p
['def'])
155 self
.StyleSetSpec(SCE_P_OPERATOR
, p
['operator'])
156 self
.StyleSetSpec(SCE_P_COMMENTBLOCK
, p
['comment'])
159 # used for writing to stdout, etc.
160 def _write(self
, text
, style
=_stdout_style
):
161 self
.lastPromptPos
= 0
162 pos
= self
.GetCurrentPos()
164 self
.StartStyling(pos
, 0xFF)
165 self
.SetStyleFor(len(text
), style
)
166 self
.EnsureCaretVisible()
171 def writeTrace(self
, text
):
172 self
._write
(text
, _trace_style
)
176 # is the current line non-empty?
177 text
, pos
= self
.GetCurrentLineText()
180 self
.AddText(self
.props
['ps1'])
181 self
.lastPromptPos
= self
.GetCurrentPos()
182 self
.EnsureCaretVisible()
183 self
.ScrollToColumn(0)
186 def PushLine(self
, text
):
187 # TODO: Add the text to the line cache, manage the cache so
188 # it doesn't get too big.
193 def OnKey(self
, evt
):
195 if key
== WXK_RETURN
:
196 pos
= self
.GetCurrentPos()
197 lastPos
= self
.GetTextLength()
199 # if not on the last line, duplicate the current line
200 if self
.GetLineCount()-1 != self
.GetCurrentLine():
201 text
, col
= self
.GetCurrentLineText()
202 prompt
= self
.props
['ps1']
204 if text
[:lp
] == prompt
:
207 self
.SetSelection(self
.lastPromptPos
, lastPos
)
208 self
.ReplaceSelection(text
[:-1])
210 else: # try to execute the text from the prompt to the end
211 if lastPos
== self
.lastPromptPos
:
216 text
= self
.GetTextRange(self
.lastPromptPos
, lastPos
)
219 more
= self
.runsource(text
)
224 # TODO: Add handlers for Alt-P and Alt-N to cycle through entries
231 def OnStyle(self
, evt
):
232 # Only style from the prompt pos to the end
233 lastPos
= self
.GetTextLength()
234 if self
.lastPromptPos
and self
.lastPromptPos
!= lastPos
:
235 self
.SetLexer(wxSTC_LEX_PYTHON
)
236 self
.SetKeywords(0, string
.join(keyword
.kwlist
))
238 self
.Colourise(self
.lastPromptPos
, lastPos
)
243 def OnUpdateUI(self
, evt
):
244 # check for matching braces
248 caretPos
= self
.GetCurrentPos()
250 charBefore
= self
.GetCharAt(caretPos
- 1)
251 styleBefore
= self
.GetStyleAt(caretPos
- 1)
254 if charBefore
and charBefore
in "[]{}()" and ord(styleBefore
) == SCE_P_OPERATOR
:
255 braceAtCaret
= caretPos
- 1
259 charAfter
= self
.GetCharAt(caretPos
)
260 styleAfter
= self
.GetStyleAt(caretPos
)
261 if charAfter
and charAfter
in "[]{}()" and ord(styleAfter
) == SCE_P_OPERATOR
:
262 braceAtCaret
= caretPos
264 if braceAtCaret
>= 0:
265 braceOpposite
= self
.BraceMatch(braceAtCaret
)
267 if braceAtCaret
!= -1 and braceOpposite
== -1:
268 self
.BraceBadlight(braceAtCaret
)
270 self
.BraceHighlight(braceAtCaret
, braceOpposite
)
274 #----------------------------------------------
275 # overloaded methods from InteractiveInterpreter
276 def runsource(self
, source
):
277 stdout
, stderr
= sys
.stdout
, sys
.stderr
278 sys
.stdout
= FauxFile(self
, _stdout_style
)
279 sys
.stderr
= FauxFile(self
, _stderr_style
)
281 more
= InteractiveInterpreter
.runsource(self
, source
)
283 sys
.stdout
, sys
.stderr
= stdout
, stderr
286 def showsyntaxerror(self
, filename
=None):
287 self
.write
= self
.writeTrace
288 InteractiveInterpreter
.showsyntaxerror(self
, filename
)
289 self
.write
= self
._write
291 def showtraceback(self
):
292 self
.write
= self
.writeTrace
293 InteractiveInterpreter
.showtraceback(self
)
294 self
.write
= self
._write
296 #----------------------------------------------------------------------
299 def __init__(self
, psw
, style
):
303 def write(self
, text
):
304 self
.psw
.write(text
, self
.style
)
306 def writelines(self
, lst
):
313 #----------------------------------------------------------------------
316 if __name__
== '__main__':
317 app
= wxPyWidgetTester(size
= (640, 480))
318 app
.SetWidget(PyShellWindow
, -1)
322 #----------------------------------------------------------------------