notepad-plus-plus/scintilla/test/ScintillaCallable.py
Christian Grasser b39ca37c3a Update: Scintilla 5.3.5 Lexilla 5.2.5
update to Scinitlla Release 5.3.5 (https://www.scintilla.org/scintilla535.zip)

    Released 31 May 2023.
    On Win32, implement IME context sensitivity with IMR_DOCUMENTFEED. Feature #1310.
    On Win32 remove dependence on MSIMG32.DLL by replacing AlphaBlend by GdiAlphaBlend. Bug #1923.
    On Qt, stop movement of IME candidate box.
    On Qt, report correct caret position within paragraph for IME retrieve surrounding text.
    On Qt for Cocoa, fix crash in entry of multi-character strings with IME.

and Lexilla Release 5.2.5 (https://www.scintilla.org/lexilla525.zip)

    Released 31 May 2023.
    Add CharacterSetArray constructor without setBase initial argument for common case where this is setNone and the initialSet argument completely defines the characters. This shortens and clarifies use of CharacterSetArray.
    Bash: implement highlighting inside quoted elements and here-docs. Controlled with properties lexer.bash.styling.inside.string, lexer.bash.styling.inside.backticks, lexer.bash.styling.inside.parameter, and lexer.bash.styling.inside.heredoc. Issue #154, Issue #153, Feature #1033.
    Bash: add property lexer.bash.command.substitution to choose how to style command substitutions. 0 → SCE_SH_BACKTICKS; 1 → surrounding "$(" and ")" as operators and contents styled as bash code; 2 → use distinct styles (base style + 64) for contents. Choice (2) is a provisional feature and details may change before it is finalized. Issue #153.
    Bash: fix nesting of parameters (SCE_SH_PARAM) like ${var/$sub/"${rep}}"}. Issue #154.
    Bash: fix single character special parameters like $? by limiting style. Issue #154.
    Bash: treat "$$" as special parameter and end scalars before "$". Issue #154.
    Bash: treat "<<" in arithmetic contexts as left bitwise shift operator instead of here-doc. Issue #137.
    Batch: style SCE_BAT_AFTER_LABEL used for rest of line after label which is not executed. Issue #148.
    F#: Lex interpolated verbatim strings as verbatim. Issue #156.
    VB: allow multiline strings when lexer.vb.strings.multiline set. Issue #151.

Close #13729
2023-06-02 14:15:54 +02:00

214 lines
6.5 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import ctypes
from ctypes import c_int, c_char_p, c_long, c_ssize_t
def IsEnumeration(t):
return t[:1].isupper()
basicTypes = ["bool", "int", "position", "line", "pointer", "colour", "colouralpha"]
def BasicTypeOrEnumeration(t):
return t in basicTypes or IsEnumeration(t)
class TEXTRANGE(ctypes.Structure):
_fields_= (\
('cpMin', c_long),
('cpMax', c_long),
('lpstrText', ctypes.POINTER(ctypes.c_char)),
)
class TEXTRANGEFULL(ctypes.Structure):
_fields_= (\
('cpMin', c_ssize_t),
('cpMax', c_ssize_t),
('lpstrText', ctypes.POINTER(ctypes.c_char)),
)
class FINDTEXT(ctypes.Structure):
_fields_= (\
('cpMin', c_long),
('cpMax', c_long),
('lpstrText', c_char_p),
('cpMinText', c_long),
('cpMaxText', c_long),
)
class FINDTEXTFULL(ctypes.Structure):
_fields_= (\
('cpMin', c_ssize_t),
('cpMax', c_ssize_t),
('lpstrText', c_char_p),
('cpMinText', c_ssize_t),
('cpMaxText', c_ssize_t),
)
class SciCall:
def __init__(self, fn, ptr, msg, stringResult=False):
self._fn = fn
self._ptr = ptr
self._msg = msg
self._stringResult = stringResult
def __call__(self, w=0, lp=0):
ww = ctypes.cast(w, c_char_p)
if self._stringResult:
lengthBytes = self._fn(self._ptr, self._msg, ww, None)
if lengthBytes == 0:
return bytearray()
result = (ctypes.c_byte * lengthBytes)(0)
lengthBytes2 = self._fn(self._ptr, self._msg, ww, ctypes.cast(result, c_char_p))
assert lengthBytes == lengthBytes2
return bytearray(result)[:lengthBytes]
else:
ll = ctypes.cast(lp, c_char_p)
return self._fn(self._ptr, self._msg, ww, ll)
sciFX = ctypes.CFUNCTYPE(c_ssize_t, c_char_p, c_int, c_char_p, c_char_p)
class ScintillaCallable:
def __init__(self, face, scifn, sciptr):
self.__dict__["face"] = face
self.__dict__["used"] = set()
self.__dict__["all"] = set()
# The k member is for accessing constants as a dictionary
self.__dict__["k"] = {}
for f in face.features:
self.all.add(f)
if face.features[f]["FeatureType"] == "val":
self.k[f] = int(self.face.features[f]["Value"], 0)
elif face.features[f]["FeatureType"] == "evt":
self.k["SCN_"+f] = int(self.face.features[f]["Value"], 0)
scifn = sciFX(scifn)
self.__dict__["_scifn"] = scifn
self.__dict__["_sciptr"] = sciptr
def __getattr__(self, name):
if name in self.face.features:
self.used.add(name)
feature = self.face.features[name]
value = int(feature["Value"], 0)
#~ print("Feature", name, feature)
if feature["FeatureType"] == "val":
self.__dict__[name] = value
return value
else:
if feature["Param2Type"] == "stringresult" and \
name not in ["GetText", "GetLine", "GetCurLine"]:
return SciCall(self._scifn, self._sciptr, value, True)
else:
return SciCall(self._scifn, self._sciptr, value)
elif ("Get" + name) in self.face.features:
self.used.add("Get" + name)
feature = self.face.features["Get" + name]
value = int(feature["Value"], 0)
if feature["FeatureType"] == "get" and \
not name.startswith("Get") and \
not feature["Param1Type"] and \
not feature["Param2Type"] and \
BasicTypeOrEnumeration(feature["ReturnType"]):
#~ print("property", feature)
return self._scifn(self._sciptr, value, None, None)
elif name.startswith("SCN_") and name in self.k:
self.used.add(name)
feature = self.face.features[name[4:]]
value = int(feature["Value"], 0)
#~ print("Feature", name, feature)
if feature["FeatureType"] == "val":
return value
raise AttributeError(name)
def __setattr__(self, name, val):
if ("Set" + name) in self.face.features:
self.used.add("Set" + name)
feature = self.face.features["Set" + name]
value = int(feature["Value"], 0)
#~ print("setproperty", feature)
if feature["FeatureType"] == "set" and not name.startswith("Set"):
if BasicTypeOrEnumeration(feature["Param1Type"]):
return self._scifn(self._sciptr, value, c_char_p(val), None)
elif feature["Param2Type"] in ["string"]:
return self._scifn(self._sciptr, value, None, c_char_p(val))
raise AttributeError(name)
raise AttributeError(name)
def getvalue(self, name):
if name in self.face.features:
feature = self.face.features[name]
if feature["FeatureType"] != "evt":
try:
return int(feature["Value"], 0)
except ValueError:
return -1
return -1
def ByteRange(self, start, end):
tr = TEXTRANGE()
tr.cpMin = start
tr.cpMax = end
length = end - start
tr.lpstrText = ctypes.create_string_buffer(length + 1)
self.GetTextRange(0, ctypes.byref(tr))
text = tr.lpstrText[:length]
text += b"\0" * (length - len(text))
return text
def ByteRangeFull(self, start, end):
tr = TEXTRANGEFULL()
tr.cpMin = start
tr.cpMax = end
length = end - start
tr.lpstrText = ctypes.create_string_buffer(length + 1)
self.GetTextRangeFull(0, ctypes.byref(tr))
text = tr.lpstrText[:length]
text += b"\0" * (length - len(text))
return text
def StyledTextRange(self, start, end):
tr = TEXTRANGE()
tr.cpMin = start
tr.cpMax = end
length = 2 * (end - start)
tr.lpstrText = ctypes.create_string_buffer(length + 2)
self.GetStyledText(0, ctypes.byref(tr))
styledText = tr.lpstrText[:length]
styledText += b"\0" * (length - len(styledText))
return styledText
def StyledTextRangeFull(self, start, end):
tr = TEXTRANGEFULL()
tr.cpMin = start
tr.cpMax = end
length = 2 * (end - start)
tr.lpstrText = ctypes.create_string_buffer(length + 2)
self.GetStyledTextFull(0, ctypes.byref(tr))
styledText = tr.lpstrText[:length]
styledText += b"\0" * (length - len(styledText))
return styledText
def FindBytes(self, start, end, s, flags):
ft = FINDTEXT()
ft.cpMin = start
ft.cpMax = end
ft.lpstrText = s
ft.cpMinText = 0
ft.cpMaxText = 0
pos = self.FindText(flags, ctypes.byref(ft))
#~ print(start, end, ft.cpMinText, ft.cpMaxText)
return pos
def FindBytesFull(self, start, end, s, flags):
ft = FINDTEXTFULL()
ft.cpMin = start
ft.cpMax = end
ft.lpstrText = s
ft.cpMinText = 0
ft.cpMaxText = 0
pos = self.FindTextFull(flags, ctypes.byref(ft))
#~ print(start, end, ft.cpMinText, ft.cpMaxText)
return pos
def Contents(self):
return self.ByteRange(0, self.Length)
def SetContents(self, s):
self.TargetStart = 0
self.TargetEnd = self.Length
self.ReplaceTarget(len(s), s)