📄 codeeditor.py
字号:
# 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, wx.stc.STC_MARGIN_SYMBOL)
self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
self.SetMarginSensitive(2, True)
self.SetMarginSensitive(1, False)
self.SetMarginMask(1, 0x4)
self.SetMarginSensitive(0, True)
self.SetMarginType(0, wx.stc.STC_MARGIN_SYMBOL)
self.SetMarginMask(0, 0x3)
self.SetMarginWidth(0, 12)
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_BOXPLUSCONNECTED, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, wx.stc.STC_MARK_LCORNER, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, wx.stc.STC_MARK_VLINE, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_BOXPLUS, "white", "black")
self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_BOXMINUS, "white", "black")
# Define the current line marker
self.MarkerDefine(CodeCtrl.CURRENT_LINE_MARKER_NUM, wx.stc.STC_MARK_SHORTARROW, wx.BLACK, (255,255,128))
# Define the breakpoint marker
self.MarkerDefine(CodeCtrl.BREAKPOINT_MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, (255,0,0))
if _WINDOWS and clearTab: # should test to see if menu item exists, if it does, add this workaround
self.CmdKeyClear(wx.stc.STC_KEY_TAB, 0) # menu item "Indent Lines" from CodeService.InstallControls() generates another INDENT_LINES_ID event, so we'll explicitly disable the tab processing in the editor
wx.stc.EVT_STC_MARGINCLICK(self, self.GetId(), self.OnMarginClick)
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
if self.GetMatchingBraces():
wx.stc.EVT_STC_UPDATEUI(self, self.GetId(), self.OnUpdateUI)
self.StyleClearAll()
self.UpdateStyles()
def OnRightUp(self, event):
#Hold onto the current line number, no way to get it later.
self._rightClickPosition = self.PositionFromPoint(event.GetPosition())
self._rightClickLine = self.LineFromPosition(self._rightClickPosition)
self.PopupMenu(self.CreatePopupMenu(), event.GetPosition())
self._rightClickLine = -1
self._rightClickPosition = -1
def CreatePopupMenu(self):
TOGGLEBREAKPOINT_ID = wx.NewId()
TOGGLEMARKER_ID = wx.NewId()
SYNCTREE_ID = wx.NewId()
menu = wx.Menu()
self.Bind(wx.EVT_MENU, self.OnPopSyncOutline, id=SYNCTREE_ID)
item = wx.MenuItem(menu, SYNCTREE_ID, _("Find in Outline View"))
menu.AppendItem(item)
menu.AppendSeparator()
self.Bind(wx.EVT_MENU, self.OnPopToggleBP, id=TOGGLEBREAKPOINT_ID)
item = wx.MenuItem(menu, TOGGLEBREAKPOINT_ID, _("Toggle Breakpoint"))
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnPopToggleMarker, id=TOGGLEMARKER_ID)
item = wx.MenuItem(menu, TOGGLEMARKER_ID, _("Toggle Bookmark"))
menu.AppendItem(item)
menu.AppendSeparator()
itemIDs = [wx.ID_UNDO, wx.ID_REDO, None,
wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL]
menuBar = wx.GetApp().GetTopWindow().GetMenuBar()
for itemID in itemIDs:
if not itemID:
menu.AppendSeparator()
else:
item = menuBar.FindItemById(itemID)
if item:
menu.Append(itemID, item.GetLabel())
wx.EVT_MENU(self, itemID, self.DSProcessEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow
wx.EVT_UPDATE_UI(self, itemID, self.DSProcessUpdateUIEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow
return menu
def OnPopToggleBP(self, event):
""" Toggle break point on right click line, not current line """
import DebuggerService
wx.GetApp().GetService(DebuggerService.DebuggerService).OnToggleBreakpoint(event, line=self._rightClickLine)
def OnPopToggleMarker(self, event):
""" Toggle marker on right click line, not current line """
wx.GetApp().GetDocumentManager().GetCurrentView().MarkerToggle(lineNum = self._rightClickLine)
def OnPopSyncOutline(self, event):
wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(wx.GetApp().GetDocumentManager().GetCurrentView(), position=self._rightClickPosition)
def HasSelection(self):
return self.GetSelectionStart() - self.GetSelectionEnd() != 0
def ClearCurrentLineMarkers(self):
self.MarkerDeleteAll(CodeCtrl.CURRENT_LINE_MARKER_NUM)
def ClearCurrentBreakpoinMarkers(self):
self.MarkerDeleteAll(CodeCtrl.BREAKPOINT_MARKER_NUM)
def GetDefaultFont(self):
if wx.Platform == '__WXMSW__':
font = "Courier New"
else:
font = "Courier"
return wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font)
def GetMatchingBraces(self):
""" Overwrite this method for language specific braces """
return "[]{}()"
def CanWordWrap(self):
return False
def SetFont(self, font):
self._font = font
def SetFontColor(self, fontColor):
self._fontColor = fontColor
def UpdateStyles(self):
if not self.GetFont():
return
faces = { 'font' : self.GetFont().GetFaceName(),
'size' : self.GetFont().GetPointSize(),
'size2': self.GetFont().GetPointSize() - 2,
'color' : "%02x%02x%02x" % (self.GetFontColor().Red(), self.GetFontColor().Green(), self.GetFontColor().Blue())
}
# Global default styles for all languages
self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(font)s,fore:#FFFFFF,size:%(size)d" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "face:%(font)s,back:#C0C0C0,face:%(font)s,size:%(size2)d" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_CONTROLCHAR, "face:%(font)s" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_BRACELIGHT, "face:%(font)s,fore:#000000,back:#70FFFF,size:%(size)d" % faces)
self.StyleSetSpec(wx.stc.STC_STYLE_BRACEBAD, "face:%(font)s,fore:#000000,back:#FF0000,size:%(size)d" % faces)
def OnKeyPressed(self, event):
if self.CallTipActive():
self.CallTipCancel()
key = event.KeyCode()
if False: # key == wx.WXK_SPACE and event.ControlDown():
pos = self.GetCurrentPos()
# Tips
if event.ShiftDown():
self.CallTipSetBackground("yellow")
self.CallTipShow(pos, 'param1, param2')
# Code completion
else:
#lst = []
#for x in range(50000):
# lst.append('%05d' % x)
#st = string.join(lst)
#print len(st)
#self.AutoCompShow(0, st)
kw = keyword.kwlist[:]
kw.append("zzzzzz")
kw.append("aaaaa")
kw.append("__init__")
kw.append("zzaaaaa")
kw.append("zzbaaaa")
kw.append("this_is_a_longer_value")
kw.append("this_is_a_much_much_much_much_much_much_much_longer_value")
kw.sort() # Python sorts are case sensitive
self.AutoCompSetIgnoreCase(False) # so this needs to match
self.AutoCompShow(0, string.join(kw))
elif key == wx.WXK_RETURN:
self.DoIndent()
else:
STCTextEditor.TextCtrl.OnKeyPressed(self, event)
def DoIndent(self):
self.AddText('\n')
self.EnsureCaretVisible()
# Need to do a default one for all languges
def OnMarginClick(self, evt):
# fold and unfold as needed
if evt.GetMargin() == 2:
if evt.GetShift() and evt.GetControl():
lineCount = self.GetLineCount()
expanding = True
# find out if we are folding or unfolding
for lineNum in range(lineCount):
if self.GetFoldLevel(lineNum) & wx.stc.STC_FOLDLEVELHEADERFLAG:
expanding = not self.GetFoldExpanded(lineNum)
break;
self.ToggleFoldAll(expanding)
else:
lineClicked = self.LineFromPosition(evt.GetPosition())
if self.GetFoldLevel(lineClicked) & wx.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)
elif evt.GetMargin() == 0:
#This is used to toggle breakpoints via the debugger service.
import DebuggerService
db_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
if db_service:
db_service.OnToggleBreakpoint(evt, line=self.LineFromPosition(evt.GetPosition()))
def OnUpdateUI(self, evt):
braces = self.GetMatchingBraces()
# 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 braces:
braceAtCaret = caretPos - 1
# check after
if braceAtCaret < 0:
charAfter = self.GetCharAt(caretPos)
styleAfter = self.GetStyleAt(caretPos)
if charAfter and chr(charAfter) in braces:
braceAtCaret = caretPos
if braceAtCaret >= 0:
braceOpposite = self.BraceMatch(braceAtCaret)
if braceAtCaret != -1 and braceOpposite == -1:
self.BraceBadLight(braceAtCaret)
else:
self.BraceHighlight(braceAtCaret, braceOpposite)
evt.Skip()
def ToggleFoldAll(self, expand = True, topLevelOnly = False):
i = 0
lineCount = self.GetLineCount()
while i < lineCount:
if not topLevelOnly or (topLevelOnly and self.GetFoldLevel(i) & wx.stc.STC_FOLDLEVELNUMBERMASK == wx.stc.STC_FOLDLEVELBASE):
if (expand and self.CanLineExpand(i)) or (not expand and self.CanLineCollapse(i)):
self.ToggleFold(i)
i = i + 1
def CanLineExpand(self, line):
return not self.GetFoldExpanded(line)
def CanLineCollapse(self, line):
return self.GetFoldExpanded(line) and self.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG
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 & wx.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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -