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