📄 codeeditor.py
字号:
self.GetCtrl().AutoCompSetAutoHide(0) self.GetCtrl().AutoCompSetChooseSingle(True) self.GetCtrl().AutoCompSetIgnoreCase(True) context, hint = self.GetAutoCompleteHint() replaceList, replaceLen = self.GetAutoCompleteKeywordList(context, hint) if replaceList and len(replaceList) != 0: self.GetCtrl().AutoCompShow(replaceLen, replaceList) def GetAutoCompleteHint(self): """ Replace this method with Editor specific method """ pos = self.GetCtrl().GetCurrentPos() if pos == 0: return None, None if chr(self.GetCtrl().GetCharAt(pos - 1)) == '.': pos = pos - 1 hint = None else: hint = '' validLetters = string.letters + string.digits + '_.' word = '' while (True): pos = pos - 1 if pos < 0: break char = chr(self.GetCtrl().GetCharAt(pos)) if char not in validLetters: break word = char + word context = word if hint is not None: lastDot = word.rfind('.') if lastDot != -1: context = word[0:lastDot] hint = word[lastDot+1:] return context, hint def GetAutoCompleteDefaultKeywords(self): """ Replace this method with Editor specific keywords """ return ['Put', 'Editor Specific', 'Keywords', 'Here'] def GetAutoCompleteKeywordList(self, context, hint): """ Replace this method with Editor specific keywords """ kw = self.GetAutoCompleteDefaultKeywords() if hint and len(hint): lowerHint = hint.lower() filterkw = filter(lambda item: item.lower().startswith(lowerHint), kw) # remove variables and methods that don't match hint kw = filterkw if hint: replaceLen = len(hint) else: replaceLen = 0 kw.sort(CaseInsensitiveCompare) return " ".join(kw), replaceLen def OnCleanWhiteSpace(self): newText = "" for lineNo in self._GetSelectedLineNumbers(): lineText = string.rstrip(self.GetCtrl().GetLine(lineNo)) indent = 0 lstrip = 0 for char in lineText: if char == '\t': indent = indent + self.GetCtrl().GetIndent() lstrip = lstrip + 1 elif char in string.whitespace: indent = indent + 1 lstrip = lstrip + 1 else: break if self.GetCtrl().GetUseTabs(): indentText = (indent / self.GetCtrl().GetIndent()) * '\t' + (indent % self.GetCtrl().GetIndent()) * ' ' else: indentText = indent * ' ' lineText = indentText + lineText[lstrip:] + '\n' newText = newText + lineText self._ReplaceSelectedLines(newText) def OnSetIndentWidth(self): dialog = wx.TextEntryDialog(self._GetParentFrame(), _("Enter new indent width (2-10):"), _("Set Indent Width"), "%i" % self.GetCtrl().GetIndent()) dialog.CenterOnParent() if dialog.ShowModal() == wx.ID_OK: try: indent = int(dialog.GetValue()) if indent >= 2 and indent <= 10: self.GetCtrl().SetIndent(indent) self.GetCtrl().SetTabWidth(indent) except: pass dialog.Destroy() def GetIndentWidth(self): return self.GetCtrl().GetIndent() def OnCommentLines(self): newText = "" for lineNo in self._GetSelectedLineNumbers(): lineText = self.GetCtrl().GetLine(lineNo) if (len(lineText) > 1 and lineText[0] == '#') or (len(lineText) > 2 and lineText[:2] == '##'): newText = newText + lineText else: newText = newText + "##" + lineText self._ReplaceSelectedLines(newText) def OnUncommentLines(self): newText = "" for lineNo in self._GetSelectedLineNumbers(): lineText = self.GetCtrl().GetLine(lineNo) if len(lineText) >= 2 and lineText[:2] == "##": lineText = lineText[2:] elif len(lineText) >= 1 and lineText[:1] == "#": lineText = lineText[1:] newText = newText + lineText self._ReplaceSelectedLines(newText) def _GetSelectedLineNumbers(self): selStart, selEnd = self._GetPositionsBoundingSelectedLines() return range(self.GetCtrl().LineFromPosition(selStart), self.GetCtrl().LineFromPosition(selEnd)) def _GetPositionsBoundingSelectedLines(self): startPos = self.GetCtrl().GetCurrentPos() endPos = self.GetCtrl().GetAnchor() if startPos > endPos: temp = endPos endPos = startPos startPos = temp if endPos == self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(endPos)): endPos = endPos - 1 # If it's at the very beginning of a line, use the line above it as the ending line selStart = self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(startPos)) selEnd = self.GetCtrl().PositionFromLine(self.GetCtrl().LineFromPosition(endPos) + 1) return selStart, selEnd def _ReplaceSelectedLines(self, text): if len(text) == 0: return selStart, selEnd = self._GetPositionsBoundingSelectedLines() self.GetCtrl().SetSelection(selStart, selEnd) self.GetCtrl().ReplaceSelection(text) self.GetCtrl().SetSelection(selStart + len(text), selStart) def OnUpdate(self, sender = None, hint = None): if wx.lib.docview.View.OnUpdate(self, sender, hint): return if hint == "ViewStuff": self.GetCtrl().SetViewDefaults() elif hint == "Font": font, color = self.GetCtrl().GetFontAndColorFromConfig() self.GetCtrl().SetFont(font) self.GetCtrl().SetFontColor(color) else: import DebuggerService dbg_service = wx.GetApp().GetService(DebuggerService.DebuggerService) if dbg_service: dbg_service.SetCurrentBreakpointMarkers(self)class CodeService(STCTextEditor.TextService): def __init__(self): STCTextEditor.TextService.__init__(self) def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None): # TODO NEED TO DO INSTANCEOF CHECK HERE FOR SDI #if document and document.GetDocumentTemplate().GetDocumentType() != TextDocument: # return if not document and wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI: return viewMenu = menuBar.GetMenu(menuBar.FindMenu(_("&View"))) isWindows = (wx.Platform == '__WXMSW__') if not menuBar.FindItemById(EXPAND_TEXT_ID): # check if below menu items have been already been installed foldingMenu = wx.Menu() if isWindows: foldingMenu.Append(EXPAND_TEXT_ID, _("&Expand\tNumpad-Plus"), _("Expands a collapsed block of text")) else: foldingMenu.Append(EXPAND_TEXT_ID, _("&Expand"), _("Expands a collapsed block of text")) wx.EVT_MENU(frame, EXPAND_TEXT_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, EXPAND_TEXT_ID, frame.ProcessUpdateUIEvent) if isWindows: foldingMenu.Append(COLLAPSE_TEXT_ID, _("&Collapse\tNumpad+Minus"), _("Collapse a block of text")) else: foldingMenu.Append(COLLAPSE_TEXT_ID, _("&Collapse"), _("Collapse a block of text")) wx.EVT_MENU(frame, COLLAPSE_TEXT_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, COLLAPSE_TEXT_ID, frame.ProcessUpdateUIEvent) if isWindows: foldingMenu.Append(EXPAND_TOP_ID, _("Expand &Top Level\tCtrl+Numpad+Plus"), _("Expands the top fold levels in the document")) else: foldingMenu.Append(EXPAND_TOP_ID, _("Expand &Top Level"), _("Expands the top fold levels in the document")) wx.EVT_MENU(frame, EXPAND_TOP_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, EXPAND_TOP_ID, frame.ProcessUpdateUIEvent) if isWindows: foldingMenu.Append(COLLAPSE_TOP_ID, _("Collapse Top &Level\tCtrl+Numpad+Minus"), _("Collapses the top fold levels in the document")) else: foldingMenu.Append(COLLAPSE_TOP_ID, _("Collapse Top &Level"), _("Collapses the top fold levels in the document")) wx.EVT_MENU(frame, COLLAPSE_TOP_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, COLLAPSE_TOP_ID, frame.ProcessUpdateUIEvent) if isWindows: foldingMenu.Append(EXPAND_ALL_ID, _("Expand &All\tShift+Numpad+Plus"), _("Expands all of the fold levels in the document")) else: foldingMenu.Append(EXPAND_ALL_ID, _("Expand &All"), _("Expands all of the fold levels in the document")) wx.EVT_MENU(frame, EXPAND_ALL_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, EXPAND_ALL_ID, frame.ProcessUpdateUIEvent) if isWindows: foldingMenu.Append(COLLAPSE_ALL_ID, _("Colla&pse All\tShift+Numpad+Minus"), _("Collapses all of the fold levels in the document")) else: foldingMenu.Append(COLLAPSE_ALL_ID, _("Colla&pse All"), _("Collapses all of the fold levels in the document")) wx.EVT_MENU(frame, COLLAPSE_ALL_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, COLLAPSE_ALL_ID, frame.ProcessUpdateUIEvent) viewMenu.AppendMenu(FOLDING_ID, _("&Folding"), foldingMenu) wx.EVT_UPDATE_UI(frame, FOLDING_ID, frame.ProcessUpdateUIEvent) formatMenuIndex = menuBar.FindMenu(_("&Format")) if formatMenuIndex > -1: formatMenu = menuBar.GetMenu(formatMenuIndex) else: formatMenu = wx.Menu() if not menuBar.FindItemById(CHECK_CODE_ID): # check if below menu items have been already been installed formatMenu.AppendSeparator() formatMenu.Append(CHECK_CODE_ID, _("&Check Code"), _("Checks the document for syntax and indentation errors")) wx.EVT_MENU(frame, CHECK_CODE_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, CHECK_CODE_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(AUTO_COMPLETE_ID, _("&Auto Complete\tCtrl+Space"), _("Provides suggestions on how to complete the current statement")) wx.EVT_MENU(frame, AUTO_COMPLETE_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, AUTO_COMPLETE_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(CLEAN_WHITESPACE, _("Clean &Whitespace"), _("Converts leading spaces to tabs or vice versa per 'use tabs' and clears trailing spaces")) wx.EVT_MENU(frame, CLEAN_WHITESPACE, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, CLEAN_WHITESPACE, frame.ProcessUpdateUIEvent) formatMenu.AppendSeparator() formatMenu.Append(INDENT_LINES_ID, _("&Indent Lines\tTab"), _("Indents the selected lines one indent width")) wx.EVT_MENU(frame, INDENT_LINES_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, INDENT_LINES_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(DEDENT_LINES_ID, _("&Dedent Lines\tShift+Tab"), _("Dedents the selected lines one indent width")) wx.EVT_MENU(frame, DEDENT_LINES_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, DEDENT_LINES_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(COMMENT_LINES_ID, _("Comment &Lines\tCtrl+Q"), _("Comments out the selected lines be prefixing each one with a comment indicator")) wx.EVT_MENU(frame, COMMENT_LINES_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, COMMENT_LINES_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(UNCOMMENT_LINES_ID, _("&Uncomment Lines\tCtrl+Shift+Q"), _("Removes comment prefixes from each of the selected lines")) wx.EVT_MENU(frame, UNCOMMENT_LINES_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, UNCOMMENT_LINES_ID, frame.ProcessUpdateUIEvent) formatMenu.AppendSeparator() formatMenu.AppendCheckItem(USE_TABS_ID, _("Use &Tabs"), _("Toggles use of tabs or whitespaces for indents")) wx.EVT_MENU(frame, USE_TABS_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, USE_TABS_ID, frame.ProcessUpdateUIEvent) formatMenu.Append(SET_INDENT_WIDTH_ID, _("&Set Indent Width..."), _("Sets the indent width")) wx.EVT_MENU(frame, SET_INDENT_WIDTH_ID, frame.ProcessEvent) wx.EVT_UPDATE_UI(frame, SET_INDENT_WIDTH_ID, frame.ProcessUpdateUIEvent) if formatMenuIndex == -1: viewMenuIndex = menuBar.FindMenu(_("&View")) menuBar.Insert(viewMenuIndex + 1, formatMenu, _("&Format"))## accelTable = wx.AcceleratorTable([## (wx.ACCEL_NORMAL, wx.WXK_TAB, INDENT_LINES_ID),## (wx.ACCEL_SHIFT, wx.WXK_TAB, DEDENT_LINES_ID),## eval(_("wx.ACCEL_CTRL, ord('Q'), COMMENT_LINES_ID")),## eval(_("wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord('Q'), UNCOMMENT_LINES_ID"))## ])## frame.SetAcceleratorTable(accelTable) def ProcessUpdateUIEvent(self, event): id = event.GetId() if (id == EXPAND_TEXT_ID or id == COLLAPSE_TEXT_ID or id == EXPAND_TOP_ID or id == COLLAPSE_TOP_ID or id == EXPAND_ALL_ID or id == COLLAPSE_ALL_ID or id == CHECK_CODE_ID or id == AUTO_COMPLETE_ID or id == CLEAN_WHITESPACE or id == SET_INDENT_WIDTH_ID or id == USE_TABS_ID or id == INDENT_LINES_ID or id == DEDENT_LINES_ID or id == COMMENT_LINES_ID or id == UNCOMMENT_LINES_ID or id == FOLDING_ID): event.Enable(False) return True else: return STCTextEditor.TextService.ProcessUpdateUIEvent(self, event)class CodeCtrl(STCTextEditor.TextCtrl): CURRENT_LINE_MARKER_NUM = 2 BREAKPOINT_MARKER_NUM = 1 CURRENT_LINE_MARKER_MASK = 0x4 BREAKPOINT_MARKER_MASK = 0x2 def __init__(self, parent, id=-1, style = wx.NO_FULL_REPAINT_ON_RESIZE, clearTab=True): STCTextEditor.TextCtrl.__init__(self, parent, id, style) self.UsePopUp(False) self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) self.SetProperty("fold", "1")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -