##// END OF EJS Templates
Merge pull request #1399 from asmeurer/sympyprinting...
Merge pull request #1399 from asmeurer/sympyprinting Use LaTeX to display, on output, various built-in types with the SymPy printing extension. SymPy's latex() function supports printing lists, tuples, and dicts using latex notation (it uses bmatrix, pmatrix, and Bmatrix, respectively). This provides a more unified experience with SymPy functions that return these types (such as solve()). Also display ints, longs, and floats using LaTeX, to get a more unified printing experience (so that, e.g., x/x will print the same as just 1). The string form can always be obtained by manually calling the actual print function, or 2d unicode printing using pprint(). SymPy's latex() function doesn't treat set() or frosenset() correctly presently (see http://code.google.com/p/sympy/issues /detail?id=3062), so for the present, we leave those alone.

File last commit:

r4872:34c10438
r6482:ba882bf7 merge
Show More
ipython_history.py
510 lines | 20.5 KiB | text/x-python | PythonLexer
#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import wx
import wx.stc as stc
import keyword
#-----------------------------------------
# History widget for IPython
__version__ = 0.5
__author__ = "Laurent Dufrechou"
__email__ = "laurent.dufrechou _at_ gmail.com"
__license__ = "BSD"
#-----------------------------------------
class IPythonHistoryPanel(wx.Panel):
def __init__(self, parent,flt_empty=True,
flt_doc=True,flt_cmd=True,flt_magic=True):
wx.Panel.__init__(self,parent,-1)
#text_ctrl = wx.TextCtrl(self, -1, style=wx.TE_MULTILINE)
text_ctrl = PythonSTC(self, -1)
st_filt = wx.StaticText(self, -1, " Filter:")
self.filter_empty = wx.CheckBox(self, -1, "Empty commands")
self.filter_doc = wx.CheckBox(self, -1, "?: Doc commands")
self.filter_cmd = wx.CheckBox(self, -1, "!: Sys commands")
self.filter_magic = wx.CheckBox(self, -1, "%: Magic keys")
self.options={'filter_empty':{'value':'True',
'checkbox':self.filter_empty, \
'True':True,'False':False,
'setfunc':lambda x:None},
'filter_doc':{'value':'True',
'checkbox':self.filter_doc, \
'True':True,'False':False,
'setfunc':lambda x:None},
'filter_cmd':{'value':'True',
'checkbox':self.filter_cmd, \
'True':True,'False':False,
'setfunc':lambda x:None},
'filter_magic':{'value':'True',
'checkbox':self.filter_magic, \
'True':True,'False':False,
'setfunc':lambda x:None},
}
self.reloadOptions(self.options)
self.filter_empty.Bind(wx.EVT_CHECKBOX, self.evtCheckEmptyFilter)
self.filter_doc.Bind(wx.EVT_CHECKBOX, self.evtCheckDocFilter)
self.filter_cmd.Bind(wx.EVT_CHECKBOX, self.evtCheckCmdFilter)
self.filter_magic.Bind(wx.EVT_CHECKBOX, self.evtCheckMagicFilter)
#self.filter_empty.SetValue(flt_empty)
#self.filter_doc.SetValue(flt_doc)
#self.filter_cmd.SetValue(flt_cmd)
#self.filter_magic.SetValue(flt_magic)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(text_ctrl, 1, wx.EXPAND)
sizer.AddMany( [(5,5),
st_filt,
(10,10),
self.filter_empty,
self.filter_doc,
self.filter_cmd,
self.filter_magic,
(10,10),
])
self.SetAutoLayout(True)
sizer.Fit(self)
sizer.SetSizeHints(self)
self.SetSizer(sizer)
self.text_ctrl=text_ctrl
#text_ctrl.SetText(demoText + open('Main.py').read())
text_ctrl.EmptyUndoBuffer()
text_ctrl.Colourise(0, -1)
# line numbers in the margin
text_ctrl.SetMarginType(1, stc.STC_MARGIN_NUMBER)
text_ctrl.SetMarginWidth(1, 15)
def write(self,history_line):
add = True
if self.filter_empty.GetValue() == True and history_line == '':
add = False
if len(history_line)>0:
if self.filter_doc.GetValue() == True and history_line[-1:] == '?':
add = False
if self.filter_cmd.GetValue() == True and history_line[0] == '!':
add = False
if self.filter_magic.GetValue() == True and history_line[0] == '%':
add = False
if add:
self.text_ctrl.AppendText(history_line+'\n')
#------------------------ Option Section -----------------------------------
def processOptionCheckedEvt(self, event, name):
if event.IsChecked():
self.options[name]['value']='True'
else:
self.options[name]['value']='False'
self.updateOptionTracker(name,
self.options[name]['value'])
def evtCheckEmptyFilter(self, event):
self.processOptionCheckedEvt(event, 'filter_empty')
def evtCheckDocFilter(self, event):
self.processOptionCheckedEvt(event, 'filter_doc')
def evtCheckCmdFilter(self, event):
self.processOptionCheckedEvt(event, 'filter_cmd')
def evtCheckMagicFilter(self, event):
self.processOptionCheckedEvt(event, 'filter_magic')
def getOptions(self):
return self.options
def reloadOptions(self,options):
self.options = options
for key in self.options.keys():
value = self.options[key]['value']
self.options[key]['checkbox'].SetValue(self.options[key][value])
self.options[key]['setfunc'](value)
#------------------------ Hook Section -----------------------------------
def updateOptionTracker(self,name,value):
'''
Default history tracker (does nothing)
'''
pass
def setOptionTrackerHook(self,func):
'''
Define a new history tracker
'''
self.updateOptionTracker = func
#----------------------------------------------------------------------
# Font definition for Styled Text Control
if wx.Platform == '__WXMSW__':
faces = { 'times': 'Times New Roman',
'mono' : 'Courier New',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 8,
'size2': 6,
}
elif wx.Platform == '__WXMAC__':
faces = { 'times': 'Times New Roman',
'mono' : 'Monaco',
'helv' : 'Arial',
'other': 'Comic Sans MS',
'size' : 8,
'size2': 6,
}
else:
faces = { 'times': 'Times',
'mono' : 'Courier',
'helv' : 'Helvetica',
'other': 'new century schoolbook',
'size' : 8,
'size2': 6,
}
#----------------------------------------------------------------------
class PythonSTC(stc.StyledTextCtrl):
fold_symbols = 3
def __init__(self, parent, ID,
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0):
stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
#self.CmdKeyAssign(ord('B'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMIN)
#self.CmdKeyAssign(ord('N'), stc.STC_SCMOD_CTRL, stc.STC_CMD_ZOOMOUT)
self.SetLexer(stc.STC_LEX_PYTHON)
self.SetKeyWords(0, " ".join(keyword.kwlist))
#self.SetProperty("fold", "1")
#self.SetProperty("tab.timmy.whinge.level", "1")
#self.SetMargins(0,0)
#self.SetViewWhiteSpace(False)
#self.SetBufferedDraw(False)
#self.SetViewEOL(True)
self.SetEOLMode(stc.STC_EOL_CRLF)
#self.SetUseAntiAliasing(True)
self.SetEdgeMode(stc.STC_EDGE_LINE)
self.SetEdgeColumn(80)
self.SetEdgeColour(wx.LIGHT_GREY)
self.SetLayoutCache(stc.STC_CACHE_PAGE)
# Setup a margin to hold fold markers
#self.SetFoldFlags(16)
### WHAT IS THIS VALUE? WHAT ARE THE OTHER FLAGS? DOES IT MATTER?
self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
self.SetMarginSensitive(2, True)
self.SetMarginWidth(2, 12)
if self.fold_symbols == 0:
# Arrow pointing right for contracted folders,
# arrow pointing down for expanded
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
stc.STC_MARK_ARROWDOWN, "black", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
stc.STC_MARK_ARROW, "black", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
stc.STC_MARK_EMPTY, "black", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
stc.STC_MARK_EMPTY, "black", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
stc.STC_MARK_EMPTY, "white", "black")
elif self.fold_symbols == 1:
# Plus for contracted folders, minus for expanded
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
stc.STC_MARK_MINUS, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
stc.STC_MARK_PLUS, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
stc.STC_MARK_EMPTY, "white", "black")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
stc.STC_MARK_EMPTY, "white", "black")
elif self.fold_symbols == 2:
# Like a flattened tree control using circular headers and curved joins
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
stc.STC_MARK_CIRCLEMINUS, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
stc.STC_MARK_CIRCLEPLUS, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
stc.STC_MARK_VLINE, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
stc.STC_MARK_LCORNERCURVE, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
stc.STC_MARK_CIRCLEPLUSCONNECTED, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
stc.STC_MARK_CIRCLEMINUSCONNECTED, "white", "#404040")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
stc.STC_MARK_TCORNERCURVE, "white", "#404040")
elif self.fold_symbols == 3:
# Like a flattened tree control using square headers
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN, \
stc.STC_MARK_BOXMINUS, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDER, \
stc.STC_MARK_BOXPLUS, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB, \
stc.STC_MARK_VLINE, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL, \
stc.STC_MARK_LCORNER, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND, \
stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, \
stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, \
stc.STC_MARK_TCORNER, "white", "#808080")
self.Bind(stc.EVT_STC_UPDATEUI, self.OnUpdateUI)
self.Bind(stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
# Make some styles, The lexer defines what each style is used for, we
# just have to define what each style looks like. This set is adapted from
# Scintilla sample property files.
# Global default styles for all languages
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
self.StyleClearAll() # Reset all to be like the default
# Global default styles for all languages
self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "face:%(helv)s,size:%(size)d" % faces)
self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,face:%(helv)s,size:%(size2)d" % faces)
self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % faces)
self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT, "fore:#FFFFFF,back:#0000FF,bold")
self.StyleSetSpec(stc.STC_STYLE_BRACEBAD, "fore:#000000,back:#FF0000,bold")
# Python styles
# Default
self.StyleSetSpec(stc.STC_P_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
# Comments
self.StyleSetSpec(stc.STC_P_COMMENTLINE, "fore:#007F00,face:%(other)s,size:%(size)d" % faces)
# Number
self.StyleSetSpec(stc.STC_P_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
# String
self.StyleSetSpec(stc.STC_P_STRING, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
# Single quoted string
self.StyleSetSpec(stc.STC_P_CHARACTER, "fore:#7F007F,face:%(helv)s,size:%(size)d" % faces)
# Keyword
self.StyleSetSpec(stc.STC_P_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
# Triple quotes
self.StyleSetSpec(stc.STC_P_TRIPLE, "fore:#7F0000,size:%(size)d" % faces)
# Triple double quotes
self.StyleSetSpec(stc.STC_P_TRIPLEDOUBLE, "fore:#7F0000,size:%(size)d" % faces)
# Class name definition
self.StyleSetSpec(stc.STC_P_CLASSNAME, "fore:#0000FF,bold,underline,size:%(size)d" % faces)
# Function or method name definition
self.StyleSetSpec(stc.STC_P_DEFNAME, "fore:#007F7F,bold,size:%(size)d" % faces)
# Operators
self.StyleSetSpec(stc.STC_P_OPERATOR, "bold,size:%(size)d" % faces)
# Identifiers
self.StyleSetSpec(stc.STC_P_IDENTIFIER, "fore:#000000,face:%(helv)s,size:%(size)d" % faces)
# Comment-blocks
self.StyleSetSpec(stc.STC_P_COMMENTBLOCK, "fore:#7F7F7F,size:%(size)d" % faces)
# End of line where string is not closed
self.StyleSetSpec(stc.STC_P_STRINGEOL, "fore:#000000,face:%(mono)s,back:#E0C0E0,eol,size:%(size)d" % faces)
self.SetCaretForeground("BLUE")
# register some images for use in the AutoComplete box.
#self.RegisterImage(1, images.getSmilesBitmap())
#self.RegisterImage(2,
# wx.ArtProvider.GetBitmap(wx.ART_NEW, size=(16,16)))
#self.RegisterImage(3,
# wx.ArtProvider.GetBitmap(wx.ART_COPY, size=(16,16)))
def OnKeyPressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
key = event.GetKeyCode()
if key == 32 and event.ControlDown():
pos = self.GetCurrentPos()
# Tips
if event.ShiftDown():
self.CallTipSetBackground("yellow")
self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
'show some suff, maybe parameters..\n\n'
'fubar(param1, param2)')
# Code completion
else:
#lst = []
#for x in range(50000):
# lst.append('%05d' % x)
#st = " ".join(lst)
#print len(st)
#self.AutoCompShow(0, st)
kw = keyword.kwlist[:]
kw.sort() # Python sorts are case sensitive
self.AutoCompSetIgnoreCase(False) # so this needs to match
# Images are specified with a appended "?type"
for i in range(len(kw)):
if kw[i] in keyword.kwlist:
kw[i] = kw[i]# + "?1"
self.AutoCompShow(0, " ".join(kw))
else:
event.Skip()
def OnUpdateUI(self, evt):
# check for matching braces
braceAtCaret = -1
braceOpposite = -1
charBefore = None
caretPos = self.GetCurrentPos()
if caretPos > 0:
charBefore = self.GetCharAt(caretPos - 1)
styleBefore = self.GetStyleAt(caretPos - 1)
# check before
if charBefore and chr(charBefore) in "[]{}()" and styleBefore == stc.STC_P_OPERATOR:
braceAtCaret = caretPos - 1
# check after
if braceAtCaret < 0:
charAfter = self.GetCharAt(caretPos)
styleAfter = self.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in "[]{}()" and styleAfter == stc.STC_P_OPERATOR:
braceAtCaret = caretPos
if braceAtCaret >= 0:
braceOpposite = self.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
#pt = self.PointFromPosition(braceOpposite)
#self.Refresh(True, wxRect(pt.x, pt.y, 5,5))
#print pt
#self.Refresh(False)
def OnMarginClick(self, evt):
# fold and unfold as needed
if evt.GetMargin() == 2:
if evt.GetShift() and evt.GetControl():
self.FoldAll()
else:
lineClicked = self.LineFromPosition(evt.GetPosition())
if self.GetFoldLevel(lineClicked) & stc.STC_FOLDLEVELHEADERFLAG:
if evt.GetShift():
self.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 1)
elif evt.GetControl():
if self.GetFoldExpanded(lineClicked):
self.SetFoldExpanded(lineClicked, False)
self.Expand(lineClicked, False, True, 0)
else:
self.SetFoldExpanded(lineClicked, True)
self.Expand(lineClicked, True, True, 100)
else:
self.ToggleFold(lineClicked)
def FoldAll(self):
lineCount = self.GetLineCount()
expanding = True
# find out if we are folding or unfolding
for lineNum in range(lineCount):
if self.GetFoldLevel(lineNum) & stc.STC_FOLDLEVELHEADERFLAG:
expanding = not self.GetFoldExpanded(lineNum)
break
lineNum = 0
while lineNum < lineCount:
level = self.GetFoldLevel(lineNum)
if level & stc.STC_FOLDLEVELHEADERFLAG and \
(level & stc.STC_FOLDLEVELNUMBERMASK) == stc.STC_FOLDLEVELBASE:
if expanding:
self.SetFoldExpanded(lineNum, True)
lineNum = self.Expand(lineNum, True)
lineNum = lineNum - 1
else:
lastChild = self.GetLastChild(lineNum, -1)
self.SetFoldExpanded(lineNum, False)
if lastChild > lineNum:
self.HideLines(lineNum+1, lastChild)
lineNum = lineNum + 1
def Expand(self, line, doExpand, force=False, visLevels=0, level=-1):
lastChild = self.GetLastChild(line, level)
line = line + 1
while line <= lastChild:
if force:
if visLevels > 0:
self.ShowLines(line, line)
else:
self.HideLines(line, line)
else:
if doExpand:
self.ShowLines(line, line)
if level == -1:
level = self.GetFoldLevel(line)
if level & stc.STC_FOLDLEVELHEADERFLAG:
if force:
if visLevels > 1:
self.SetFoldExpanded(line, True)
else:
self.SetFoldExpanded(line, False)
line = self.Expand(line, doExpand, force, visLevels-1)
else:
if doExpand and self.GetFoldExpanded(line):
line = self.Expand(line, True, force, visLevels-1)
else:
line = self.Expand(line, False, force, visLevels-1)
else:
line = line + 1
return line
#----------------------------------------------------------------------