]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/pyshell.py
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 #----------------------------------------------------------------------
13 # 12/10/2003 - Jeff Grimmett (grimmtooth@softhome.net)
15 # o 2.5 compatability update.
16 # o Added deprecation warning.
20 PyShellWindow is a class that provides an Interactive Interpreter running
21 inside a wxStyledTextCtrl, similar to the Python shell windows found in
24 There is still much to be done to improve this class, such as line
25 buffering/recall, autoindent, calltips, autocomplete, fixing the colourizer,
26 etc... But it's a good start.
29 8-10-2001 THIS MODULE IS NOW DEPRECATED. Please see the most excellent
30 PyCrust package instead.
38 from code
import InteractiveInterpreter
45 ########################################\
46 # THIS MODULE IS NOW DEPRECATED |
48 # Please see the most excellent PyCrust |
50 ########################################/
54 warnings
.warn(warningmsg
, DeprecationWarning, stacklevel
=2)
56 #----------------------------------------------------------------------
57 # default styles, etc. to use for the STC
59 if wx
.Platform
== '__WXMSW__':
65 _default_properties
= {
69 'stdout' : 'fore:#0000FF',
70 'stderr' : 'fore:#007f00',
71 'trace' : 'fore:#FF0000',
73 'default' : 'size:%d' % _defaultSize
,
74 'bracegood' : 'fore:#FFFFFF,back:#0000FF,bold',
75 'bracebad' : 'fore:#000000,back:#FF0000,bold',
77 # properties for the various Python lexer styles
78 'comment' : 'fore:#007F00',
79 'number' : 'fore:#007F7F',
80 'string' : 'fore:#7F007F,italic',
81 'char' : 'fore:#7F007F,italic',
82 'keyword' : 'fore:#00007F,bold',
83 'triple' : 'fore:#7F0000',
84 'tripledouble': 'fore:#7F0000',
85 'class' : 'fore:#0000FF,bold,underline',
86 'def' : 'fore:#007F7F,bold',
98 #----------------------------------------------------------------------
100 class PyShellWindow(stc
.StyledTextCtrl
, InteractiveInterpreter
):
101 def __init__(self
, parent
, ID
, pos
=wx
.DefaultPosition
,
102 size
=wx
.DefaultSize
, style
=0,
103 locals=None, properties
=None, banner
=None):
104 stc
.StyledTextCtrl
.__init
__(self
, parent
, ID
, pos
, size
, style
)
105 InteractiveInterpreter
.__init
__(self
, locals)
107 self
.lastPromptPos
= 0
109 # the line cache is used to cycle through previous commands
111 self
.lastUsedLine
= self
.curLine
= 0
113 # set defaults and then deal with any user defined properties
115 self
.props
.update(_default_properties
)
117 self
.props
.update(properties
)
118 self
.UpdateProperties()
120 # copyright/banner message
122 self
.write("Python %s on %s\n" % #%s\n(%s)\n" %
123 (sys
.version
, sys
.platform
,
124 #sys.copyright, self.__class__.__name__
127 self
.write("%s\n" % banner
)
129 # write the initial prompt
133 self
.Bind(wx
.EVT_KEY_DOWN
, self
.OnKey
)
134 self
.Bind(stc
.EVT_STC_UPDATEUI
, self
.OnUpdateUI
, id=ID
)
135 #self.Bind(stc.EVT_STC_STYLENEEDED, self.OnStyle, id=ID)
138 def GetLocals(self
): return self
.locals
139 def SetLocals(self
, locals): self
.locals = locals
141 def GetProperties(self
): return self
.props
142 def SetProperties(self
, properties
):
143 self
.props
.update(properties
)
144 self
.UpdateProperties()
147 def UpdateProperties(self
):
149 Reset the editor and other settings based on the contents of the
150 current properties dictionary.
154 #self.SetEdgeMode(stc.STC_EDGE_LINE)
155 #self.SetEdgeColumn(80)
158 # set the selection margin and window margin
159 self
.SetMarginWidth(1, p
['selMargin'])
160 self
.SetMargins(p
['marginWidth'], p
['marginWidth'])
163 self
.StyleSetSpec(stc
.STC_STYLE_DEFAULT
, p
['default'])
165 self
.StyleSetSpec(_stdout_style
, p
['stdout'])
166 self
.StyleSetSpec(_stderr_style
, p
['stderr'])
167 self
.StyleSetSpec(_trace_style
, p
['trace'])
169 self
.StyleSetSpec(stc
.STC_STYLE_BRACELIGHT
, p
['bracegood'])
170 self
.StyleSetSpec(stc
.STC_STYLE_BRACEBAD
, p
['bracebad'])
171 self
.StyleSetSpec(stc
.STC_P_COMMENTLINE
, p
['comment'])
172 self
.StyleSetSpec(stc
.STC_P_NUMBER
, p
['number'])
173 self
.StyleSetSpec(stc
.STC_P_STRING
, p
['string'])
174 self
.StyleSetSpec(stc
.STC_P_CHARACTER
, p
['char'])
175 self
.StyleSetSpec(stc
.STC_P_WORD
, p
['keyword'])
176 self
.StyleSetSpec(stc
.STC_P_TRIPLE
, p
['triple'])
177 self
.StyleSetSpec(stc
.STC_P_TRIPLEDOUBLE
, p
['tripledouble'])
178 self
.StyleSetSpec(stc
.STC_P_CLASSNAME
, p
['class'])
179 self
.StyleSetSpec(stc
.STC_P_DEFNAME
, p
['def'])
180 self
.StyleSetSpec(stc
.STC_P_OPERATOR
, p
['operator'])
181 self
.StyleSetSpec(stc
.STC_P_COMMENTBLOCK
, p
['comment'])
184 # used for writing to stdout, etc.
185 def _write(self
, text
, style
=_stdout_style
):
186 self
.lastPromptPos
= 0
187 pos
= self
.GetCurrentPos()
189 self
.StartStyling(pos
, 0xFF)
190 self
.SetStyling(len(text
), style
)
191 self
.EnsureCaretVisible()
196 def writeTrace(self
, text
):
197 self
._write
(text
, _trace_style
)
201 # is the current line non-empty?
202 text
, pos
= self
.GetCurLine()
205 self
.AddText(self
.props
['ps1'])
206 self
.lastPromptPos
= self
.GetCurrentPos()
207 self
.EnsureCaretVisible()
208 self
.ScrollToColumn(0)
211 def PushLine(self
, text
):
212 # TODO: Add the text to the line cache, manage the cache so
213 # it doesn't get too big.
218 def OnKey(self
, evt
):
219 key
= evt
.GetKeyCode()
220 if key
== wx
.WXK_RETURN
:
221 pos
= self
.GetCurrentPos()
222 lastPos
= self
.GetTextLength()
224 # if not on the last line, duplicate the current line
225 if self
.GetLineCount()-1 != self
.GetCurrentLine():
226 text
, col
= self
.GetCurLine()
227 prompt
= self
.props
['ps1']
229 if text
[:lp
] == prompt
:
232 self
.SetSelection(self
.lastPromptPos
, lastPos
)
233 self
.ReplaceSelection(text
[:-1])
235 else: # try to execute the text from the prompt to the end
236 if lastPos
== self
.lastPromptPos
:
241 text
= self
.GetTextRange(self
.lastPromptPos
, lastPos
)
244 more
= self
.runsource(text
)
249 # TODO: Add handlers for Alt-P and Alt-N to cycle through entries
256 def OnStyle(self
, evt
):
257 # Only style from the prompt pos to the end
258 lastPos
= self
.GetTextLength()
259 if self
.lastPromptPos
and self
.lastPromptPos
!= lastPos
:
260 self
.SetLexer(stc
.STC_LEX_PYTHON
)
261 self
.SetKeywords(0, ' '.join(keyword
.kwlist
))
263 self
.Colourise(self
.lastPromptPos
, lastPos
)
268 def OnUpdateUI(self
, evt
):
269 # check for matching braces
273 caretPos
= self
.GetCurrentPos()
275 charBefore
= self
.GetCharAt(caretPos
- 1)
276 styleBefore
= self
.GetStyleAt(caretPos
- 1)
279 if charBefore
and chr(charBefore
) in "[]{}()" and styleBefore
== stc
.STC_P_OPERATOR
:
280 braceAtCaret
= caretPos
- 1
284 charAfter
= self
.GetCharAt(caretPos
)
285 styleAfter
= self
.GetStyleAt(caretPos
)
286 if charAfter
and chr(charAfter
) in "[]{}()" and styleAfter
== stc
.STC_P_OPERATOR
:
287 braceAtCaret
= caretPos
289 if braceAtCaret
>= 0:
290 braceOpposite
= self
.BraceMatch(braceAtCaret
)
292 if braceAtCaret
!= -1 and braceOpposite
== -1:
293 self
.BraceBadlight(braceAtCaret
)
295 self
.BraceHighlight(braceAtCaret
, braceOpposite
)
299 #----------------------------------------------
300 # overloaded methods from InteractiveInterpreter
301 def runsource(self
, source
):
302 stdout
, stderr
= sys
.stdout
, sys
.stderr
303 sys
.stdout
= FauxFile(self
, _stdout_style
)
304 sys
.stderr
= FauxFile(self
, _stderr_style
)
306 more
= InteractiveInterpreter
.runsource(self
, source
)
308 sys
.stdout
, sys
.stderr
= stdout
, stderr
311 def showsyntaxerror(self
, filename
=None):
312 self
.write
= self
.writeTrace
313 InteractiveInterpreter
.showsyntaxerror(self
, filename
)
314 self
.write
= self
._write
316 def showtraceback(self
):
317 self
.write
= self
.writeTrace
318 InteractiveInterpreter
.showtraceback(self
)
319 self
.write
= self
._write
321 #----------------------------------------------------------------------
324 def __init__(self
, psw
, style
):
328 def write(self
, text
):
329 self
.psw
.write(text
, self
.style
)
331 def writelines(self
, lst
):
338 #----------------------------------------------------------------------
341 if __name__
== '__main__':
342 app
= wx
.PyWidgetTester(size
= (640, 480))
343 app
.SetWidget(PyShellWindow
, -1)
347 #----------------------------------------------------------------------