Merge pull request #5948 from RaiKoHoff/dev_master

Update Scintilla (v5.6.4) and Lexilla (v.5.5.1)
This commit is contained in:
Rainer Kottenhoff 2026-07-09 09:22:14 +02:00 committed by GitHub
commit edf40a0ff4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
67 changed files with 707 additions and 308 deletions

View File

@ -117,7 +117,6 @@ knownConditionTrueFalse:lexilla/lexers/LexJulia.cxx
unreadVariable:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLisp.cxx
constParameterPointer:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMagik.cxx

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20260429" />
<meta name="Date.Modified" content="20260706" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -62,8 +62,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.4.9<br />
Site last modified April 29 2026</font>
<font color="#FFCC99" size="3">Release version 5.5.1<br />
Site last modified July 6 2026</font>
</td>
<td width="20%">
&nbsp;
@ -78,11 +78,11 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.5.1 improves Baan, HTML, and XML.</li>
<li>Version 5.5.0 improves Fortran and LaTeX.</li>
<li>Version 5.4.9 improves Assembler, C++, F#, LaTeX, Pascal, and Ruby.</li>
<li>Version 5.4.8 improves Batch, Forth, JavaScript, and JSON.</li>
<li>Version 5.4.7 adds EscapeSequence lexer escseq. Improves Errorlist, Makefile, Perl, and Progress.</li>
<li>Version 5.4.6 adds SINEX lexer. Improves Errorlist, Progress, and Python.</li>
<li>Version 5.4.5 improves Dart, Makefile, Nix, TOML, and Zig.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -70,7 +70,7 @@
<h1>Lexilla Documentation</h1>
<p>Last edited 21 April 2021 NH</p>
<p>Last edited 24 May 2026 NH</p>
<h2>Introduction</h2>
@ -250,6 +250,21 @@
<span class="console">make check</span>.
</p>
<h2>Other implementations</h2>
<p>There are projects that provide libraries that implement the Lexilla protocol and can be used to augment or replace Lexilla.</p>
<p>
<a href="https://orbitalquark.github.io/scintillua">Scintillua</a> provides lexers implemented in Lua with
<a href="https://www.inf.puc-rio.br/~roberto/lpeg/">LPeg</a>.
</p>
<p>
<a href="https://github.com/Thorium/NppTreeSitter">NppTreeSitter</a> wraps
<a href="https://tree-sitter.github.io/tree-sitter/">Tree-sitter</a> for
<a href="https://notepad-plus-plus.org/">Notepad++</a>.
</p>
</body>
</html>

View File

@ -26,9 +26,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr>
<td>
<font size="4"> <a href="https://www.scintilla.org/lexilla549.zip">
<font size="4"> <a href="https://www.scintilla.org/lexilla551.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/lexilla549.tgz">
<a href="https://www.scintilla.org/lexilla551.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.4.9
Release 5.5.1
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Lexilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/lexilla549.zip">zip format</a> (1.5M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla549.tgz">tgz format</a> (1.1M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/lexilla551.zip">zip format</a> (1.5M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla551.tgz">tgz format</a> (1.1M) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -595,21 +595,48 @@
<td>Franck Reinquin</td>
<td>Peter C. Jones</td>
<td>Stefan Löffler</td>
<td>p4p3r of CYBERONE</td>
</tr>
</table>
<h2 id="Releases">Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla551.zip">Release 5.5.1</a>
</h3>
<ul>
<li>
Released 6 July 2026.
</li>
<li>
Baan: Fix stack out-of-bounds write for with long preprocessor token and long identifier.
<a href="https://github.com/ScintillaOrg/lexilla/issues/364">Issue #364</a>.
</li>
<li>
XML and HTML: Change CDATA styling so that only the contents are in SCE_H_CDATA.
The "CDATA" is styled as SCE_H_SGML_COMMAND and the punctuation as SCE_H_SGML_DEFAULT.
<a href="https://github.com/ScintillaOrg/lexilla/issues/365">Issue #365</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla550.zip">Release 5.5.0</a>
</h3>
<ul>
<li>
Released 29 April 2026.
Released 6 June 2026.
</li>
<li>
Fortran: Fold enumeration type and select rank. Treat GFortran !GCC$ as preprocessor.
<a href="https://github.com/ScintillaOrg/lexilla/issues/363">Issue #363</a>,
<a href="https://sourceforge.net/p/scintilla/bugs/2509/">Bug #2509</a>.
</li>
<li>
LaTeX: Fix issues at end of file.
<a href="https://github.com/ScintillaOrg/lexilla/issues/355">Issue #355</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/358">Pull request #358</a>.
</li>
<li>
LaTeX: Fix non-terminating optional argument by lexing as SCE_L_MATH.
<a href="https://github.com/ScintillaOrg/lexilla/issues/360">Issue #360</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla549.zip">Release 5.4.9</a>

View File

@ -474,9 +474,9 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos_, Sci_Position length, int
}
if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
if (userDefinedFoldMarkers) {
if (styler.Match(i, options.foldExplicitStart.c_str())) {
if (styler.Match(i, options.foldExplicitStart)) {
levelNext++;
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
} else if (styler.Match(i, options.foldExplicitEnd)) {
levelNext--;
}
} else {

View File

@ -1453,7 +1453,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false);
Tokens tokens = Tokenize(restOfLine);
if (!tokens.empty()) {
const std::string key = tokens[0];
const std::string &key = tokens[0];
preprocessorDefinitions.erase(key);
ppDefineHistory.emplace_back(lineCurrent, key, "", true, "");
definitionsChanged = true;
@ -1544,9 +1544,9 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
}
if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
if (userDefinedFoldMarkers) {
if (styler.Match(i, options.foldExplicitStart.c_str())) {
if (styler.Match(i, std::string_view(options.foldExplicitStart))) {
levelNext++;
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
} else if (styler.Match(i, std::string_view(options.foldExplicitEnd))) {
levelNext--;
}
} else {
@ -1749,7 +1749,7 @@ void LexerCPP::EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDef
// Evaluate logical negations
for (size_t j=0; (j+1)<tokens.size();) {
if (setNegationOp.Contains(tokens[j][0]) && (tokens[j] != "!=")) {
int isTrue = atoi(tokens[j+1].c_str());
bool isTrue = atoi(tokens[j+1].c_str());
if (tokens[j] == "!")
isTrue = !isTrue;
const Tokens::iterator itInsert =

View File

@ -37,8 +37,9 @@
using namespace Lexilla;
namespace {
static inline bool IsAWordChar(const unsigned int ch) {
inline bool IsAWordChar(const unsigned int ch) {
/* FIXME:
* The CSS spec allows "ISO 10646 characters U+00A1 and higher" to be treated as word chars.
* Unfortunately, we are only getting string bytes here, and not full unicode characters. We cannot guarantee
@ -75,7 +76,7 @@ inline int NestingLevelLookBehind(Sci_PositionU startPos, Accessor &styler) {
return nestingLevel;
}
static void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], Accessor &styler) {
WordList &css1Props = *keywordlists[0];
WordList &pseudoClasses = *keywordlists[1];
WordList &css2Props = *keywordlists[2];
@ -505,7 +506,7 @@ static void ColouriseCssDoc(Sci_PositionU startPos, Sci_Position length, int ini
sc.Complete();
}
static void FoldCSSDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
void FoldCSSDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
Sci_PositionU endPos = startPos + length;
@ -555,7 +556,7 @@ static void FoldCSSDoc(Sci_PositionU startPos, Sci_Position length, int, WordLis
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
static const char * const cssWordListDesc[] = {
const char * const cssWordListDesc[] = {
"CSS1 Properties",
"Pseudo-classes",
"CSS2 Properties",
@ -567,4 +568,6 @@ static const char * const cssWordListDesc[] = {
0
};
}
extern const LexerModule lmCss(SCLEX_CSS, ColouriseCssDoc, "css", FoldCSSDoc, cssWordListDesc);

View File

@ -34,6 +34,8 @@
using namespace Scintilla;
using namespace Lexilla;
namespace {
/* Nested comments require keeping the value of the nesting level for every
position in the document. But since scintilla always styles line by line,
we only need to store one value per line. The non-negative number indicates
@ -42,15 +44,15 @@ using namespace Lexilla;
// Underscore, letter, digit and universal alphas from C99 Appendix D.
static bool IsWordStart(int ch) {
bool IsWordStart(int ch) {
return (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch);
}
static bool IsWord(int ch) {
bool IsWord(int ch) {
return (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch);
}
static bool IsDoxygen(int ch) {
bool IsDoxygen(int ch) {
if (IsASCII(ch) && islower(ch))
return true;
if (ch == '$' || ch == '@' || ch == '\\' ||
@ -60,11 +62,11 @@ static bool IsDoxygen(int ch) {
return false;
}
static bool IsStringSuffix(int ch) {
bool IsStringSuffix(int ch) {
return ch == 'c' || ch == 'w' || ch == 'd';
}
static bool IsStreamCommentStyle(int style) {
bool IsStreamCommentStyle(int style) {
return style == SCE_D_COMMENT ||
style == SCE_D_COMMENTDOC ||
style == SCE_D_COMMENTDOCKEYWORD ||
@ -101,7 +103,7 @@ struct OptionsD {
}
};
static const char * const dWordLists[] = {
const char * const dWordLists[] = {
"Primary keywords and identifiers",
"Secondary keywords and identifiers",
"Documentation comment keywords",
@ -568,4 +570,6 @@ void SCI_METHOD LexerD::Fold(Sci_PositionU startPos, Sci_Position length, int in
}
}
}
extern const LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);

View File

@ -30,24 +30,26 @@
using namespace Lexilla;
namespace {
/***********************************************/
static inline bool IsAWordChar(const int ch) {
inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%');
}
/**********************************************/
static inline bool IsAWordStart(const int ch) {
inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch));
}
/***************************************/
static inline bool IsABlank(unsigned int ch) {
inline bool IsABlank(unsigned int ch) {
return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}
/***************************************/
static inline bool IsALineEnd(char ch) {
inline bool IsALineEnd(char ch) {
return ((ch == '\n') || (ch == '\r')) ;
}
/***************************************/
static Sci_PositionU GetContinuedPos(Sci_PositionU pos, Accessor &styler) {
Sci_PositionU GetContinuedPos(Sci_PositionU pos, Accessor &styler) {
while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue;
if (styler.SafeGetCharAt(pos) == '\n') pos++;
while (IsABlank(styler.SafeGetCharAt(pos++))) continue;
@ -60,7 +62,7 @@ static Sci_PositionU GetContinuedPos(Sci_PositionU pos, Accessor &styler) {
}
}
/***************************************/
static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler, bool isFixFormat) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
@ -94,7 +96,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") || sc.MatchIgnoreCase("!dec$") ||
sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("cms$") || sc.MatchIgnoreCase("*ms$") || sc.MatchIgnoreCase("!ms$") ||
sc.chNext == '$') {
sc.MatchIgnoreCase("!gcc$") || sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR);
} else {
sc.SetState(SCE_F_COMMENT);
@ -228,7 +230,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
if (sc.state == SCE_F_DEFAULT) {
if (sc.ch == '!') {
if (sc.MatchIgnoreCase("!dec$") || sc.MatchIgnoreCase("!dir$") ||
sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
sc.MatchIgnoreCase("!gcc$") || sc.MatchIgnoreCase("!ms$") || sc.chNext == '$') {
sc.SetState(SCE_F_PREPROCESSOR);
} else {
sc.SetState(SCE_F_COMMENT);
@ -257,7 +259,7 @@ static void ColouriseFortranDoc(Sci_PositionU startPos, Sci_Position length, int
sc.Complete();
}
/***************************************/
static void CheckLevelCommentLine(const unsigned int nComL,
void CheckLevelCommentLine(const unsigned int nComL,
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
bool comLineB[], bool comLineF[], bool &comLineCur,
int &levelDeltaNext) {
@ -290,7 +292,7 @@ static void CheckLevelCommentLine(const unsigned int nComL,
}
}
/***************************************/
static void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {
void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Position line, bool &isComLine, Sci_Position &comCol) {
Sci_Position col = 0;
isComLine = false;
Sci_Position pos = styler.LineStart(line);
@ -310,7 +312,7 @@ static void GetIfLineComment(Accessor &styler, bool isFixFormat, const Sci_Posit
}
}
/***************************************/
static void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position &nComCur,
bool comLineB[], bool comLineF[], bool &comLineCur) {
Sci_Position nLineTotal = styler.GetLine(styler.Length()-1) + 1;
@ -339,7 +341,7 @@ static void StepCommentLine(Accessor &styler, bool isFixFormat, Sci_Position lin
}
}
/***************************************/
static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position lineCurrent, const unsigned int nComL,
Sci_Position nComColB[], Sci_Position nComColF[], Sci_Position nComCur,
bool comLineB[], bool comLineF[], bool &comLineCur) {
unsigned int nLines = nComL + nComL + 1;
@ -361,7 +363,7 @@ static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position l
comL[copyTo] = comLineF[i];
nComCol[copyTo] = nComColF[i];
}
Sci_Position lineC = lineCurrent - nComL + 1;
Sci_PositionU iStart;
if (lineC <= 0) {
@ -373,7 +375,7 @@ static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position l
}
bool levChanged = false;
int lev = styler.LevelAt(lineC) & SC_FOLDLEVELNUMBERMASK;
for (Sci_PositionU i=iStart; i<=nComL; i++) {
if (comL[i] && (!comL[i-1] || nComCol[i] != nComCol[i-1])) {
bool increase = true;
@ -417,7 +419,7 @@ static void CheckBackComLines(Accessor &styler, bool isFixFormat, Sci_Position l
}
/***************************************/
// To determine the folding level depending on keywords
static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) {
int lev = 0;
if ((strcmp(prevWord, "module") == 0 && strcmp(s, "subroutine") == 0)
@ -426,17 +428,18 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
} else if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0
|| strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0
|| strcmp(s, "selecttype") == 0 || strcmp(s, "selectcase") == 0
|| strcmp(s, "do") == 0 || strcmp(s, "enum") ==0
|| strcmp(s, "do") == 0 || strcmp(s, "enum") == 0
|| strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
|| strcmp(s, "module") == 0 || strcmp(s, "program") == 0
|| strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
|| (strcmp(s, "type") == 0 && chNextNonBlank != '(')
|| (strcmp(s, "type") == 0 && chNextNonBlank != '(' && strcmp(prevWord, "enumeration") != 0)
|| strcmp(s, "enumeration") == 0
|| strcmp(s, "critical") == 0 || strcmp(s, "submodule") == 0){
if (strcmp(prevWord, "end") == 0)
lev = 0;
else
lev = 1;
} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=')
} else if ((strcmp(s, "end") == 0 && chNextNonBlank != '=' && chNextNonBlank != '(')
|| strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0
|| strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0
|| strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0
@ -462,7 +465,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
}
/***************************************/
// Folding the code
static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
Accessor &styler, bool isFixFormat) {
bool foldComment = styler.GetPropertyInt("fold.comment", 1) != 0;
@ -515,7 +518,7 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
GetIfLineComment(styler, isFixFormat, chL, comLineF[i], nComColF[i]);
}
GetIfLineComment(styler, isFixFormat, lineCurrent, comLineCur, nComCur);
CheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
CheckBackComLines(styler, isFixFormat, lineCurrent, nComL, nComColB, nComColF, nComCur,
comLineB, comLineF, comLineCur);
}
int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
@ -636,7 +639,8 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
levelCurrent--;
}
} else if ((strcmp(prevWord, "select") == 0 && strcmp(s, "case") == 0) || strcmp(s, "selectcase") == 0 ||
(strcmp(prevWord, "select") == 0 && strcmp(s, "type") == 0) || strcmp(s, "selecttype") == 0) {
(strcmp(prevWord, "select") == 0 && strcmp(s, "type") == 0) || strcmp(s, "selecttype") == 0 ||
(strcmp(prevWord, "select") == 0 && strcmp(s, "rank") == 0)) {
levelDeltaNext += 2;
} else if ((strcmp(s, "case") == 0 && chNextNonBlank == '(') || (strcmp(prevWord, "case") == 0 && strcmp(s, "default") == 0) ||
(strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0) ||
@ -693,32 +697,35 @@ static void FoldFortranDoc(Sci_PositionU startPos, Sci_Position length, int init
/***************************************/
}
/***************************************/
static const char * const FortranWordLists[] = {
const char * const FortranWordLists[] = {
"Primary keywords and identifiers",
"Intrinsic functions",
"Extended and user defined functions",
0,
};
/***************************************/
static void ColouriseFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
void ColouriseFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false);
}
/***************************************/
static void ColouriseFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
void ColouriseFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true);
}
/***************************************/
static void FoldFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldFortranDocFreeFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, false);
}
/***************************************/
static void FoldFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldFortranDocFixFormat(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler) {
FoldFortranDoc(startPos, length, initStyle,styler, true);
}
}
/***************************************/
extern const LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists);
extern const LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists);

View File

@ -1693,6 +1693,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
}
} else if ((state != SCE_H_SGML_BLOCK_DEFAULT) && isWordCdata(i + 1, i + 7, styler)) {
state = SCE_H_CDATA;
styler.ColourTo(i + 1, SCE_H_SGML_DEFAULT);
styler.ColourTo(i + 1 + 5, SCE_H_SGML_COMMAND);
styler.ColourTo(i + 1 + 5 + 1, SCE_H_SGML_DEFAULT);
} else {
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
beforeLanguage = scriptLanguage;
@ -1944,7 +1947,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
break;
case SCE_H_CDATA:
if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) {
styler.ColourTo(i, StateToPrint);
styler.ColourTo(i - 3, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
state = SCE_H_DEFAULT;
levelCurrent--;
}
@ -2570,7 +2574,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} else if (ch == '$' && IsPhpWordStart(chNext)) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HPHP_HSTRING_VARIABLE;
} else if (styler.Match(i, phpStringDelimiter.c_str())) {
} else if (styler.Match(i, phpStringDelimiter)) {
if (phpStringDelimiter == "\"") {
styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT;
@ -2594,7 +2598,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT;
}
} else if (lineStartVisibleChars == 1 && styler.Match(i, phpStringDelimiter.c_str())) {
} else if (lineStartVisibleChars == 1 && styler.Match(i, phpStringDelimiter)) {
const int psdLength = static_cast<int>(phpStringDelimiter.length());
if (!IsPhpWordChar(styler.SafeGetCharAt(i + psdLength))) {
i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1;

View File

@ -40,7 +40,9 @@
using namespace Scintilla;
using namespace Lexilla;
static const int MAX_JULIA_IDENT_CHARS = 1023;
namespace {
const int MAX_JULIA_IDENT_CHARS = 1023;
// Options used for LexerJulia
struct OptionsJulia {
@ -199,7 +201,7 @@ Sci_Position SCI_METHOD LexerJulia::WordListSet(int n, const char *wl) {
return firstModification;
}
static inline bool IsJuliaOperator(int ch) {
inline bool IsJuliaOperator(int ch) {
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
ch == '<' || ch == '>' || ch == '/' || ch == '~' ||
@ -210,7 +212,7 @@ static inline bool IsJuliaOperator(int ch) {
}
// The list contains non-ascii unary operators
static inline bool IsJuliaUnaryOperator (int ch) {
inline bool IsJuliaUnaryOperator (int ch) {
if (ch == 0x00ac || ch == 0x221a || ch == 0x221b ||
ch == 0x221c || ch == 0x22c6 || ch == 0x00b1 ||
ch == 0x2213 ) {
@ -219,7 +221,7 @@ static inline bool IsJuliaUnaryOperator (int ch) {
return false;
}
static inline bool IsJuliaParen (int ch) {
inline bool IsJuliaParen (int ch) {
if (ch == '(' || ch == ')' || ch == '{' || ch == '}' ||
ch == '[' || ch == ']' ) {
return true;
@ -230,7 +232,7 @@ static inline bool IsJuliaParen (int ch) {
// Unicode parsing from Julia source code:
// https://github.com/JuliaLang/julia/blob/master/src/flisp/julia_extensions.c
// keep the same function name to be easy to find again
static int is_wc_cat_id_start(uint32_t wc) {
int is_wc_cat_id_start(uint32_t wc) {
const CharacterCategory cat = CategoriseCharacter((int) wc);
return (cat == ccLu || cat == ccLl ||
@ -291,7 +293,7 @@ static int is_wc_cat_id_start(uint32_t wc) {
(wc >= 0x1D7CE && wc <= 0x1D7E1)); // 𝟎 through 𝟗 (inclusive), 𝟘 through 𝟡 (inclusive)
}
static inline bool IsIdentifierFirstCharacter (int ch) {
inline bool IsIdentifierFirstCharacter (int ch) {
if (IsASCII(ch)) {
return (bool) (isalpha(ch) || ch == '_');
}
@ -302,7 +304,7 @@ static inline bool IsIdentifierFirstCharacter (int ch) {
return is_wc_cat_id_start((uint32_t) ch);
}
static inline bool IsIdentifierCharacter (int ch) {
inline bool IsIdentifierCharacter (int ch) {
if (IsASCII(ch)) {
return (bool) (isalnum(ch) || ch == '_' || ch == '!');
}
@ -328,7 +330,7 @@ static inline bool IsIdentifierCharacter (int ch) {
}
// keep the same function name to be easy to find again
static const uint32_t opsuffs[] = {
const uint32_t opsuffs[] = {
0x00b2, // ²
0x00b3, // ³
0x00b9, // ¹
@ -447,10 +449,10 @@ static const uint32_t opsuffs[] = {
0xa71c, // ꜜ
0xa71d // ꜝ
};
static const size_t opsuffs_len = sizeof(opsuffs) / (sizeof(uint32_t));
const size_t opsuffs_len = sizeof(opsuffs) / (sizeof(uint32_t));
// keep the same function name to be easy to find again
static bool jl_op_suffix_char(uint32_t wc) {
bool jl_op_suffix_char(uint32_t wc) {
if (wc < 0xA1 || wc > 0x10ffff) {
return false;
}
@ -469,7 +471,7 @@ static bool jl_op_suffix_char(uint32_t wc) {
}
// keep the same function name to be easy to find again
static bool never_id_char(uint32_t wc) {
bool never_id_char(uint32_t wc) {
const CharacterCategory cat = CategoriseCharacter((int) wc);
return (
// spaces and control characters:
@ -494,7 +496,7 @@ static bool never_id_char(uint32_t wc) {
}
static bool IsOperatorFirstCharacter (int ch) {
bool IsOperatorFirstCharacter (int ch) {
if (IsASCII(ch)) {
if (IsJuliaOperator(ch) ||
ch == '!' || ch == '?' ||
@ -513,7 +515,7 @@ static bool IsOperatorFirstCharacter (int ch) {
return false;
}
static bool IsOperatorCharacter (int ch) {
bool IsOperatorCharacter (int ch) {
if (IsOperatorFirstCharacter(ch) ||
(!IsASCII(ch) && jl_op_suffix_char((uint32_t) ch)) ) {
return true;
@ -521,14 +523,14 @@ static bool IsOperatorCharacter (int ch) {
return false;
}
static bool CheckBoundsIndexing(char *str) {
bool CheckBoundsIndexing(char *str) {
if (strcmp("begin", str) == 0 || strcmp("end", str) == 0 ) {
return true;
}
return false;
}
static int CheckKeywordFoldPoint(char *str) {
int CheckKeywordFoldPoint(char *str) {
if (strcmp ("if", str) == 0 ||
strcmp ("for", str) == 0 ||
strcmp ("while", str) == 0 ||
@ -551,7 +553,7 @@ static int CheckKeywordFoldPoint(char *str) {
return 0;
}
static bool IsNumberExpon(int ch, int base) {
bool IsNumberExpon(int ch, int base) {
if ((base == 10 && (ch == 'e' || ch == 'E' || ch == 'f')) ||
(base == 16 && (ch == 'p' || ch == 'P'))) {
return true;
@ -560,7 +562,7 @@ static bool IsNumberExpon(int ch, int base) {
}
/* Scans a sequence of digits, returning true if it found any. */
static bool ScanDigits(StyleContext& sc, int base, bool allow_sep) {
bool ScanDigits(StyleContext& sc, int base, bool allow_sep) {
bool found = false;
for (;;) {
if (IsADigit(sc.chNext, base) || (allow_sep && sc.chNext == '_')) {
@ -573,7 +575,7 @@ static bool ScanDigits(StyleContext& sc, int base, bool allow_sep) {
return found;
}
static inline bool ScanNHexas(StyleContext &sc, int max) {
inline bool ScanNHexas(StyleContext &sc, int max) {
int n = 0;
bool error = false;
@ -589,7 +591,7 @@ static inline bool ScanNHexas(StyleContext &sc, int max) {
return error;
}
static void resumeCharacter(StyleContext &sc, bool lexerror) {
void resumeCharacter(StyleContext &sc, bool lexerror) {
bool error = false;
// ''' case
@ -674,11 +676,11 @@ static void resumeCharacter(StyleContext &sc, bool lexerror) {
}
}
static inline bool IsACharacter(StyleContext &sc) {
inline bool IsACharacter(StyleContext &sc) {
return (sc.chPrev == '\'' && sc.chNext == '\'');
}
static void ScanParenInterpolation(StyleContext &sc) {
void ScanParenInterpolation(StyleContext &sc) {
// TODO: no syntax highlighting inside a string interpolation
// Level of nested parenthesis
@ -712,7 +714,7 @@ static void ScanParenInterpolation(StyleContext &sc) {
/*
* Start parsing a number, parse the base.
*/
static void initNumber (StyleContext &sc, int &base, bool &with_dot) {
void initNumber (StyleContext &sc, int &base, bool &with_dot) {
base = 10;
with_dot = false;
sc.SetState(SCE_JULIA_NUMBER);
@ -741,7 +743,7 @@ static void initNumber (StyleContext &sc, int &base, bool &with_dot) {
* The `triple` argument specifies if it is a triple-quote String or Command.
* Interpolation is detected (with `$`), and parsed if `allow_interp` is true.
*/
static void resumeStringLike(StyleContext &sc, int quote, bool triple, bool allow_interp, bool full_highlight) {
void resumeStringLike(StyleContext &sc, int quote, bool triple, bool allow_interp, bool full_highlight) {
int stylePrev = sc.state;
bool checkcurrent = false;
@ -799,15 +801,15 @@ static void resumeStringLike(StyleContext &sc, int quote, bool triple, bool allo
}
}
static void resumeCommand(StyleContext &sc, bool triple, bool allow_interp) {
void resumeCommand(StyleContext &sc, bool triple, bool allow_interp) {
return resumeStringLike(sc, '`', triple, allow_interp, true);
}
static void resumeString(StyleContext &sc, bool triple, bool allow_interp) {
void resumeString(StyleContext &sc, bool triple, bool allow_interp) {
return resumeStringLike(sc, '"', triple, allow_interp, true);
}
static void resumeNumber (StyleContext &sc, int base, bool &with_dot, bool lexerror) {
void resumeNumber (StyleContext &sc, int base, bool &with_dot, bool lexerror) {
if (IsNumberExpon(sc.ch, base)) {
if (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-') {
sc.Forward();
@ -837,7 +839,7 @@ static void resumeNumber (StyleContext &sc, int base, bool &with_dot, bool lexer
}
}
static void resumeOperator (StyleContext &sc) {
void resumeOperator (StyleContext &sc) {
if (sc.chNext == ':' && (sc.ch == ':' || sc.ch == '<' ||
(sc.ch == '>' && (sc.chPrev != '-' && sc.chPrev != '=')))) {
// Case `:a=>:b`
@ -1259,4 +1261,6 @@ void SCI_METHOD LexerJulia::Fold(Sci_PositionU startPos, Sci_Position length, in
}
}
}
extern const LexerModule lmJulia(SCLEX_JULIA, LexerJulia::LexerFactoryJulia, "julia", juliaWordLists);

View File

@ -5,14 +5,14 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some minor behaviors.
// Modified by G. HU in 2013. Added folding, syntax highlighting inside math environments, and changed some minor behaviors.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cstdarg>
#include <string>
#include <string_view>
@ -37,6 +37,8 @@ using namespace Lexilla;
using namespace std;
namespace {
struct latexFoldSave {
latexFoldSave() : structLev(0) {
for (int i = 0; i < 8; ++i) openBegins[i] = 0;
@ -103,24 +105,24 @@ public:
}
};
static bool latexIsSpecial(int ch) {
bool latexIsSpecial(int ch) noexcept {
return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
(ch == '{') || (ch == '}') || (ch == ' ');
}
static bool latexIsBlank(int ch) {
bool latexIsBlank(int ch) noexcept {
return (ch == ' ') || (ch == '\t');
}
static bool latexIsBlankAndNL(int ch) {
bool latexIsBlankAndNL(int ch) noexcept {
return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}
static bool latexIsLetter(int ch) {
bool latexIsLetter(int ch) {
return IsASCII(ch) && isalpha(ch);
}
static bool latexIsTagValid(Sci_Position &i, Sci_Position l, Accessor &styler) {
bool latexIsTagValid(Sci_Position &i, Sci_Position l, Accessor &styler) {
while (i < l) {
if (styler.SafeGetCharAt(i) == '{') {
while (i < l) {
@ -140,22 +142,33 @@ static bool latexIsTagValid(Sci_Position &i, Sci_Position l, Accessor &styler) {
return false;
}
static bool latexNextNotBlankIs(Sci_Position i, Accessor &styler, char needle) {
char ch;
while (i < styler.Length()) {
ch = styler.SafeGetCharAt(i);
if (!latexIsBlankAndNL(ch) && ch != '*') {
if (ch == needle)
return true;
else
return false;
// Determine if there is a valid [optional argument] after a command.
// Heuristic searches for '[' followed by non-special characters then ']'
// but is not exhaustive and may fail.
bool latexIsCmdOpt(Sci_Position i, Accessor &styler) {
bool beforeOptional = true;
for (; i < styler.Length(); i++) {
const char ch = styler.SafeGetCharAt(i);
if (beforeOptional) {
if (ch == '[') {
beforeOptional = false;
} else if (!latexIsBlankAndNL(ch) && ch != '*') {
return false;
}
} else {
if (ch == ']') { // Whole [optional] -> success
return true;
}
if (ch > ' ' && latexIsSpecial(ch)) {
// Prefer inner highlighting inside optional command argument
return false;
}
}
i++;
}
return false;
}
static bool latexLastWordIs(Sci_Position start, Accessor &styler, const char *needle) {
bool latexLastWordIs(Sci_Position start, Accessor &styler, const char *needle) {
Sci_PositionU i = 0;
Sci_PositionU l = static_cast<Sci_PositionU>(strlen(needle));
Sci_Position ini = start-l+1;
@ -170,7 +183,7 @@ static bool latexLastWordIs(Sci_Position start, Accessor &styler, const char *ne
return (strcmp(s, needle) == 0);
}
static bool latexLastWordIsMathEnv(Sci_Position pos, Accessor &styler) {
bool latexLastWordIsMathEnv(Sci_Position pos, Accessor &styler) {
Sci_Position i, j;
char s[32];
const char *mathEnvs[] = { "align", "alignat", "flalign", "gather",
@ -192,7 +205,7 @@ static bool latexLastWordIsMathEnv(Sci_Position pos, Accessor &styler) {
return false;
}
static inline void latexStateReset(int &mode, int &state) {
void latexStateReset(int mode, int &state) noexcept {
switch (mode) {
case 1: state = SCE_L_MATH; break;
case 2: state = SCE_L_MATH2; break;
@ -285,7 +298,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int
case SCE_L_COMMAND :
if (!latexIsLetter(chNext)) {
styler.ColourTo(i, state);
if (latexNextNotBlankIs(i + 1, styler, '[' )) {
if (latexIsCmdOpt(i + 1, styler)) {
state = SCE_L_CMDOPT;
} else if (latexLastWordIs(i, styler, "\\begin")) {
state = SCE_L_TAG;
@ -490,7 +503,7 @@ void SCI_METHOD LexerLaTeX::Lex(Sci_PositionU startPos, Sci_Position length, int
styler.Flush();
}
static int latexFoldSaveToInt(const latexFoldSave &save) {
int latexFoldSaveToInt(const latexFoldSave &save) {
int sum = 0;
for (int i = 0; i <= save.structLev; ++i)
sum += save.openBegins[i];
@ -562,8 +575,10 @@ void SCI_METHOD LexerLaTeX::Fold(Sci_PositionU startPos, Sci_Position length, in
styler.Flush();
}
static const char *const emptyWordListDesc[] = {
0
const char *const emptyWordListDesc[] = {
nullptr
};
}
extern const LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, "latex", emptyWordListDesc);

View File

@ -52,21 +52,23 @@
using namespace Lexilla;
static bool IsMatlabCommentChar(int c) {
namespace {
bool IsMatlabCommentChar(int c) {
return (c == '%') ;
}
static bool IsOctaveCommentChar(int c) {
bool IsOctaveCommentChar(int c) {
return (c == '%' || c == '#') ;
}
static inline int LowerCase(int c) {
inline int LowerCase(int c) {
if (c >= 'A' && c <= 'Z')
return 'a' + c - 'A';
return c;
}
static int CheckKeywordFoldPoint(char *str) {
int CheckKeywordFoldPoint(char *str) {
if (strcmp ("if", str) == 0 ||
strcmp ("for", str) == 0 ||
strcmp ("switch", str) == 0 ||
@ -88,7 +90,7 @@ static int CheckKeywordFoldPoint(char *str) {
return 0;
}
static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
Sci_Position line = styler.GetLine(startPos);
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = startPos; i < eol_pos; i++) {
@ -107,7 +109,7 @@ static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
#define MATLAB_STATE_IN_CLASS_SCOPE (1 <<(MATLAB_STATE_FLAGS_OFFSET+1))
#define MATLAB_STATE_IN_ARGUMENTS_SCOPE (1 <<(MATLAB_STATE_FLAGS_OFFSET+2))
static int ComposeLineState(int commentDepth,
int ComposeLineState(int commentDepth,
int foldingLevel,
int expectingArgumentsBlock,
int inClassScope,
@ -125,7 +127,7 @@ static int ComposeLineState(int commentDepth,
& MATLAB_STATE_IN_ARGUMENTS_SCOPE);
}
static void ColouriseMatlabOctaveDoc(
void ColouriseMatlabOctaveDoc(
Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler,
bool (*IsCommentChar)(int),
@ -419,17 +421,17 @@ static void ColouriseMatlabOctaveDoc(
sc.Complete();
}
static void ColouriseMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void ColouriseMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar, true);
}
static void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void ColouriseOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar, false);
}
static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler,
bool (*IsComment)(int ch)) {
@ -503,26 +505,28 @@ static void FoldMatlabOctaveDoc(Sci_PositionU startPos, Sci_Position length, int
}
}
static void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldMatlabDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
}
static void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
void FoldOctaveDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
}
static const char * const matlabWordListDesc[] = {
const char * const matlabWordListDesc[] = {
"Keywords",
0
};
static const char * const octaveWordListDesc[] = {
const char * const octaveWordListDesc[] = {
"Keywords",
0
};
}
extern const LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
extern const LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);

View File

@ -117,6 +117,7 @@ contains requires
#include <string>
#include <string_view>
#include <map>
#include <algorithm>
#include "ILexer.h"
#include "Scintilla.h"

View File

@ -620,7 +620,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
bool indentGood = true;
Sci_Position startIndicator = sc.currentPos;
Sci_Position startIndent = sc.currentPos;
bool inContinuedString = false;
for (; sc.More(); sc.Forward()) {
@ -638,8 +638,8 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
indentGood = (spaceFlags & wsTab) == 0;
}
if (!indentGood) {
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
startIndicator = sc.currentPos;
styler.IndicatorFill(startIndent, sc.currentPos, indicatorWhitespace, 0);
startIndent = sc.currentPos;
}
}
@ -857,8 +857,8 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
// End of code to find the end of a state
if (!indentGood && !IsASpaceOrTab(sc.ch)) {
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
startIndicator = sc.currentPos;
styler.IndicatorFill(startIndent, sc.currentPos, indicatorWhitespace, 1);
startIndent = sc.currentPos;
indentGood = true;
}
@ -928,7 +928,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
}
}
}
styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
styler.IndicatorFill(startIndent, sc.currentPos, indicatorWhitespace, 0);
sc.Complete();
}

View File

@ -28,11 +28,11 @@ using namespace Lexilla;
namespace {
inline bool IsAWordChar(int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
}
inline bool IsAWordStart(int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
return IsAlphaNumeric(ch) || ch == '_';
}
constexpr bool IsAnOperator(int ch) noexcept {

View File

@ -16,6 +16,7 @@
#include <string_view>
#include <vector>
#include <map>
#include <algorithm>
#include "ILexer.h"
#include "Scintilla.h"

View File

@ -28,17 +28,19 @@
using namespace Lexilla;
namespace {
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
inline bool IsAWordChar(int ch) {
return ch >= 0x80 ||
(isalnum(ch) || ch == '_' || ch ==':' || ch=='.'); // : name space separator
}
static inline bool IsAWordStart(int ch) {
inline bool IsAWordStart(int ch) {
return ch >= 0x80 || (ch ==':' || isalpha(ch) || ch == '_');
}
static inline bool IsANumberChar(int ch) {
inline bool IsANumberChar(int ch) {
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
return (ch < 0x80) &&
@ -46,7 +48,7 @@ static inline bool IsANumberChar(int ch) {
ch == '.' || ch == '-' || ch == '+');
}
static void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int , WordList *keywordlists[], Accessor &styler) {
void ColouriseTCLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *keywordlists[], Accessor &styler) {
#define isComment(s) (s==SCE_TCL_COMMENT || s==SCE_TCL_COMMENTLINE || s==SCE_TCL_COMMENT_BOX || s==SCE_TCL_BLOCK_COMMENT)
const bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@ -358,7 +360,7 @@ next:
sc.Complete();
}
static const char *const tclWordListDesc[] = {
const char *const tclWordListDesc[] = {
"TCL Keywords",
"TK Keywords",
"iTCL Keywords",
@ -371,5 +373,7 @@ static const char *const tclWordListDesc[] = {
0
};
}
// this code supports folding in the colourizer
extern const LexerModule lmTCL(SCLEX_TCL, ColouriseTCLDoc, "tcl", 0, tclWordListDesc);

View File

@ -33,6 +33,8 @@
using namespace Lexilla;
namespace {
static void ColouriseVHDLDoc(
Sci_PositionU startPos,
Sci_Position length,
@ -42,22 +44,22 @@ static void ColouriseVHDLDoc(
/***************************************/
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' );
inline bool IsAWordChar(const int ch) {
return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
}
/***************************************/
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
inline bool IsAWordStart(const int ch) {
return IsAlphaNumeric(ch) || ch == '_';
}
/***************************************/
static inline bool IsABlank(unsigned int ch) {
inline bool IsABlank(unsigned int ch) {
return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}
/***************************************/
static void ColouriseVHDLDoc(
void ColouriseVHDLDoc(
Sci_PositionU startPos,
Sci_Position length,
int initStyle,
@ -177,7 +179,7 @@ static void ColouriseVHDLDoc(
sc.Complete();
}
//=============================================================================
static bool IsCommentLine(Sci_Position line, Accessor &styler) {
bool IsCommentLine(Sci_Position line, Accessor &styler) {
Sci_Position pos = styler.LineStart(line);
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
for (Sci_Position i = pos; i < eol_pos; i++) {
@ -190,7 +192,7 @@ static bool IsCommentLine(Sci_Position line, Accessor &styler) {
}
return false;
}
static bool IsCommentBlockStart(Sci_Position line, Accessor &styler)
bool IsCommentBlockStart(Sci_Position line, Accessor &styler)
{
Sci_Position pos = styler.LineStart(line);
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
@ -204,7 +206,7 @@ static bool IsCommentBlockStart(Sci_Position line, Accessor &styler)
return false;
}
static bool IsCommentBlockEnd(Sci_Position line, Accessor &styler)
bool IsCommentBlockEnd(Sci_Position line, Accessor &styler)
{
Sci_Position pos = styler.LineStart(line);
Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
@ -219,14 +221,14 @@ static bool IsCommentBlockEnd(Sci_Position line, Accessor &styler)
return false;
}
static bool IsCommentStyle(char style)
bool IsCommentStyle(char style)
{
return style == SCE_VHDL_BLOCK_COMMENT || style == SCE_VHDL_COMMENT || style == SCE_VHDL_COMMENTLINEBANG;
}
//=============================================================================
// Folding the code
static void FoldNoBoxVHDLDoc(
void FoldNoBoxVHDLDoc(
Sci_PositionU startPos,
Sci_Position length,
int,
@ -289,7 +291,7 @@ static void FoldNoBoxVHDLDoc(
char s[32];
Sci_PositionU k;
for(k=0; (k<31 ) && (k<end-j+1 ); k++) {
s[k] = static_cast<char>(tolower(styler[j+k]));
s[k] = MakeLowerCase(styler[j+k]);
}
s[k] = '\0';
@ -387,7 +389,7 @@ static void FoldNoBoxVHDLDoc(
char s[32];
Sci_PositionU k;
for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
s[k] = static_cast<char>(tolower(styler[lastStart+k]));
s[k] = MakeLowerCase(styler[lastStart+k]);
}
s[k] = '\0';
@ -543,13 +545,13 @@ static void FoldNoBoxVHDLDoc(
}
//=============================================================================
static void FoldVHDLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],
void FoldVHDLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],
Accessor &styler) {
FoldNoBoxVHDLDoc(startPos, length, initStyle, styler);
}
//=============================================================================
static const char * const VHDLWordLists[] = {
const char * const VHDLWordLists[] = {
"Keywords",
"Operators",
"Attributes",
@ -560,6 +562,7 @@ static const char * const VHDLWordLists[] = {
0,
};
}
extern const LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLists);

View File

@ -193,7 +193,7 @@ void ColouriseYAMLLine(
}
const Sci_PositionU i2 = i;
while ((i < startComment) && lineBuffer[i]) {
if (!(IsASCII(lineBuffer[i]) && isdigit(lineBuffer[i])) && lineBuffer[i] != '-'
if (!(IsASCII(lineBuffer[i]) && IsADigit(lineBuffer[i])) && lineBuffer[i] != '-'
&& lineBuffer[i] != '.' && lineBuffer[i] != ',' && lineBuffer[i] != ' ') {
styler.ColourTo(startLine + startComment - 1, SCE_YAML_DEFAULT);
if (startComment < lengthLine)

View File

@ -20,6 +20,15 @@ using namespace Lexilla;
namespace Lexilla {
bool LexAccessor::Match(Sci_Position pos, std::string_view sv) {
for (unsigned int i = 0; i < sv.size(); i++) {
if (sv[i] != SafeGetCharAt(pos + i)) {
return false;
}
}
return true;
}
bool LexAccessor::MatchIgnoreCase(Sci_Position pos, const char *s) {
assert(s);
for (; *s; s++, pos++) {

View File

@ -113,6 +113,7 @@ public:
}
return true;
}
[[nodiscard]] bool Match(Sci_Position pos, std::string_view sv);
bool MatchIgnoreCase(Sci_Position pos, const char *s);
// Get first len - 1 characters in range [startPos_, endPos_).

View File

@ -10,6 +10,7 @@
#include <cstring>
#include <string>
#include <string_view>
#include <algorithm>
#include <iterator>
#include <memory>

View File

@ -34,6 +34,7 @@
#include <cstdarg>
// C++ standard library
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
@ -46,7 +47,7 @@
#include <iterator>
#include <functional>
#include <memory>
#include <regex>
#include <ios>
#include <iostream>
#include <sstream>
#include <fstream>

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>5.4.9</string>
<string>5.5.1</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>

View File

@ -900,7 +900,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.4.9;
CURRENT_PROJECT_VERSION = 5.5.1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
@ -928,7 +928,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.4.9;
CURRENT_PROJECT_VERSION = 5.5.1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;

View File

@ -4,8 +4,8 @@
#include <windows.h>
#define VERSION_LEXILLA "5.4.9"
#define VERSION_WORDS 5, 4, 9, 0
#define VERSION_LEXILLA "5.5.1"
#define VERSION_WORDS 5, 5, 1, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -1 +1 @@
549
551

View File

@ -3567,6 +3567,14 @@ void ScintillaCall::SetILexer(void *ilexer) {
CallPointer(Message::SetILexer, 0, ilexer);
}
void ScintillaCall::SetScaleTechnique(Scintilla::ScaleTechnique technique) {
Call(Message::SetScaleTechnique, static_cast<uintptr_t>(technique));
}
ScaleTechnique ScintillaCall::ScaleTechnique() {
return static_cast<Scintilla::ScaleTechnique>(Call(Message::GetScaleTechnique));
}
Bidirectional ScintillaCall::Bidirectional() {
return static_cast<Scintilla::Bidirectional>(Call(Message::GetBidirectional));
}

View File

@ -43,6 +43,9 @@ knownConditionTrueFalse:scintilla/win32/ScintillaWin.cxx
// GetData is implementing interface so shouldn't add const
constParameterPointer:scintilla/win32/ScintillaWin.cxx
// Window::SetCursor could be static if only on Win32 but not on other platforms
functionStatic:scintilla/win32/PlatWin.cxx
// Doesn't handle intptr_t (long long) being signed
knownConditionTrueFalse:scintilla/src/Editor.cxx
knownConditionTrueFalse:scintilla/src/EditView.cxx
@ -94,7 +97,6 @@ unusedFunction:scintilla/call/ScintillaCall.cxx
// Don't want to unnecessarily allow const pointers to be made mutable through reinterpret_cast
constParameterPointer:scintilla/call/ScintillaCall.cxx
constParameterPointer:scintilla/src/Editor.cxx
constVariablePointer:scintilla/src/Editor.cxx
// The performance cost of by-value passing is often small and using a reference decreases

View File

@ -5106,6 +5106,8 @@ struct Sci_TextToFindFull {
</code>
<div class="provisional">
<code>
<a class="message" href="#SCI_SETSCALETECHNIQUE">SCI_SETSCALETECHNIQUE(int technique)</a><br />
<a class="message" href="#SCI_GETSCALETECHNIQUE">SCI_GETSCALETECHNIQUE &rarr; int</a><br />
<a class="message" href="#SCI_SETBIDIRECTIONAL"><span class="provisional">SCI_SETBIDIRECTIONAL(int bidirectional)</span></a><br />
<a class="message" href="#SCI_GETBIDIRECTIONAL">SCI_GETBIDIRECTIONAL &rarr; int</a><br />
</code>
@ -5355,6 +5357,35 @@ struct Sci_TextToFindFull {
<a class="message" href="#SCN_CHARADDED">SCN_CHARADDED</a>
notification (with <code class="parameter">characterSource</code> set to <code>SC_CHARACTERSOURCE_TENTATIVE_INPUT</code>) is sent for each character.</p>
<div class="provisional">
<p><b id="SCI_SETSCALETECHNIQUE">SCI_SETSCALETECHNIQUE(int technique)</b><br />
<b id="SCI_GETSCALETECHNIQUE">SCI_GETSCALETECHNIQUE &rarr; int</b><br />
This setting changes the implementation of display scaling on some platforms.</p>
<table class="standard" summary="Technology choice">
<tbody valign="top">
<tr>
<th align="left"><code>SCALE_TECHNIQUE_DEFAULT</code></th>
<td>0</td>
<td>Default behaviour for the platform.</td>
</tr>
<tr>
<th align="left"><code>SCALE_TECHNIQUE_PIXEL_ALIGNED</code></th>
<td>1</td>
<td>Align top and bottom of lines to physical pixels and avoid 'seams' between background rectangles for fractional scaling.
Implemented on Qt. This mode may be slower than the default.</td>
</tr>
</tbody>
</table>
</div>
<br />
<div class="provisional">
<a href="#ProvisionalMessages">These bidirectional features are experimental and incomplete.</a><br />
<p><b id="SCI_SETBIDIRECTIONAL">SCI_SETBIDIRECTIONAL(int bidirectional)</b><br />

View File

@ -26,9 +26,9 @@
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
<tr>
<td>
<font size="4"> <a href="https://www.scintilla.org/scintilla562.zip">
<font size="4"> <a href="https://www.scintilla.org/scintilla564.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/scintilla562.tgz">
<a href="https://www.scintilla.org/scintilla564.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.6.2
Release 5.6.4
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Scintilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/scintilla562.zip">zip format</a> (1.8M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla562.tgz">tgz format</a> (1.7M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/scintilla564.zip">zip format</a> (1.8M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla564.tgz">tgz format</a> (1.7M) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -595,9 +595,68 @@
<td>Nathaniel Braun</td>
</tr><tr>
<td>Stephan T. Lavavej</td>
<td>RealMalWare</td>
<td>Schreiner</td>
</tr>
</table>
<h2 id="Releases">Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla564.zip">Release 5.6.4</a>
</h3>
<ul>
<li>
Released 6 July 2026.
</li>
<li>
On Qt improve display for fractional scaling by providing SCI_SETSCALETECHNIQUE API.
The SCALE_TECHNIQUE_PIXEL_ALIGNED value will eliminate potential 'seams' between lines
and between runs on a line.
<a href="https://sourceforge.net/p/scintilla/bugs/2450/">Bug #2450</a>.
</li>
<li>
Scintilla.iface is augmented with comments indicating which APIs take pixel values so may
be automatically scaled by wrappers.
For compatibility this is currently indicated in comments after each affected API but this will
change to using the 'pixels' type in a future version,
Downstream projects should examine this and make any needed changes, such as using floating
point types for wrapper methods.
To help migration, the scripts/FilterPixels.py script can convert this Scintilla.iface into the previous form
with no mention of 'pixels' or into the final form with 'pixels' as the only type for these features.
</li>
<li>
On Qt always place ScintillaEditBase library in scintilla/bin instead of depending on Qt version.
</li>
<li>
Optimize SCI_CHANGEINSERTION that sets empty insertion by not producing empty undo action
and potential save point change.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1588/">Feature #1588</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla563.zip">Release 5.6.3</a>
</h3>
<ul>
<li>
Released 6 June 2026.
</li>
<li>
Restore selection and scroll position for undo and redo on additional views instead of just the view
performing the undo or redo.
<a href="https://github.com/notepad-plus-plus/notepad-plus-plus/pull/18014">Notepad++ Pull Request #18014</a>.
</li>
<li>
Improve performance of rectangular paste when many spaces must be inserted.
<a href="https://sourceforge.net/p/scintilla/bugs/2302/">Bug #2302</a>.
</li>
<li>
On Win32, close the clipboard before inserting pasted or dropped text so that the clipboard is not blocked while
the insertion is performed.
<a href="https://sourceforge.net/p/scintilla/bugs/2507/">Bug #2507</a>.
</li>
<li>
On Qt with Wayland, fix failures with displaying calltips and autocompletion lists.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla562.zip">Release 5.6.2</a>
</h3>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20260429" />
<meta name="Date.Modified" content="20260706" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -61,8 +61,8 @@
GTK, and macOS</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 5.6.2<br />
Site last modified April 29 2026</font>
<font color="#FFCC99" size="3"> Release version 5.6.4<br />
Site last modified July 6 2026</font>
</td>
<td width="20%">
&nbsp;
@ -77,11 +77,11 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.6.4 implements pixel-aligned fractional scaling for Qt.</li>
<li>Version 5.6.3 restores selection and scroll position for undo and redo on additional views.</li>
<li>Version 5.6.2 adds error status SC_STATUS_OUTSIDE_DOCUMENT and stops out-of-bounds insertions earlier.</li>
<li>Version 5.6.1 adds mode to draw tabs as HT blobs and fixes a regression in SCI_CONVERTEOLS.</li>
<li>Version 5.6.0 fixes crash when window is too narrow to show any text.</li>
<li>Version 5.5.9 adds an option to disable drag &amp; drop. Fixes colour after line end.</li>
<li>Version 5.5.8 changes format of SCI_GETSELECTIONSERIALIZED and fixes redraw after undo.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -1351,6 +1351,10 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCN_MARGINRIGHTCLICK 2031
#define SCN_AUTOCSELECTIONCHANGE 2032
#ifndef SCI_DISABLE_PROVISIONAL
#define SCALE_TECHNIQUE_DEFAULT 0
#define SCALE_TECHNIQUE_PIXEL_ALIGNED 1
#define SCI_SETSCALETECHNIQUE 2820
#define SCI_GETSCALETECHNIQUE 2821
#define SC_BIDIRECTIONAL_DISABLED 0
#define SC_BIDIRECTIONAL_L2R 1
#define SC_BIDIRECTIONAL_R2L 2

View File

@ -66,6 +66,7 @@
## keymod -> integer containing key in low half and modifiers in high half
## formatrange
## formatrangefull
## pixels -> intptr_t pixel positions and sizes (experimental: used in ## line following definition)
## Enumeration types always start with a capital letter
## Types no longer used:
## findtextex -> searchrange
@ -214,10 +215,12 @@ set void SetTabDrawMode=2699(TabDrawMode tabDrawMode,)
# Find the position from a point within the window.
fun position PositionFromPoint=2022(int x, int y)
## fun position PositionFromPoint=2022(pixels x, pixels y)
# Find the position from a point within the window but return
# INVALID_POSITION if not close to text.
fun position PositionFromPointClose=2023(int x, int y)
## fun position PositionFromPointClose=2023(pixels x, pixels y)
# Set caret to start of a line and ensure it is visible.
fun void GotoLine=2024(line line,)
@ -276,9 +279,11 @@ get int GetTabWidth=2121(,)
# Set the minimum visual width of a tab.
set void SetTabMinimumWidth=2724(int pixels,)
## set void SetTabMinimumWidth=2724(pixels pixels,)
# Get the minimum visual width of a tab.
get int GetTabMinimumWidth=2725(,)
## get pixels GetTabMinimumWidth=2725(,)
# Clear explicit tabstops on a line.
fun void ClearTabStops=2675(line line,)
@ -443,6 +448,7 @@ set void MarkerSetBackSelectedTranslucent=2296(int markerNumber, colouralpha bac
# Set the width of strokes used in .01 pixels so 50 = 1/2 pixel width.
set void MarkerSetStrokeWidth=2297(int markerNumber, int hundredths)
## set void MarkerSetStrokeWidth=2297(int markerNumber, pixels hundredths)
# Enable/disable highlight for current folding block (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
@ -502,9 +508,11 @@ get MarginType GetMarginTypeN=2241(int margin,)
# Set the width of a margin to a width expressed in pixels.
set void SetMarginWidthN=2242(int margin, int pixelWidth)
## set void SetMarginWidthN=2242(int margin, pixels pixelWidth)
# Retrieve the width of a margin in pixels.
get int GetMarginWidthN=2243(int margin,)
## get pixels GetMarginWidthN=2243(int margin,)
# Set a mask that determines which markers are displayed in a margin.
set void SetMarginMaskN=2244(int margin, int mask)
@ -1023,9 +1031,11 @@ get IndicFlag IndicGetFlags=2685(int indicator,)
# Set the stroke width of an indicator in hundredths of a pixel.
set void IndicSetStrokeWidth=2751(int indicator, int hundredths)
## set void IndicSetStrokeWidth=2751(int indicator, pixels hundredths)
# Retrieve the stroke width of an indicator.
get int IndicGetStrokeWidth=2752(int indicator,)
## get pixels IndicGetStrokeWidth=2752(int indicator,)
# Set the foreground colour of all whitespace and whether to use this setting.
fun void SetWhitespaceFore=2084(bool useSetting, colour fore)
@ -1035,9 +1045,11 @@ fun void SetWhitespaceBack=2085(bool useSetting, colour back)
# Set the size of the dots used to mark space characters.
set void SetWhitespaceSize=2086(int size,)
## set void SetWhitespaceSize=2086(pixels size,)
# Get the size of the dots used to mark space characters.
get int GetWhitespaceSize=2087(,)
## get pixels GetWhitespaceSize=2087(,)
# Used to hold extra styling information for each line.
set void SetLineState=2092(line line, int state)
@ -1063,10 +1075,12 @@ set void SetCaretLineBack=2098(colour back,)
# Retrieve the caret line frame width.
# Width = 0 means this option is disabled.
get int GetCaretLineFrame=2704(,)
## get pixels GetCaretLineFrame=2704(,)
# Display the caret line framed.
# Set width != 0 to enable this option and width = 0 to disable it.
set void SetCaretLineFrame=2705(int width,)
## set void SetCaretLineFrame=2705(pixels width,)
# Set a style to be changeable or not (read only).
# Experimental feature, currently buggy.
@ -1390,15 +1404,19 @@ set void AllocateLines=2089(line lines,)
# Sets the size in pixels of the left margin.
set void SetMarginLeft=2155(, int pixelWidth)
## set void SetMarginLeft=2155(, pixels pixelWidth)
# Returns the size in pixels of the left margin.
get int GetMarginLeft=2156(,)
## get pixels GetMarginLeft=2156(,)
# Sets the size in pixels of the right margin.
set void SetMarginRight=2157(, int pixelWidth)
## set void SetMarginRight=2157(, pixels pixelWidth)
# Returns the size in pixels of the right margin.
get int GetMarginRight=2158(,)
## get pixels GetMarginRight=2158(,)
# Is the document different from when it was last saved?
get bool GetModify=2159(,)
@ -1427,9 +1445,11 @@ get bool GetSelectionHidden=2088(,)
# Retrieve the x value of the point in the window where a position is displayed.
fun int PointXFromPosition=2164(, position pos)
## fun pixels PointXFromPosition=2164(, position pos)
# Retrieve the y value of the point in the window where a position is displayed.
fun int PointYFromPosition=2165(, position pos)
## fun pixels PointYFromPosition=2165(, position pos)
# Retrieve the line containing a position.
fun line LineFromPosition=2166(position pos,)
@ -1513,9 +1533,11 @@ get bool GetOvertype=2187(,)
# Set the width of the insert mode caret.
set void SetCaretWidth=2188(int pixelWidth,)
## set void SetCaretWidth=2188(pixels pixelWidth,)
# Returns the width of the insert mode caret.
get int GetCaretWidth=2189(,)
## get pixels GetCaretWidth=2189(,)
# Sets the position that starts the target which is used for updating the
# document without affecting the scroll position.
@ -1612,6 +1634,7 @@ set void CallTipSetForeHlt=2207(colour fore,)
# Enable use of STYLE_CALLTIP and set call tip tab size in pixels.
set void CallTipUseStyle=2212(int tabSize,)
## set void CallTipUseStyle=2212(pixels tabSize,)
# Set position of calltip, above or below text.
set void CallTipSetPosition=2213(bool above,)
@ -1830,9 +1853,11 @@ get WrapVisualLocation GetWrapVisualFlagsLocation=2463(,)
# Set the start indent for wrapped lines.
set void SetWrapStartIndent=2464(int indent,)
## set void SetWrapStartIndent=2464(pixels indent,)
# Retrive the start indent for wrapped lines.
get int GetWrapStartIndent=2465(,)
## get pixels GetWrapStartIndent=2465(,)
enu WrapIndentMode=SC_WRAPINDENT_
val SC_WRAPINDENT_FIXED=0
@ -1862,9 +1887,11 @@ get LineCache GetLayoutCache=2273(,)
# Sets the document width assumed for scrolling.
set void SetScrollWidth=2274(int pixelWidth,)
## set void SetScrollWidth=2274(pixels pixelWidth,)
# Retrieve the document width assumed for scrolling.
get int GetScrollWidth=2275(,)
## get pixels GetScrollWidth=2275(,)
# Sets whether the maximum width line displayed is used to set scroll width.
set void SetScrollWidthTracking=2516(bool tracking,)
@ -1876,6 +1903,7 @@ get bool GetScrollWidthTracking=2517(,)
# NUL terminated text argument.
# Does not handle tab or control characters.
fun int TextWidth=2276(int style, string text)
## fun pixels TextWidth=2276(int style, string text)
# Sets the scroll range so that maximum scroll position has
# the last line at the bottom of the view (default).
@ -1888,6 +1916,7 @@ get bool GetEndAtLastLine=2278(,)
# Retrieve the height of a particular line of text in pixels.
fun int TextHeight=2279(line line,)
## fun pixels TextHeight=2279(line line,)
# Show or hide the vertical scroll bar.
set void SetVScrollBar=2280(bool visible,)
@ -1950,6 +1979,7 @@ fun void LinesJoin=2288(,)
# Split the lines in the target into lines that are less wide than pixelWidth
# where possible.
fun void LinesSplit=2289(int pixelWidth,)
## fun void LinesSplit=2289(pixels pixelWidth,)
# Set one of the colours used as a chequerboard pattern in the fold margin
fun void SetFoldMarginColour=2290(bool useSetting, colour back)
@ -2368,9 +2398,11 @@ fun void DelLineRight=2396(,)
# Set the xOffset (ie, horizontal scroll position).
set void SetXOffset=2397(int xOffset,)
## set void SetXOffset=2397(pixels xOffset,)
# Get the xOffset (ie, horizontal scroll position).
get int GetXOffset=2398(,)
## get pixels GetXOffset=2398(,)
# Set the last x chosen value to be the caret x position.
fun void ChooseCaretX=2399(,)
@ -2405,6 +2437,7 @@ val CARET_EVEN=0x08
# Set the way the caret is kept visible when going sideways.
# The exclusion zone is given in pixels.
fun void SetXCaretPolicy=2402(CaretPolicy caretPolicy, int caretSlop)
## fun void SetXCaretPolicy=2402(CaretPolicy caretPolicy, pixels caretSlop)
# Set the way the line the caret is on is kept visible.
# The exclusion zone is given in lines.
@ -2773,15 +2806,19 @@ get Alpha IndicGetOutlineAlpha=2559(int indicator,)
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
## set void SetExtraAscent=2525(pixels extraAscent,)
# Get extra ascent for each line
get int GetExtraAscent=2526(,)
## get pixels GetExtraAscent=2526(,)
# Set extra descent for each line
set void SetExtraDescent=2527(int extraDescent,)
## set void SetExtraDescent=2527(pixels extraDescent,)
# Get extra descent for each line
get int GetExtraDescent=2528(,)
## get pixels GetExtraDescent=2528(,)
# Which symbol was defined for markerNumber with MarkerDefine
fun MarkerSymbol MarkerSymbolDefined=2529(int markerNumber,)
@ -2882,10 +2919,12 @@ fun void AddUndoAction=2560(int token, UndoFlags flags)
# Find the position of a character from a point within the window.
fun position CharPositionFromPoint=2561(int x, int y)
## fun position CharPositionFromPoint=2561(pixels x, pixels y)
# Find the position of a character from a point within the window.
# Return INVALID_POSITION if not close to text.
fun position CharPositionFromPointClose=2562(int x, int y)
## fun position CharPositionFromPointClose=2562(pixels x, pixels y)
# Set whether switching to rectangular mode while selecting with the mouse is allowed.
set void SetMouseSelectionRectangularSwitch=2668(bool mouseSelectionRectangularSwitch,)
@ -2934,6 +2973,7 @@ fun void AddSelection=2573(position caret, position anchor)
# Find the selection index for a point. -1 when not at a selection.
fun int SelectionFromPoint=2474(int x, int y)
## fun int SelectionFromPoint=2474(pixels x, pixels y)
# Drop one selection
fun void DropSelectionN=2671(int selection,)
@ -3558,6 +3598,16 @@ evt void AutoCSelectionChange=2032(int listType, string text, int position)
cat Provisional
enu ScaleTechnique=SCALE_TECHNIQUE_
val SCALE_TECHNIQUE_DEFAULT=0
val SCALE_TECHNIQUE_PIXEL_ALIGNED=1
# Set the scale technique
set void SetScaleTechnique=2820(ScaleTechnique technique,)
# Get the scale technique
get ScaleTechnique GetScaleTechnique=2821(,)
enu Bidirectional=SC_BIDIRECTIONAL_
val SC_BIDIRECTIONAL_DISABLED=0
val SC_BIDIRECTIONAL_L2R=1

View File

@ -937,6 +937,8 @@ public:
int DescriptionOfStyle(int style, char *description);
std::string DescriptionOfStyle(int style);
void SetILexer(void *ilexer);
void SetScaleTechnique(Scintilla::ScaleTechnique technique);
Scintilla::ScaleTechnique ScaleTechnique();
Scintilla::Bidirectional Bidirectional();
void SetBidirectional(Scintilla::Bidirectional bidirectional);

View File

@ -833,6 +833,8 @@ enum class Message {
TagsOfStyle = 4031,
DescriptionOfStyle = 4032,
SetILexer = 4033,
SetScaleTechnique = 2820,
GetScaleTechnique = 2821,
GetBidirectional = 2708,
SetBidirectional = 2709,
};

View File

@ -679,6 +679,11 @@ enum class CharacterSource {
ImeResult = 2,
};
enum class ScaleTechnique {
Default = 0,
PixelAligned = 1,
};
enum class Bidirectional {
Disabled = 0,
L2R = 1,

View File

@ -67,12 +67,17 @@ class Face:
self.events = {}
self.aliases = {}
def ReadFromFile(self, name):
def ReadFromFile(self, name, pickUpPixels=False):
currentCategory = ""
currentComment = []
currentCommentFinished = 0
file = open(name)
for line in file:
if pickUpPixels:
stripped = line.strip()
if stripped.startswith("## "):
self.ApplyPixelComment(stripped[3:])
continue
line = sanitiseLine(line)
if line:
if line[0] == "#":
@ -145,3 +150,24 @@ class Face:
self.aliases[name] = value
currentComment = []
file.close()
def ApplyPixelComment(self, featureVal):
# A '## <fun|get|set ... pixels ...>' comment below a message re-types
# the named feature's pixels slots, so a caller passing pickUpPixels=True
# sees them. Other consumers ignore it, since sanitiseLine strips '##'.
featureType, _, rest = featureVal.partition(" ")
if featureType not in ("fun", "get", "set") or not rest:
return
try:
retType, name, value, param1, param2 = decodeFunction(rest)
except ValueError:
return
feature = self.features.get(name)
if feature is None:
return
if retType == "pixels":
feature["ReturnType"] = "pixels"
if decodeParam(param1)[0] == "pixels":
feature["Param1Type"] = "pixels"
if decodeParam(param2)[0] == "pixels":
feature["Param2Type"] = "pixels"

View File

@ -37,7 +37,9 @@
// C++ standard library
#include <stdexcept>
#include <system_error>
#include <new>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -54,6 +56,8 @@
#include <chrono>
#include <charconv>
#include <regex>
#include <ios>
#include <ostream>
#include <iostream>
#include <sstream>
#include <fstream>
@ -63,6 +67,7 @@
#include <thread>
#include <future>
#include <type_traits>
#include <locale>
// GTK headers
#include <glib.h>

View File

@ -11,6 +11,7 @@
#include <cassert>
#include <stdexcept>
#include <utility>
#include <vector>
#include <set>
#include <algorithm>

View File

@ -9,6 +9,7 @@
// Copyright 2013 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <utility>
#include <vector>
#include <algorithm>
#include <iterator>

View File

@ -10,6 +10,7 @@
#include <cstring>
#include <stdexcept>
#include <utility>
#include <string_view>
#include <vector>
#include <optional>

View File

@ -12,6 +12,7 @@
#include <cstdarg>
#include <stdexcept>
#include <utility>
#include <string_view>
#include <vector>
#include <optional>

View File

@ -14,6 +14,8 @@
#include <cmath>
#include <stdexcept>
#include <new>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -22,6 +24,7 @@
#include <forward_list>
#include <optional>
#include <algorithm>
#include <iterator>
#include <memory>
#include <chrono>
@ -1509,6 +1512,10 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci:
position, insertLength,
0, s));
if (insertionSet) {
if (insertion.empty()) {
enteredModification--;
return 0;
}
s = insertion.c_str();
insertLength = insertion.length();
}
@ -1630,7 +1637,7 @@ Sci::Position Document::Undo() {
modFlags |= ModificationFlags::MultilineUndoRedo;
}
NotifyModified(DocModification(modFlags, action.position, action.lenData,
linesAdded, action.data));
linesAdded, action.data, 0, newPos));
}
const bool endSavePoint = cb.IsSavePoint();
@ -1690,7 +1697,7 @@ Sci::Position Document::Redo() {
}
NotifyModified(
DocModification(modFlags, action.position, action.lenData,
linesAdded, action.data));
linesAdded, action.data, 0, newPos));
}
const bool endSavePoint = cb.IsSavePoint();
@ -1896,13 +1903,13 @@ constexpr std::string_view EOLForMode(EndOfLine eolMode) noexcept {
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eolModeWanted) {
std::string Document::TransformLineEnds(std::string_view s, EndOfLine eolModeWanted) {
std::string dest;
const std::string_view eol = EOLForMode(eolModeWanted);
for (size_t i = 0; (i < len) && (s[i]); i++) {
for (size_t i = 0; (i < s.length()) && (s[i]); i++) {
if (s[i] == '\n' || s[i] == '\r') {
dest.append(eol);
if ((s[i] == '\r') && (i+1 < len) && (s[i+1] == '\n')) {
if ((s[i] == '\r') && (i+1 < s.length()) && (s[i+1] == '\n')) {
i++;
}
} else {
@ -1912,6 +1919,10 @@ std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eol
return dest;
}
std::string Document::TransformLineEnds(const char *s, size_t len, EndOfLine eolModeWanted) {
return TransformLineEnds(std::string_view(s, len), eolModeWanted);
}
void Document::ConvertLineEnds(EndOfLine eolModeSet) {
UndoGroup ug(this);

View File

@ -138,6 +138,9 @@ struct StyledText {
size_t StyleAt(size_t i) const noexcept {
return multipleStyles ? styles[i] : style;
}
std::string_view AsView() const noexcept {
return { text, length };
}
};
class HighlightDelimiter {
@ -470,7 +473,8 @@ public:
Sci::Position CountUTF16(Sci::Position startPos, Sci::Position endPos) const noexcept;
Sci::Position FindColumn(Sci::Line line, Sci::Position column) const noexcept;
void Indent(bool forwards, Sci::Line lineBottom, Sci::Line lineTop);
static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted);
static std::string TransformLineEnds(std::string_view s, Scintilla::EndOfLine eolModeWanted);
[[deprecated]]static std::string TransformLineEnds(const char *s, size_t len, Scintilla::EndOfLine eolModeWanted);
void ConvertLineEnds(Scintilla::EndOfLine eolModeSet);
std::string_view EOLString() const noexcept;
void SetReadOnly(bool set) noexcept { cb.SetReadOnly(set); }
@ -658,9 +662,10 @@ public:
Scintilla::FoldLevel foldLevelPrev;
Sci::Line annotationLinesAdded;
Sci::Position token;
Sci::Position newPos = -1; /**< Reasonable new caret position after undo or redo. */
DocModification(Scintilla::ModificationFlags modificationType_, Sci::Position position_=0, Sci::Position length_=0,
Sci::Line linesAdded_=0, const char *text_=nullptr, Sci::Line line_=0) noexcept :
Sci::Line linesAdded_=0, const char *text_=nullptr, Sci::Line line_=0, Sci::Position newPos_=-1) noexcept :
modificationType(modificationType_),
position(position_),
length(length_),
@ -670,7 +675,8 @@ public:
foldLevelNow(Scintilla::FoldLevel::None),
foldLevelPrev(Scintilla::FoldLevel::None),
annotationLinesAdded(0),
token(0) {}
token(0),
newPos(newPos_) {}
DocModification(Scintilla::ModificationFlags modificationType_, const Action &act, Sci::Line linesAdded_=0) noexcept :
modificationType(modificationType_),

View File

@ -14,6 +14,7 @@
#include <cmath>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -806,7 +807,7 @@ Sci::Position EditView::StartEndDisplayLine(Surface *surface, const EditModel &m
const Sci::Position posLineStart = model.pdoc->LineStart(line);
LayoutLine(model, surface, vs, ll.get(), model.wrapWidth);
const Sci::Position posInLine = pos - posLineStart;
if (posInLine <= ll->maxLineLength) {
if (posInLine <= ll->numCharsInLine) {
for (int subLine = 0; subLine < ll->lines; subLine++) {
if ((posInLine >= ll->LineStart(subLine)) &&
(posInLine <= ll->LineStart(subLine + 1)) &&

View File

@ -14,6 +14,7 @@
#include <cmath>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -115,6 +116,10 @@ constexpr bool IsAllSpacesOrTabs(std::string_view sv) noexcept {
return true;
}
sptr_t SPtrFromPtr(const void *ptr) noexcept {
return reinterpret_cast<sptr_t>(ptr);
}
}
Timer::Timer() noexcept :
@ -1613,10 +1618,10 @@ bool Editor::WrapBlock(Surface *surface, Sci::Line lineToWrap, Sci::Line lineToW
std::shared_ptr<LineLayout> llLarge = std::make_shared<LineLayout>(-1, 200);
for (size_t indexLarge = 0; indexLarge < linesBeingWrapped; indexLarge++) {
const Sci::Line lineNumber = lineToWrap + indexLarge;
const Range rangeLine = pdoc->LineRange(lineNumber);
const Sci::Position lengthLine = rangeLine.Length();
if (lengthLine >= lengthToMultiThread) {
if (linesAfterWrap[indexLarge] == 0) {
const Sci::Line lineNumber = lineToWrap + indexLarge;
const Range rangeLine = pdoc->LineRange(lineNumber);
const Sci::Position lengthLine = rangeLine.Length();
std::shared_ptr<LineLayout> ll;
if (significantLines.LineMayCache(lineNumber)) {
ll = view.RetrieveLineLayout(lineNumber, *this);
@ -2170,7 +2175,7 @@ void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) {
if (recordingMacro && charSource != CharacterSource::TentativeInput) {
std::string copy(sv); // ensure NUL-terminated
NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast<sptr_t>(copy.data()));
NotifyMacroRecord(Message::ReplaceSel, 0, SPtrFromPtr(copy.data()));
}
}
@ -2199,11 +2204,11 @@ void Editor::ClearBeforeTentativeStart() {
}
}
void Editor::InsertPaste(const char *text, Sci::Position len) {
void Editor::InsertPaste(std::string_view text) {
if (multiPasteMode == MultiPaste::Once) {
SelectionPosition selStart = sel.Start();
selStart = RealizeVirtualSpace(selStart);
const Sci::Position lengthInserted = pdoc->InsertString(selStart.Position(), text, len);
const Sci::Position lengthInserted = pdoc->InsertString(selStart.Position(), text);
if (lengthInserted > 0) {
SetEmptySelection(selStart.Position() + lengthInserted);
}
@ -2214,7 +2219,7 @@ void Editor::InsertPaste(const char *text, Sci::Position len) {
Sci::Position positionInsert = sel.Range(r).Start().Position();
ClearSelectionRange(sel.Range(r));
positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text, len);
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text);
if (lengthInserted > 0) {
sel.Range(r) = SelectionRange(positionInsert + lengthInserted);
}
@ -2224,22 +2229,25 @@ void Editor::InsertPaste(const char *text, Sci::Position len) {
}
}
void Editor::InsertPasteShape(const char *text, Sci::Position len, PasteShape shape) {
void Editor::InsertPaste(const char *text, Sci::Position len) {
InsertPaste(std::string_view(text, len));
}
void Editor::InsertPasteShape(std::string_view text, PasteShape shape) {
std::string convertedText;
if (convertPastes) {
// Convert line endings of the paste into our local line-endings mode
convertedText = Document::TransformLineEnds(text, len, pdoc->eolMode);
len = convertedText.length();
text = convertedText.c_str();
convertedText = Document::TransformLineEnds(text, pdoc->eolMode);
text = convertedText;
}
if (shape == PasteShape::rectangular) {
PasteRectangular(sel.Start(), text, len);
PasteRectangular(sel.Start(), text);
} else {
if (shape == PasteShape::line) {
const Sci::Position insertPos = pdoc->LineStartPosition(sel.MainCaret());
Sci::Position lengthInserted = pdoc->InsertString(insertPos, text, len);
Sci::Position lengthInserted = pdoc->InsertString(insertPos, text);
// add the newline if necessary
if ((len > 0) && (text[len - 1] != '\n' && text[len - 1] != '\r')) {
if ((!text.empty()) && (!AnyOf(text.back(), '\n', '\r'))) {
const std::string_view endline = pdoc->EOLString();
lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline);
}
@ -2247,11 +2255,15 @@ void Editor::InsertPasteShape(const char *text, Sci::Position len, PasteShape sh
SetEmptySelection(sel.MainCaret() + lengthInserted);
}
} else {
InsertPaste(text, len);
InsertPaste(text);
}
}
}
void Editor::InsertPasteShape(const char *text, Sci::Position len, PasteShape shape) {
InsertPasteShape(std::string_view(text, len), shape);
}
void Editor::ClearSelection(bool retainMultipleSelections) {
if (!sel.IsRectangular() && !retainMultipleSelections)
FilterSelections();
@ -2331,7 +2343,7 @@ void Editor::Cut() {
}
}
void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len) {
void Editor::PasteRectangular(SelectionPosition pos, std::string_view text) {
if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
return;
}
@ -2342,11 +2354,17 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit
sel.RangeMain().caret = RealizeVirtualSpace(sel.RangeMain().caret);
const int xInsert = XFromPosition(sel.RangeMain().caret);
bool prevCr = false;
while ((len > 0) && IsEOLCharacter(ptr[len-1]))
len--;
for (Sci::Position i = 0; i < len; i++) {
if (IsEOLCharacter(ptr[i])) {
if ((ptr[i] == '\r') || (!prevCr))
constexpr Sci::Position maxBatchSpaces = 8192;
XYPOSITION maxSpaceWidth = 0;
for (const Style &style : vs.styles) {
maxSpaceWidth = std::max(maxSpaceWidth, style.spaceWidth);
}
while ((!text.empty()) && IsEOLCharacter(text.back())) {
text.remove_suffix(1);
}
for (size_t i = 0; i < text.length(); i++) {
if (IsEOLCharacter(text[i])) {
if ((text[i] == '\r') || (!prevCr))
line++;
if (line >= pdoc->LinesTotal()) {
const std::string_view eol = pdoc->EOLString();
@ -2354,16 +2372,33 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit
}
// Pad the end of lines with spaces if required
sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
if ((XFromPosition(sel.RangeMain().caret) < xInsert) && (i + 1 < len)) {
const int xCurrent = XFromPosition(sel.RangeMain().caret);
if ((xCurrent < xInsert) && (i + 1 < text.length())) {
if (pdoc->IsLineEndPosition(sel.MainCaret())) {
int xAfterBatch = xCurrent;
while ((xAfterBatch < xInsert) && (maxSpaceWidth > 0)) {
const int missing = xInsert - xAfterBatch;
const Sci::Position spacesEstimate = static_cast<Sci::Position>(missing / maxSpaceWidth);
if (spacesEstimate <= 2) {
break;
}
const Sci::Position batchSpaces = std::min(spacesEstimate - 1, maxBatchSpaces);
const std::string pad(static_cast<size_t>(batchSpaces), ' ');
const Sci::Position lengthInserted = pdoc->InsertString(sel.MainCaret(), pad);
sel.RangeMain().caret.Add(lengthInserted);
xAfterBatch = XFromPosition(sel.RangeMain().caret);
}
}
while (XFromPosition(sel.RangeMain().caret) < xInsert) {
assert(pdoc);
const Sci::Position lengthInserted = pdoc->InsertString(sel.MainCaret(), " ", 1);
sel.RangeMain().caret.Add(lengthInserted);
}
}
prevCr = ptr[i] == '\r';
prevCr = text[i] == '\r';
} else {
const Sci::Position lengthInserted = pdoc->InsertString(sel.MainCaret(), ptr + i, 1);
const Sci::Position lengthInserted = pdoc->InsertString(sel.MainCaret(), text.substr(i, 1));
sel.RangeMain().caret.Add(lengthInserted);
prevCr = false;
}
@ -2371,6 +2406,10 @@ void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Posit
SetEmptySelection(pos);
}
void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len) {
PasteRectangular(pos, std::string_view(ptr, len));
}
bool Editor::CanPaste() {
return !pdoc->IsReadOnly() && !SelectionContainsProtected();
}
@ -2446,15 +2485,13 @@ void Editor::RestoreSelection(Sci::Position newPos, UndoRedo history) {
void Editor::Undo() {
if (pdoc->CanUndo()) {
InvalidateCaret();
const Sci::Position newPos = pdoc->Undo();
RestoreSelection(newPos, UndoRedo::undo);
pdoc->Undo();
}
}
void Editor::Redo() {
if (pdoc->CanRedo()) {
const Sci::Position newPos = pdoc->Redo();
RestoreSelection(newPos, UndoRedo::redo);
pdoc->Redo();
}
}
@ -2926,6 +2963,14 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
Redraw();
}
if (FlagSet(mh.modificationType, ModificationFlags::Undo | ModificationFlags::Redo)
&& FlagSet(mh.modificationType, ModificationFlags::LastStepInUndoRedo)
&& !pdoc->TentativeActive()) {
// Update selection and scroll
RestoreSelection(mh.newPos,
FlagSet(mh.modificationType, ModificationFlags::Undo) ? UndoRedo::undo : UndoRedo::redo);
}
// If client wants to see this modification
if (FlagSet(mh.modificationType, modEventMask)) {
if (commandEvents) {
@ -3321,7 +3366,7 @@ void Editor::NewLine() {
NotifyChar(ch, CharacterSource::DirectInput);
if (recordingMacro) {
const char txt[2] = { ch, '\0' };
NotifyMacroRecord(Message::ReplaceSel, 0, reinterpret_cast<sptr_t>(txt));
NotifyMacroRecord(Message::ReplaceSel, 0, SPtrFromPtr(txt));
}
}
}
@ -3464,12 +3509,14 @@ Sci::Position Editor::StartEndDisplayLine(Sci::Position pos, bool start) {
namespace {
constexpr short HighShortFromWParam(uptr_t x) {
return static_cast<short>(x >> 16);
constexpr KeyMod KeyModFromWParam(uptr_t x) {
constexpr uptr_t shiftForKeyMod = 16;
return static_cast<KeyMod>(x >> shiftForKeyMod);
}
constexpr short LowShortFromWParam(uptr_t x) {
return static_cast<short>(x & 0xffff);
constexpr Keys KeysFromWParam(uptr_t x) {
constexpr uptr_t maskForKeys = 0xffff;
return static_cast<Keys>(x & maskForKeys);
}
constexpr Message WithExtends(Message iMessage) noexcept {
@ -4529,7 +4576,7 @@ void Editor::StartDrag() {
// Always handled by subclasses
}
void Editor::DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular) {
void Editor::DropAt(SelectionPosition position, std::string_view value, bool moving, bool rectangular) {
//Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position);
if (inDragDrop == DragDrop::dragging)
dropWentOutside = false;
@ -4569,10 +4616,10 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length
}
position = positionAfterDeletion;
std::string convertedText = Document::TransformLineEnds(value, lengthValue, pdoc->eolMode);
std::string convertedText = Document::TransformLineEnds(value, pdoc->eolMode);
if (rectangular) {
PasteRectangular(position, convertedText.c_str(), convertedText.length());
PasteRectangular(position, convertedText);
// Should try to select new rectangle but it may not be a rectangle now so just select the drop position
SetEmptySelection(position);
} else {
@ -4591,8 +4638,12 @@ void Editor::DropAt(SelectionPosition position, const char *value, size_t length
}
}
void Editor::DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular) {
DropAt(position, std::string_view(value, lengthValue), moving, rectangular);
}
void Editor::DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular) {
DropAt(position, value, strlen(value), moving, rectangular);
DropAt(position, std::string_view(value), moving, rectangular);
}
/**
@ -6208,10 +6259,6 @@ constexpr Selection::SelTypes SelTypeFromMode(SelectionMode mode) {
}
}
sptr_t SPtrFromPtr(void *ptr) noexcept {
return reinterpret_cast<sptr_t>(ptr);
}
}
void Editor::SetSelectionMode(uptr_t wParam, bool setMoveExtends) {
@ -6357,7 +6404,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
if (!sel.Empty()) {
ClearSelection(); // want to replace rectangular selection contents
}
InsertPasteShape(ConstCharPtrFromSPtr(lParam), PositionFromUPtr(wParam), PasteShape::rectangular);
InsertPasteShape(std::string_view(ConstCharPtrFromSPtr(lParam), PositionFromUPtr(wParam)), PasteShape::rectangular);
break;
}
@ -8097,13 +8144,13 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
return vs.caret.width;
case Message::AssignCmdKey:
kmap.AssignCmdKey(static_cast<Keys>(LowShortFromWParam(wParam)),
static_cast<KeyMod>(HighShortFromWParam(wParam)), static_cast<Message>(lParam));
kmap.AssignCmdKey(KeysFromWParam(wParam),
KeyModFromWParam(wParam), static_cast<Message>(lParam));
break;
case Message::ClearCmdKey:
kmap.AssignCmdKey(static_cast<Keys>(LowShortFromWParam(wParam)),
static_cast<KeyMod>(HighShortFromWParam(wParam)), Message::Null);
kmap.AssignCmdKey(KeysFromWParam(wParam),
KeyModFromWParam(wParam), Message::Null);
break;
case Message::ClearAllCmdKeys:
@ -8473,7 +8520,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
doc->SetUndoCollection(false);
pcs = ContractionStateCreate(pdoc->IsLarge());
ILoader *loader = doc;
return reinterpret_cast<sptr_t>(loader);
return SPtrFromPtr(loader);
}
case Message::SetModEventMask:
@ -8706,10 +8753,10 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
return convertPastes ? 1 : 0;
case Message::GetCharacterPointer:
return reinterpret_cast<sptr_t>(pdoc->BufferPointer());
return SPtrFromPtr(pdoc->BufferPointer());
case Message::GetRangePointer:
return reinterpret_cast<sptr_t>(pdoc->RangePointer(
return SPtrFromPtr(pdoc->RangePointer(
PositionFromUPtr(wParam), lParam));
case Message::GetGapPosition:
@ -8776,7 +8823,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::MarginGetText: {
const StyledText st = pdoc->MarginStyledText(LineFromUPtr(wParam));
return BytesResult(lParam, reinterpret_cast<const unsigned char *>(st.text), st.length);
return BytesResult(lParam, st.AsView());
}
case Message::MarginSetStyle:
@ -8807,7 +8854,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::AnnotationGetText: {
const StyledText st = pdoc->AnnotationStyledText(LineFromUPtr(wParam));
return BytesResult(lParam, reinterpret_cast<const unsigned char *>(st.text), st.length);
return BytesResult(lParam, st.AsView());
}
case Message::AnnotationGetStyle: {
@ -8856,7 +8903,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::EOLAnnotationGetText: {
const StyledText st = pdoc->EOLAnnotationStyledText(LineFromUPtr(wParam));
return BytesResult(lParam, reinterpret_cast<const unsigned char *>(st.text), st.length);
return BytesResult(lParam, st.AsView());
}
case Message::EOLAnnotationGetStyle: {

View File

@ -100,9 +100,15 @@ public:
size_t Length() const noexcept {
return s.length();
}
std::string_view AsView() const noexcept {
return std::string_view(s);
}
size_t LengthWithTerminator() const noexcept {
return s.length() + 1;
}
std::string_view AsViewWithTerminator() const noexcept {
return std::string_view(s.c_str(), s.length()+1);
}
bool Empty() const noexcept {
return s.empty();
}
@ -443,14 +449,17 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void InsertCharacter(std::string_view sv, Scintilla::CharacterSource charSource);
void ClearSelectionRange(SelectionRange &range);
void ClearBeforeTentativeStart();
void InsertPaste(const char *text, Sci::Position len);
void InsertPaste(std::string_view text);
[[deprecated]] void InsertPaste(const char *text, Sci::Position len);
enum class PasteShape { stream=0, rectangular = 1, line = 2 };
void InsertPasteShape(const char *text, Sci::Position len, PasteShape shape);
void InsertPasteShape(std::string_view text, PasteShape shape);
[[deprecated]] void InsertPasteShape(const char *text, Sci::Position len, PasteShape shape);
void ClearSelection(bool retainMultipleSelections = false);
void ClearAll();
void ClearDocumentStyle();
virtual void Cut();
void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len);
void PasteRectangular(SelectionPosition pos, std::string_view text);
[[deprecated]] void PasteRectangular(SelectionPosition pos, const char *ptr, Sci::Position len);
virtual void Copy() = 0;
void CopyAllowLine();
void CutAllowLine();
@ -544,8 +553,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void DisplayCursor(Window::Cursor c);
virtual bool DragThreshold(Point ptStart, Point ptNow) noexcept;
virtual void StartDrag();
void DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular);
void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
void DropAt(SelectionPosition position, std::string_view value, bool moving, bool rectangular);
[[deprecated]] void DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular);
[[deprecated]] void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular);
/** PositionInSelection returns true if position in selection. */
bool PositionInSelection(Sci::Position pos);
bool PointInSelection(Point pt);

View File

@ -45,6 +45,10 @@ public:
return Point(x - other.x, y - other.y);
}
constexpr Point operator*(XYPOSITION multiplier) const noexcept {
return Point(x * multiplier, y * multiplier);
}
// Other automatically defined methods (assignment, copy constructor, destructor) are fine
};
@ -101,6 +105,15 @@ public:
return (rc.left == left) && (rc.right == right) &&
(rc.top == top) && (rc.bottom == bottom);
}
constexpr PRectangle operator*(XYPOSITION multiplier) const noexcept {
return PRectangle(left * multiplier, top * multiplier, right * multiplier, bottom * multiplier);
}
constexpr PRectangle operator/(XYPOSITION divisor) const noexcept {
return PRectangle(left / divisor, top / divisor, right / divisor, bottom / divisor);
}
constexpr bool Contains(Point pt) const noexcept {
return (pt.x >= left) && (pt.x <= right) &&
(pt.y >= top) && (pt.y <= bottom);

View File

@ -11,6 +11,7 @@
#include <cstring>
#include <stdexcept>
#include <utility>
#include <string_view>
#include <vector>
#include <forward_list>

View File

@ -12,6 +12,7 @@
#include <cmath>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -64,20 +65,7 @@ void BidiData::Resize(size_t maxLineLength_) {
}
LineLayout::LineLayout(Sci::Line lineNumber_, int maxLineLength_) :
lenLineStarts(0),
lineNumber(lineNumber_),
maxLineLength(-1),
numCharsInLine(0),
numCharsBeforeEOL(0),
validity(ValidLevel::invalid),
xHighlightGuide(0),
highlightColumn(false),
containsCaret(false),
edgeColumn(0),
bracePreviousStyles{},
widthLine(wrapWidthInfinite),
lines(1),
wrapIndent(0) {
lineNumber(lineNumber_) {
Resize(maxLineLength_);
}
@ -270,11 +258,6 @@ int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition)
Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const noexcept {
Point pt;
// In case of very long line put x at arbitrary large position
if (posInLine > maxLineLength) {
pt.x = positions[maxLineLength] - positions[LineStart(lines)];
}
for (int subLine = 0; subLine < lines; subLine++) {
const Range rangeSubLine = SubLineRange(subLine, Scope::visibleOnly);
if (posInLine >= rangeSubLine.start) {
@ -617,7 +600,7 @@ std::shared_ptr<LineLayout> LineLayoutCache::Retrieve(Sci::Line lineNumber, Sci:
if (pos < cache.size()) {
if (cache[pos] && !cache[pos]->CanHold(lineNumber, maxChars)) {
cache[pos].reset();
cache[pos]->ReSet(lineNumber, maxChars);
}
if (!cache[pos]) {
cache[pos] = std::make_shared<LineLayout>(lineNumber, maxChars);

View File

@ -49,31 +49,32 @@ public:
class LineLayout {
private:
std::unique_ptr<int []>lineStarts;
int lenLineStarts;
int lenLineStarts = 0;
/// Drawing is only performed for @a maxLineLength characters on each line.
Sci::Line lineNumber;
public:
enum { wrapWidthInfinite = 0x7ffffff };
int maxLineLength;
int numCharsInLine;
int numCharsBeforeEOL;
enum class ValidLevel { invalid, checkTextAndStyle, positions, lines } validity;
int xHighlightGuide;
bool highlightColumn;
bool containsCaret;
int edgeColumn;
int maxLineLength = -1;
int numCharsInLine = 0;
int numCharsBeforeEOL = 0;
enum class ValidLevel { invalid, checkTextAndStyle, positions, lines };
ValidLevel validity = ValidLevel::invalid;
int xHighlightGuide = 0;
bool highlightColumn = false;
bool containsCaret = false;
unsigned char bracePreviousStyles[2]{};
int edgeColumn = 0;
std::unique_ptr<char[]> chars;
std::unique_ptr<unsigned char[]> styles;
std::unique_ptr<XYPOSITION[]> positions;
unsigned char bracePreviousStyles[2];
std::unique_ptr<BidiData> bidiData;
// Wrapped line support
int widthLine;
int lines;
XYPOSITION wrapIndent; // In pixels
int widthLine = wrapWidthInfinite;
int lines = 1;
XYPOSITION wrapIndent = 0; // In pixels
LineLayout(Sci::Line lineNumber_, int maxLineLength_);
void Resize(int maxLineLength_);

View File

@ -9,6 +9,8 @@
#include <cstdlib>
#include <stdexcept>
#include <system_error>
#include <utility>
#include <string>
#include <string_view>
#include <vector>

View File

@ -8,6 +8,7 @@
#include <cstdint>
#include <stdexcept>
#include <utility>
#include <string_view>
#include <vector>
#include <optional>

View File

@ -15,6 +15,7 @@
#include <climits>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>

View File

@ -12,6 +12,7 @@
#include <cmath>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>

View File

@ -11,6 +11,7 @@
#include <climits>
#include <stdexcept>
#include <utility>
#include <string_view>
#include <vector>
#include <map>

View File

@ -1 +1 @@
562
564

View File

@ -15,6 +15,7 @@
#include <cmath>
#include <climits>
#include <string>
#include <string_view>
#include <vector>
#include <map>

View File

@ -15,6 +15,7 @@
#include <cmath>
#include <climits>
#include <utility>
#include <string_view>
#include <vector>
#include <map>

View File

@ -6,8 +6,8 @@
#include <windows.h>
#define VERSION_SCINTILLA "5.6.2"
#define VERSION_WORDS 5, 6, 2, 0
#define VERSION_SCINTILLA "5.6.4"
#define VERSION_WORDS 5, 6, 4, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -16,6 +16,7 @@
#include <stdexcept>
#include <new>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
@ -1419,7 +1420,7 @@ void ScintillaWin::SelectionToHangul() {
const std::string hangul = StringEncode(uniStr, CodePageOfDocument());
UndoGroup ug(pdoc);
ClearSelection();
InsertPaste(hangul.data(), hangul.size());
InsertPaste(hangul);
}
}
}
@ -2558,7 +2559,7 @@ sptr_t ScintillaWin::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
}
} catch (std::bad_alloc &) {
errorStatus = Status::BadAlloc;
} catch (Failure &failure) {
} catch (const Failure &failure) {
errorStatus = failure.status;
} catch (...) {
errorStatus = Status::Failure;
@ -3135,32 +3136,44 @@ bool SupportedFormat(const FORMATETC *pFE) noexcept {
}
void ScintillaWin::Paste() {
Clipboard clipboard(MainHWND());
if (!clipboard) {
return;
}
UndoGroup ug(pdoc);
const bool isLine = SelectionEmpty() &&
(::IsClipboardFormatAvailable(cfLineSelect) || ::IsClipboardFormatAvailable(cfVSLineTag));
ClearSelection(multiPasteMode == MultiPaste::Each);
bool isRectangular = (::IsClipboardFormatAvailable(cfColumnSelect) != 0);
bool isLine = false;
bool isRectangular = false;
bool hasUnicodeText = false;
std::string putf;
if (!isRectangular) {
// Evaluate "Borland IDE Block Type" explicitly
GlobalMemory memBorlandSelection(::GetClipboardData(cfBorlandIDEBlockType));
if (memBorlandSelection) {
isRectangular = (memBorlandSelection.Size() == 1) && (static_cast<BYTE *>(memBorlandSelection.ptr)[0] == 0x02);
memBorlandSelection.Unlock();
{
Clipboard clipboard(MainHWND());
if (!clipboard) {
return;
}
isLine = SelectionEmpty() &&
(::IsClipboardFormatAvailable(cfLineSelect) || ::IsClipboardFormatAvailable(cfVSLineTag));
isRectangular = (::IsClipboardFormatAvailable(cfColumnSelect) != 0);
if (!isRectangular) {
// Evaluate "Borland IDE Block Type" explicitly
GlobalMemory memBorlandSelection(::GetClipboardData(cfBorlandIDEBlockType));
if (memBorlandSelection) {
isRectangular = (memBorlandSelection.Size() == 1) && (static_cast<BYTE *>(memBorlandSelection.ptr)[0] == 0x02);
memBorlandSelection.Unlock();
}
}
// Use CF_UNICODETEXT if available
GlobalMemory memUSelection(::GetClipboardData(CF_UNICODETEXT));
if (const wchar_t *uptr = static_cast<const wchar_t *>(memUSelection.ptr)) {
hasUnicodeText = true;
putf = EncodeWString(uptr);
memUSelection.Unlock();
}
}
const PasteShape pasteShape = isRectangular ? PasteShape::rectangular : (isLine ? PasteShape::line : PasteShape::stream);
// Use CF_UNICODETEXT if available
GlobalMemory memUSelection(::GetClipboardData(CF_UNICODETEXT));
if (const wchar_t *uptr = static_cast<const wchar_t *>(memUSelection.ptr)) {
const std::string putf = EncodeWString(uptr);
InsertPasteShape(putf.c_str(), putf.length(), pasteShape);
memUSelection.Unlock();
if (hasUnicodeText) {
UndoGroup ug(pdoc);
const PasteShape pasteShape = isRectangular ? PasteShape::rectangular : (isLine ? PasteShape::line : PasteShape::stream);
ClearSelection(multiPasteMode == MultiPaste::Each);
InsertPasteShape(putf, pasteShape);
}
Redraw();
}
@ -3583,7 +3596,7 @@ void ScintillaWin::GetMouseParameters() noexcept {
}
void ScintillaWin::CopyToGlobal(GlobalMemory &gmUnicode, const SelectionText &selectedText) {
const std::string_view svSelected(selectedText.Data(), selectedText.LengthWithTerminator());
const std::string_view svSelected = selectedText.AsViewWithTerminator();
if (IsUnicodeMode()) {
const size_t uchars = UTF16Length(svSelected);
gmUnicode.Allocate(2 * uchars);
@ -3875,6 +3888,9 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
memUDrop.Unlock();
}
// Free data
::ReleaseStgMedium(&medium);
if (putf.empty()) {
return S_OK;
}
@ -3886,10 +3902,7 @@ STDMETHODIMP ScintillaWin::Drop(LPDATAOBJECT pIDataSource, DWORD grfKeyState,
::ScreenToClient(MainHWND(), &rpt);
const SelectionPosition movePos = SPositionFromLocation(PointFromPOINT(rpt), false, false, UserVirtualSpace());
DropAt(movePos, putf.c_str(), putf.size(), *pdwEffect == DROPEFFECT_MOVE, isRectangular);
// Free data
::ReleaseStgMedium(&medium);
DropAt(movePos, putf, *pdwEffect == DROPEFFECT_MOVE, isRectangular);
return S_OK;
} catch (...) {

View File

@ -15,6 +15,9 @@
#include <cmath>
#include <climits>
#include <stdexcept>
#include <utility>
#include <string>
#include <string_view>
#include <vector>
#include <map>

View File

@ -15,6 +15,7 @@
#include <cmath>
#include <climits>
#include <stdexcept>
#include <string_view>
#include <vector>
#include <map>