Update to scintilla 5.3.1 and lexilla 5.2.0

Close #12327
This commit is contained in:
Christian Grasser 2022-10-12 20:45:40 +02:00 committed by Don Ho
parent 22489a1311
commit b502266e8d
78 changed files with 1152 additions and 290 deletions

View File

@ -43,6 +43,7 @@
**.pl text
**.p6 text
**.ps1 text
**.r text
**.rb text
**.rs text
**.sql text

View File

@ -17,10 +17,12 @@ noExplicitConstructor
// code legibility.
passedByValue
// This could be fixed but it should be rewritten to use string_view which doesn't have resize
uselessCallsSubstr:lexilla/lexers/LexCPP.cxx
// Suppress most lexer warnings since the lexers are maintained by others
redundantCondition:lexilla/lexers/LexA68k.cxx
constParameter:lexilla/lexers/LexAbaqus.cxx
unusedStructMember:lexilla/lexers/LexAsciidoc.cxx
constParameterCallback:lexilla/lexers/LexAsn1.cxx
knownConditionTrueFalse:lexilla/lexers/LexAU3.cxx
shadowVariable:lexilla/lexers/LexAU3.cxx
@ -43,6 +45,7 @@ knownConditionTrueFalse:lexilla/lexers/LexEiffel.cxx
variableScope:lexilla/lexers/LexErlang.cxx
knownConditionTrueFalse:lexilla/lexers/LexEScript.cxx
constParameter:lexilla/lexers/LexFortran.cxx
redundantContinue:lexilla/lexers/LexFortran.cxx
redundantCondition:lexilla/lexers/LexFSharp.cxx
knownConditionTrueFalse:lexilla/lexers/LexFSharp.cxx
constParameter:lexilla/lexers/LexGDScript.cxx
@ -102,12 +105,16 @@ knownConditionTrueFalse:lexilla/lexers/LexTxt2tags.cxx
knownConditionTrueFalse:lexilla/lexers/LexVB.cxx
constParameter:lexilla/lexers/LexVerilog.cxx
variableScope:lexilla/lexers/LexVerilog.cxx
badBitmaskCheck:lexilla/lexers/LexVerilog.cxx
uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx
constParameter:lexilla/lexers/LexVHDL.cxx
shadowVariable:lexilla/lexers/LexVHDL.cxx
unreadVariable:lexilla/lexers/LexVHDL.cxx
variableScope:lexilla/lexers/LexVHDL.cxx
unreadVariable:lexilla/lexers/LexVisualProlog.cxx
unreadVariable:lexilla/lexers/LexX12.cxx
constVariable:lexilla/lexers/LexX12.cxx
uselessCallsSubstr:lexilla/lexers/LexX12.cxx
constParameter:lexilla/lexers/LexYAML.cxx
knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx
@ -136,7 +143,6 @@ constVariable:lexilla/lexers/LexModula.cxx
constVariable:lexilla/lexers/LexOpal.cxx
constVariable:lexilla/lexers/LexPS.cxx
constVariable:lexilla/lexers/LexPascal.cxx
constVariable:lexilla/lexers/LexR.cxx
constVariable:lexilla/lexers/LexRebol.cxx
constVariable:lexilla/lexers/LexRuby.cxx
constVariable:lexilla/lexers/LexSorcus.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="20220827" />
<meta name="Date.Modified" content="20221012" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -61,8 +61,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.1.9<br />
Site last modified August 27 2022</font>
<font color="#FFCC99" size="3">Release version 5.2.0<br />
Site last modified October 12 2022</font>
</td>
<td width="20%">
&nbsp;
@ -77,12 +77,12 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.2.0 improves PowerShell and R.</li>
<li>Version 5.1.9 improves Julia and Properties.</li>
<li>Version 5.1.8 improves F#, MS SQL, PowerShell, and Visual Prolog.</li>
<li>Version 5.1.7 improves CMake, HTML, Matlab, Raku, Ruby, and VHDL.</li>
<li>Version 5.1.6 improves Markdown and Ruby.</li>
<li>Version 5.1.5 improves Bash, Batch, F#, HTML, Inno Setup, and Python.</li>
<li>Version 5.1.4 adds lexers for AsciiDoc and GDScript.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

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/lexilla519.zip">
<font size="4"> <a href="https://www.scintilla.org/lexilla520.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/lexilla519.tgz">
<a href="https://www.scintilla.org/lexilla520.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.1.9
Release 5.2.0
</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/lexilla519.zip">zip format</a> (1.1M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla519.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/lexilla520.zip">zip format</a> (1.2M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla520.tgz">tgz format</a> (0.9M) 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

@ -585,6 +585,43 @@
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla520.zip">Release 5.2.0</a>
</h3>
<ul>
<li>
Released 12 October 2022.
</li>
<li>
PowerShell: End comment before \r carriage return so \r and \n in same
SCE_POWERSHELL_DEFAULT style.
<a href="https://github.com/ScintillaOrg/lexilla/pull/99">Pull request #99</a>.
</li>
<li>
PowerShell: Fix character truncation bug that lead to 'ġ' styled as an operator since its low 8 bits
are equal to '!'.
</li>
<li>
R: Support hexadecimal, float exponent and number suffix.
<a href="https://github.com/ScintillaOrg/lexilla/issues/101">Issue #101</a>.
</li>
<li>
R: Highlight backticks.
<a href="https://github.com/ScintillaOrg/lexilla/pull/102">Pull request #102</a>.
</li>
<li>
R: Highlight raw strings.
<a href="https://github.com/ScintillaOrg/lexilla/issues/100">Issue #100</a>.
</li>
<li>
R: Optionally highlight escape sequences in strings.
<a href="https://github.com/ScintillaOrg/lexilla/issues/100">Issue #100</a>.
</li>
<li>
Fix early truncation from LexAccessor::GetRange and LexAccessor::GetRangeLowered.
<a href="https://github.com/ScintillaOrg/lexilla/issues/17">Issue #17</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla519.zip">Release 5.1.9</a>
</h3>

View File

@ -1569,6 +1569,10 @@ val SCE_R_OPERATOR=8
val SCE_R_IDENTIFIER=9
val SCE_R_INFIX=10
val SCE_R_INFIXEOL=11
val SCE_R_BACKTICKS=12
val SCE_R_RAWSTRING=13
val SCE_R_RAWSTRING2=14
val SCE_R_ESCAPESEQUENCE=15
# Lexical state for SCLEX_MAGIK
lex MagikSF=SCLEX_MAGIK SCE_MAGIK_
val SCE_MAGIK_DEFAULT=0

View File

@ -1522,6 +1522,10 @@
#define SCE_R_IDENTIFIER 9
#define SCE_R_INFIX 10
#define SCE_R_INFIXEOL 11
#define SCE_R_BACKTICKS 12
#define SCE_R_RAWSTRING 13
#define SCE_R_RAWSTRING2 14
#define SCE_R_ESCAPESEQUENCE 15
#define SCE_MAGIK_DEFAULT 0
#define SCE_MAGIK_COMMENT 1
#define SCE_MAGIK_HYPER_COMMENT 16

View File

@ -169,7 +169,7 @@ class EscapeSequence {
int digitsLeft = 0;
public:
EscapeSequence() = default;
void resetEscapeState(int nextChar) {
void resetEscapeState(int nextChar) noexcept {
digitsLeft = 0;
escapeSetValid = &setNoneNumeric;
if (nextChar == 'U') {
@ -186,7 +186,7 @@ public:
escapeSetValid = &setOctDigits;
}
}
bool atEscapeEnd(int currChar) const {
bool atEscapeEnd(int currChar) const noexcept {
return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar);
}
void consumeDigit() noexcept {
@ -314,9 +314,8 @@ public:
LinePPState ForLine(Sci_Position line) const noexcept {
if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
return vlls[line];
} else {
return LinePPState();
}
return {};
}
void Add(Sci_Position line, LinePPState lls) {
vlls.resize(line+1);
@ -728,6 +727,8 @@ Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
case 5:
wordListN = &markerList;
break;
default:
break;
}
Sci_Position firstModification = -1;
if (wordListN) {
@ -1427,7 +1428,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
if (options.updatePreprocessor && preproc.IsActive()) {
const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false);
Tokens tokens = Tokenize(restOfLine);
if (tokens.size() >= 1) {
if (!tokens.empty()) {
const std::string key = tokens[0];
preprocessorDefinitions.erase(key);
ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true));
@ -1813,7 +1814,7 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const SymbolTable &pr
// "0" or "" -> false else true
const bool isFalse = tokens.empty() ||
((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0"));
((tokens.size() == 1) && (tokens[0].empty() || tokens[0] == "0"));
return !isFalse;
}

View File

@ -29,19 +29,19 @@
using namespace Lexilla;
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
static inline bool IsAWordChar(int ch) noexcept {
return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
}
static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
WordList &keywords5 = *keywordlists[4];
WordList &keywords6 = *keywordlists[5];
const WordList &keywords = *keywordlists[0];
const WordList &keywords2 = *keywordlists[1];
const WordList &keywords3 = *keywordlists[2];
const WordList &keywords4 = *keywordlists[3];
const WordList &keywords5 = *keywordlists[4];
const WordList &keywords6 = *keywordlists[5];
styler.StartAt(startPos);
@ -50,7 +50,7 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
for (; sc.More(); sc.Forward()) {
if (sc.state == SCE_POWERSHELL_COMMENT) {
if (sc.atLineEnd) {
if (sc.MatchLineEnd()) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
@ -107,7 +107,7 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_OPERATOR) {
if (!isoperator(static_cast<char>(sc.ch))) {
if (!isoperator(sc.ch)) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
} else if (sc.state == SCE_POWERSHELL_IDENTIFIER) {
@ -148,7 +148,7 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
sc.SetState(SCE_POWERSHELL_VARIABLE);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_POWERSHELL_NUMBER);
} else if (isoperator(static_cast<char>(sc.ch))) {
} else if (isoperator(sc.ch)) {
sc.SetState(SCE_POWERSHELL_OPERATOR);
} else if (IsAWordChar(sc.ch)) {
sc.SetState(SCE_POWERSHELL_IDENTIFIER);
@ -165,10 +165,10 @@ static void ColourisePowerShellDoc(Sci_PositionU startPos, Sci_Position length,
// and to make it possible to fiddle the current level for "} else {".
static void FoldPowerShellDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
Sci_PositionU endPos = startPos + length;
const bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
const bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
const Sci_PositionU endPos = startPos + length;
int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
@ -180,12 +180,12 @@ static void FoldPowerShellDoc(Sci_PositionU startPos, Sci_Position length, int i
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext;
const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
const int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_POWERSHELL_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow

View File

@ -6,12 +6,8 @@
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <cassert>
#include <cctype>
#include <string>
#include <string_view>
@ -29,17 +25,17 @@
using namespace Lexilla;
static inline bool IsAWordChar(const int ch) {
namespace {
inline bool IsAWordChar(int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
static inline bool IsAWordStart(const int ch) {
inline bool IsAWordStart(int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
static inline bool IsAnOperator(const int ch) {
if (IsASCII(ch) && isalnum(ch))
return false;
constexpr bool IsAnOperator(int ch) noexcept {
// '.' left out as it is used to make up numbers
if (ch == '-' || ch == '+' || ch == '!' || ch == '~' ||
ch == '?' || ch == ':' || ch == '*' || ch == '/' ||
@ -51,36 +47,103 @@ static inline bool IsAnOperator(const int ch) {
return false;
}
static void ColouriseRDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
constexpr bool IsOctalOrHex(int ch, bool hex) noexcept {
return IsAnOctalDigit(ch) || (hex && IsAHeXDigit(ch));
}
// https://search.r-project.org/R/refmans/base/html/Quotes.html
struct EscapeSequence {
int outerState = SCE_R_DEFAULT;
int digitsLeft = 0;
bool hex = false;
bool brace = false;
// highlight any character as escape sequence, unrecognized escape sequence is syntax error.
void resetEscapeState(int state, int chNext) noexcept {
outerState = state;
digitsLeft = 1;
hex = true;
brace = false;
if (chNext == 'x') {
digitsLeft = 3;
} else if (chNext == 'u') {
digitsLeft = 5;
} else if (chNext == 'U') {
digitsLeft = 9;
} else if (IsAnOctalDigit(chNext)) {
digitsLeft = 3;
hex = false;
}
}
bool atEscapeEnd(int ch) noexcept {
--digitsLeft;
return digitsLeft <= 0 || !IsOctalOrHex(ch, hex);
}
};
int CheckRawString(LexAccessor &styler, Sci_Position pos, int &dashCount) {
dashCount = 0;
while (true) {
const char ch = styler.SafeGetCharAt(pos++);
switch (ch) {
case '-':
++dashCount;
break;
case '(':
return ')';
case '[':
return ']';
case '{':
return '}';
default:
dashCount = 0;
return 0;
}
}
}
void ColouriseRDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
Accessor &styler) {
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
// Do not leak onto next line
if (initStyle == SCE_R_INFIXEOL)
initStyle = SCE_R_DEFAULT;
const WordList &keywords = *keywordlists[0];
const WordList &keywords2 = *keywordlists[1];
const WordList &keywords3 = *keywordlists[2];
// state for raw string
int matchingDelimiter = 0;
int dashCount = 0;
// property lexer.r.escape.sequence
// Set to 1 to enable highlighting of escape sequences in strings.
const bool escapeSequence = styler.GetPropertyInt("lexer.r.escape.sequence", 0) != 0;
EscapeSequence escapeSeq;
StyleContext sc(startPos, length, initStyle, styler);
if (sc.currentLine > 0) {
const int lineState = styler.GetLineState(sc.currentLine - 1);
matchingDelimiter = lineState & 0xff;
dashCount = lineState >> 8;
}
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart && (sc.state == SCE_R_STRING)) {
// Prevent SCE_R_STRINGEOL from leaking back to previous line
sc.SetState(SCE_R_STRING);
}
// Determine if the current state should terminate.
if (sc.state == SCE_R_OPERATOR) {
switch (sc.state) {
case SCE_R_OPERATOR:
sc.SetState(SCE_R_DEFAULT);
} else if (sc.state == SCE_R_NUMBER) {
if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
break;
case SCE_R_NUMBER:
// https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants
if (AnyOf(sc.ch, 'e', 'E', 'p', 'P') && (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
sc.Forward(); // exponent part
} else if (!(IsAHeXDigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))) {
if (AnyOf(sc.ch, 'L', 'i')) {
sc.Forward(); // integer and complex qualifier
}
sc.SetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_IDENTIFIER) {
break;
case SCE_R_IDENTIFIER:
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrent(s, sizeof(s));
@ -93,53 +156,122 @@ static void ColouriseRDoc(Sci_PositionU startPos, Sci_Position length, int initS
}
sc.SetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_COMMENT) {
if (sc.ch == '\r' || sc.ch == '\n') {
break;
case SCE_R_COMMENT:
if (sc.MatchLineEnd()) {
sc.SetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_STRING) {
break;
case SCE_R_STRING:
case SCE_R_STRING2:
case SCE_R_BACKTICKS:
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
if (escapeSequence) {
escapeSeq.resetEscapeState(sc.state, sc.chNext);
sc.SetState(SCE_R_ESCAPESEQUENCE);
sc.Forward();
if (sc.chNext == '{' && AnyOf(sc.ch, 'u', 'U')) {
escapeSeq.brace = true;
sc.Forward();
} else if (sc.MatchLineEnd()) {
// don't highlight line ending as escape sequence:
// escapeSeq.outerState is lost when editing on next line.
sc.SetState(escapeSeq.outerState);
}
} else {
sc.Forward(); // Skip all characters after the backslash
}
} else if (sc.ch == '\"') {
} else if ((sc.state == SCE_R_STRING && sc.ch == '\"')
|| (sc.state == SCE_R_STRING2 && sc.ch == '\'')
|| (sc.state == SCE_R_BACKTICKS && sc.ch == '`')) {
sc.ForwardSetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_INFIX) {
break;
case SCE_R_ESCAPESEQUENCE:
if (escapeSeq.atEscapeEnd(sc.ch)) {
if (escapeSeq.brace && sc.ch == '}') {
sc.Forward();
}
sc.SetState(escapeSeq.outerState);
continue;
}
break;
case SCE_R_RAWSTRING:
case SCE_R_RAWSTRING2:
while (sc.ch == matchingDelimiter) {
sc.Forward();
int count = dashCount;
while (count != 0 && sc.ch == '-') {
--count;
sc.Forward();
}
if (count == 0 && sc.ch == ((sc.state == SCE_R_RAWSTRING) ? '\"' : '\'')) {
matchingDelimiter = 0;
dashCount = 0;
sc.ForwardSetState(SCE_R_DEFAULT);
break;
}
}
break;
case SCE_R_INFIX:
if (sc.ch == '%') {
sc.ForwardSetState(SCE_R_DEFAULT);
} else if (sc.atLineEnd) {
sc.ChangeState(SCE_R_INFIXEOL);
sc.ForwardSetState(SCE_R_DEFAULT);
}
}else if (sc.state == SCE_R_STRING2) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_R_DEFAULT);
break;
case SCE_R_INFIXEOL:
if (sc.atLineStart) {
sc.SetState(SCE_R_DEFAULT);
}
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_R_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_R_NUMBER);
if (sc.ch == '0' && AnyOf(sc.chNext, 'x', 'X')) {
sc.Forward();
}
} else if (AnyOf(sc.ch, 'r', 'R') && AnyOf(sc.chNext, '\"', '\'')) {
const int chNext = sc.chNext;
matchingDelimiter = CheckRawString(styler, sc.currentPos + 2, dashCount);
if (matchingDelimiter) {
sc.SetState((chNext == '\"') ? SCE_R_RAWSTRING : SCE_R_RAWSTRING2);
sc.Forward(dashCount + 2);
} else {
// syntax error
sc.SetState(SCE_R_IDENTIFIER);
sc.ForwardSetState((chNext == '\"') ? SCE_R_STRING : SCE_R_STRING2);
}
} else if (IsAWordStart(sc.ch) ) {
sc.SetState(SCE_R_IDENTIFIER);
} else if (sc.Match('#')) {
sc.SetState(SCE_R_COMMENT);
sc.SetState(SCE_R_COMMENT);
} else if (sc.ch == '\"') {
sc.SetState(SCE_R_STRING);
} else if (sc.ch == '%') {
sc.SetState(SCE_R_INFIX);
} else if (sc.ch == '\'') {
sc.SetState(SCE_R_STRING2);
} else if (sc.ch == '`') {
sc.SetState(SCE_R_BACKTICKS);
} else if (IsAnOperator(sc.ch)) {
sc.SetState(SCE_R_OPERATOR);
}
}
if (sc.atLineEnd) {
const int lineState = matchingDelimiter | (dashCount << 8);
styler.SetLineState(sc.currentLine, lineState);
}
}
sc.Complete();
}
@ -147,11 +279,11 @@ static void ColouriseRDoc(Sci_PositionU startPos, Sci_Position length, int initS
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldRDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
void FoldRDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
Sci_PositionU endPos = startPos + length;
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
const bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
const Sci_PositionU endPos = startPos + length;
int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
@ -162,11 +294,11 @@ static void FoldRDoc(Sci_PositionU startPos, Sci_Position length, int, WordList
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext;
const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
const int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_R_OPERATOR) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
@ -203,15 +335,15 @@ static void FoldRDoc(Sci_PositionU startPos, Sci_Position length, int, WordList
}
static const char * const RWordLists[] = {
"Language Keywords",
"Base / Default package function",
"Other Package Functions",
"Unused",
"Unused",
0,
};
const char * const RWordLists[] = {
"Language Keywords",
"Base / Default package function",
"Other Package Functions",
"Unused",
"Unused",
nullptr,
};
}
LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists);

View File

@ -93,6 +93,16 @@ constexpr bool IsADigit(int ch) noexcept {
return (ch >= '0') && (ch <= '9');
}
constexpr bool IsAHeXDigit(int ch) noexcept {
return (ch >= '0' && ch <= '9')
|| (ch >= 'A' && ch <= 'F')
|| (ch >= 'a' && ch <= 'f');
}
constexpr bool IsAnOctalDigit(int ch) noexcept {
return ch >= '0' && ch <= '7';
}
constexpr bool IsADigit(int ch, int base) noexcept {
if (base <= 10) {
return (ch >= '0') && (ch < '0' + base);

View File

@ -58,7 +58,7 @@ std::string LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_
assert(startPos_ < endPos_);
const Sci_PositionU len = endPos_ - startPos_;
std::string s(len, '\0');
GetRange(startPos_, endPos_, s.data(), len);
GetRange(startPos_, endPos_, s.data(), len + 1);
return s;
}
@ -66,7 +66,7 @@ std::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU
assert(startPos_ < endPos_);
const Sci_PositionU len = endPos_ - startPos_;
std::string s(len, '\0');
GetRangeLowered(startPos_, endPos_, s.data(), len);
GetRangeLowered(startPos_, endPos_, s.data(), len + 1);
return s;
}

View File

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

View File

@ -851,7 +851,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.1.9;
CURRENT_PROJECT_VERSION = 5.2.0;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
@ -877,7 +877,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.1.9;
CURRENT_PROJECT_VERSION = 5.2.0;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;

View File

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

View File

@ -0,0 +1,62 @@
# Enumerate all styles: 0 to 16
# line comment = 1
# more comment
# whitespace = 0
# spaces
# string = 2
"a string"
# character = 3
'c'
# number = 4
123
# variable = 5
$variable
# operator = 6
();
# identifier = 7
identifier
# keyword = 8
break
;
# cmdlet = 9
Write-Output "test output"
# alias = 10
chdir C:\Temp\
# function = 11
Get-Verb -Group Security
# user-defined keyword = 12
lexilla
# multi-line comment = 13
<#
multi-line comment
#>
# here string = 14
@"
here string double
"@
# here string single quote = 15
@'
here string single
'@
# comment keyword = 16
<#
.synopsis
End of file.
#>

View File

@ -0,0 +1,63 @@
0 400 400 # Enumerate all styles: 0 to 16
1 400 400
0 400 400 # line comment = 1
0 400 400 # more comment
1 400 400
0 400 400 # whitespace = 0
0 400 400 # spaces
1 400 400
0 400 400 # string = 2
0 400 400 "a string"
1 400 400
0 400 400 # character = 3
0 400 400 'c'
1 400 400
0 400 400 # number = 4
0 400 400 123
1 400 400
0 400 400 # variable = 5
0 400 400 $variable
1 400 400
0 400 400 # operator = 6
0 400 400 ();
1 400 400
0 400 400 # identifier = 7
0 400 400 identifier
1 400 400
0 400 400 # keyword = 8
0 400 400 break
0 400 400 ;
1 400 400
0 400 400 # cmdlet = 9
0 400 400 Write-Output "test output"
1 400 400
0 400 400 # alias = 10
0 400 400 chdir C:\Temp\
1 400 400
0 400 400 # function = 11
0 400 400 Get-Verb -Group Security
1 400 400
0 400 400 # user-defined keyword = 12
0 400 400 lexilla
1 400 400
0 400 400 # multi-line comment = 13
0 400 400 <#
0 400 400 multi-line comment
0 400 400 #>
1 400 400
0 400 400 # here string = 14
0 400 400 @"
0 400 400 here string double
0 400 400 "@
1 400 400
0 400 400 # here string single quote = 15
0 400 400 @'
0 400 400 here string single
0 400 400 '@
1 400 400
0 400 400 # comment keyword = 16
0 400 400 <#
0 400 400 .synopsis
0 400 400 End of file.
0 400 400 #>
0 400 0

View File

@ -0,0 +1,62 @@
{1}# Enumerate all styles: 0 to 16{0}
{1}# line comment = 1{0}
{1}# more comment{0}
{1}# whitespace = 0{0}
{1}# spaces{0}
{1}# string = 2{0}
{2}"a string"{0}
{1}# character = 3{0}
{3}'c'{0}
{1}# number = 4{0}
{4}123{0}
{1}# variable = 5{0}
{5}$variable{0}
{1}# operator = 6{0}
{6}();{0}
{1}# identifier = 7{0}
{7}identifier{0}
{1}# keyword = 8{0}
{8}break{0}
{6};{0}
{1}# cmdlet = 9{0}
{9}Write-Output{0} {2}"test output"{0}
{1}# alias = 10{0}
{10}chdir{0} {7}C{6}:{0}\{7}Temp{0}\
{1}# function = 11{0}
{11}Get-Verb{0} {6}-{7}Group{0} {7}Security{0}
{1}# user-defined keyword = 12{0}
{12}lexilla{0}
{1}# multi-line comment = 13{0}
{13}<#
multi-line comment
#>{0}
{1}# here string = 14{0}
{14}@"
here string double
"@{0}
{1}# here string single quote = 15{0}
{15}@'
here string single
'@{0}
{1}# comment keyword = 16{0}
{13}<#
{16}.synopsis{13}
End of file.
#>{0}

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE)
# to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator
# Isolate
ġ
# Continuing from operator
(ġ)

View File

@ -0,0 +1,10 @@
0 400 400 # -*- coding: utf-8 -*-
0 400 400 # Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE)
0 400 400 # to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator
1 400 400
0 400 400 # Isolate
0 400 400 ġ
1 400 400
0 400 400 # Continuing from operator
0 400 400 (ġ)
0 400 0

View File

@ -0,0 +1,9 @@
{1}# -*- coding: utf-8 -*-{0}
{1}# Show problem with character value truncation causing U+0121 'ġ' (LATIN SMALL LETTER G WITH DOT ABOVE){0}
{1}# to be styled as an operator as static_cast<char>(0x121) = 0x21 == '!' which is an operator{0}
{1}# Isolate{0}
{7}ġ{0}
{1}# Continuing from operator{0}
{6}({7}ġ{6}){0}

View File

@ -0,0 +1 @@
# End comment before \r carriage return.

View File

@ -0,0 +1,2 @@
0 400 400 # End comment before \r carriage return.
0 400 0

View File

@ -0,0 +1 @@
{1}# End comment before \r carriage return.{0}

View File

@ -1,7 +1,9 @@
lexer.*.ps1=powershell
fold=1
keywords.*.ps1=if else in local
keywords.*.ps1=break if else in local
keywords2.*.ps1=write-host write-output
keywords3.*.ps1=cd chdir cat
keywords4.*.ps1=mkdir prompt
keywords4.*.ps1=mkdir prompt get-verb
keywords5.*.ps1=lexilla
keywords6.*.ps1=synopsis

View File

@ -0,0 +1,10 @@
# ugly code to demonstrate multiline string.
`Hello
World` <- function(x, y, z) {
print(x);
print(y);
print(z);
}
`Hello\nWorld`("Hello\nMoon!", "Hello
Venus", 'Hello\
Mars');

View File

@ -0,0 +1,11 @@
0 400 400 # ugly code to demonstrate multiline string.
0 400 400 `Hello
2 400 401 + World` <- function(x, y, z) {
0 401 401 | print(x);
0 401 401 | print(y);
0 401 401 | print(z);
0 401 400 | }
0 400 400 `Hello\nWorld`("Hello\nMoon!", "Hello
0 400 400 Venus", 'Hello\
0 400 400 Mars');
0 400 0

View File

@ -0,0 +1,10 @@
{1}# ugly code to demonstrate multiline string.{0}
{12}`Hello
World`{0} {8}<-{0} {9}function{8}({9}x{0}, {9}y{0}, {9}z{8}){0} {8}{{0}
{9}print{8}({9}x{8}){0};
{9}print{8}({9}y{8}){0};
{9}print{8}({9}z{8}){0};
{8}}{0}
{12}`Hello\nWorld`{8}({6}"Hello\nMoon!"{0}, {6}"Hello
Venus"{0}, {7}'Hello\
Mars'{8}){0};

View File

@ -0,0 +1,48 @@
# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words
if
# base keyword (3)
abbreviate
# other keyword (4)
acme
# infix operator
# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators
%x%
# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants
# Valid integer constants
1L, 0x10L, 1000000L, 1e6L
# Valid numeric constants
1 10 0.1 .2 1e-7 1.2e+7
1.1L, 1e-3L, 0x1.1p-2
# Valid complex constants
2i 4.1i 1e-2i
# https://search.r-project.org/R/refmans/base/html/Quotes.html
# single quotes
'"It\'s alive!", he screamed.'
# double quotes
"\"It's alive!\", he screamed."
# escape sequence
"\n0\r1\t2\b3\a4\f5\\6\'7\"8\`9"
"\1230\x121\u12342\U000123453\u{1234}4\U{00012345}5\
6\ 7"
# Backticks
d$`1st column`
# double quoted raw string
r"---(\1--)-)---"
# single quoted raw string
R'---(\1--)-)---'
# infix EOL (11)
%a
#back to comment

View File

@ -0,0 +1,49 @@
0 400 400 # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words
0 400 400 if
1 400 400
0 400 400 # base keyword (3)
0 400 400 abbreviate
1 400 400
0 400 400 # other keyword (4)
0 400 400 acme
1 400 400
0 400 400 # infix operator
0 400 400 # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators
0 400 400 %x%
1 400 400
0 400 400 # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants
0 400 400 # Valid integer constants
0 400 400 1L, 0x10L, 1000000L, 1e6L
1 400 400
0 400 400 # Valid numeric constants
0 400 400 1 10 0.1 .2 1e-7 1.2e+7
0 400 400 1.1L, 1e-3L, 0x1.1p-2
1 400 400
0 400 400 # Valid complex constants
0 400 400 2i 4.1i 1e-2i
1 400 400
0 400 400 # https://search.r-project.org/R/refmans/base/html/Quotes.html
0 400 400 # single quotes
0 400 400 '"It\'s alive!", he screamed.'
1 400 400
0 400 400 # double quotes
0 400 400 "\"It's alive!\", he screamed."
1 400 400
0 400 400 # escape sequence
0 400 400 "\n0\r1\t2\b3\a4\f5\\6\'7\"8\`9"
0 400 400 "\1230\x121\u12342\U000123453\u{1234}4\U{00012345}5\
0 400 400 6\ 7"
1 400 400
0 400 400 # Backticks
0 400 400 d$`1st column`
1 400 400
0 400 400 # double quoted raw string
0 400 400 r"---(\1--)-)---"
1 400 400
0 400 400 # single quoted raw string
0 400 400 R'---(\1--)-)---'
1 400 400
0 400 400 # infix EOL (11)
0 400 400 %a
0 400 400 #back to comment
0 400 0

View File

@ -0,0 +1,48 @@
{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Reserved-words{0}
{2}if{0}
{1}# base keyword (3){0}
{3}abbreviate{0}
{1}# other keyword (4){0}
{4}acme{0}
{1}# infix operator{0}
{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Special-operators{0}
{10}%x%{0}
{1}# https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Literal-constants{0}
{1}# Valid integer constants{0}
{5}1L{0}, {5}0x10L{0}, {5}1000000L{0}, {5}1e6L{0}
{1}# Valid numeric constants{0}
{5}1{0} {5}10{0} {5}0.1{0} {5}.2{0} {5}1e-7{0} {5}1.2e+7{0}
{5}1.1L{0}, {5}1e-3L{0}, {5}0x1.1p-2{0}
{1}# Valid complex constants{0}
{5}2i{0} {5}4.1i{0} {5}1e-2i{0}
{1}# https://search.r-project.org/R/refmans/base/html/Quotes.html{0}
{1}# single quotes{0}
{7}'"It{15}\'{7}s alive!", he screamed.'{0}
{1}# double quotes{0}
{6}"{15}\"{6}It's alive!{15}\"{6}, he screamed."{0}
{1}# escape sequence{0}
{6}"{15}\n{6}0{15}\r{6}1{15}\t{6}2{15}\b{6}3{15}\a{6}4{15}\f{6}5{15}\\{6}6{15}\'{6}7{15}\"{6}8{15}\`{6}9"{0}
{6}"{15}\123{6}0{15}\x12{6}1{15}\u1234{6}2{15}\U00012345{6}3{15}\u{1234}{6}4{15}\U{00012345}{6}5{15}\{6}
6{15}\ {6}7"{0}
{1}# Backticks{0}
{9}d{8}${12}`1st column`{0}
{1}# double quoted raw string{0}
{13}r"---(\1--)-)---"{0}
{1}# single quoted raw string{0}
{14}R'---(\1--)-)---'{0}
{1}# infix EOL (11){0}
{11}%a
{1}#back to comment{0}

View File

@ -0,0 +1,9 @@
lexer.*.r=r
keywords.*.r=if
keywords2.*.r=abbreviate
keywords3.*.r=acme
fold=1
fold.compact=1
match AllStyles.r
lexer.r.escape.sequence=1

View File

@ -1 +1 @@
519
520

4
scintilla/.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[**]
indent_style = tab

View File

@ -647,6 +647,18 @@ bool ScintillaCall::StyleGetCheckMonospaced(int style) {
return Call(Message::StyleGetCheckMonospaced, style);
}
void ScintillaCall::StyleSetInvisibleRepresentation(int style, const char *representation) {
CallString(Message::StyleSetInvisibleRepresentation, style, representation);
}
int ScintillaCall::StyleGetInvisibleRepresentation(int style, char *representation) {
return static_cast<int>(CallPointer(Message::StyleGetInvisibleRepresentation, style, representation));
}
std::string ScintillaCall::StyleGetInvisibleRepresentation(int style) {
return CallReturnString(Message::StyleGetInvisibleRepresentation, style);
}
void ScintillaCall::SetElementColour(Scintilla::Element element, ColourAlpha colourElement) {
Call(Message::SetElementColour, static_cast<uintptr_t>(element), colourElement);
}

View File

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

View File

@ -573,7 +573,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.0;
CURRENT_PROJECT_VERSION = 5.3.1;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@ -635,7 +635,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.0;
CURRENT_PROJECT_VERSION = 5.3.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -665,7 +665,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.0;
CURRENT_PROJECT_VERSION = 5.3.1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
@ -699,7 +699,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.0;
CURRENT_PROJECT_VERSION = 5.3.1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -129,7 +129,7 @@
<h1>Scintilla Documentation</h1>
<p>Last edited 26 August 2022 NH</p>
<p>Last edited 1 October 2022 NH</p>
<p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new
<a href="Lexilla.html">Lexilla</a> project.<br />
@ -1338,11 +1338,17 @@ struct Sci_TextToFindFull {
<p>Scintilla can display document changes (modified, saved, ...) in the margin or in the text.</p>
<p>The main states are original text that has not been modified, modified, and modified then saved.
As it is possible to undo to before the save point, there are additional states for reverted from save and
reverted back to original from save.
The reverted states are different to the saved document on disk so some applications may want to
display these states just like the main modified state.</p>
<p><img src="ChangeHistory.png" alt="Change history markers and indicators." /></p>
<p>The image shows the default visuals which can be altered by the application.
In the text, inserted characters appear with coloured underlines and points where characters were deleted are shown with small triangles.
The margin shows a block indicating the overall state of the line, prioritising the more consequential modified states.
The margin shows a block indicating the overall state of the line, prioritizing the more consequential modified states.
The states are
modified (<span style="color:#FF8000">orange</span>),
saved (<span style="color:#00A000">green</span>),
@ -1353,6 +1359,9 @@ struct Sci_TextToFindFull {
<p>This feature uses a moderate amount of memory proportional to the amount of modifications made.
On huge documents, this could be significant so could be disabled when it would cause excessive memory use.</p>
<p>If the applications wants to display a simplified set of visuals without differentiating between modifications
that have been reverted then assign the same attributes to multiple markers and indicators.</p>
<code><a class="message" href="#SCI_SETCHANGEHISTORY">SCI_SETCHANGEHISTORY(int changeHistory)</a><br />
<a class="message" href="#SCI_GETCHANGEHISTORY">SCI_GETCHANGEHISTORY &rarr; int</a><br />
</code>
@ -1414,8 +1423,8 @@ struct Sci_TextToFindFull {
<td>21</td>
<td>A change was made to this line and saved but then reverted to its original state.
This line is different to its state on disk.</td>
<td>A change was made to this line and saved but then reverted to its original state.</td>
<td>This line is different to its state on disk.</td>
</tr>
<tr>
@ -1423,7 +1432,8 @@ struct Sci_TextToFindFull {
<td>22</td>
<td>This line was modified and saved. This line is the same as its state on disk.</td>
<td>This line was modified and saved.</td>
<td>This line is the same as its state on disk.</td>
</tr>
<tr>
@ -1431,7 +1441,8 @@ struct Sci_TextToFindFull {
<td>23</td>
<td>This line was modified but not yet saved. This line is different to its state on disk.</td>
<td>This line was modified but not yet saved.</td>
<td>This line is different to its state on disk.</td>
</tr>
<tr>
@ -1439,8 +1450,8 @@ struct Sci_TextToFindFull {
<td>24</td>
<td>A change was made to this line and saved but then reverted but not to its original state.
This line is different to its state on disk.</td>
<td>A change was made to this line and saved but then reverted but not to its original state.</td>
<td>This line is different to its state on disk.</td>
</tr>
</tbody>
</table>
@ -1452,50 +1463,54 @@ struct Sci_TextToFindFull {
<tr>
<th align="left"><code>INDICATOR_HISTORY_REVERTED_TO_ORIGIN_INSERTION</code></th>
<td>36</td>
<td>Text was deleted and saved but then reverted to its original state.
This text is not present on disk.</td>
<td>Text was deleted and saved but then reverted to its original state.</td>
<td>This text has not been saved to disk.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_REVERTED_TO_ORIGIN_DELETION</code></th>
<td>37</td>
<td>Text was inserted and saved but then reverted to its original state.
This range is different to its state on disk.</td>
<td>Text was inserted and saved but then reverted to its original state.</td>
<td>There is text on disk that is missing.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_SAVED_INSERTION</code></th>
<td>38</td>
<td>Text was inserted and saved. This text is the same as on disk.</td>
<td>Text was inserted and saved.</td>
<td>This text is the same as on disk.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_SAVED_DELETION</code></th>
<td>39</td>
<td>Text was deleted and saved. This range is the same as on disk.</td>
<td>Text was deleted and saved.</td>
<td>This range is the same as on disk.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_MODIFIED_INSERTION</code></th>
<td>40</td>
<td>Text was inserted but not yet saved. This text is not present on disk.</td>
<td>Text was inserted but not yet saved.</td>
<td>This text has not been saved to disk.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_MODIFIED_DELETION</code></th>
<td>41</td>
<td>Text was deleted but not yet saved. This range is different to its state on disk.</td>
<td>Text was deleted but not yet saved.</td>
<td>There is text on disk that is missing.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_REVERTED_TO_MODIFIED_INSERTION</code></th>
<td>42</td>
<td>Text was deleted and saved but then reverted but not to its original state.
This text is not present on disk.</td>
<td>Text was deleted and saved but then reverted but not to its original state.</td>
<td>This text has not been saved to disk.</td>
</tr>
<tr>
<th align="left"><code>INDICATOR_HISTORY_REVERTED_TO_MODIFIED_DELETION</code></th>
<td>43</td>
<td>Text was inserted and saved but then reverted but not to its original state.
This range is different to its state on disk.</td>
<td>Text was inserted and saved but then reverted but not to its original state.</td>
<td>There is text on disk that is missing.</td>
</tr>
</tbody>
</table>
@ -3233,6 +3248,8 @@ struct Sci_TextToFindFull {
<a class="message" href="#SCI_STYLESETCHECKMONOSPACED">SCI_STYLESETCHECKMONOSPACED(int style, bool
checkMonospaced)</a><br />
<a class="message" href="#SCI_STYLEGETCHECKMONOSPACED">SCI_STYLEGETCHECKMONOSPACED(int style) &rarr; bool</a><br />
<a class="message" href="#SCI_STYLESETINVISIBLEREPRESENTATION">SCI_STYLESETINVISIBLEREPRESENTATION(int style, const char *representation)</a><br />
<a class="message" href="#SCI_STYLEGETINVISIBLEREPRESENTATION">SCI_STYLEGETINVISIBLEREPRESENTATION(int style, char *representation NUL-terminated) &rarr; int</a><br />
<a class="message" href="#SCI_SETFONTLOCALE">SCI_SETFONTLOCALE(&lt;unused&gt;, const char *localeName)</a><br />
<a class="message" href="#SCI_GETFONTLOCALE">SCI_GETFONTLOCALE(&lt;unused&gt;, char *localeName) &rarr; int</a><br />
</code>
@ -3499,6 +3516,15 @@ struct Sci_TextToFindFull {
Applications may apply the 'check monospaced' attribute just to fonts known to be monospaced or on all fonts, leaving it to Scintilla to
reject fonts that are proportional.</p>
<p><b id="SCI_STYLESETINVISIBLEREPRESENTATION">SCI_STYLESETINVISIBLEREPRESENTATION(int style, const char *representation)</b><br />
<b id="SCI_STYLEGETINVISIBLEREPRESENTATION">SCI_STYLEGETINVISIBLEREPRESENTATION(int style, char *representation NUL-terminated) &rarr; int</b><br />
When a style is made invisible with <a class="seealso" href="#SCI_STYLESETVISIBLE">SCI_STYLESETVISIBLE</a>, text is difficult to edit as
the cursor can be at both sides of the invisible text segment. With these messages invisible text segements can be made visible with a single
UTF8 characater giving the user an indication if the cursor is left or right of the invisible text. The character is displayed using the current style.</p>
<p>The <code>representation</code> parameter is a zero terminated string holding the one character used to represent the invisible text segment. Only the first character
is used, the character is decoded as UTF-8.</p>
<p><b id="SCI_SETFONTLOCALE">SCI_SETFONTLOCALE(&lt;unused&gt;, const char *localeName)</b><br />
<b id="SCI_GETFONTLOCALE">SCI_GETFONTLOCALE(&lt;unused&gt;, char *localeName NUL-terminated) &rarr; int</b><br />
These messages set the locale used for font selection with language-dependent glyphs.
@ -5160,8 +5186,11 @@ struct Sci_TextToFindFull {
(<code>SC_MARK_</code>*) or you can use characters. By default, all 32 markers are set to
<code>SC_MARK_CIRCLE</code> with a black foreground and a white background.</p>
<p>The markers are drawn in the order of their numbers, so higher numbered markers appear on
top of lower numbered ones. Markers try to move with their text by tracking where the start of
<p>The markers are drawn in the order of their numbers (except for <code>SC_MARK_BAR</code>), so higher
numbered markers appear on top of lower numbered ones.
<code>SC_MARK_BAR</code> markers are drawn first so they are underneath as they often cover
multiple lines for change history and other markers mark individual lines.
Markers try to move with their text by tracking where the start of
their line moves. When a line is deleted, its markers are combined, by an <code>OR</code>
operation, with the markers of the next line.</p>
<code><a class="message" href="#SCI_MARKERDEFINE">SCI_MARKERDEFINE(int markerNumber, int

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/scintilla530.zip">
<font size="4"> <a href="https://www.scintilla.org/scintilla531.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/scintilla530.tgz">
<a href="https://www.scintilla.org/scintilla531.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.3.0
Release 5.3.1
</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/scintilla530.zip">zip format</a> (1.3M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla530.tgz">tgz format</a> (1.2M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/scintilla531.zip">zip format</a> (1.4M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/scintilla531.tgz">tgz format</a> (1.2M) 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

@ -571,9 +571,67 @@
<td>Christian Schmitz</td>
<td>Michael Berlenz</td>
<td>Jacky Yang</td>
</tr><tr>
<td>Reinhard Nißl</td>
<td>Ferdinand Oeinck</td>
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla531.zip">Release 5.3.1</a>
</h3>
<ul>
<li>
Released 12 October 2022.
</li>
<li>
Added SCI_STYLESETINVISIBLEREPRESENTATION to make it easier to edit around invisible text.
This also allows representing long lexemes with a single character to provide a summarized view.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1453/">Feature #1453</a>.
</li>
<li>
Removed NotifyLexerChanged notification from DocWatcher.
This is a private interface but could be used by independent platform layers
and was exposed by ScintillaDocument in the Qt implementation of ScintillaEdit.
</li>
<li>
Draw lines more consistently in SC_PHASES_TWO and SC_PHASES_ONE modes by
clipping drawing to just the line rectangle.
This stops drawing some extreme ascenders, descenders and portions of indicators which
may appear and then disappear depending on which lines were drawn.
</li>
<li>
Draw SC_MARK_BAR markers underneath other markers
as they often cover multiple lines for change history and other markers mark individual lines.
</li>
<li>
Enlarge point and point top indicators and scale to be larger with larger text.
</li>
<li>
Suppress change history background line shading when printing.
<a href="https://sourceforge.net/p/scintilla/bugs/2358/">Bug #2358</a>.
</li>
<li>
Make SCI_LINESCROLL more accurate when width of space not integer.
<a href="https://sourceforge.net/p/scintilla/bugs/2357/">Bug #2357</a>.
</li>
<li>
On Win32 implement horizontal scrolling mouse wheel.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1450/">Feature #1450</a>.
</li>
<li>
On Win32 implement horizontal scrolling with Shift + mouse wheel.
<a href="https://sourceforge.net/p/scintilla/feature-requests/749/">Feature #749</a>,
<a href="https://sourceforge.net/p/scintilla/feature-requests/1451/">Feature #1451</a>.
</li>
<li>
On Win32 ensure page and step clicks on horizontal scroll bar do not overshoot document width.
</li>
<li>
On GTK, fix bug where there were too many or too few lines when wrapping.
<a href="https://sourceforge.net/p/scintilla/bugs/2349/">Bug #2349</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla530.zip">Release 5.3.0</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="20220827" />
<meta name="Date.Modified" content="20221012" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#versionlist {
@ -56,8 +56,8 @@
GTK, and macOS</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 5.3.0<br />
Site last modified August 27 2022</font>
<font color="#FFCC99" size="3"> Release version 5.3.1<br />
Site last modified October 12 2022</font>
</td>
<td width="20%">
&nbsp;
@ -72,12 +72,11 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.3.1 can represent invisible text with a character to simplify editing and provide summarized views.</li>
<li>Version 5.3.0 adds change history.</li>
<li>Version 5.2.4 fixes failures on GTK with multi-threaded layout.</li>
<li>Version 5.2.3 adds 64-bit safe APIs and fixes scrollbar on GTK with Xorg.</li>
<li>Version 5.2.2 on GTK, scroll horizontally with Shift + Scroll Wheel.</li>
<li>Version 5.2.1 fixes leaks on GTK.</li>
<li>Version 5.2.0 adds multithreaded layout to significantly improve performance for very wide lines.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -1786,6 +1786,12 @@ void ScintillaGTK::Resize(int width, int height) {
}
if (IS_WIDGET_MAPPED(PWidget(wMain))) {
ChangeSize();
} else {
const PRectangle rcTextArea = GetTextRectangle();
if (wrapWidth != rcTextArea.Width()) {
wrapWidth = rcTextArea.Width();
NeedWrapping();
}
}
alloc.x = 0;

View File

@ -280,6 +280,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
#define SCI_STYLESETHOTSPOT 2409
#define SCI_STYLESETCHECKMONOSPACED 2254
#define SCI_STYLEGETCHECKMONOSPACED 2255
#define SCI_STYLESETINVISIBLEREPRESENTATION 2256
#define SCI_STYLEGETINVISIBLEREPRESENTATION 2257
#define SC_ELEMENT_LIST 0
#define SC_ELEMENT_LIST_BACK 1
#define SC_ELEMENT_LIST_SELECTED 2

View File

@ -694,6 +694,12 @@ set void StyleSetCheckMonospaced=2254(int style, bool checkMonospaced)
# Get whether a style may be monospaced.
get bool StyleGetCheckMonospaced=2255(int style,)
# Set the invisible representation for a style.
set void StyleSetInvisibleRepresentation=2256(int style, string representation)
# Get the invisible representation for a style.
get int StyleGetInvisibleRepresentation=2257(int style, stringresult representation)
enu Element=SC_ELEMENT_
val SC_ELEMENT_LIST=0
val SC_ELEMENT_LIST_BACK=1

View File

@ -200,6 +200,9 @@ public:
void StyleSetHotSpot(int style, bool hotspot);
void StyleSetCheckMonospaced(int style, bool checkMonospaced);
bool StyleGetCheckMonospaced(int style);
void StyleSetInvisibleRepresentation(int style, const char *representation);
int StyleGetInvisibleRepresentation(int style, char *representation);
std::string StyleGetInvisibleRepresentation(int style);
void SetElementColour(Scintilla::Element element, ColourAlpha colourElement);
ColourAlpha ElementColour(Scintilla::Element element);
void ResetElementColour(Scintilla::Element element);

View File

@ -136,6 +136,8 @@ enum class Message {
StyleSetHotSpot = 2409,
StyleSetCheckMonospaced = 2254,
StyleGetCheckMonospaced = 2255,
StyleSetInvisibleRepresentation = 2256,
StyleGetInvisibleRepresentation = 2257,
SetElementColour = 2753,
GetElementColour = 2754,
ResetElementColour = 2755,

View File

@ -54,7 +54,6 @@ public:
void NotifyModified(Document *doc, DocModification mh, void *userData) override;
void NotifyDeleted(Document *doc, void *userData) noexcept override;
void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endPos) override;
void NotifyLexerChanged(Document *doc, void *userData) override;
void NotifyErrorOccurred(Document *doc, void *userData, Status status) override;
};
@ -85,10 +84,6 @@ void WatcherHelper::NotifyStyleNeeded(Document *, void *, Sci::Position endPos)
emit owner->style_needed(endPos);
}
void WatcherHelper::NotifyLexerChanged(Document *, void *) {
emit owner->lexer_changed();
}
void WatcherHelper::NotifyErrorOccurred(Document *, void *, Status status) {
emit owner->error_occurred(static_cast<int>(status));
}

View File

@ -82,7 +82,6 @@ signals:
void modified(int position, int modification_type, const QByteArray &text, int length,
int linesAdded, int line, int foldLevelNow, int foldLevelPrev);
void style_needed(int pos);
void lexer_changed();
void error_occurred(int status);
friend class ::WatcherHelper;

View File

@ -13,7 +13,7 @@ TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.3.0
VERSION = 5.3.1
SOURCES += \
ScintillaEdit.cpp \

View File

@ -12,7 +12,7 @@ TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.3.0
VERSION = 5.3.1
SOURCES += \
PlatQt.cpp \

View File

@ -32,7 +32,7 @@ def UpdateFile(filename, updated):
newOrChanged = "New"
with codecs.open(filename, "w", "utf-8") as outfile:
outfile.write(updated)
print("%s %s" % (newOrChanged, filename))
print("%s:0: %s" % (filename, newOrChanged))
# Automatically generated sections contain start and end comments,
# a definition line and the results.

View File

@ -1397,7 +1397,7 @@ void CellBuffer::PerformRedoStep() {
void CellBuffer::ChangeHistorySet(bool set) {
if (set) {
if (!changeHistory) {
if (!changeHistory && !uh.CanUndo()) {
changeHistory = std::make_unique<ChangeHistory>(Length());
}
} else {

View File

@ -45,7 +45,7 @@ void ChangeStack::PushDeletion(Sci::Position positionDeletion, int edition) {
void ChangeStack::PushInsertion(Sci::Position positionInsertion, Sci::Position length, int edition) {
steps.back()++;
insertions.push_back({ positionInsertion, length, edition, InsertionSpan::Direction::insertion });
};
}
size_t ChangeStack::PopStep() noexcept {
const size_t spans = steps.back();

View File

@ -58,7 +58,6 @@ LexInterface::~LexInterface() noexcept = default;
void LexInterface::SetInstance(ILexer5 *instance_) {
instance.reset(instance_);
pdoc->LexerChanged();
}
void LexInterface::Colourise(Sci::Position start, Sci::Position end) {
@ -2432,13 +2431,6 @@ void Document::StyleToAdjustingLineDuration(Sci::Position pos) {
durationStyleOneByte.AddSample(pos - stylingStart, epStyling.Duration());
}
void Document::LexerChanged() {
// Tell the watchers the lexer has changed.
for (const WatcherWithUserData &watcher : watchers) {
watcher.watcher->NotifyLexerChanged(this, watcher.userData);
}
}
LexInterface *Document::GetLexInterface() const noexcept {
return pli.get();
}

View File

@ -484,7 +484,6 @@ public:
Sci::Position GetEndStyled() const noexcept { return endStyled; }
void EnsureStyledTo(Sci::Position pos);
void StyleToAdjustingLineDuration(Sci::Position pos);
void LexerChanged();
int GetStyleClock() const noexcept { return styleClock; }
void IncrementStyleClock() noexcept;
void SCI_METHOD DecorationSetCurrentIndicator(int indicator) override;
@ -621,7 +620,6 @@ public:
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
virtual void NotifyDeleted(Document *doc, void *userData) noexcept = 0;
virtual void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endPos) = 0;
virtual void NotifyLexerChanged(Document *doc, void *userData) = 0;
virtual void NotifyErrorOccurred(Document *doc, void *userData, Scintilla::Status status) = 0;
};

View File

@ -435,6 +435,21 @@ void LayoutSegments(IPositionCache *pCache,
std::string_view(&ll->chars[ts.start], ts.length), &ll->positions[ts.start + 1], multiThreaded);
}
}
} else if (vstyle.styles[ll->styles[ts.start]].invisibleRepresentation[0]) {
const int styleInvisible = ll->styles[ts.start];
const std::string_view text = vstyle.styles[styleInvisible].invisibleRepresentation;
XYPOSITION positionsRepr[Representation::maxLength + 1];
// invisibleRepresentation is UTF-8 which only matches cache if document is UTF-8
// or it only contains ASCII which is a subset of all currently supported encodings.
if (textUnicode || ViewIsASCII(text)) {
pCache->MeasureWidths(surface, vstyle, styleInvisible, text, positionsRepr, multiThreaded);
} else {
surface->MeasureWidthsUTF8(vstyle.styles[styleInvisible].font.get(), text, positionsRepr);
}
const XYPOSITION representationWidth = positionsRepr[text.length() - 1];
for (int ii = 0; ii < ts.length; ii++) {
ll->positions[ts.start + 1 + ii] = representationWidth;
}
}
}
}
@ -1244,7 +1259,8 @@ static void DrawIndicator(int indicNum, Sci::Position startPos, Sci::Position en
const XYPOSITION left = ll->XInLine(startPos) + horizontalOffset;
const XYPOSITION right = ll->XInLine(endPos) + horizontalOffset;
const PRectangle rcIndic(left, rcLine.top + vsDraw.maxAscent, right, rcLine.top + vsDraw.maxAscent + 3);
const PRectangle rcIndic(left, rcLine.top + vsDraw.maxAscent, right,
std::max(rcLine.top + vsDraw.maxAscent + 3, rcLine.bottom));
if (bidiEnabled) {
ScreenLine screenLine(ll, subLine, vsDraw, rcLine.right - xStart, tabWidthMinimumPixels);
@ -1638,6 +1654,11 @@ void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const Vi
surface->FillRectangle(Side(rcBorder, Edge::bottom, 1), colourBorder);
}
}
} else {
// No annotation to draw so show bug with bugColour
if (FlagSet(phase, DrawPhase::back)) {
surface->FillRectangle(rcSegment, bugColour.Opaque());
}
}
}
@ -2224,6 +2245,15 @@ void EditView::DrawForeground(Surface *surface, const EditModel &model, const Vi
surface->DrawTextNoClip(rcSegment, textFont,
rcSegment.top + vsDraw.maxAscent, text, textFore, textBack);
}
} else if (vsDraw.styles[styleMain].invisibleRepresentation[0]) {
const std::string_view text = vsDraw.styles[styleMain].invisibleRepresentation;
if (phasesDraw != PhasesDraw::One) {
surface->DrawTextTransparentUTF8(rcSegment, textFont,
rcSegment.top + vsDraw.maxAscent, text, textFore);
} else {
surface->DrawTextNoClipUTF8(rcSegment, textFont,
rcSegment.top + vsDraw.maxAscent, text, textFore, textBack);
}
}
if (vsDraw.viewWhitespace != WhiteSpace::Invisible ||
(inIndentation && vsDraw.viewIndentationGuides != IndentView::None)) {
@ -2349,6 +2379,11 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl
return; // No further drawing
}
const bool clipLine = !bufferedDraw && !LinesOverlap();
if (clipLine) {
surface->SetClip(rcLine);
}
// See if something overrides the line background colour.
const std::optional<ColourRGBA> background = vsDraw.Background(model.GetMark(line), model.caret.active, ll->containsCaret);
@ -2424,6 +2459,10 @@ void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyl
if (FlagSet(phase, DrawPhase::lineTranslucent)) {
DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine, subLine, Layer::OverText);
}
if (clipLine) {
surface->PopClip();
}
}
static void DrawFoldLines(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll,
@ -2771,10 +2810,10 @@ Sci::Position EditView::FormatRange(bool draw, CharacterRangeFull chrg, Rectangl
// Turn off change history marker backgrounds
constexpr unsigned int changeMarkers =
1u << static_cast<unsigned int>(MarkerOutline::HistoryRevertedToOrigin) |
1u << static_cast<unsigned int>(MarkerOutline::HistorySaved) |
1u << static_cast<unsigned int>(MarkerOutline::HistoryModified) |
1u << static_cast<unsigned int>(MarkerOutline::HistoryRevertedToModified);
1u << static_cast<unsigned int>(MarkerOutline::HistoryRevertedToOrigin) |
1u << static_cast<unsigned int>(MarkerOutline::HistorySaved) |
1u << static_cast<unsigned int>(MarkerOutline::HistoryModified) |
1u << static_cast<unsigned int>(MarkerOutline::HistoryRevertedToModified);
vsPrint.maskInLine &= ~changeMarkers;
const Sci::Line linePrintStart = model.pdoc->SciLineFromPosition(chrg.cpMin);

View File

@ -2379,9 +2379,6 @@ void Editor::NotifyStyleNeeded(Document *, void *, Sci::Position endStyleNeeded)
NotifyStyleToNeeded(endStyleNeeded);
}
void Editor::NotifyLexerChanged(Document *, void *) {
}
void Editor::NotifyErrorOccurred(Document *, void *, Status status) {
errorStatus = status;
}
@ -5835,6 +5832,19 @@ void Editor::StyleSetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleSetVisible:
vs.styles[wParam].visible = lParam != 0;
break;
case Message::StyleSetInvisibleRepresentation: {
const char *utf8 = ConstCharPtrFromSPtr(lParam);
char *rep = vs.styles[wParam].invisibleRepresentation;
const int classified = UTF8Classify(utf8);
if (!(classified & UTF8MaskInvalid)) {
// valid UTF-8
int len = classified & UTF8MaskWidth;
while (len--)
*rep++ = *utf8++;
}
*rep = 0;
break;
}
case Message::StyleSetChangeable:
vs.styles[wParam].changeable = lParam != 0;
break;
@ -5881,6 +5891,8 @@ sptr_t Editor::StyleGetMessage(Message iMessage, uptr_t wParam, sptr_t lParam) {
return vs.styles[wParam].visible ? 1 : 0;
case Message::StyleGetChangeable:
return vs.styles[wParam].changeable ? 1 : 0;
case Message::StyleGetInvisibleRepresentation:
return StringResult(lParam, vs.styles[wParam].invisibleRepresentation);
case Message::StyleGetHotSpot:
return vs.styles[wParam].hotspot ? 1 : 0;
case Message::StyleGetCheckMonospaced:
@ -6245,7 +6257,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::LineScroll:
ScrollTo(topLine + lParam);
HorizontalScrollTo(xOffset + static_cast<int>(wParam) * static_cast<int>(vs.spaceWidth));
HorizontalScrollTo(xOffset + static_cast<int>(static_cast<int>(wParam) * vs.spaceWidth));
return 1;
case Message::SetXOffset:
@ -7331,6 +7343,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleSetChangeable:
case Message::StyleSetHotSpot:
case Message::StyleSetCheckMonospaced:
case Message::StyleSetInvisibleRepresentation:
StyleSetMessage(iMessage, wParam, lParam);
break;
@ -7350,6 +7363,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case Message::StyleGetChangeable:
case Message::StyleGetHotSpot:
case Message::StyleGetCheckMonospaced:
case Message::StyleGetInvisibleRepresentation:
return StyleGetMessage(iMessage, wParam, lParam);
case Message::StyleResetDefault:

View File

@ -471,7 +471,6 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyModified(Document *document, DocModification mh, void *userData) override;
void NotifyDeleted(Document *document, void *userData) noexcept override;
void NotifyStyleNeeded(Document *doc, void *userData, Sci::Position endStyleNeeded) override;
void NotifyLexerChanged(Document *doc, void *userData) override;
void NotifyErrorOccurred(Document *doc, void *userData, Scintilla::Status status) override;
void NotifyMacroRecord(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);

View File

@ -75,10 +75,14 @@ XYPOSITION PixelAlignFloor(XYPOSITION xy, int pixelDivisions) noexcept {
return std::floor(xy * pixelDivisions) / pixelDivisions;
}
XYPOSITION PixelAlignCeil(XYPOSITION xy, int pixelDivisions) noexcept {
return std::ceil(xy * pixelDivisions) / pixelDivisions;
}
Point PixelAlign(const Point &pt, int pixelDivisions) noexcept {
return Point(
std::round(pt.x * pixelDivisions) / pixelDivisions,
std::round(pt.y * pixelDivisions) / pixelDivisions);
PixelAlign(pt.x, pixelDivisions),
PixelAlign(pt.y, pixelDivisions));
}
PRectangle PixelAlign(const PRectangle &rc, int pixelDivisions) noexcept {
@ -88,19 +92,19 @@ PRectangle PixelAlign(const PRectangle &rc, int pixelDivisions) noexcept {
// On retina displays, the positions should be moved to the nearest device
// pixel which is the nearest half logical pixel.
return PRectangle(
std::round(rc.left * pixelDivisions) / pixelDivisions,
PixelAlign(rc.left, pixelDivisions),
PixelAlignFloor(rc.top, pixelDivisions),
std::round(rc.right * pixelDivisions) / pixelDivisions,
PixelAlign(rc.right, pixelDivisions),
PixelAlignFloor(rc.bottom, pixelDivisions));
}
PRectangle PixelAlignOutside(const PRectangle &rc, int pixelDivisions) noexcept {
// Move left and right side to extremes (floor(left) ceil(right)) to avoid blurry visuals.
return PRectangle(
std::floor(rc.left * pixelDivisions) / pixelDivisions,
std::floor(rc.top * pixelDivisions) / pixelDivisions,
std::ceil(rc.right * pixelDivisions) / pixelDivisions,
std::floor(rc.bottom * pixelDivisions) / pixelDivisions);
PixelAlignFloor(rc.left, pixelDivisions),
PixelAlignFloor(rc.top, pixelDivisions),
PixelAlignCeil(rc.right, pixelDivisions),
PixelAlignFloor(rc.bottom, pixelDivisions));
}
ColourRGBA ColourRGBA::MixedWith(ColourRGBA other) const noexcept {

View File

@ -149,6 +149,7 @@ Interval HorizontalBounds(PRectangle rc) noexcept;
XYPOSITION PixelAlign(XYPOSITION xy, int pixelDivisions) noexcept;
XYPOSITION PixelAlignFloor(XYPOSITION xy, int pixelDivisions) noexcept;
XYPOSITION PixelAlignCeil(XYPOSITION xy, int pixelDivisions) noexcept;
Point PixelAlign(const Point &pt, int pixelDivisions) noexcept;

View File

@ -265,15 +265,15 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
case IndicatorStyle::Point:
case IndicatorStyle::PointCharacter:
if (rcCharacter.Width() >= 0.1) {
const XYPOSITION pixelHeight = std::floor(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase
const XYPOSITION pixelHeight = std::floor(rc.Height()); // 1 pixel onto next line if multiphase
const XYPOSITION x = (sacDraw.style == IndicatorStyle::Point) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2);
// 0.5f is to hit midpoint of pixels:
const XYPOSITION ix = std::round(x) + 0.5f;
const XYPOSITION iy = std::floor(rc.top) + 0.5f;
const XYPOSITION iy = std::ceil(rc.bottom) + 0.5f;
const Point pts[] = {
Point(ix - pixelHeight, iy + pixelHeight), // Left
Point(ix + pixelHeight, iy + pixelHeight), // Right
Point(ix, iy) // Top
Point(ix - pixelHeight, iy), // Left
Point(ix + pixelHeight, iy), // Right
Point(ix, iy - pixelHeight) // Top
};
surface->Polygon(pts, std::size(pts), FillStroke(sacDraw.fore));
}
@ -281,11 +281,11 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
case IndicatorStyle::PointTop:
if (rcCharacter.Width() >= 0.1) {
const XYPOSITION pixelHeight = std::floor(rc.Height() - 1.0f); // 1 pixel onto previous line if multiphase
const XYPOSITION pixelHeight = std::floor(rc.Height()); // 1 pixel onto previous line if multiphase
const XYPOSITION x = rcCharacter.left;
// 0.5f is to hit midpoint of pixels:
const XYPOSITION ix = std::round(x) + 0.5f;
const XYPOSITION iy = std::floor(rcLine.top) + 0.5f;
const XYPOSITION iy = std::floor(rcLine.top) - 0.5f;
const Point pts[] = {
Point(ix - pixelHeight, iy), // Left
Point(ix + pixelHeight, iy), // Right

View File

@ -239,10 +239,42 @@ int FoldingMark(FoldLevel level, FoldLevel levelNext, bool firstSubLine, bool la
return 0;
}
LineMarker::FoldPart PartForFoldHighlight(const HighlightDelimiter &highlightDelimiter, Sci::Line lineDoc, bool firstSubLine, bool headWithTail, bool isExpanded) noexcept {
if (highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) {
if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) {
return LineMarker::FoldPart::body;
}
if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) {
if (firstSubLine) {
return headWithTail ? LineMarker::FoldPart::headWithTail : LineMarker::FoldPart::head;
}
if (isExpanded || headWithTail) {
return LineMarker::FoldPart::body;
}
} else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) {
return LineMarker::FoldPart::tail;
}
}
return LineMarker::FoldPart::undefined;
}
constexpr LineMarker::FoldPart PartForBar(bool markBefore, bool markAfter) {
if (markBefore) {
if (markAfter) {
return LineMarker::FoldPart::body;
}
return LineMarker::FoldPart::tail;
}
if (markAfter) {
return LineMarker::FoldPart::head;
}
return LineMarker::FoldPart::headWithTail;
}
}
void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOneMargin, const MarginStyle &marginStyle,
const EditModel &model, const ViewStyle &vs) {
const EditModel &model, const ViewStyle &vs) const {
const Point ptOrigin = model.GetVisibleOriginInMain();
const Sci::Line lineStartPaint = static_cast<Sci::Line>(rcOneMargin.top + ptOrigin.y) / vs.lineHeight;
Sci::Line visibleLine = model.TopLineOfMain() + lineStartPaint;
@ -290,25 +322,27 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn
}
bool headWithTail = false;
bool isExpanded = false;
if (marginStyle.ShowsFolding()) {
// Decide which fold indicator should be displayed
const FoldLevel level = model.pdoc->GetFoldLevel(lineDoc);
const FoldLevel levelNext = model.pdoc->GetFoldLevel(lineDoc + 1);
const FoldLevel levelNum = LevelNumberPart(level);
const FoldLevel levelNextNum = LevelNumberPart(levelNext);
const bool isExpanded = model.pcs->GetExpanded(lineDoc);
isExpanded = model.pcs->GetExpanded(lineDoc);
marks |= FoldingMark(level, levelNext, firstSubLine, lastSubLine,
isExpanded, needWhiteClosure, folderOpenMid, folderEnd);
const FoldLevel levelNum = LevelNumberPart(level);
const FoldLevel levelNextNum = LevelNumberPart(levelNext);
// Change needWhiteClosure and headWithTail if needed
if (LevelIsHeader(level)) {
needWhiteClosure = false;
const Sci::Line firstFollowupLine = model.pcs->DocFromDisplay(model.pcs->DisplayFromDoc(lineDoc + 1));
const FoldLevel firstFollowupLineLevel = model.pdoc->GetFoldLevel(firstFollowupLine);
const FoldLevel secondFollowupLineLevelNum = LevelNumberPart(model.pdoc->GetFoldLevel(firstFollowupLine + 1));
if (!isExpanded) {
const Sci::Line firstFollowupLine = model.pcs->DocFromDisplay(model.pcs->DisplayFromDoc(lineDoc + 1));
const FoldLevel firstFollowupLineLevel = model.pdoc->GetFoldLevel(firstFollowupLine);
const FoldLevel secondFollowupLineLevelNum = LevelNumberPart(model.pdoc->GetFoldLevel(firstFollowupLine + 1));
if (LevelIsWhitespace(firstFollowupLineLevel) &&
(levelNum > secondFollowupLineLevelNum))
needWhiteClosure = true;
@ -397,44 +431,25 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn
marks &= marginStyle.mask;
if (marks) {
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if (marks & 1) {
LineMarker::FoldPart part = LineMarker::FoldPart::undefined;
if (marginStyle.ShowsFolding() && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) {
if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) {
part = LineMarker::FoldPart::body;
} else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) {
if (firstSubLine) {
part = headWithTail ? LineMarker::FoldPart::headWithTail : LineMarker::FoldPart::head;
} else {
if (model.pcs->GetExpanded(lineDoc) || headWithTail) {
part = LineMarker::FoldPart::body;
} else {
part = LineMarker::FoldPart::undefined;
}
}
} else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) {
part = LineMarker::FoldPart::tail;
}
}
if (vs.markers[markBit].markType == MarkerSymbol::Bar) {
const int mask = 1 << markBit;
const bool markBefore = firstSubLine ? (model.GetMark(lineDoc-1) & mask) : true;
const bool markAfter = lastSubLine ? (model.GetMark(lineDoc+1) & mask) : true;
if (markBefore) {
if (markAfter) {
part = LineMarker::FoldPart::body;
} else {
part = LineMarker::FoldPart::tail;
}
} else {
if (markAfter) {
part = LineMarker::FoldPart::head;
} else {
part = LineMarker::FoldPart::headWithTail;
}
}
}
// Draw all the bar markers first so they are underneath as they often cover
// multiple lines for change history and other markers mark individual lines.
int marksBar = marks;
for (int markBit = 0; (markBit <= MarkerMax) && marksBar; markBit++) {
if ((marksBar & 1) && (vs.markers[markBit].markType == MarkerSymbol::Bar)) {
const int mask = 1 << markBit;
const bool markBefore = firstSubLine ? (model.GetMark(lineDoc - 1) & mask) : true;
const bool markAfter = lastSubLine ? (model.GetMark(lineDoc + 1) & mask) : true;
vs.markers[markBit].Draw(surface, rcMarker, vs.styles[StyleLineNumber].font.get(),
PartForBar(markBefore, markAfter), marginStyle.style);
}
marksBar >>= 1;
}
// Draw all the other markers over the bar markers
for (int markBit = 0; (markBit <= MarkerMax) && marks; markBit++) {
if ((marks & 1) && (vs.markers[markBit].markType != MarkerSymbol::Bar)) {
const LineMarker::FoldPart part = marginStyle.ShowsFolding() ?
PartForFoldHighlight(highlightDelimiter, lineDoc, firstSubLine, headWithTail, isExpanded) :
LineMarker::FoldPart::undefined;
vs.markers[markBit].Draw(surface, rcMarker, vs.styles[StyleLineNumber].font.get(), part, marginStyle.style);
}
marks >>= 1;

View File

@ -37,7 +37,7 @@ public:
void DropGraphics() noexcept;
void RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw);
void PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOneMargin, const MarginStyle &marginStyle,
const EditModel &model, const ViewStyle &vs);
const EditModel &model, const ViewStyle &vs) const;
void PaintMargin(Surface *surface, Sci::Line topLine, PRectangle rc, PRectangle rcMargin,
const EditModel &model, const ViewStyle &vs);
};

View File

@ -809,10 +809,6 @@ void ScintillaBase::NotifyStyleToNeeded(Sci::Position endStyleNeeded) {
Editor::NotifyStyleToNeeded(endStyleNeeded);
}
void ScintillaBase::NotifyLexerChanged(Document *, void *) {
vs.EnsureStyle(0xff);
}
sptr_t ScintillaBase::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
case Message::AutoCShow:

View File

@ -82,7 +82,6 @@ protected:
void RightButtonDownWithModifiers(Point pt, unsigned int curTime, Scintilla::KeyMod modifiers) override;
void NotifyStyleToNeeded(Sci::Position endStyleNeeded) override;
void NotifyLexerChanged(Document *doc, void *userData) override;
public:
~ScintillaBase() override;

View File

@ -72,7 +72,8 @@ Style::Style(const char *fontName_) noexcept :
caseForce(CaseForce::mixed),
visible(true),
changeable(true),
hotspot(false) {
hotspot(false),
invisibleRepresentation{} {
}
void Style::Copy(std::shared_ptr<Font> font_, const FontMeasurements &fm_) noexcept {

View File

@ -51,6 +51,7 @@ public:
bool visible;
bool changeable;
bool hotspot;
char invisibleRepresentation[5];
std::shared_ptr<Font> font;

View File

@ -168,6 +168,17 @@ class XiteWin():
self.face.features.update(faceLex.features)
except FileNotFoundError:
print("Can't find " + "LexicalStyles.iface")
if scintillaIncludesLexers:
sciName = "SciLexer.DLL"
else:
sciName = "Scintilla.DLL"
try:
scintillaDLLPath = os.path.join(scintillaBinDirectory, sciName)
ctypes.cdll.LoadLibrary(scintillaDLLPath)
except OSError:
print("Can't find " + sciName)
print("Python is built for " + " ".join(platform.architecture()))
sys.exit()
self.titleDirty = True
self.fullPath = ""
@ -208,17 +219,6 @@ class XiteWin():
def OnCreate(self, hwnd):
self.win = hwnd
if scintillaIncludesLexers:
sciName = "SciLexer.DLL"
else:
sciName = "Scintilla.DLL"
try:
scintillaDLLPath = os.path.join(scintillaBinDirectory, sciName)
ctypes.cdll.LoadLibrary(scintillaDLLPath)
except OSError:
print("Can't find " + sciName)
print("Python is built for " + " ".join(platform.architecture()))
sys.exit()
self.sciHwnd = user32.CreateWindowExW(0,
"Scintilla", "Source",
WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN,

View File

@ -708,6 +708,32 @@ class TestSimple(unittest.TestCase):
self.assertEquals(self.ed.IsRangeWord(6, 7), 0)
self.assertEquals(self.ed.IsRangeWord(6, 8), 1)
class TestChangeHistory(unittest.TestCase):
def setUp(self):
self.xite = Xite.xiteFrame
self.ed = self.xite.ed
self.ed.ClearAll()
self.ed.EmptyUndoBuffer()
self.data = b"xy"
def testChangeHistory(self):
self.assertEquals(self.ed.ChangeHistory, 0)
self.assertEquals(self.ed.UndoCollection, 1)
self.ed.UndoCollection = 0
self.assertEquals(self.ed.UndoCollection, 0)
self.ed.InsertText(0, self.data)
self.ed.UndoCollection = 1
self.ed.ChangeHistory = 1
self.assertEquals(self.ed.ChangeHistory, 1)
self.ed.InsertText(0, self.data)
self.ed.DeleteRange(0, 2)
self.ed.ChangeHistory = 0
self.assertEquals(self.ed.ChangeHistory, 0)
self.ed.ChangeHistory = 1
self.assertEquals(self.ed.ChangeHistory, 1)
self.ed.Undo()
MODI = 1
UNDO = 2
REDO = 4
@ -1930,6 +1956,7 @@ class TestStyleAttributes(unittest.TestCase):
self.ed.EmptyUndoBuffer()
self.testColour = 0x171615
self.testFont = b"Georgia"
self.testRepresentation = "\N{BULLET}".encode("utf-8")
def tearDown(self):
self.ed.StyleResetDefault()
@ -1945,6 +1972,13 @@ class TestStyleAttributes(unittest.TestCase):
self.ed.StyleSetSizeFractional(self.ed.STYLE_DEFAULT, 1234)
self.assertEquals(self.ed.StyleGetSizeFractional(self.ed.STYLE_DEFAULT), 1234)
def testInvisibleRepresentation(self):
self.assertEquals(self.ed.StyleGetInvisibleRepresentation(self.ed.STYLE_DEFAULT), b"")
self.ed.StyleSetInvisibleRepresentation(self.ed.STYLE_DEFAULT, self.testRepresentation)
self.assertEquals(self.ed.StyleGetInvisibleRepresentation(self.ed.STYLE_DEFAULT), self.testRepresentation)
self.ed.StyleSetInvisibleRepresentation(self.ed.STYLE_DEFAULT, b"\000")
self.assertEquals(self.ed.StyleGetInvisibleRepresentation(self.ed.STYLE_DEFAULT), b"")
def testBold(self):
self.ed.StyleSetBold(self.ed.STYLE_DEFAULT, 1)
self.assertEquals(self.ed.StyleGetBold(self.ed.STYLE_DEFAULT), 1)

View File

@ -148,36 +148,49 @@ TEST_CASE("PRectangle") {
// Whole pixels
REQUIRE(PixelAlign(1.0, 1) == 1.0);
REQUIRE(PixelAlignFloor(1.0, 1) == 1.0);
REQUIRE(PixelAlignCeil(1.0, 1) == 1.0);
REQUIRE(PixelAlign(1.25, 1) == 1.0);
REQUIRE(PixelAlignFloor(1.25, 1) == 1.0);
REQUIRE(PixelAlignCeil(1.25, 1) == 2.0);
REQUIRE(PixelAlign(1.5, 1) == 2.0);
REQUIRE(PixelAlignFloor(1.5, 1) == 1.0);
REQUIRE(PixelAlignCeil(1.5, 1) == 2.0);
REQUIRE(PixelAlign(1.75, 1) == 2.0);
REQUIRE(PixelAlignFloor(1.75, 1) == 1.0);
REQUIRE(PixelAlignCeil(1.75, 1) == 2.0);
REQUIRE(PixelAlign(Point(1.75, 1.25), 1) == Point(2.0, 1.0));
REQUIRE(PixelAlign(Point(1.5, 1.0), 1) == Point(2.0, 1.0));
// Half pixels
REQUIRE(PixelAlign(1.0, 2) == 1.0);
REQUIRE(PixelAlignFloor(1.0, 2) == 1.0);
REQUIRE(PixelAlignCeil(1.0, 2) == 1.0);
REQUIRE(PixelAlign(1.25, 2) == 1.5);
REQUIRE(PixelAlignFloor(1.25, 2) == 1.0);
REQUIRE(PixelAlignCeil(1.25, 2) == 1.5);
REQUIRE(PixelAlign(1.5, 2) == 1.5);
REQUIRE(PixelAlignFloor(1.5, 2) == 1.5);
REQUIRE(PixelAlignCeil(1.5, 2) == 1.5);
REQUIRE(PixelAlign(1.75, 2) == 2.0);
REQUIRE(PixelAlignFloor(1.75, 2) == 1.5);
REQUIRE(PixelAlignCeil(1.75, 2) == 2.0);
REQUIRE(PixelAlign(Point(1.75, 1.25), 2) == Point(2.0, 1.5));
REQUIRE(PixelAlign(Point(1.5, 1.0), 2) == Point(1.5, 1.0));
// x->round, y->floored
REQUIRE(PixelAlign(PRectangle(1.0, 1.25, 1.5, 1.75), 1) == PRectangle(1.0, 1.0, 2.0, 1.0));
REQUIRE(PixelAlign(PRectangle(1.0, 1.25, 1.5, 1.75), 2) == PRectangle(1.0, 1.0, 1.5, 1.5));
// x->outside(floor left, ceil right), y->floored
REQUIRE(PixelAlignOutside(PRectangle(1.1, 1.25, 1.6, 1.75), 1) == PRectangle(1.0, 1.0, 2.0, 1.0));
REQUIRE(PixelAlignOutside(PRectangle(1.1, 1.25, 1.6, 1.75), 2) == PRectangle(1.0, 1.0, 2.0, 1.5));
}

View File

@ -1 +1 @@
530
531

View File

@ -3203,15 +3203,17 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) {
ID2D1DCRenderTarget *pDCRT = nullptr;
HRESULT hr = pD2DFactory->CreateDCRenderTarget(&props, &pDCRT);
if (SUCCEEDED(hr) && pDCRT) {
RECT rcWindow;
GetClientRect(pDrawItem->hwndItem, &rcWindow);
hr = pDCRT->BindDC(pDrawItem->hDC, &rcWindow);
const long left = pDrawItem->rcItem.left + static_cast<long>(ItemInset.x + ImageInset.x);
RECT rcItem = pDrawItem->rcItem;
rcItem.left = left;
rcItem.right = rcItem.left + images.GetWidth();
hr = pDCRT->BindDC(pDrawItem->hDC, &rcItem);
if (SUCCEEDED(hr)) {
surfaceItem->Init(pDCRT, pDrawItem->hwndItem);
pDCRT->BeginDraw();
const long left = pDrawItem->rcItem.left + static_cast<long>(ItemInset.x + ImageInset.x);
const PRectangle rcImage = PRectangle::FromInts(left, pDrawItem->rcItem.top,
left + images.GetWidth(), pDrawItem->rcItem.bottom);
const PRectangle rcImage = PRectangle::FromInts(0, 0, images.GetWidth(), rcItem.bottom - rcItem.top);
surfaceItem->DrawRGBAImage(rcImage,
pimage->GetWidth(), pimage->GetHeight(), pimage->Pixels());
pDCRT->EndDraw();

View File

@ -4,8 +4,8 @@
#include <windows.h>
#define VERSION_SCINTILLA "5.3.0"
#define VERSION_WORDS 5, 3, 0, 0
#define VERSION_SCINTILLA "5.3.1"
#define VERSION_WORDS 5, 3, 1, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -309,6 +309,25 @@ public:
}
};
class MouseWheelDelta {
int wheelDelta = 0;
public:
bool Accumulate(WPARAM wParam) noexcept {
wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam);
return std::abs(wheelDelta) >= WHEEL_DELTA;
}
int Actions() noexcept {
const int actions = wheelDelta / WHEEL_DELTA;
wheelDelta = wheelDelta % WHEEL_DELTA;
return actions;
}
};
struct HorizontalScrollRange {
int pageWidth;
int documentWidth;
};
}
namespace Scintilla::Internal {
@ -326,7 +345,9 @@ class ScintillaWin :
SetCoalescableTimerSig SetCoalescableTimerFn;
unsigned int linesPerScroll; ///< Intellimouse support
int wheelDelta; ///< Wheel delta from roll
unsigned int charsPerScroll; ///< Intellimouse support
MouseWheelDelta verticalWheelDelta;
MouseWheelDelta horizontalWheelDelta;
UINT dpi = USER_DEFAULT_SCREEN_DPI;
ReverseArrowCursor reverseArrowCursor;
@ -437,6 +458,8 @@ class ScintillaWin :
void UpdateSystemCaret() override;
void SetVerticalScrollPos() override;
void SetHorizontalScrollPos() override;
void HorizontalScrollToClamped(int xPos);
HorizontalScrollRange GetHorizontalScrollRange() const;
bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) override;
void NotifyChange() override;
void NotifyFocus(bool focus) override;
@ -537,7 +560,7 @@ ScintillaWin::ScintillaWin(HWND hwnd) {
SetCoalescableTimerFn = nullptr;
linesPerScroll = 0;
wheelDelta = 0; // Wheel delta from roll
charsPerScroll = 0;
dpi = DpiForWindow(hwnd);
@ -1575,6 +1598,7 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
if (!mouseWheelCaptures) {
// if the mouse wheel is not captured, test if the mouse
// pointer is over the editor window and if not, don't
@ -1592,27 +1616,30 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l
break;
}
// Don't handle datazoom.
// (A good idea for datazoom would be to "fold" or "unfold" details.
// i.e. if datazoomed out only class structures are visible, when datazooming in the control
// structures appear, then eventually the individual statements...)
if (wParam & MK_SHIFT) {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
// Treat Shift+WM_MOUSEWHEEL as horizontal scrolling, not data-zoom.
if (iMessage == WM_MOUSEHWHEEL || (wParam & MK_SHIFT)) {
if (vs.wrap.state != Wrap::None || charsPerScroll == 0) {
return ::DefWindowProc(MainHWND(), iMessage, wParam, lParam);
}
MouseWheelDelta &wheelDelta = (iMessage == WM_MOUSEHWHEEL) ? horizontalWheelDelta : verticalWheelDelta;
if (wheelDelta.Accumulate(wParam)) {
const int charsToScroll = charsPerScroll * wheelDelta.Actions();
const int widthToScroll = static_cast<int>(std::lround(charsToScroll * vs.aveCharWidth));
HorizontalScrollToClamped(xOffset + widthToScroll);
}
return 0;
}
// Either SCROLL or ZOOM. We handle the wheel steppings calculation
wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam);
if (std::abs(wheelDelta) >= WHEEL_DELTA && linesPerScroll > 0) {
// Either SCROLL vertically or ZOOM. We handle the wheel steppings calculation
if (linesPerScroll != 0 && verticalWheelDelta.Accumulate(wParam)) {
Sci::Line linesToScroll = linesPerScroll;
if (linesPerScroll == WHEEL_PAGESCROLL)
linesToScroll = LinesOnScreen() - 1;
if (linesToScroll == 0) {
linesToScroll = 1;
}
linesToScroll *= (wheelDelta / WHEEL_DELTA);
if (wheelDelta >= 0)
wheelDelta = wheelDelta % WHEEL_DELTA;
else
wheelDelta = -(-wheelDelta % WHEEL_DELTA);
linesToScroll *= verticalWheelDelta.Actions();
if (wParam & MK_CONTROL) {
// Zoom! We play with the font sizes in the styles.
@ -2045,6 +2072,7 @@ sptr_t ScintillaWin::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_MOUSEWHEEL:
case WM_MOUSEHWHEEL:
return MouseMessage(msg, wParam, lParam);
case WM_SETCURSOR:
@ -2318,7 +2346,7 @@ void ScintillaWin::SetTrackMouseLeaveEvent(bool on) noexcept {
void ScintillaWin::UpdateBaseElements() {
struct ElementToIndex { Element element; int nIndex; };
ElementToIndex eti[] = {
const ElementToIndex eti[] = {
{ Element::List, COLOR_WINDOWTEXT },
{ Element::ListBack, COLOR_WINDOW },
{ Element::ListSelected, COLOR_HIGHLIGHTTEXT },
@ -2420,6 +2448,20 @@ bool ScintillaWin::ChangeScrollRange(int nBar, int nMin, int nMax, UINT nPage) n
return false;
}
void ScintillaWin::HorizontalScrollToClamped(int xPos) {
const HorizontalScrollRange range = GetHorizontalScrollRange();
HorizontalScrollTo(std::clamp(xPos, 0, range.documentWidth - range.pageWidth + 1));
}
HorizontalScrollRange ScintillaWin::GetHorizontalScrollRange() const {
const PRectangle rcText = GetTextRectangle();
int pageWidth = static_cast<int>(rcText.Width());
const int horizEndPreferred = std::max({ scrollWidth, pageWidth - 1, 0 });
if (!horizontalScrollBarVisible || Wrapping())
pageWidth = horizEndPreferred + 1;
return { pageWidth, horizEndPreferred };
}
bool ScintillaWin::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) {
if (!IsVisible()) {
return false;
@ -2432,15 +2474,10 @@ bool ScintillaWin::ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) {
if (ChangeScrollRange(SB_VERT, 0, static_cast<int>(vertEndPreferred), static_cast<unsigned int>(nPage))) {
modified = true;
}
const PRectangle rcText = GetTextRectangle();
int pageWidth = static_cast<int>(rcText.Width());
const int horizEndPreferred = std::max({scrollWidth, pageWidth - 1, 0});
if (!horizontalScrollBarVisible || Wrapping())
pageWidth = horizEndPreferred + 1;
if (ChangeScrollRange(SB_HORZ, 0, horizEndPreferred, pageWidth)) {
const HorizontalScrollRange range = GetHorizontalScrollRange();
if (ChangeScrollRange(SB_HORZ, 0, range.documentWidth, range.pageWidth)) {
modified = true;
if (scrollWidth < pageWidth) {
if (scrollWidth < range.pageWidth) {
HorizontalScrollTo(0);
}
}
@ -3180,6 +3217,10 @@ LRESULT ScintillaWin::ImeOnReconvert(LPARAM lParam) {
void ScintillaWin::GetIntelliMouseParameters() noexcept {
// This retrieves the number of lines per scroll as configured in the Mouse Properties sheet in Control Panel
::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &linesPerScroll, 0);
if (!::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &charsPerScroll, 0)) {
// no horizontal scrolling configuration on Windows XP
charsPerScroll = (linesPerScroll == WHEEL_PAGESCROLL) ? 3 : linesPerScroll;
}
}
void ScintillaWin::CopyToGlobal(GlobalMemory &gmUnicode, const SelectionText &selectedText) {
@ -3283,9 +3324,6 @@ void ScintillaWin::HorizontalScrollMessage(WPARAM wParam) {
break;
case SB_PAGEDOWN:
xPos += pageWidth;
if (xPos > scrollWidth - rcText.Width()) { // Hit the end exactly
xPos = scrollWidth - static_cast<int>(rcText.Width());
}
break;
case SB_TOP:
xPos = 0;
@ -3305,7 +3343,7 @@ void ScintillaWin::HorizontalScrollMessage(WPARAM wParam) {
}
break;
}
HorizontalScrollTo(xPos);
HorizontalScrollToClamped(xPos);
}
/**

View File

@ -15,7 +15,7 @@ DIR_BIN=../bin
COMPONENT = $(DIR_BIN)/Scintilla.dll
LIBSCI = $(DIR_BIN)/libscintilla.a
WARNINGS = -Wpedantic -Wall
WARNINGS = -Wpedantic -Wall -Wextra
ifdef CLANG
CXX = clang++