📄 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 + -