Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
control.py570 linesDownload Raw Back to scintilla
1# An Python interface to the Scintilla control.2#3# Exposes Python classes that allow you to use Scintilla as4# a "standard" MFC edit control (eg, control.GetTextLength(), control.GetSel()5# plus many Scintilla specific features (eg control.SCIAddStyledText())6 7import array8import os9import struct10 11import win32api12import win32con13import win32ui14from pywin import default_scintilla_encoding15from pywin.mfc import window16 17from . import scintillacon18 19# Load Scintilla.dll to get access to the control.20# We expect to find this in the same directory as win32ui.pyd21dllid = None22if win32ui.debug:  # If running _d version of Pythonwin...23    try:24        dllid = win32api.LoadLibrary(25            os.path.join(os.path.split(win32ui.__file__)[0], "Scintilla_d.DLL")26        )27    except (28        win32api.error29    ):  # Not there - we dont _need_ a debug ver, so ignore this error.30        pass31if dllid is None:32    try:33        dllid = win32api.LoadLibrary(34            os.path.join(os.path.split(win32ui.__file__)[0], "Scintilla.DLL")35        )36    except win32api.error:37        pass38if dllid is None:39    # Still not there - lets see if Windows can find it by searching?40    dllid = win32api.LoadLibrary("Scintilla.DLL")41 42# null_byte is str in py2k, bytes on py3k43null_byte = "\0".encode("ascii")44 45## These are from Richedit.h - need to add to win32con or commctrl46EM_GETTEXTRANGE = 109947EM_EXLINEFROMCHAR = 107848EM_FINDTEXTEX = 110349EM_GETSELTEXT = 108650EM_EXSETSEL = win32con.WM_USER + 5551 52 53class ScintillaNotification:54    def __init__(self, **args):55        self.__dict__.update(args)56 57 58class ScintillaControlInterface:59    def SCIUnpackNotifyMessage(self, msg):60        format = "iiiiPiiiPPiiii"61        bytes = win32ui.GetBytes(msg, struct.calcsize(format))62        (63            position,64            ch,65            modifiers,66            modificationType,67            text_ptr,68            length,69            linesAdded,70            msg,71            wParam,72            lParam,73            line,74            foldLevelNow,75            foldLevelPrev,76            margin,77        ) = struct.unpack(format, bytes)78        return ScintillaNotification(79            position=position,80            ch=ch,81            modifiers=modifiers,82            modificationType=modificationType,83            text_ptr=text_ptr,84            length=length,85            linesAdded=linesAdded,86            msg=msg,87            wParam=wParam,88            lParam=lParam,89            line=line,90            foldLevelNow=foldLevelNow,91            foldLevelPrev=foldLevelPrev,92            margin=margin,93        )94 95    def SCIAddText(self, text):96        self.SendMessage(97            scintillacon.SCI_ADDTEXT, text.encode(default_scintilla_encoding)98        )99 100    def SCIAddStyledText(self, text, style=None):101        # If style is None, text is assumed to be a "native" Scintilla buffer.102        # If style is specified, text is a normal string, and the style is103        # assumed to apply to the entire string.104        if style is not None:105            text = list(map(lambda char, style=style: char + chr(style), text))106            text = "".join(text)107        self.SendMessage(108            scintillacon.SCI_ADDSTYLEDTEXT, text.encode(default_scintilla_encoding)109        )110 111    def SCIInsertText(self, text, pos=-1):112        # SCIInsertText allows unicode or bytes - but if they are bytes,113        # the caller must ensure it is encoded correctly.114        if isinstance(text, str):115            text = text.encode(default_scintilla_encoding)116        self.SendScintilla(scintillacon.SCI_INSERTTEXT, pos, text + null_byte)117 118    def SCISetSavePoint(self):119        self.SendScintilla(scintillacon.SCI_SETSAVEPOINT)120 121    def SCISetUndoCollection(self, collectFlag):122        self.SendScintilla(scintillacon.SCI_SETUNDOCOLLECTION, collectFlag)123 124    def SCIBeginUndoAction(self):125        self.SendScintilla(scintillacon.SCI_BEGINUNDOACTION)126 127    def SCIEndUndoAction(self):128        self.SendScintilla(scintillacon.SCI_ENDUNDOACTION)129 130    def SCIGetCurrentPos(self):131        return self.SendScintilla(scintillacon.SCI_GETCURRENTPOS)132 133    def SCIGetCharAt(self, pos):134        # Must ensure char is unsigned!135        return chr(self.SendScintilla(scintillacon.SCI_GETCHARAT, pos) & 0xFF)136 137    def SCIGotoLine(self, line):138        self.SendScintilla(scintillacon.SCI_GOTOLINE, line)139 140    def SCIBraceMatch(self, pos, maxReStyle):141        return self.SendScintilla(scintillacon.SCI_BRACEMATCH, pos, maxReStyle)142 143    def SCIBraceHighlight(self, pos, posOpposite):144        return self.SendScintilla(scintillacon.SCI_BRACEHIGHLIGHT, pos, posOpposite)145 146    def SCIBraceBadHighlight(self, pos):147        return self.SendScintilla(scintillacon.SCI_BRACEBADLIGHT, pos)148 149    ####################################150    # Styling151    # 	def SCIColourise(self, start=0, end=-1):152    #   NOTE - dependent on of we use builtin lexer, so handled below.153    def SCIGetEndStyled(self):154        return self.SendScintilla(scintillacon.SCI_GETENDSTYLED)155 156    def SCIStyleSetFore(self, num, v):157        return self.SendScintilla(scintillacon.SCI_STYLESETFORE, num, v)158 159    def SCIStyleSetBack(self, num, v):160        return self.SendScintilla(scintillacon.SCI_STYLESETBACK, num, v)161 162    def SCIStyleSetEOLFilled(self, num, v):163        return self.SendScintilla(scintillacon.SCI_STYLESETEOLFILLED, num, v)164 165    def SCIStyleSetFont(self, num, name, characterset=0):166        buff = (name + "\0").encode(default_scintilla_encoding)167        self.SendScintilla(scintillacon.SCI_STYLESETFONT, num, buff)168        self.SendScintilla(scintillacon.SCI_STYLESETCHARACTERSET, num, characterset)169 170    def SCIStyleSetBold(self, num, bBold):171        self.SendScintilla(scintillacon.SCI_STYLESETBOLD, num, bBold)172 173    def SCIStyleSetItalic(self, num, bItalic):174        self.SendScintilla(scintillacon.SCI_STYLESETITALIC, num, bItalic)175 176    def SCIStyleSetSize(self, num, size):177        self.SendScintilla(scintillacon.SCI_STYLESETSIZE, num, size)178 179    def SCIGetViewWS(self):180        return self.SendScintilla(scintillacon.SCI_GETVIEWWS)181 182    def SCISetViewWS(self, val):183        self.SendScintilla(scintillacon.SCI_SETVIEWWS, not (val == 0))184        self.InvalidateRect()185 186    def SCISetIndentationGuides(self, val):187        self.SendScintilla(scintillacon.SCI_SETINDENTATIONGUIDES, val)188 189    def SCIGetIndentationGuides(self):190        return self.SendScintilla(scintillacon.SCI_GETINDENTATIONGUIDES)191 192    def SCISetIndent(self, val):193        self.SendScintilla(scintillacon.SCI_SETINDENT, val)194 195    def SCIGetIndent(self, val):196        return self.SendScintilla(scintillacon.SCI_GETINDENT)197 198    def SCIGetViewEOL(self):199        return self.SendScintilla(scintillacon.SCI_GETVIEWEOL)200 201    def SCISetViewEOL(self, val):202        self.SendScintilla(scintillacon.SCI_SETVIEWEOL, not (val == 0))203        self.InvalidateRect()204 205    def SCISetTabWidth(self, width):206        self.SendScintilla(scintillacon.SCI_SETTABWIDTH, width, 0)207 208    def SCIStartStyling(self, pos, mask):209        self.SendScintilla(scintillacon.SCI_STARTSTYLING, pos, mask)210 211    def SCISetStyling(self, pos, attr):212        self.SendScintilla(scintillacon.SCI_SETSTYLING, pos, attr)213 214    def SCISetStylingEx(self, ray):  # ray is an array.215        address, length = ray.buffer_info()216        self.SendScintilla(scintillacon.SCI_SETSTYLINGEX, length, address)217 218    def SCIGetStyleAt(self, pos):219        return self.SendScintilla(scintillacon.SCI_GETSTYLEAT, pos)220 221    def SCISetMarginWidth(self, width):222        self.SendScintilla(scintillacon.SCI_SETMARGINWIDTHN, 1, width)223 224    def SCISetMarginWidthN(self, n, width):225        self.SendScintilla(scintillacon.SCI_SETMARGINWIDTHN, n, width)226 227    def SCISetFoldFlags(self, flags):228        self.SendScintilla(scintillacon.SCI_SETFOLDFLAGS, flags)229 230    # Markers231    def SCIMarkerDefineAll(self, markerNum, markerType, fore, back):232        self.SCIMarkerDefine(markerNum, markerType)233        self.SCIMarkerSetFore(markerNum, fore)234        self.SCIMarkerSetBack(markerNum, back)235 236    def SCIMarkerDefine(self, markerNum, markerType):237        self.SendScintilla(scintillacon.SCI_MARKERDEFINE, markerNum, markerType)238 239    def SCIMarkerSetFore(self, markerNum, fore):240        self.SendScintilla(scintillacon.SCI_MARKERSETFORE, markerNum, fore)241 242    def SCIMarkerSetBack(self, markerNum, back):243        self.SendScintilla(scintillacon.SCI_MARKERSETBACK, markerNum, back)244 245    def SCIMarkerAdd(self, lineNo, markerNum):246        self.SendScintilla(scintillacon.SCI_MARKERADD, lineNo, markerNum)247 248    def SCIMarkerDelete(self, lineNo, markerNum):249        self.SendScintilla(scintillacon.SCI_MARKERDELETE, lineNo, markerNum)250 251    def SCIMarkerDeleteAll(self, markerNum=-1):252        self.SendScintilla(scintillacon.SCI_MARKERDELETEALL, markerNum)253 254    def SCIMarkerGet(self, lineNo):255        return self.SendScintilla(scintillacon.SCI_MARKERGET, lineNo)256 257    def SCIMarkerNext(self, lineNo, markerNum):258        return self.SendScintilla(scintillacon.SCI_MARKERNEXT, lineNo, markerNum)259 260    def SCICancel(self):261        self.SendScintilla(scintillacon.SCI_CANCEL)262 263    # AutoComplete264    def SCIAutoCShow(self, text):265        if type(text) in [type([]), type(())]:266            text = " ".join(text)267        buff = (text + "\0").encode(default_scintilla_encoding)268        return self.SendScintilla(scintillacon.SCI_AUTOCSHOW, 0, buff)269 270    def SCIAutoCCancel(self):271        self.SendScintilla(scintillacon.SCI_AUTOCCANCEL)272 273    def SCIAutoCActive(self):274        return self.SendScintilla(scintillacon.SCI_AUTOCACTIVE)275 276    def SCIAutoCComplete(self):277        return self.SendScintilla(scintillacon.SCI_AUTOCCOMPLETE)278 279    def SCIAutoCStops(self, stops):280        buff = (stops + "\0").encode(default_scintilla_encoding)281        self.SendScintilla(scintillacon.SCI_AUTOCSTOPS, 0, buff)282 283    def SCIAutoCSetAutoHide(self, hide):284        self.SendScintilla(scintillacon.SCI_AUTOCSETAUTOHIDE, hide)285 286    def SCIAutoCSetFillups(self, fillups):287        self.SendScintilla(scintillacon.SCI_AUTOCSETFILLUPS, fillups)288 289    # Call tips290    def SCICallTipShow(self, text, pos=-1):291        if pos == -1:292            pos = self.GetSel()[0]293        buff = (text + "\0").encode(default_scintilla_encoding)294        self.SendScintilla(scintillacon.SCI_CALLTIPSHOW, pos, buff)295 296    def SCICallTipCancel(self):297        self.SendScintilla(scintillacon.SCI_CALLTIPCANCEL)298 299    def SCICallTipActive(self):300        return self.SendScintilla(scintillacon.SCI_CALLTIPACTIVE)301 302    def SCICallTipPosStart(self):303        return self.SendScintilla(scintillacon.SCI_CALLTIPPOSSTART)304 305    def SCINewline(self):306        self.SendScintilla(scintillacon.SCI_NEWLINE)307 308    # Lexer etc309    def SCISetKeywords(self, keywords, kw_list_no=0):310        buff = (keywords + "\0").encode(default_scintilla_encoding)311        self.SendScintilla(scintillacon.SCI_SETKEYWORDS, kw_list_no, buff)312 313    def SCISetProperty(self, name, value):314        name_buff = array.array("b", (name + "\0").encode(default_scintilla_encoding))315        val_buff = array.array(316            "b", (str(value) + "\0").encode(default_scintilla_encoding)317        )318        address_name_buffer = name_buff.buffer_info()[0]319        address_val_buffer = val_buff.buffer_info()[0]320        self.SendScintilla(321            scintillacon.SCI_SETPROPERTY, address_name_buffer, address_val_buffer322        )323 324    def SCISetStyleBits(self, nbits):325        self.SendScintilla(scintillacon.SCI_SETSTYLEBITS, nbits)326 327    # Folding328    def SCIGetFoldLevel(self, lineno):329        return self.SendScintilla(scintillacon.SCI_GETFOLDLEVEL, lineno)330 331    def SCIToggleFold(self, lineno):332        return self.SendScintilla(scintillacon.SCI_TOGGLEFOLD, lineno)333 334    def SCIEnsureVisible(self, lineno):335        self.SendScintilla(scintillacon.SCI_ENSUREVISIBLE, lineno)336 337    def SCIGetFoldExpanded(self, lineno):338        return self.SendScintilla(scintillacon.SCI_GETFOLDEXPANDED, lineno)339 340    # right edge341    def SCISetEdgeColumn(self, edge):342        self.SendScintilla(scintillacon.SCI_SETEDGECOLUMN, edge)343 344    def SCIGetEdgeColumn(self):345        return self.SendScintilla(scintillacon.SCI_GETEDGECOLUMN)346 347    def SCISetEdgeMode(self, mode):348        self.SendScintilla(scintillacon.SCI_SETEDGEMODE, mode)349 350    def SCIGetEdgeMode(self):351        return self.SendScintilla(scintillacon.SCI_GETEDGEMODE)352 353    def SCISetEdgeColor(self, color):354        self.SendScintilla(scintillacon.SCI_SETEDGECOLOUR, color)355 356    def SCIGetEdgeColor(self):357        return self.SendScintilla(scintillacon.SCI_GETEDGECOLOR)358 359    # Multi-doc360    def SCIGetDocPointer(self):361        return self.SendScintilla(scintillacon.SCI_GETDOCPOINTER)362 363    def SCISetDocPointer(self, p):364        return self.SendScintilla(scintillacon.SCI_SETDOCPOINTER, 0, p)365 366    def SCISetWrapMode(self, mode):367        return self.SendScintilla(scintillacon.SCI_SETWRAPMODE, mode)368 369    def SCIGetWrapMode(self):370        return self.SendScintilla(scintillacon.SCI_GETWRAPMODE)371 372 373class CScintillaEditInterface(ScintillaControlInterface):374    def close(self):375        self.colorizer = None376 377    def Clear(self):378        self.SendScintilla(win32con.WM_CLEAR)379 380    def FindText(self, flags, range, findText):381        """LPARAM for EM_FINDTEXTEX:382                typedef struct _findtextex {383                CHARRANGE chrg;384                LPCTSTR lpstrText;385                CHARRANGE chrgText;} FINDTEXTEX;386        typedef struct _charrange {387                LONG cpMin;388                LONG cpMax;} CHARRANGE;389        """390        findtextex_fmt = "llPll"391        ## Scintilla does not handle unicode in EM_FINDTEXT msg (FINDTEXTEX struct)392        txt_buff = (findText + "\0").encode(default_scintilla_encoding)393        txt_array = array.array("b", txt_buff)394        ft_buff = struct.pack(395            findtextex_fmt, range[0], range[1], txt_array.buffer_info()[0], 0, 0396        )397        ft_array = array.array("b", ft_buff)398        rc = self.SendScintilla(EM_FINDTEXTEX, flags, ft_array.buffer_info()[0])399        ftUnpacked = struct.unpack(findtextex_fmt, ft_array)400        return rc, (ftUnpacked[3], ftUnpacked[4])401 402    def GetSel(self):403        currentPos = self.SendScintilla(scintillacon.SCI_GETCURRENTPOS)404        anchorPos = self.SendScintilla(scintillacon.SCI_GETANCHOR)405        if currentPos < anchorPos:406            return (currentPos, anchorPos)407        else:408            return (anchorPos, currentPos)409        return currentPos410 411    def GetSelText(self):412        start, end = self.GetSel()413        txtBuf = array.array("b", null_byte * (end - start + 1))414        addressTxtBuf = txtBuf.buffer_info()[0]415        # EM_GETSELTEXT is documented as returning the number of chars416        # not including the NULL, but scintilla includes the NULL.  A417        # quick glance at the scintilla impl doesn't make this418        # obvious - the NULL is included in the 'selection' object419        # and reflected in the length of that 'selection' object.420        # I expect that is a bug in scintilla and may be fixed by now,421        # but we just blindly assume that the last char is \0 and422        # strip it.423        self.SendScintilla(EM_GETSELTEXT, 0, addressTxtBuf)424        return txtBuf.tobytes()[:-1].decode(default_scintilla_encoding)425 426    def SetSel(self, start=0, end=None):427        if type(start) == type(()):428            assert (429                end is None430            ), "If you pass a point in the first param, the second must be None"431            start, end = start432        elif end is None:433            end = start434        if start < 0:435            start = self.GetTextLength()436        if end < 0:437            end = self.GetTextLength()438        assert start <= self.GetTextLength(), "The start postion is invalid (%d/%d)" % (439            start,440            self.GetTextLength(),441        )442        assert end <= self.GetTextLength(), "The end postion is invalid (%d/%d)" % (443            end,444            self.GetTextLength(),445        )446        cr = struct.pack("ll", start, end)447        crBuff = array.array("b", cr)448        addressCrBuff = crBuff.buffer_info()[0]449        rc = self.SendScintilla(EM_EXSETSEL, 0, addressCrBuff)450 451    def GetLineCount(self):452        return self.SendScintilla(win32con.EM_GETLINECOUNT)453 454    def LineFromChar(self, charPos=-1):455        if charPos == -1:456            charPos = self.GetSel()[0]457        assert (458            charPos >= 0 and charPos <= self.GetTextLength()459        ), "The charPos postion (%s) is invalid (max=%s)" % (460            charPos,461            self.GetTextLength(),462        )463        # return self.SendScintilla(EM_EXLINEFROMCHAR, charPos)464        # EM_EXLINEFROMCHAR puts charPos in lParam, not wParam465        return self.SendScintilla(EM_EXLINEFROMCHAR, 0, charPos)466 467    def LineIndex(self, line):468        return self.SendScintilla(win32con.EM_LINEINDEX, line)469 470    def ScrollCaret(self):471        return self.SendScintilla(win32con.EM_SCROLLCARET)472 473    def GetCurLineNumber(self):474        return self.LineFromChar(self.SCIGetCurrentPos())475 476    def GetTextLength(self):477        return self.SendScintilla(scintillacon.SCI_GETTEXTLENGTH)478 479    def GetTextRange(self, start=0, end=-1, decode=True):480        if end == -1:481            end = self.SendScintilla(scintillacon.SCI_GETTEXTLENGTH)482        assert end >= start, "Negative index requested (%d/%d)" % (start, end)483        assert (484            start >= 0 and start <= self.GetTextLength()485        ), "The start postion is invalid"486        assert end >= 0 and end <= self.GetTextLength(), "The end postion is invalid"487        initer = null_byte * (end - start + 1)488        buff = array.array("b", initer)489        addressBuffer = buff.buffer_info()[0]490        tr = struct.pack("llP", start, end, addressBuffer)491        trBuff = array.array("b", tr)492        addressTrBuff = trBuff.buffer_info()[0]493        num_bytes = self.SendScintilla(EM_GETTEXTRANGE, 0, addressTrBuff)494        ret = buff.tobytes()[:num_bytes]495        if decode:496            ret = ret.decode(default_scintilla_encoding)497        return ret498 499    def ReplaceSel(self, str):500        buff = (str + "\0").encode(default_scintilla_encoding)501        self.SendScintilla(scintillacon.SCI_REPLACESEL, 0, buff)502 503    def GetLine(self, line=-1):504        if line == -1:505            line = self.GetCurLineNumber()506        start = self.LineIndex(line)507        end = self.LineIndex(line + 1)508        return self.GetTextRange(start, end)509 510    def SetReadOnly(self, flag=1):511        return self.SendScintilla(win32con.EM_SETREADONLY, flag)512 513    def LineScroll(self, lines, cols=0):514        return self.SendScintilla(win32con.EM_LINESCROLL, cols, lines)515 516    def GetFirstVisibleLine(self):517        return self.SendScintilla(win32con.EM_GETFIRSTVISIBLELINE)518 519    def SetWordWrap(self, mode):520        if mode != win32ui.CRichEditView_WrapNone:521            raise ValueError("We dont support word-wrap (I dont think :-)")522 523 524class CScintillaColorEditInterface(CScintillaEditInterface):525    ################################526    # Plug-in colorizer support527    def _GetColorizer(self):528        if not hasattr(self, "colorizer"):529            self.colorizer = self._MakeColorizer()530        return self.colorizer531 532    def _MakeColorizer(self):533        # Give parent a chance to hook.534        parent_func = getattr(self.GetParentFrame(), "_MakeColorizer", None)535        if parent_func is not None:536            return parent_func()537        from . import formatter538 539        ##		return formatter.PythonSourceFormatter(self)540        return formatter.BuiltinPythonSourceFormatter(self)541 542    def Colorize(self, start=0, end=-1):543        c = self._GetColorizer()544        if c is not None:545            c.Colorize(start, end)546 547    def ApplyFormattingStyles(self, bReload=1):548        c = self._GetColorizer()549        if c is not None:550            c.ApplyFormattingStyles(bReload)551 552    # The Parent window will normally hook553    def HookFormatter(self, parent=None):554        c = self._GetColorizer()555        if c is not None:  # No need if we have no color!556            c.HookFormatter(parent)557 558 559class CScintillaEdit(window.Wnd, CScintillaColorEditInterface):560    def __init__(self, wnd=None):561        if wnd is None:562            wnd = win32ui.CreateWnd()563        window.Wnd.__init__(self, wnd)564 565    def SendScintilla(self, msg, w=0, l=0):566        return self.SendMessage(msg, w, l)567 568    def CreateWindow(self, style, rect, parent, id):569        self._obj_.CreateWindow("Scintilla", "Scintilla", style, rect, parent, id, None)570 
codekingpro/portable-devtools · Team Ai