mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-07-28 16:24:27 +02:00
Update to scintilla 5.5.7 & Lexilla 5.4.5
Release 5.5.7 (https://www.scintilla.org/scintilla557.zip) Released 8 June 2025 1. Add SCI_SCROLLVERTICAL method to restore view position and maintain it while performing line wrapping. 2. Add SC_UNDO_SELECTION_HISTORY_SCROLL flag to SCI_SETUNDOSELECTIONHISTORY which controls whether undo and redo restore vertical scroll position. 3. Tweak SC_MARK_BAR to be slightly wider by using next higher whole pixel instead of next lower for margin width / 3. 4. Scale images in autocompletion lists with SCI_AUTOCSETIMAGESCALE to match high DPI screens. Initially only on GTK and Qt. 5. Fix wrapping bug for UTF-8 where \r\n could wrap between the characters. Notepad++ Pull Request #16373. 6. Fix crash during painting when scroll bars changed. Bug #2481. 7. On GTK, reset vertical scroll bar synchronously in SCI_SETDOCPOINTER to fix bug where scroll position not restored in non-wrap mode. Bug #2416. 8. On GTK, fix IME problem when tentative composition interfered with delete surrounding. Feature #1476. 9. On GTK, update IME cursor position inside retrieve surrounding to better position candidate window. Feature #1488. Release 5.4.5 (https://www.scintilla.org/lexilla545.zip) Released 8 June 2025 1. Dart: Add error state SCE_DART_STRINGEOL for unterminated string. Pull request #315. 2. Makefile: Add a keyword list to makefile lexer to highlight GNU Make directives like 'ifdef' and 'vpath' as SCE_MAKE_PREPROCESSOR since these are similar to NMAKE directives like '!IFDEF'. 3. Nix: Add error state SCE_NIX_STRINGEOL for unterminated string. Pull request #315. 4. TOML: Add error state SCE_TOML_STRINGEOL for unterminated string. Pull request #315. 5. Zig: Add error state SCE_ZIG_STRINGEOL for unterminated string. Pull request #315. Close #16649
This commit is contained in:
parent
5b26ef1ca8
commit
e85c354135
Binary file not shown.
Binary file not shown.
@ -27,12 +27,12 @@ directory conventionally called "lexilla".
|
||||
To use GCC, run lexilla/src/makefile:
|
||||
make
|
||||
|
||||
To use Clang, run lexilla/test/makefile:
|
||||
To use Clang, run lexilla/src/makefile:
|
||||
make CLANG=1
|
||||
On macOS, CLANG is set automatically so this can just be
|
||||
make
|
||||
|
||||
To use MSVC, run lexilla/test/lexilla.mak:
|
||||
To use MSVC, run lexilla/src/lexilla.mak:
|
||||
nmake -f lexilla.mak
|
||||
|
||||
To build a debugging version of the library, add DEBUG=1 to the command:
|
||||
|
@ -171,7 +171,6 @@ constParameterPointer:lexilla/lexers/LexTCMD.cxx
|
||||
invalidscanf:lexilla/lexers/LexTCMD.cxx
|
||||
constParameterReference:lexilla/lexers/LexTeX.cxx
|
||||
variableScope:lexilla/lexers/LexTeX.cxx
|
||||
constVariableReference:lexilla/lexers/LexTroff.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexVB.cxx
|
||||
constParameterReference:lexilla/lexers/LexVerilog.cxx
|
||||
variableScope:lexilla/lexers/LexVerilog.cxx
|
||||
|
@ -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="20250402" />
|
||||
<meta name="Date.Modified" content="20250608" />
|
||||
<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.4<br />
|
||||
Site last modified April 2 2025</font>
|
||||
<font color="#FFCC99" size="3">Release version 5.4.5<br />
|
||||
Site last modified June 8 2025</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -78,11 +78,11 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.4.4 fixes a problem when building for ARM654 on Windows.</li>
|
||||
<li>Version 5.4.5 improves Dart, Makefile, Nix, TOML, and Zig.</li>
|
||||
<li>Version 5.4.4 fixes a problem when building for ARM64 on Windows.</li>
|
||||
<li>Version 5.4.3 improves C++, Modula 3, Pascal, Python, and Ruby.</li>
|
||||
<li>Version 5.4.2 adds Nix lexer. Improves JavaScript, PHP, Rust, TOML, and Zig.</li>
|
||||
<li>Version 5.4.1 adds Dart, troff, and Zig lexers. Improves C++, F#, HTML, and Smalltalk.</li>
|
||||
<li>Version 5.4.0 adds a TOML lexer.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
@ -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/lexilla544.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/lexilla545.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/lexilla544.tgz">
|
||||
<a href="https://www.scintilla.org/lexilla545.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.4.4
|
||||
Release 5.4.5
|
||||
</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/lexilla544.zip">zip format</a> (1.4M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla544.tgz">tgz format</a> (1.0M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla545.zip">zip format</a> (1.4M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla545.tgz">tgz format</a> (1.0M) 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>
|
||||
|
@ -594,6 +594,34 @@
|
||||
</tr>
|
||||
</table>
|
||||
<h2 id="Releases">Releases</h2>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla545.zip">Release 5.4.5</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 8 June 2025.
|
||||
</li>
|
||||
<li>
|
||||
Dart: Add error state SCE_DART_STRINGEOL for unterminated string.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
|
||||
</li>
|
||||
<li>
|
||||
Makefile: Add a keyword list to makefile lexer to highlight GNU Make directives like 'ifdef' and 'vpath' as
|
||||
SCE_MAKE_PREPROCESSOR since these are similar to NMAKE directives like '!IFDEF'.
|
||||
</li>
|
||||
<li>
|
||||
Nix: Add error state SCE_NIX_STRINGEOL for unterminated string.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
|
||||
</li>
|
||||
<li>
|
||||
TOML: Add error state SCE_TOML_STRINGEOL for unterminated string.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
|
||||
</li>
|
||||
<li>
|
||||
Zig: Add error state SCE_ZIG_STRINGEOL for unterminated string.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla544.zip">Release 5.4.4</a>
|
||||
</h3>
|
||||
|
@ -2349,6 +2349,7 @@ val SCE_TOML_TRIPLE_STRING_SQ=11
|
||||
val SCE_TOML_TRIPLE_STRING_DQ=12
|
||||
val SCE_TOML_ESCAPECHAR=13
|
||||
val SCE_TOML_DATETIME=14
|
||||
val SCE_TOML_STRINGEOL=15
|
||||
# Lexical states for SCLEX_TROFF
|
||||
lex troff=SCLEX_TROFF SCE_TROFF_
|
||||
val SCE_TROFF_DEFAULT=0
|
||||
@ -2408,6 +2409,7 @@ val SCE_DART_KW_PRIMARY=23
|
||||
val SCE_DART_KW_SECONDARY=24
|
||||
val SCE_DART_KW_TERTIARY=25
|
||||
val SCE_DART_KW_TYPE=26
|
||||
val SCE_DART_STRINGEOL=27
|
||||
# Lexical states for SCLEX_ZIG
|
||||
lex Zig=SCLEX_ZIG SCE_ZIG_
|
||||
val SCE_ZIG_DEFAULT=0
|
||||
@ -2428,6 +2430,7 @@ val SCE_ZIG_KW_SECONDARY=14
|
||||
val SCE_ZIG_KW_TERTIARY=15
|
||||
val SCE_ZIG_KW_TYPE=16
|
||||
val SCE_ZIG_IDENTIFIER_STRING=17
|
||||
val SCE_ZIG_STRINGEOL=18
|
||||
# Lexical states for SCLEX_NIX
|
||||
lex Nix=SCLEX_NIX SCE_NIX_
|
||||
val SCE_NIX_DEFAULT=0
|
||||
@ -2446,3 +2449,4 @@ val SCE_NIX_KEYWORD1=12
|
||||
val SCE_NIX_KEYWORD2=13
|
||||
val SCE_NIX_KEYWORD3=14
|
||||
val SCE_NIX_KEYWORD4=15
|
||||
val SCE_NIX_STRINGEOL=16
|
||||
|
@ -2098,6 +2098,7 @@
|
||||
#define SCE_TOML_TRIPLE_STRING_DQ 12
|
||||
#define SCE_TOML_ESCAPECHAR 13
|
||||
#define SCE_TOML_DATETIME 14
|
||||
#define SCE_TOML_STRINGEOL 15
|
||||
#define SCE_TROFF_DEFAULT 0
|
||||
#define SCE_TROFF_REQUEST 1
|
||||
#define SCE_TROFF_COMMAND 2
|
||||
@ -2153,6 +2154,7 @@
|
||||
#define SCE_DART_KW_SECONDARY 24
|
||||
#define SCE_DART_KW_TERTIARY 25
|
||||
#define SCE_DART_KW_TYPE 26
|
||||
#define SCE_DART_STRINGEOL 27
|
||||
#define SCE_ZIG_DEFAULT 0
|
||||
#define SCE_ZIG_COMMENTLINE 1
|
||||
#define SCE_ZIG_COMMENTLINEDOC 2
|
||||
@ -2171,6 +2173,7 @@
|
||||
#define SCE_ZIG_KW_TERTIARY 15
|
||||
#define SCE_ZIG_KW_TYPE 16
|
||||
#define SCE_ZIG_IDENTIFIER_STRING 17
|
||||
#define SCE_ZIG_STRINGEOL 18
|
||||
#define SCE_NIX_DEFAULT 0
|
||||
#define SCE_NIX_COMMENTLINE 1
|
||||
#define SCE_NIX_COMMENTBLOCK 2
|
||||
@ -2187,6 +2190,7 @@
|
||||
#define SCE_NIX_KEYWORD2 13
|
||||
#define SCE_NIX_KEYWORD3 14
|
||||
#define SCE_NIX_KEYWORD4 15
|
||||
#define SCE_NIX_STRINGEOL 16
|
||||
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
@ -40,26 +39,19 @@ using namespace Lexilla;
|
||||
namespace {
|
||||
|
||||
bool IsAWordChar(const int ch) noexcept {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
|
||||
ch == '_' || ch == '?');
|
||||
return IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == '?';
|
||||
}
|
||||
|
||||
bool IsAWordStart(const int ch) noexcept {
|
||||
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
|
||||
ch == '%' || ch == '@' || ch == '$' || ch == '?');
|
||||
return IsAlphaNumeric(ch) || ch == '_' || ch == '.' ||
|
||||
ch == '%' || ch == '@' || ch == '$' || ch == '?';
|
||||
}
|
||||
|
||||
bool IsAsmOperator(const int ch) noexcept {
|
||||
if ((ch < 0x80) && (isalnum(ch)))
|
||||
if (IsAlphaNumeric(ch))
|
||||
return false;
|
||||
// '.' left out as it is used to make up numbers
|
||||
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
|
||||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
|
||||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
|
||||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
|
||||
ch == '%' || ch == ':')
|
||||
return true;
|
||||
return false;
|
||||
return AnyOf(ch, '*', '/', '-', '+', '(', ')', '=', '^', '[', ']', '<', '&', '>', ',', '|', '~', '%', ':');
|
||||
}
|
||||
|
||||
constexpr bool IsStreamCommentStyle(int style) noexcept {
|
||||
@ -71,26 +63,17 @@ constexpr bool IsStreamCommentStyle(int style) noexcept {
|
||||
// Options used for LexerAsm
|
||||
struct OptionsAsm {
|
||||
std::string delimiter;
|
||||
bool fold;
|
||||
bool foldSyntaxBased;
|
||||
bool foldCommentMultiline;
|
||||
bool foldCommentExplicit;
|
||||
bool fold = false;
|
||||
bool foldSyntaxBased = true;
|
||||
bool foldCommentMultiline = false;
|
||||
bool foldCommentExplicit = false;
|
||||
std::string foldExplicitStart;
|
||||
std::string foldExplicitEnd;
|
||||
bool foldExplicitAnywhere;
|
||||
bool foldCompact;
|
||||
bool foldExplicitAnywhere = false;
|
||||
bool foldCompact = true;
|
||||
std::string commentChar;
|
||||
OptionsAsm() {
|
||||
delimiter = "";
|
||||
fold = false;
|
||||
foldSyntaxBased = true;
|
||||
foldCommentMultiline = false;
|
||||
foldCommentExplicit = false;
|
||||
foldExplicitStart = "";
|
||||
foldExplicitEnd = "";
|
||||
foldExplicitAnywhere = false;
|
||||
foldCompact = true;
|
||||
commentChar = "";
|
||||
[[nodiscard]] char Delimiter() const noexcept {
|
||||
return delimiter.empty() ? '~' : delimiter[0];
|
||||
}
|
||||
};
|
||||
|
||||
@ -153,12 +136,11 @@ class LexerAsm : public DefaultLexer {
|
||||
WordList directives4foldend;
|
||||
OptionsAsm options;
|
||||
OptionSetAsm osAsm;
|
||||
int commentChar;
|
||||
char commentChar;
|
||||
public:
|
||||
LexerAsm(const char *languageName_, int language_, int commentChar_) : DefaultLexer(languageName_, language_) {
|
||||
commentChar = commentChar_;
|
||||
}
|
||||
virtual ~LexerAsm() {
|
||||
LexerAsm(const char *languageName_, int language_, char commentChar_) :
|
||||
DefaultLexer(languageName_, language_),
|
||||
commentChar(commentChar_) {
|
||||
}
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
@ -166,27 +148,27 @@ public:
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvRelease5;
|
||||
}
|
||||
const char * SCI_METHOD PropertyNames() override {
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osAsm.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osAsm.PropertyType(name);
|
||||
}
|
||||
const char * SCI_METHOD DescribeProperty(const char *name) override {
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osAsm.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char * SCI_METHOD PropertyGet(const char *key) override {
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osAsm.PropertyGet(key);
|
||||
}
|
||||
const char * SCI_METHOD DescribeWordListSets() override {
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osAsm.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void * SCI_METHOD PrivateCall(int, void *) override {
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -233,6 +215,8 @@ Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
|
||||
case 7:
|
||||
wordListN = &directives4foldend;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN) {
|
||||
@ -255,8 +239,7 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
|
||||
StyleContext sc(startPos, length, initStyle, styler);
|
||||
|
||||
for (; sc.More(); sc.Forward())
|
||||
{
|
||||
for (; sc.More(); sc.Forward()) {
|
||||
|
||||
if (sc.atLineStart) {
|
||||
switch (sc.state) {
|
||||
@ -285,16 +268,21 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
}
|
||||
|
||||
// Determine if the current state should terminate.
|
||||
if (sc.state == SCE_ASM_OPERATOR) {
|
||||
switch (sc.state) {
|
||||
case SCE_ASM_OPERATOR:
|
||||
if (!IsAsmOperator(sc.ch)) {
|
||||
sc.SetState(SCE_ASM_DEFAULT);
|
||||
sc.SetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_ASM_NUMBER) {
|
||||
break;
|
||||
|
||||
case SCE_ASM_NUMBER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
sc.SetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_ASM_IDENTIFIER) {
|
||||
if (!IsAWordChar(sc.ch) ) {
|
||||
break;
|
||||
|
||||
case SCE_ASM_IDENTIFIER:
|
||||
if (!IsAWordChar(sc.ch)) {
|
||||
char s[100];
|
||||
sc.GetCurrentLowered(s, sizeof(s));
|
||||
bool IsDirective = false;
|
||||
@ -315,24 +303,26 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
}
|
||||
sc.SetState(SCE_ASM_DEFAULT);
|
||||
if (IsDirective && !strcmp(s, "comment")) {
|
||||
const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
|
||||
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
|
||||
sc.ForwardSetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
if (sc.ch == delimiter) {
|
||||
if (sc.ch == options.Delimiter()) {
|
||||
sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
|
||||
const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
|
||||
if (sc.ch == delimiter) {
|
||||
break;
|
||||
|
||||
case SCE_ASM_COMMENTDIRECTIVE:
|
||||
if (sc.ch == options.Delimiter()) {
|
||||
while (!sc.MatchLineEnd()) {
|
||||
sc.Forward();
|
||||
}
|
||||
sc.SetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_ASM_STRING) {
|
||||
break;
|
||||
|
||||
case SCE_ASM_STRING:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
@ -343,7 +333,9 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
sc.ChangeState(SCE_ASM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
} else if (sc.state == SCE_ASM_CHARACTER) {
|
||||
break;
|
||||
|
||||
case SCE_ASM_CHARACTER:
|
||||
if (sc.ch == '\\') {
|
||||
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
|
||||
sc.Forward();
|
||||
@ -354,13 +346,17 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
sc.ChangeState(SCE_ASM_STRINGEOL);
|
||||
sc.ForwardSetState(SCE_ASM_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine if a new state should be entered.
|
||||
if (sc.state == SCE_ASM_DEFAULT) {
|
||||
if (sc.ch == commentCharacter) {
|
||||
sc.SetState(SCE_ASM_COMMENT);
|
||||
} else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) {
|
||||
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
|
||||
sc.SetState(SCE_ASM_NUMBER);
|
||||
} else if (IsAWordStart(sc.ch)) {
|
||||
sc.SetState(SCE_ASM_IDENTIFIER);
|
||||
@ -381,32 +377,32 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
// level store to make it easy to pick up with each increment
|
||||
// and to make it possible to fiddle the current level for "else".
|
||||
|
||||
void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {
|
||||
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
LexAccessor styler(pAccess);
|
||||
|
||||
const Sci_PositionU endPos = startPos + length;
|
||||
const Sci_Position startPos = static_cast<Sci_Position>(startPos_);
|
||||
const Sci_Position endPos = startPos + length;
|
||||
int visibleChars = 0;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0)
|
||||
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
|
||||
levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));
|
||||
int levelNext = levelCurrent;
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int styleNext = styler.StyleIndexAt(startPos);
|
||||
int style = initStyle;
|
||||
char word[100]{};
|
||||
int wordlen = 0;
|
||||
std::string word;
|
||||
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
for (Sci_Position i = startPos; i < endPos; i++) {
|
||||
const char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
const int stylePrev = style;
|
||||
style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
styleNext = styler.StyleIndexAt(i + 1);
|
||||
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
|
||||
if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
|
||||
if (!IsStreamCommentStyle(stylePrev)) {
|
||||
@ -419,10 +415,10 @@ 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())) {
|
||||
levelNext++;
|
||||
levelNext++;
|
||||
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
|
||||
levelNext--;
|
||||
}
|
||||
levelNext--;
|
||||
}
|
||||
} else {
|
||||
if (ch == ';') {
|
||||
if (chNext == '{') {
|
||||
@ -431,41 +427,30 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
|
||||
word[wordlen++] = MakeLowerCase(ch);
|
||||
if (wordlen == 100) { // prevent overflow
|
||||
word[0] = '\0';
|
||||
wordlen = 1;
|
||||
}
|
||||
}
|
||||
if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
|
||||
word.push_back(MakeLowerCase(ch));
|
||||
if (styleNext != SCE_ASM_DIRECTIVE) { // reading directive ready
|
||||
word[wordlen] = '\0';
|
||||
wordlen = 0;
|
||||
if (directives4foldstart.InList(word)) {
|
||||
levelNext++;
|
||||
} else if (directives4foldend.InList(word)){
|
||||
} else if (directives4foldend.InList(word)) {
|
||||
levelNext--;
|
||||
}
|
||||
word.clear();
|
||||
}
|
||||
}
|
||||
if (!IsASpace(ch))
|
||||
visibleChars++;
|
||||
if (atEOL || (i == endPos-1)) {
|
||||
const int levelUse = levelCurrent;
|
||||
int lev = levelUse | levelNext << 16;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if (levelUse < levelNext)
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
const int lev = FoldLevelForCurrentNext(levelCurrent, levelNext) |
|
||||
FoldLevelFlags(levelCurrent, levelNext, visibleChars == 0 && options.foldCompact);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
levelCurrent = levelNext;
|
||||
if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {
|
||||
if (atEOL && (i == (styler.Length() - 1))) {
|
||||
// There is an empty line at end of file so give it same level and empty
|
||||
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
|
||||
styler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);
|
||||
}
|
||||
visibleChars = 0;
|
||||
}
|
||||
|
@ -1268,14 +1268,9 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in
|
||||
}
|
||||
|
||||
if (atEOL) {
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0))
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
const int lev = levelPrev |
|
||||
FoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && options.foldCompact, visibleChars > 0);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
visibleChars = 0;
|
||||
|
@ -121,7 +121,7 @@ struct BracketPair {
|
||||
BracketPair FindBracketPair(Tokens &tokens) {
|
||||
const Tokens::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
|
||||
if (itBracket != tokens.end()) {
|
||||
size_t nest = 0;
|
||||
ptrdiff_t nest = 0;
|
||||
for (Tokens::iterator itTok = itBracket; itTok != tokens.end(); ++itTok) {
|
||||
if (*itTok == "(") {
|
||||
nest++;
|
||||
@ -1502,7 +1502,7 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0)
|
||||
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
|
||||
levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));
|
||||
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);
|
||||
int levelMinCurrent = levelCurrent;
|
||||
int levelNext = levelCurrent;
|
||||
@ -1583,21 +1583,16 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
) {
|
||||
levelUse = levelMinCurrent;
|
||||
}
|
||||
int lev = levelUse | levelNext << 16;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if (levelUse < levelNext)
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
const int lev = FoldLevelForCurrentNext(levelUse, levelNext) |
|
||||
FoldLevelFlags(levelUse, levelNext, visibleChars == 0 && options.foldCompact);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
lineStartNext = styler.LineStart(lineCurrent+1);
|
||||
levelCurrent = levelNext;
|
||||
levelMinCurrent = levelCurrent;
|
||||
if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {
|
||||
// There is an empty line at end of file so give it same level and empty
|
||||
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
|
||||
styler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);
|
||||
}
|
||||
visibleChars = 0;
|
||||
inLineComment = false;
|
||||
@ -1825,7 +1820,7 @@ Tokens LexerCPP::Tokenize(const std::string &expr) const {
|
||||
word += *cp;
|
||||
cp++;
|
||||
}
|
||||
tokens.push_back(word);
|
||||
tokens.push_back(std::move(word));
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
@ -204,6 +204,7 @@ LexicalClass lexicalClasses[] = {
|
||||
24, "SCE_DART_KW_SECONDARY", "identifier", "Secondary keywords",
|
||||
25, "SCE_DART_KW_TERTIARY", "identifier", "Tertiary keywords",
|
||||
26, "SCE_DART_KW_TYPE", "identifier", "Global types",
|
||||
27, "SCE_DART_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
};
|
||||
|
||||
class LexerDart : public DefaultLexer {
|
||||
@ -342,6 +343,10 @@ void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyl
|
||||
int chPrevNonWhite = 0;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
if (initStyle == SCE_DART_STRINGEOL) {
|
||||
initStyle = SCE_DART_DEFAULT;
|
||||
}
|
||||
|
||||
if (startPos != 0) {
|
||||
// backtrack to the line where interpolation starts
|
||||
BacktrackToStart(styler, DartLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
|
||||
@ -457,6 +462,8 @@ void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyl
|
||||
case SCE_DART_TRIPLE_RAWSTRING_DQ:
|
||||
if (sc.atLineStart && !IsTripleString(sc.state)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
} else if (sc.atLineEnd && !IsTripleString(sc.state)) {
|
||||
sc.ChangeState(SCE_DART_STRINGEOL);
|
||||
} else if (sc.ch == '\\' && !IsRaw(sc.state)) {
|
||||
if (escSeq.resetEscapeState(sc.state, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_ESCAPECHAR);
|
||||
@ -489,6 +496,12 @@ void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyl
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
if (escSeq.brace && sc.ch == '}') {
|
||||
|
@ -168,7 +168,8 @@ void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocume
|
||||
{
|
||||
posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish);
|
||||
// Mark whitespace as default
|
||||
styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);
|
||||
if (posCurrent > 0)
|
||||
styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);
|
||||
if (posCurrent >= posFinish)
|
||||
break;
|
||||
|
||||
|
@ -617,16 +617,9 @@ void LexerLua::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle,
|
||||
}
|
||||
|
||||
if (atEOL) {
|
||||
int lev = levelPrev;
|
||||
if (visibleChars == 0 && foldCompact) {
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
}
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0)) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
const int lev = levelPrev |
|
||||
FoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && foldCompact, visibleChars > 0);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
visibleChars = 0;
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
@ -25,19 +26,110 @@
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
using namespace Lexilla;
|
||||
|
||||
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
namespace {
|
||||
|
||||
// Options used for LexerMakeFile
|
||||
struct OptionsMake {
|
||||
};
|
||||
|
||||
const char *const makeWordListDescription[] = {
|
||||
"Directives",
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetMake : public OptionSet<OptionsMake> {
|
||||
OptionSetMake() {
|
||||
DefineWordListSets(makeWordListDescription);
|
||||
}
|
||||
};
|
||||
|
||||
const LexicalClass lexicalClasses[] = {
|
||||
// Lexer makefile SCLEX_MAKEFILE SCE_MAKE_
|
||||
0, "SCE_MAKE_DEFAULT", "default", "White space",
|
||||
1, "SCE_MAKE_COMMENT", "comment", "Comment",
|
||||
2, "SCE_MAKE_PREPROCESSOR", "preprocessor", "Preprocessor",
|
||||
3, "SCE_MAKE_IDENTIFIER", "identifier", "Identifiers",
|
||||
4, "SCE_MAKE_OPERATOR", "operator", "Operator",
|
||||
5, "SCE_MAKE_TARGET", "identifier", "Identifiers",
|
||||
9, "SCE_MAKE_IDEOL", "error identifier", "Incomplete identifier reference",
|
||||
};
|
||||
|
||||
bool AtEOL(Accessor &styler, Sci_PositionU i) {
|
||||
return (styler[i] == '\n') ||
|
||||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
|
||||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
|
||||
}
|
||||
|
||||
static void ColouriseMakeLine(
|
||||
const std::string &lineBuffer,
|
||||
Sci_PositionU startLine,
|
||||
Sci_PositionU endPos,
|
||||
Accessor &styler) {
|
||||
class LexerMakeFile : public DefaultLexer {
|
||||
WordList directives;
|
||||
OptionsMake options;
|
||||
OptionSetMake osMake;
|
||||
public:
|
||||
LexerMakeFile() :
|
||||
DefaultLexer("makefile", SCLEX_MAKEFILE, lexicalClasses, std::size(lexicalClasses)) {
|
||||
}
|
||||
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osMake.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osMake.PropertyType(name);
|
||||
}
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osMake.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osMake.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osMake.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void ColouriseMakeLine(std::string_view lineBuffer,
|
||||
Sci_PositionU startLine, Sci_PositionU endPos, Accessor &styler);
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
static ILexer5 *LexerFactoryMakeFile() {
|
||||
return new LexerMakeFile();
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerMakeFile::PropertySet(const char *key, const char *val) {
|
||||
if (osMake.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerMakeFile::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &directives;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN && wordListN->Set(wl)) {
|
||||
firstModification = 0;
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerMakeFile::ColouriseMakeLine(
|
||||
const std::string_view lineBuffer,
|
||||
Sci_PositionU startLine,
|
||||
Sci_PositionU endPos,
|
||||
Accessor &styler) {
|
||||
|
||||
const Sci_PositionU lengthLine = lineBuffer.length();
|
||||
Sci_PositionU i = 0;
|
||||
@ -46,9 +138,7 @@ static void ColouriseMakeLine(
|
||||
bool bSpecial = false;
|
||||
|
||||
// check for a tab character in column 0 indicating a command
|
||||
bool bCommand = false;
|
||||
if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
|
||||
bCommand = true;
|
||||
const bool bCommand = StartsWith(lineBuffer, '\t');
|
||||
|
||||
// Skip initial spaces
|
||||
while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
|
||||
@ -63,10 +153,22 @@ static void ColouriseMakeLine(
|
||||
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
|
||||
return;
|
||||
}
|
||||
if (IsUpperOrLowerCase(lineBuffer[i]) &&
|
||||
(lineBuffer.find_first_of(":=") == std::string::npos)) {
|
||||
const std::string_view firstWord(lineBuffer.substr(i));
|
||||
size_t endWord = 0;
|
||||
while ((endWord < firstWord.length()) && IsUpperOrLowerCase(firstWord[endWord])) {
|
||||
endWord++;
|
||||
}
|
||||
if (directives.InList(firstWord.substr(0, endWord))) {
|
||||
styler.ColourTo(startLine + i + endWord - 1, SCE_MAKE_PREPROCESSOR);
|
||||
i += endWord;
|
||||
}
|
||||
}
|
||||
}
|
||||
int varCount = 0;
|
||||
while (i < lengthLine) {
|
||||
if (((i + 1) < lengthLine) && (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(')) {
|
||||
if (lineBuffer.substr(i, 2) == "$(") {
|
||||
styler.ColourTo(startLine + i - 1, state);
|
||||
state = SCE_MAKE_IDENTIFIER;
|
||||
varCount++;
|
||||
@ -78,32 +180,22 @@ static void ColouriseMakeLine(
|
||||
}
|
||||
|
||||
// skip identifier and target styling if this is a command line
|
||||
if (!bSpecial && !bCommand) {
|
||||
if (lineBuffer[i] == ':') {
|
||||
if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
|
||||
// it's a ':=', so style as an identifier
|
||||
if (lastNonSpace >= 0)
|
||||
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
|
||||
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
|
||||
styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
|
||||
} else {
|
||||
// We should check that no colouring was made since the beginning of the line,
|
||||
// to avoid colouring stuff like /OUT:file
|
||||
if (lastNonSpace >= 0)
|
||||
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
|
||||
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
|
||||
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
|
||||
}
|
||||
bSpecial = true; // Only react to the first ':' of the line
|
||||
state = SCE_MAKE_DEFAULT;
|
||||
} else if (lineBuffer[i] == '=') {
|
||||
if (lastNonSpace >= 0)
|
||||
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
|
||||
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
|
||||
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
|
||||
bSpecial = true; // Only react to the first '=' of the line
|
||||
state = SCE_MAKE_DEFAULT;
|
||||
if (!bSpecial && !bCommand && AnyOf(lineBuffer[i], ':', '=')) {
|
||||
// Three cases:
|
||||
// : target
|
||||
// := immediate assignment
|
||||
// = lazy assignment
|
||||
const bool colon = lineBuffer[i] == ':';
|
||||
const bool immediate = colon && ((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=');
|
||||
const Sci_PositionU lengthOperator = immediate ? 1 : 0;
|
||||
if (lastNonSpace >= 0) {
|
||||
const int attribute = (colon && !immediate) ? SCE_MAKE_TARGET : SCE_MAKE_IDENTIFIER;
|
||||
styler.ColourTo(startLine + lastNonSpace, attribute);
|
||||
}
|
||||
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
|
||||
styler.ColourTo(startLine + i + lengthOperator, SCE_MAKE_OPERATOR);
|
||||
bSpecial = true; // Only react to the first ':' or '=' of the line
|
||||
state = SCE_MAKE_DEFAULT;
|
||||
}
|
||||
if (!isspacechar(lineBuffer[i])) {
|
||||
lastNonSpace = i;
|
||||
@ -117,7 +209,8 @@ static void ColouriseMakeLine(
|
||||
}
|
||||
}
|
||||
|
||||
static void ColouriseMakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
|
||||
void LexerMakeFile::Lex(Sci_PositionU startPos, Sci_Position length, int /* initStyle */, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, nullptr);
|
||||
std::string lineBuffer;
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
@ -134,10 +227,9 @@ static void ColouriseMakeDoc(Sci_PositionU startPos, Sci_Position length, int, W
|
||||
if (!lineBuffer.empty()) { // Last line does not have ending characters
|
||||
ColouriseMakeLine(lineBuffer, startLine, startPos + length - 1, styler);
|
||||
}
|
||||
styler.Flush();
|
||||
}
|
||||
|
||||
static const char *const emptyWordListDesc[] = {
|
||||
nullptr
|
||||
};
|
||||
}
|
||||
|
||||
extern const LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", nullptr, emptyWordListDesc);
|
||||
extern const LexerModule lmMake(SCLEX_MAKEFILE, LexerMakeFile::LexerFactoryMakeFile, "makefile", makeWordListDescription);
|
||||
|
@ -43,10 +43,10 @@ static void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int
|
||||
|
||||
styler.StartAt(startPos);
|
||||
|
||||
Sci_PositionU lengthDoc = startPos + length;
|
||||
Sci_Position lengthDoc = startPos + length;
|
||||
styler.StartSegment(startPos);
|
||||
|
||||
Sci_PositionU i = startPos;
|
||||
Sci_Position i = startPos;
|
||||
|
||||
// If we are in the middle of a comment we go back to its start before highlighting
|
||||
if(lastStyle == SCE_MAXIMA_COMMENT)
|
||||
@ -201,7 +201,7 @@ static void ColouriseMaximaDoc(Sci_PositionU startPos, Sci_Position length, int
|
||||
// All other keywords are functions if they are followed
|
||||
// by an opening parenthesis
|
||||
char nextNonwhitespace = ' ';
|
||||
for (Sci_PositionU o = i + 1; o < lengthDoc; o++)
|
||||
for (Sci_Position o = i + 1; o < lengthDoc; o++)
|
||||
{
|
||||
nextNonwhitespace = styler.SafeGetCharAt(o);
|
||||
if(!IsASCII(nextNonwhitespace) || !isspacechar(nextNonwhitespace))
|
||||
|
@ -150,6 +150,7 @@ LexicalClass lexicalClasses[] = {
|
||||
13, "SCE_NIX_KEYWORD2", "identifier", "Keywords 2",
|
||||
14, "SCE_NIX_KEYWORD3", "identifier", "Keywords 3",
|
||||
15, "SCE_NIX_KEYWORD4", "identifier", "Keywords 4",
|
||||
16, "SCE_NIX_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
};
|
||||
|
||||
class LexerNix : public DefaultLexer {
|
||||
@ -266,6 +267,10 @@ void LexerNix::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
|
||||
std::vector<InterpolatingState> interpolatingStack;
|
||||
|
||||
if (initStyle == SCE_NIX_STRINGEOL) {
|
||||
initStyle = SCE_NIX_DEFAULT;
|
||||
}
|
||||
|
||||
if (startPos != 0) {
|
||||
// backtrack to the line where interpolation starts
|
||||
BacktrackToStart(styler, NixLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
|
||||
@ -323,6 +328,8 @@ void LexerNix::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
case SCE_NIX_STRING:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_NIX_DEFAULT);
|
||||
} else if (sc.atLineEnd) {
|
||||
sc.ChangeState(SCE_NIX_STRINGEOL);
|
||||
} else if (sc.ch == '\\' && AnyOf(sc.chNext, '"', '\\', 'n', 'r', 't', '$')) {
|
||||
sc.SetState(SCE_NIX_STRING);
|
||||
sc.ChangeState(SCE_NIX_ESCAPECHAR);
|
||||
@ -339,6 +346,12 @@ void LexerNix::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_NIX_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_NIX_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_NIX_PATH:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_NIX_DEFAULT);
|
||||
|
@ -1742,7 +1742,7 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
|
||||
int levelPrev = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0)
|
||||
levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
levelPrev = FoldLevelStart(styler.LevelAt(lineCurrent - 1));
|
||||
int levelCurrent = levelPrev;
|
||||
char chNext = styler[startPos];
|
||||
char chPrev = styler.SafeGetCharAt(startPos - 1);
|
||||
@ -1875,14 +1875,9 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
levelCurrent = SC_FOLDLEVELBASE + 1;
|
||||
isPackageLine = false;
|
||||
}
|
||||
lev |= levelCurrent << 16;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if ((levelCurrent > levelPrev) && (visibleChars > 0))
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
lev |= levelCurrent << FoldLevelShift;
|
||||
lev |= FoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && options.foldCompact, visibleChars > 0);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
visibleChars = 0;
|
||||
@ -1892,7 +1887,7 @@ void SCI_METHOD LexerPerl::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
chPrev = ch;
|
||||
}
|
||||
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
|
||||
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
const int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,6 @@ public:
|
||||
explicit LexerPython() :
|
||||
DefaultLexer("python", SCLEX_PYTHON, lexicalClasses, std::size(lexicalClasses)) {
|
||||
}
|
||||
~LexerPython() override = default;
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
@ -534,11 +533,7 @@ void LexerPython::ProcessLineEnd(StyleContext &sc, std::vector<SingleFStringExpS
|
||||
}
|
||||
|
||||
if (!fstringStateStack.empty()) {
|
||||
std::pair<Sci_Position, std::vector<SingleFStringExpState> > val;
|
||||
val.first = sc.currentLine;
|
||||
val.second = fstringStateStack;
|
||||
|
||||
ftripleStateAtEol.insert(val);
|
||||
ftripleStateAtEol.insert({sc.currentLine, fstringStateStack});
|
||||
}
|
||||
|
||||
if ((sc.state == SCE_P_DEFAULT)
|
||||
|
@ -1424,7 +1424,7 @@ void SCI_METHOD LexerRaku::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
const int state = sc.state;
|
||||
sc.Forward();
|
||||
char ch_delim = 0;
|
||||
int ch_delim = 0;
|
||||
if (setSpecialVar.Contains(sc.ch)
|
||||
&& !setWord.Contains(sc.chNext)) { // Process Special Var
|
||||
ch_delim = -1;
|
||||
@ -1532,7 +1532,7 @@ void SCI_METHOD LexerRaku::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
|
||||
// init char and style variables
|
||||
char chNext = styler[startPos];
|
||||
int stylePrev = styler.StyleAt(startPos - 1);
|
||||
int stylePrev = startPos > 0 ? styler.StyleAt(startPos - 1) : 0;
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
int styleNextStartLine = styler.StyleAt(lineStartNext);
|
||||
int visibleChars = 0;
|
||||
|
@ -489,7 +489,7 @@ void InterpolateVariable(LexAccessor &styler, int state, Sci_Position &i, char &
|
||||
styler.ColourTo(pos, SCE_RB_OPERATOR);
|
||||
state = SCE_RB_GLOBAL;
|
||||
pos += 2;
|
||||
unsigned len = 0;
|
||||
int len = 0;
|
||||
if (chNext == '$') {
|
||||
if (chNext2 == '-') {
|
||||
++pos;
|
||||
|
@ -671,7 +671,7 @@ void SCI_METHOD LexerSQL::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
lineCurrent = styler.GetLine(startPos);
|
||||
if (lineCurrent > 0)
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent - 1));
|
||||
}
|
||||
// And because folding ends at ';', keep going until we find one
|
||||
// Otherwise if create ... view ... as is split over multiple
|
||||
@ -947,15 +947,9 @@ void SCI_METHOD LexerSQL::Fold(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
}
|
||||
if (atEOL) {
|
||||
const int levelUse = levelCurrent;
|
||||
int lev = levelUse | levelNext << 16;
|
||||
if (visibleChars == 0 && options.foldCompact)
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
if (levelUse < levelNext)
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
const int lev = FoldLevelForCurrentNext(levelCurrent, levelNext) |
|
||||
FoldLevelFlags(levelCurrent, levelNext, visibleChars == 0 && options.foldCompact);
|
||||
styler.SetLevelIfDifferent(lineCurrent, lev);
|
||||
lineCurrent++;
|
||||
levelCurrent = levelNext;
|
||||
visibleChars = 0;
|
||||
|
@ -163,6 +163,10 @@ void ColouriseTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt
|
||||
TOMLKeyState keyState = TOMLKeyState::Unquoted;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
if (initStyle == SCE_TOML_STRINGEOL) {
|
||||
initStyle = SCE_TOML_DEFAULT;
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, lengthDoc, initStyle, styler);
|
||||
if (sc.currentLine > 0) {
|
||||
const int lineState = styler.GetLineState(sc.currentLine - 1);
|
||||
@ -274,6 +278,8 @@ void ColouriseTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt
|
||||
case SCE_TOML_TRIPLE_STRING_DQ:
|
||||
if (sc.atLineStart && !IsTripleString(sc.state)) {
|
||||
sc.SetState(SCE_TOML_DEFAULT);
|
||||
} else if (sc.atLineEnd && !IsTripleString(sc.state)) {
|
||||
sc.ChangeState(SCE_TOML_STRINGEOL);
|
||||
} else if (sc.ch == '\\' && IsDoubleQuoted(sc.state)) {
|
||||
if (escSeq.resetEscapeState(sc.state, sc.chNext)) {
|
||||
sc.SetState(SCE_TOML_ESCAPECHAR);
|
||||
@ -293,6 +299,12 @@ void ColouriseTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_TOML_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_TOML_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_TOML_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
sc.SetState(escSeq.outerState);
|
||||
|
@ -163,6 +163,7 @@ LexicalClass lexicalClasses[] = {
|
||||
15, "SCE_ZIG_KW_TERTIARY", "identifier", "Tertiary keywords",
|
||||
16, "SCE_ZIG_KW_TYPE", "identifier", "Global types",
|
||||
17, "SCE_ZIG_IDENTIFIER_STRING", "identifier", "Identifier using @\"\" syntax",
|
||||
18, "SCE_ZIG_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
};
|
||||
|
||||
class LexerZig : public DefaultLexer {
|
||||
@ -262,6 +263,10 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
int lineState = 0;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
if (initStyle == SCE_ZIG_STRINGEOL) {
|
||||
initStyle = SCE_ZIG_DEFAULT;
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, lengthDoc, initStyle, styler);
|
||||
|
||||
while (sc.More()) {
|
||||
@ -311,6 +316,8 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
case SCE_ZIG_IDENTIFIER_STRING:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
} else if (sc.atLineEnd && sc.state != SCE_ZIG_MULTISTRING) {
|
||||
sc.ChangeState(SCE_ZIG_STRINGEOL);
|
||||
} else if (sc.ch == '\\' && sc.state != SCE_ZIG_MULTISTRING) {
|
||||
escSeq.resetEscapeState(sc.state, sc.chNext);
|
||||
sc.SetState(SCE_ZIG_ESCAPECHAR);
|
||||
@ -326,6 +333,12 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
if (escSeq.brace && sc.ch == '}') {
|
||||
|
@ -58,9 +58,8 @@ int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept {
|
||||
}
|
||||
if (len == 0)
|
||||
return 0;
|
||||
else
|
||||
// Either *a or *b is nul
|
||||
return *a - *b;
|
||||
// Either *a or *b is nul
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -190,6 +190,10 @@ int CompareCaseInsensitive(const char *a, const char *b) noexcept;
|
||||
bool EqualCaseInsensitive(std::string_view a, std::string_view b) noexcept;
|
||||
int CompareNCaseInsensitive(const char *a, const char *b, size_t len) noexcept;
|
||||
|
||||
constexpr bool StartsWith(std::string_view s, char start) noexcept {
|
||||
return !s.empty() && (s.front() == start);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -139,3 +139,6 @@ int SCI_METHOD DefaultLexer::GetIdentifier() {
|
||||
return language;
|
||||
}
|
||||
|
||||
const char *SCI_METHOD DefaultLexer::PropertyGet(const char * /* key */) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
// ILexer5 methods
|
||||
const char * SCI_METHOD GetName() override;
|
||||
int SCI_METHOD GetIdentifier() override;
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
|
||||
#include "LexAccessor.h"
|
||||
#include "CharacterSet.h"
|
||||
@ -73,4 +74,21 @@ std::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU
|
||||
return s;
|
||||
}
|
||||
|
||||
void LexAccessor::SetLevelIfDifferent(Sci_Position line, int level) {
|
||||
if (level != pAccess->GetLevel(line)) {
|
||||
pAccess->SetLevel(line, level);
|
||||
}
|
||||
}
|
||||
|
||||
int FoldLevelFlags(int levelLine, int levelNext, bool white, bool headerPermitted) noexcept {
|
||||
int flags = 0;
|
||||
if (white) {
|
||||
flags |= SC_FOLDLEVELWHITEFLAG;
|
||||
}
|
||||
if ((levelLine < levelNext) && (headerPermitted)) {
|
||||
flags |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -205,6 +205,8 @@ public:
|
||||
void SetLevel(Sci_Position line, int level) {
|
||||
pAccess->SetLevel(line, level);
|
||||
}
|
||||
// Avoids some overhead when level same as before
|
||||
void SetLevelIfDifferent(Sci_Position line, int level);
|
||||
void IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) {
|
||||
pAccess->DecorationSetCurrentIndicator(indicator);
|
||||
pAccess->DecorationFillRange(start, value, end - start);
|
||||
@ -222,6 +224,21 @@ struct LexicalClass {
|
||||
const char *description;
|
||||
};
|
||||
|
||||
// Fold level setting
|
||||
|
||||
constexpr int FoldLevelShift = 16;
|
||||
constexpr int FoldLevelStart(int levelPrevious) noexcept {
|
||||
return levelPrevious >> FoldLevelShift;
|
||||
}
|
||||
constexpr int FoldLevelForCurrentNext(int levelCurrent, int levelNext) noexcept {
|
||||
return levelCurrent | levelNext << FoldLevelShift;
|
||||
}
|
||||
// Where lexer uses current/next but only has one value, commonly at end of range
|
||||
constexpr int FoldLevelForCurrent(int levelCurrent) noexcept {
|
||||
return FoldLevelForCurrentNext(levelCurrent, levelCurrent);
|
||||
}
|
||||
int FoldLevelFlags(int levelLine, int levelNext, bool white, bool headerPermitted=true) noexcept;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
void Set(Sci_Position position, T value) {
|
||||
Delete(position);
|
||||
if (states.empty() || (value != states[states.size()-1].value)) {
|
||||
states.push_back(State(position, value));
|
||||
states.emplace_back(position, value);
|
||||
}
|
||||
}
|
||||
T ValueAt(Sci_Position position) {
|
||||
|
@ -191,8 +191,29 @@ bool WordList::InList(const char *s) const noexcept {
|
||||
|
||||
/** convenience overload so can easily call with std::string.
|
||||
*/
|
||||
bool WordList::InList(const std::string &s) const noexcept {
|
||||
return InList(s.c_str());
|
||||
|
||||
bool WordList::InList(std::string_view sv) const noexcept {
|
||||
if (!words || sv.empty())
|
||||
return false;
|
||||
const char first = sv[0];
|
||||
const unsigned char firstChar = first;
|
||||
if (int j = starts[firstChar]; j >= 0) {
|
||||
const std::string_view after = sv.substr(1);
|
||||
for (; words[j][0] == first; j++) {
|
||||
if (std::string_view(words[j] + 1) == after) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (int j = starts[static_cast<unsigned int>('^')]; j >= 0) {
|
||||
for (; words[j][0] == '^';j++) {
|
||||
// Use rfind with 0 position to act like C++20 starts_with for C++17
|
||||
if (sv.rfind(words[j] + 1, 0) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** similar to InList, but word s can be a substring of keyword.
|
||||
|
@ -33,7 +33,7 @@ public:
|
||||
void Clear() noexcept;
|
||||
bool Set(const char *s, bool lowerCase=false);
|
||||
bool InList(const char *s) const noexcept;
|
||||
bool InList(const std::string &s) const noexcept;
|
||||
bool InList(std::string_view sv) const noexcept;
|
||||
bool InListAbbreviated(const char *s, const char marker) const noexcept;
|
||||
bool InListAbridged(const char *s, const char marker) const noexcept;
|
||||
const char *WordAt(int n) const noexcept;
|
||||
|
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.4.4</string>
|
||||
<string>5.4.5</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
@ -876,7 +876,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.4.4;
|
||||
CURRENT_PROJECT_VERSION = 5.4.5;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -904,7 +904,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.4.4;
|
||||
CURRENT_PROJECT_VERSION = 5.4.5;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VERSION_LEXILLA "5.4.4"
|
||||
#define VERSION_WORDS 5, 4, 4, 0
|
||||
#define VERSION_LEXILLA "5.4.5"
|
||||
#define VERSION_WORDS 5, 4, 5, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_WORDS
|
||||
|
@ -41,6 +41,7 @@ $(DIR_O)/LexAccessor.o: \
|
||||
../lexlib/LexAccessor.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/CharacterSet.h
|
||||
$(DIR_O)/LexerBase.o: \
|
||||
@ -897,7 +898,9 @@ $(DIR_O)/LexMake.o: \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexMarkdown.o: \
|
||||
../lexers/LexMarkdown.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
|
@ -41,6 +41,7 @@ $(DIR_O)/LexAccessor.obj: \
|
||||
../lexlib/LexAccessor.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/CharacterSet.h
|
||||
$(DIR_O)/LexerBase.obj: \
|
||||
@ -897,7 +898,9 @@ $(DIR_O)/LexMake.obj: \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexMarkdown.obj: \
|
||||
../lexers/LexMarkdown.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
|
@ -49,4 +49,9 @@ movq
|
||||
comment ~ A multiple-line
|
||||
comment directive~
|
||||
|
||||
; test for folding from segment to ends
|
||||
data segment
|
||||
hw db "HW!"
|
||||
data ends
|
||||
|
||||
;end
|
||||
|
@ -1,53 +1,58 @@
|
||||
0 400 0 ; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.
|
||||
0 400 0 ; This is not a viable source file, it just illustrates the different states in isolation.
|
||||
0 400 0
|
||||
0 400 0 ; comment=1
|
||||
0 400 0 ; Comment
|
||||
0 400 0
|
||||
0 400 0 ; whitespace=0
|
||||
0 400 0 ; w
|
||||
0 400 0
|
||||
0 400 0 ; number=2
|
||||
0 400 0 11
|
||||
0 400 0
|
||||
0 400 0 ; string=3
|
||||
0 400 0 "String"
|
||||
0 400 0
|
||||
0 400 0 ; operator=4
|
||||
0 400 0 +
|
||||
0 400 0
|
||||
0 400 0 ; identifier=5
|
||||
0 400 0 identifier
|
||||
0 400 0
|
||||
0 400 0 ; CPU instruction=6
|
||||
0 400 0 add
|
||||
0 400 0
|
||||
0 400 0 ; math Instruction=7
|
||||
0 400 0 fadd
|
||||
0 400 0
|
||||
0 400 0 ; register=8
|
||||
0 400 0 ECX
|
||||
0 400 0
|
||||
0 400 0 ; directive=9
|
||||
0 400 0 section
|
||||
0 400 0
|
||||
0 400 0 ; directive operand=10
|
||||
0 400 0 rel
|
||||
0 400 0
|
||||
0 400 0 ; comment block=11 is for future expansion
|
||||
0 400 0
|
||||
0 400 0 ; character=12
|
||||
0 400 0 'character'
|
||||
0 400 0
|
||||
0 400 0 ; string EOL=13
|
||||
0 400 0 "no line end
|
||||
0 400 0
|
||||
0 400 0 ; extended instruction=14
|
||||
0 400 0 movq
|
||||
0 400 0
|
||||
0 400 0 ; comment directive=15
|
||||
0 400 0 comment ~ A multiple-line
|
||||
0 400 0 comment directive~
|
||||
0 400 0
|
||||
0 400 0 ;end
|
||||
0 400 0
|
||||
0 400 400 ; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.
|
||||
0 400 400 ; This is not a viable source file, it just illustrates the different states in isolation.
|
||||
1 400 400
|
||||
0 400 400 ; comment=1
|
||||
0 400 400 ; Comment
|
||||
1 400 400
|
||||
0 400 400 ; whitespace=0
|
||||
0 400 400 ; w
|
||||
1 400 400
|
||||
0 400 400 ; number=2
|
||||
0 400 400 11
|
||||
1 400 400
|
||||
0 400 400 ; string=3
|
||||
0 400 400 "String"
|
||||
1 400 400
|
||||
0 400 400 ; operator=4
|
||||
0 400 400 +
|
||||
1 400 400
|
||||
0 400 400 ; identifier=5
|
||||
0 400 400 identifier
|
||||
1 400 400
|
||||
0 400 400 ; CPU instruction=6
|
||||
0 400 400 add
|
||||
1 400 400
|
||||
0 400 400 ; math Instruction=7
|
||||
0 400 400 fadd
|
||||
1 400 400
|
||||
0 400 400 ; register=8
|
||||
0 400 400 ECX
|
||||
1 400 400
|
||||
0 400 400 ; directive=9
|
||||
0 400 400 section
|
||||
1 400 400
|
||||
0 400 400 ; directive operand=10
|
||||
0 400 400 rel
|
||||
1 400 400
|
||||
0 400 400 ; comment block=11 is for future expansion
|
||||
1 400 400
|
||||
0 400 400 ; character=12
|
||||
0 400 400 'character'
|
||||
1 400 400
|
||||
0 400 400 ; string EOL=13
|
||||
0 400 400 "no line end
|
||||
1 400 400
|
||||
0 400 400 ; extended instruction=14
|
||||
0 400 400 movq
|
||||
1 400 400
|
||||
0 400 400 ; comment directive=15
|
||||
0 400 400 comment ~ A multiple-line
|
||||
0 400 400 comment directive~
|
||||
1 400 400
|
||||
0 400 400 ; test for folding from segment to ends
|
||||
2 400 401 + data segment
|
||||
0 401 401 | hw db "HW!"
|
||||
0 401 400 | data ends
|
||||
1 400 400
|
||||
0 400 400 ;end
|
||||
1 400 400
|
@ -49,4 +49,9 @@
|
||||
{0} {9}comment{0} {15}~ A multiple-line
|
||||
comment directive~{0}
|
||||
|
||||
{1}; test for folding from segment to ends
|
||||
{5}data{0} {9}segment{0}
|
||||
{5}hw{0} {9}db{0} {3}"HW!"{0}
|
||||
{5}data{0} {9}ends{0}
|
||||
|
||||
{1};end
|
||||
|
@ -3,7 +3,10 @@ lexer.*.asm=asm
|
||||
keywords.*.asm=add sub xor mov lea call
|
||||
keywords2.*.asm=fadd
|
||||
keywords3.*.asm=rsp rax rcx rdx r8 r9 ecx
|
||||
keywords4.*.asm=db section alignb resq resqdb global extern equ .bss .text .data start comment
|
||||
keywords4.*.asm=db section segment ends alignb resq resqdb global extern equ .bss .text .data start comment
|
||||
keywords5.*.asm=qword rel
|
||||
keywords6.*.asm=movd movq
|
||||
keywords7.*.asm=segment
|
||||
keywords8.*.asm=ends
|
||||
|
||||
fold=1
|
||||
|
@ -332,3 +332,8 @@ var s3 = """multi-line
|
||||
${x}
|
||||
strings
|
||||
""";
|
||||
|
||||
var s1 = 'Unterminated string;
|
||||
var s2 = "Unterminated string;
|
||||
var s3 = r'Unterminated raw string;
|
||||
var s4 = r'Unterminated raw string;
|
||||
|
@ -332,4 +332,9 @@
|
||||
0 401 401 | ${x}
|
||||
0 401 401 | strings
|
||||
0 401 400 | """;
|
||||
0 400 400
|
||||
0 400 400 var s1 = 'Unterminated string;
|
||||
0 400 400 var s2 = "Unterminated string;
|
||||
0 400 400 var s3 = r'Unterminated raw string;
|
||||
0 400 400 var s4 = r'Unterminated raw string;
|
||||
0 400 0
|
@ -332,3 +332,8 @@ strings
|
||||
{17}${{14}x{17}}{8}
|
||||
strings
|
||||
"""{16};{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {27}'Unterminated string;
|
||||
{23}var{0} {14}s2{0} {16}={0} {27}"Unterminated string;
|
||||
{23}var{0} {14}s3{0} {16}={0} {27}r'Unterminated raw string;
|
||||
{23}var{0} {14}s4{0} {16}={0} {27}r'Unterminated raw string;
|
||||
|
@ -1 +1,2 @@
|
||||
lexer.*.mak=makefile
|
||||
keywords.*.mak=ifdef
|
||||
|
@ -7,10 +7,17 @@
|
||||
# 'LD' identifier=3, '=' operator=4, 'link' default=0
|
||||
LD=link
|
||||
|
||||
# '!IFDEF DEBUG' preprocessor=2
|
||||
# '!IFDEF DEBUG' NMAKE preprocessor=2
|
||||
!IFDEF DEBUG
|
||||
|
||||
# 'ifdef DEBUG' GNI make directive default=0
|
||||
ifdef DEBUG
|
||||
|
||||
# '$(' ID EOL=9
|
||||
X=$(
|
||||
|
||||
# Recipe with variable reference $(CXX)
|
||||
cake.o: cake.cxx
|
||||
$(CXX) -c $< -o $@
|
||||
|
||||
# End of file
|
||||
|
@ -7,11 +7,18 @@
|
||||
0 400 0 # 'LD' identifier=3, '=' operator=4, 'link' default=0
|
||||
0 400 0 LD=link
|
||||
0 400 0
|
||||
0 400 0 # '!IFDEF DEBUG' preprocessor=2
|
||||
0 400 0 # '!IFDEF DEBUG' NMAKE preprocessor=2
|
||||
0 400 0 !IFDEF DEBUG
|
||||
0 400 0
|
||||
0 400 0 # 'ifdef DEBUG' GNI make directive default=0
|
||||
0 400 0 ifdef DEBUG
|
||||
0 400 0
|
||||
0 400 0 # '$(' ID EOL=9
|
||||
0 400 0 X=$(
|
||||
0 400 0
|
||||
0 400 0 # Recipe with variable reference $(CXX)
|
||||
0 400 0 cake.o: cake.cxx
|
||||
0 400 0 $(CXX) -c $< -o $@
|
||||
0 400 0
|
||||
0 400 0 # End of file
|
||||
0 400 0
|
@ -7,10 +7,17 @@
|
||||
{1}# 'LD' identifier=3, '=' operator=4, 'link' default=0
|
||||
{3}LD{4}={0}link
|
||||
|
||||
{1}# '!IFDEF DEBUG' preprocessor=2
|
||||
{1}# '!IFDEF DEBUG' NMAKE preprocessor=2
|
||||
{2}!IFDEF DEBUG
|
||||
{0}
|
||||
{1}# 'ifdef DEBUG' GNI make directive default=0
|
||||
{2}ifdef{0} DEBUG
|
||||
|
||||
{1}# '$(' ID EOL=9
|
||||
{3}X{4}={9}$(
|
||||
{0}
|
||||
{1}# Recipe with variable reference $(CXX)
|
||||
{5}cake.o{4}:{0} cake.cxx
|
||||
{3}$(CXX){0} -c $< -o $@
|
||||
|
||||
{1}# End of file
|
||||
|
@ -347,3 +347,6 @@ stdenv.mkDerivation rec {
|
||||
'';
|
||||
|
||||
}
|
||||
|
||||
message = "unterminated string;
|
||||
message2 = "unterminated string;
|
||||
|
@ -347,4 +347,7 @@
|
||||
0 402 401 | '';
|
||||
0 401 401 |
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 message = "unterminated string;
|
||||
0 400 400 message2 = "unterminated string;
|
||||
0 400 0
|
@ -347,3 +347,6 @@ string
|
||||
''{7};{0}
|
||||
|
||||
{7}}{0}
|
||||
|
||||
{10}message{0} {7}={0} {16}"unterminated string;
|
||||
{10}message2{0} {7}={0} {16}"unterminated string;
|
||||
|
@ -189,3 +189,5 @@ points = [ { x = 1, y = 2, z = 3 },
|
||||
~~~~ = true # invalid character in key
|
||||
invalid # invalid, missing value
|
||||
key = identifier # also invalid, identifier must be one of true, false, inf, nan
|
||||
key = "unterminated string
|
||||
key = 'other unterminated string
|
||||
|
@ -189,4 +189,6 @@
|
||||
0 401 0 | ~~~~ = true # invalid character in key
|
||||
0 401 0 | invalid # invalid, missing value
|
||||
0 401 0 | key = identifier # also invalid, identifier must be one of true, false, inf, nan
|
||||
0 401 0 | key = "unterminated string
|
||||
0 401 0 | key = 'other unterminated string
|
||||
0 401 0 |
|
@ -189,3 +189,5 @@ trimmed in raw strings.
|
||||
{7}~~~~ = true {1}# invalid character in key
|
||||
{6}invalid{0} {1}# invalid, missing value
|
||||
{6}key{0} {8}={0} {2}identifier{0} {1}# also invalid, identifier must be one of true, false, inf, nan
|
||||
{6}key{0} {8}={0} {15}"unterminated string
|
||||
{6}key{0} {8}={0} {15}'other unterminated string
|
||||
|
@ -288,3 +288,7 @@ const Color = enum {
|
||||
@"really red",
|
||||
};
|
||||
const color: Color = .@"really red";
|
||||
|
||||
const s1 = "Unterminated string
|
||||
const s2 = 'Unterminated character
|
||||
const s3 = @"Unterminated identifier string
|
||||
|
@ -288,4 +288,8 @@
|
||||
0 401 401 | @"really red",
|
||||
0 401 400 | };
|
||||
0 400 400 const color: Color = .@"really red";
|
||||
0 400 400
|
||||
0 400 400 const s1 = "Unterminated string
|
||||
0 400 400 const s2 = 'Unterminated character
|
||||
0 400 400 const s3 = @"Unterminated identifier string
|
||||
0 400 0
|
@ -288,3 +288,7 @@
|
||||
{17}@"really red"{5},{0}
|
||||
{5}};{0}
|
||||
{13}const{0} {10}color{5}:{0} {10}Color{0} {5}={0} {5}.{17}@"really red"{5};{0}
|
||||
|
||||
{13}const{0} {10}s1{0} {5}={0} {18}"Unterminated string
|
||||
{13}const{0} {10}s2{0} {5}={0} {18}'Unterminated character
|
||||
{13}const{0} {10}s3{0} {5}={0} {18}@"Unterminated identifier string
|
||||
|
@ -44,6 +44,24 @@ TEST_CASE("WordList") {
|
||||
REQUIRE(!wl.InList(sClass));
|
||||
}
|
||||
|
||||
SECTION("StringViewInList") {
|
||||
wl.Set("else struct i ^gtk");
|
||||
std::string_view svStruct = "struct";
|
||||
REQUIRE(wl.InList(svStruct));
|
||||
std::string_view svClass = "class";
|
||||
REQUIRE(!wl.InList(svClass));
|
||||
|
||||
// Test single characters
|
||||
std::string_view svI = "i";
|
||||
REQUIRE(wl.InList(svI));
|
||||
std::string_view svA = "a";
|
||||
REQUIRE(!wl.InList(svA));
|
||||
|
||||
// Test prefix
|
||||
std::string_view svPrefix = "gtk_prefix";
|
||||
REQUIRE(wl.InList(svPrefix));
|
||||
}
|
||||
|
||||
SECTION("InListUnicode") {
|
||||
// "cheese" in English
|
||||
// "kase" ('k', 'a with diaeresis', 's', 'e') in German
|
||||
|
@ -1 +1 @@
|
||||
544
|
||||
545
|
@ -1115,6 +1115,14 @@ int ScintillaCall::AutoCGetStyle() {
|
||||
return static_cast<int>(Call(Message::AutoCGetStyle));
|
||||
}
|
||||
|
||||
void ScintillaCall::AutoCSetImageScale(int scalePercent) {
|
||||
Call(Message::AutoCSetImageScale, scalePercent);
|
||||
}
|
||||
|
||||
int ScintillaCall::AutoCGetImageScale() {
|
||||
return static_cast<int>(Call(Message::AutoCGetImageScale));
|
||||
}
|
||||
|
||||
void ScintillaCall::SetIndent(int indentSize) {
|
||||
Call(Message::SetIndent, indentSize);
|
||||
}
|
||||
@ -1367,6 +1375,10 @@ void ScintillaCall::LineScroll(Position columns, Line lines) {
|
||||
Call(Message::LineScroll, columns, lines);
|
||||
}
|
||||
|
||||
void ScintillaCall::ScrollVertical(Line docLine, Line subLine) {
|
||||
Call(Message::ScrollVertical, docLine, subLine);
|
||||
}
|
||||
|
||||
void ScintillaCall::ScrollCaret() {
|
||||
Call(Message::ScrollCaret);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.5.6</string>
|
||||
<string>5.5.7</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
@ -586,7 +586,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.5.6;
|
||||
CURRENT_PROJECT_VERSION = 5.5.7;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -650,7 +650,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.5.6;
|
||||
CURRENT_PROJECT_VERSION = 5.5.7;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
@ -682,7 +682,7 @@
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 5.5.6;
|
||||
CURRENT_PROJECT_VERSION = 5.5.7;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
@ -717,7 +717,7 @@
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 5.5.6;
|
||||
CURRENT_PROJECT_VERSION = 5.5.7;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
|
@ -1951,6 +1951,7 @@ void ScintillaCocoa::ScrollText(Sci::Line) {
|
||||
* Modifies the vertical scroll position to make the current top line show up as such.
|
||||
*/
|
||||
void ScintillaCocoa::SetVerticalScrollPos() {
|
||||
Editor::SetVerticalScrollPos();
|
||||
NSScrollView *scrollView = ScrollContainer();
|
||||
if (scrollView) {
|
||||
NSClipView *clipView = scrollView.contentView;
|
||||
|
@ -130,7 +130,7 @@
|
||||
|
||||
<h1>Scintilla Documentation</h1>
|
||||
|
||||
<p>Last edited 29 March 2025 NH</p>
|
||||
<p>Last edited 29 May 2025 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 />
|
||||
@ -151,6 +151,8 @@
|
||||
discussion of folding</a>.<br />
|
||||
<a class="jump" href="https://github.com/geany/geany/files/5204338/Scintilla-var.aq-Tutorial.pdf">
|
||||
Beginner's Guide to lexing and folding</a>.<br />
|
||||
<a class="jump" href="https://www.youtube.com/watch?v=M07iGUA07rY">
|
||||
Video on writing a lexer with wxStyledTextCtrl</a>.<br />
|
||||
The <a class="jump" href="SciCoding.html">coding style</a> used in Scintilla and SciTE is
|
||||
worth following if you want to contribute code to Scintilla but is not compulsory.</p>
|
||||
|
||||
@ -1324,6 +1326,35 @@ struct Sci_TextRangeFull {
|
||||
This is most commonly desired in conjunction with virtual space but is an independent
|
||||
setting so works without virtual space.</p>
|
||||
|
||||
<table class="standard" summary="Virtual space options">
|
||||
<tbody valign="top">
|
||||
<tr>
|
||||
<th align="left"><code>SCVS_NONE</code></th>
|
||||
<td>0</td>
|
||||
<td>The default: no virtual space.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="left"><code>SCVS_RECTANGULARSELECTION</code></th>
|
||||
<td>1</td>
|
||||
<td>Virtual space is enabled for rectangular selections.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="left"><code>SCVS_USERACCESSIBLE</code></th>
|
||||
<td>2</td>
|
||||
<td>Virtual space is enabled for user actions such as right arrow key or clicking beyond line end.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="left"><code>SCVS_NOWRAPLINESTART</code></th>
|
||||
<td>4</td>
|
||||
<td>Left arrow does not wrap to the previous line.</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
<b id="SCI_SETRECTANGULARSELECTIONMODIFIER">SCI_SETRECTANGULARSELECTIONMODIFIER(int modifier)</b><br />
|
||||
<b id="SCI_GETRECTANGULARSELECTIONMODIFIER">SCI_GETRECTANGULARSELECTIONMODIFIER → int</b><br />
|
||||
@ -2054,6 +2085,14 @@ struct Sci_TextToFindFull {
|
||||
<td>Restore selection for each undo and redo.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th align="left"><code>SC_UNDO_SELECTION_HISTORY_SCROLL</code></th>
|
||||
|
||||
<td>2</td>
|
||||
|
||||
<td>Restore vertical scroll position. Has no effect without <code>SC_UNDO_SELECTION_HISTORY_ENABLED</code>.</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -2358,6 +2397,7 @@ struct Sci_TextToFindFull {
|
||||
<a class="message" href="#SCI_GETFIRSTVISIBLELINE">SCI_GETFIRSTVISIBLELINE → line</a><br />
|
||||
<a class="message" href="#SCI_SETXOFFSET">SCI_SETXOFFSET(int xOffset)</a><br />
|
||||
<a class="message" href="#SCI_GETXOFFSET">SCI_GETXOFFSET → int</a><br />
|
||||
<a class="message" href="#SCI_SCROLLVERTICAL">SCI_SCROLLVERTICAL(line docLine, line subLine)</a><br />
|
||||
<a class="message" href="#SCI_LINESCROLL">SCI_LINESCROLL(position columns, line lines)</a><br />
|
||||
<a class="message" href="#SCI_SCROLLCARET">SCI_SCROLLCARET</a><br />
|
||||
<a class="message" href="#SCI_SCROLLRANGE">SCI_SCROLLRANGE(position secondary, position primary)</a><br />
|
||||
@ -2391,6 +2431,26 @@ struct Sci_TextToFindFull {
|
||||
view. A value of 0 is the normal position with the first text column visible at the left of the
|
||||
view.</p>
|
||||
|
||||
<p><b id="SCI_SCROLLVERTICAL">SCI_SCROLLVERTICAL(line docLine, line subLine)</b><br />
|
||||
Sets the vertical scroll position to be the display line for the
|
||||
<code class="parameter">subLine</code> of the <code class="parameter">docLine</code>, similar to<br>
|
||||
<code>SCI_SETFIRSTVISIBLELINE(SCI_VISIBLEFROMDOCLINE(docLine) + subLine)</code>.</p>
|
||||
|
||||
<p>The <code class="parameter">subLine</code> is capped to the maximum number of sublines
|
||||
for that document line which may change because of styling and wrapping. It is ignored when line
|
||||
wrapping is off.</p>
|
||||
|
||||
<p>If line wrapping is on, then that
|
||||
<code class="parameter">docLine</code>/<code class="parameter">subLine</code>
|
||||
is remembered and reapplied as lines are wrapped.
|
||||
This ensures that when wrapping is completed, which may take some time, the line at the top of the view is that
|
||||
requested by the application and the view range is stable during the wrapping process.
|
||||
It is forgotten once the document is fully wrapped or the user
|
||||
performs scrolling manually such as by dragging the scroll bar.</p>
|
||||
|
||||
<p>This method is a good way for applications to restore the user's positional context when re-selecting a
|
||||
document as it is robust to changes in window width and styles.</p>
|
||||
|
||||
<p><b id="SCI_LINESCROLL">SCI_LINESCROLL(position columns, line lines)</b><br />
|
||||
This will attempt to scroll the display by the number of columns and lines that you specify.
|
||||
Positive line values increase the line number at the top of the screen (i.e. they move the text
|
||||
@ -3631,7 +3691,7 @@ struct Sci_TextToFindFull {
|
||||
<td>✓</td>
|
||||
<td>✓</td></tr>
|
||||
<tr>
|
||||
<th align="left"><code>SC_CHARSET_GREEK</code></td>
|
||||
<th align="left"><code>SC_CHARSET_GREEK</code></th>
|
||||
<td>161</td>
|
||||
<td>✓</td>
|
||||
<td></td>
|
||||
@ -4539,8 +4599,8 @@ struct Sci_TextToFindFull {
|
||||
<p>Using a margin number outside the valid range has no
|
||||
effect. By default, margin 0 is set to display line numbers, but is given a width of 0, so it
|
||||
is hidden. Margin 1 is set to display non-folding symbols and is given a width of 16 pixels, so
|
||||
it is visible. Margin 2 is set to display the folding symbols, but is given a width of 0, so it
|
||||
is hidden. Of course, you can set the margins to be whatever you wish.</p>
|
||||
it is visible. Margin 2 is a symbol margin that is given a width of 0, so it is hidden.
|
||||
Of course, you can set the margins to be whatever you wish.</p>
|
||||
|
||||
<p>Styled text margins used to show revision and blame information:</p>
|
||||
<p><img src="styledmargin.png" alt="Styled text margins used to show revision and blame information" /></p>
|
||||
@ -5221,7 +5281,7 @@ struct Sci_TextToFindFull {
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p></p>
|
||||
<br />
|
||||
|
||||
<table class="standard" summary="IME interaction">
|
||||
<caption>IME interaction support</caption>
|
||||
@ -6475,6 +6535,8 @@ struct Sci_TextToFindFull {
|
||||
<a class="message" href="#SCI_AUTOCGETMAXWIDTH">SCI_AUTOCGETMAXWIDTH → int</a><br />
|
||||
<a class="message" href="#SCI_AUTOCSETSTYLE">SCI_AUTOCSETSTYLE(int style)</a><br />
|
||||
<a class="message" href="#SCI_AUTOCGETSTYLE">SCI_AUTOCGETSTYLE → int</a><br />
|
||||
<a class="message" href="#SCI_AUTOCSETIMAGESCALE">SCI_AUTOCSETIMAGESCALE(int scale)</a><br />
|
||||
<a class="message" href="#SCI_AUTOCGETIMAGESCALE">SCI_AUTOCGETIMAGESCALE → int</a><br />
|
||||
<a class="element" href="#SC_ELEMENT_LIST">SC_ELEMENT_LIST : colouralpha</a><br />
|
||||
<a class="element" href="#SC_ELEMENT_LIST_BACK">SC_ELEMENT_LIST_BACK : colouralpha</a><br />
|
||||
<a class="element" href="#SC_ELEMENT_LIST_SELECTED">SC_ELEMENT_LIST_SELECTED : colouralpha</a><br />
|
||||
@ -6706,6 +6768,16 @@ struct Sci_TextToFindFull {
|
||||
result as the argument to <code>SCI_AUTOCSETSTYLE</code> and <code>SCI_STYLESETFONT</code> and others.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b id="SCI_AUTOCSETIMAGESCALE">SCI_AUTOCSETIMAGESCALE(int scalePercent)</b><br />
|
||||
<b id="SCI_AUTOCGETIMAGESCALE">SCI_AUTOCGETIMAGESCALE → int</b><br />
|
||||
|
||||
Get or set the scale factor in percent for <em>all</em> autocompletion list images. This is useful on macOS with
|
||||
a retina display where each display unit is 2 pixels: use a factor of 200 so that each image pixel is displayed using a screen pixel.
|
||||
The default scale, 100, will stretch each image pixel to cover 4 screen pixels on a retina display.
|
||||
</p>
|
||||
<p>This is currently only implemented for the Qt and GTK platforms.</p>
|
||||
|
||||
<p>
|
||||
<b id="SC_ELEMENT_LIST">SC_ELEMENT_LIST : colouralpha</b><br />
|
||||
<b id="SC_ELEMENT_LIST_BACK">SC_ELEMENT_LIST_BACK : colouralpha</b><br />
|
||||
|
@ -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/scintilla556.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/scintilla557.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/scintilla556.tgz">
|
||||
<a href="https://www.scintilla.org/scintilla557.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.5.6
|
||||
Release 5.5.7
|
||||
</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/scintilla556.zip">zip format</a> (1.8M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla556.tgz">tgz format</a> (1.7M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla557.zip">zip format</a> (1.8M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla557.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>
|
||||
|
@ -593,6 +593,49 @@
|
||||
</tr>
|
||||
</table>
|
||||
<h2 id="Releases">Releases</h2>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/scintilla557.zip">Release 5.5.7</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 8 June 2025.
|
||||
</li>
|
||||
<li>
|
||||
Add SCI_SCROLLVERTICAL method to restore view position and maintain it while performing line wrapping.
|
||||
</li>
|
||||
<li>
|
||||
Add SC_UNDO_SELECTION_HISTORY_SCROLL flag to SCI_SETUNDOSELECTIONHISTORY which controls
|
||||
whether undo and redo restore vertical scroll position.
|
||||
</li>
|
||||
<li>
|
||||
Tweak SC_MARK_BAR to be slightly wider by using next higher whole pixel instead of next lower for margin width / 3.
|
||||
</li>
|
||||
<li>
|
||||
Scale images in autocompletion lists with SCI_AUTOCSETIMAGESCALE to match high DPI screens.
|
||||
Initially only on GTK and Qt.
|
||||
</li>
|
||||
<li>
|
||||
Fix wrapping bug for UTF-8 where \r\n could wrap between the characters.
|
||||
<a href="https://github.com/notepad-plus-plus/notepad-plus-plus/pull/16373">Notepad++ Pull Request #16373</a>.
|
||||
</li>
|
||||
<li>
|
||||
Fix crash during painting when scroll bars changed.
|
||||
<a href="https://sourceforge.net/p/scintilla/bugs/2481/">Bug #2481</a>.
|
||||
</li>
|
||||
<li>
|
||||
On GTK, reset vertical scroll bar synchronously in SCI_SETDOCPOINTER to fix bug where
|
||||
scroll position not restored in non-wrap mode.
|
||||
<a href="https://sourceforge.net/p/scintilla/bugs/2416/">Bug #2416</a>.
|
||||
</li>
|
||||
<li>
|
||||
On GTK, fix IME problem when tentative composition interfered with delete surrounding.
|
||||
<a href="https://sourceforge.net/p/scintilla/feature-requests/1476/">Feature #1476</a>.
|
||||
</li>
|
||||
<li>
|
||||
On GTK, update IME cursor position inside retrieve surrounding to better position candidate window.
|
||||
<a href="https://sourceforge.net/p/scintilla/feature-requests/1488/">Feature #1488</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/scintilla556.zip">Release 5.5.6</a>
|
||||
</h3>
|
||||
|
@ -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="20250402" />
|
||||
<meta name="Date.Modified" content="20250608" />
|
||||
<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.5.6<br />
|
||||
Site last modified April 2 2025</font>
|
||||
<font color="#FFCC99" size="3"> Release version 5.5.7<br />
|
||||
Site last modified June 8 2025</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -77,11 +77,11 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.5.7 can prevent storing scroll position in undo selection history and adds a wrap-aware SCI_SCROLLVERTICAL API.</li>
|
||||
<li>Version 5.5.6 improves DBCS and autocompletion drawing on Win32 and improves dwell, encoding and text clipping on Qt.</li>
|
||||
<li>Version 5.5.5 can remember selection with undo and redo. Update to use DirectWrite 1.1.</li>
|
||||
<li>Version 5.5.4 fixes wrapping of removed lines and edge cases for moving lines. On GTK, middle click can be repeated with one value.</li>
|
||||
<li>Version 5.5.3 fixes horizontal scrolling with a touchpad on Win32.</li>
|
||||
<li>Version 5.5.2 adds multiple selection copy with separator, a font stretch setting, and access to whether an undo sequence is active.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
@ -27,6 +27,9 @@
|
||||
#if defined(GDK_WINDOWING_WAYLAND)
|
||||
#include <gdk/gdkwayland.h>
|
||||
#endif
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
#include <cairo/cairo-gobject.h>
|
||||
#endif
|
||||
|
||||
#include "ScintillaTypes.h"
|
||||
#include "ScintillaMessages.h"
|
||||
@ -1432,6 +1435,7 @@ class ListBoxX : public ListBox {
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
std::unique_ptr<GtkCssProvider, GObjectReleaser> cssProvider;
|
||||
#endif
|
||||
float imageScale;
|
||||
public:
|
||||
IListBoxDelegate *delegate;
|
||||
|
||||
@ -1439,7 +1443,7 @@ public:
|
||||
pixhash(nullptr), pixbuf_renderer(nullptr),
|
||||
renderer(nullptr),
|
||||
desiredVisibleRows(5), maxItemCharacters(0),
|
||||
aveCharWidth(1),
|
||||
aveCharWidth(1), imageScale(1.0),
|
||||
delegate(nullptr) {
|
||||
}
|
||||
// Deleted so ListBoxX objects can not be copied.
|
||||
@ -1673,7 +1677,13 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, Technology) {
|
||||
|
||||
/* Tree and its model */
|
||||
GtkListStore *store =
|
||||
gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
|
||||
gtk_list_store_new(N_COLUMNS,
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
CAIRO_GOBJECT_TYPE_SURFACE,
|
||||
#else
|
||||
GDK_TYPE_PIXBUF,
|
||||
#endif
|
||||
G_TYPE_STRING);
|
||||
|
||||
list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
g_signal_connect(G_OBJECT(list), "style-set", G_CALLBACK(StyleSet), nullptr);
|
||||
@ -1701,7 +1711,13 @@ void ListBoxX::Create(Window &parent, int, Point, int, bool, Technology) {
|
||||
gtk_cell_renderer_set_fixed_size(pixbuf_renderer, 0, -1);
|
||||
gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE);
|
||||
gtk_tree_view_column_add_attribute(column, pixbuf_renderer,
|
||||
"pixbuf", PIXBUF_COLUMN);
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
"surface",
|
||||
#else
|
||||
"pixbuf",
|
||||
#endif
|
||||
PIXBUF_COLUMN);
|
||||
|
||||
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
gtk_cell_renderer_text_set_fixed_height_from_font(GTK_CELL_RENDERER_TEXT(renderer), 1);
|
||||
@ -1915,11 +1931,20 @@ void ListBoxX::Append(char *s, int type) {
|
||||
if (nullptr == list_image->pixbuf)
|
||||
init_pixmap(list_image);
|
||||
if (list_image->pixbuf) {
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
cairo_surface_t *surface = gdk_cairo_surface_create_from_pixbuf(list_image->pixbuf, imageScale, nullptr);
|
||||
gtk_list_store_set(GTK_LIST_STORE(store), &iter,
|
||||
PIXBUF_COLUMN, surface,
|
||||
TEXT_COLUMN, s, -1);
|
||||
|
||||
const gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf) / imageScale;
|
||||
#else
|
||||
gtk_list_store_set(GTK_LIST_STORE(store), &iter,
|
||||
PIXBUF_COLUMN, list_image->pixbuf,
|
||||
TEXT_COLUMN, s, -1);
|
||||
|
||||
const gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf);
|
||||
#endif
|
||||
gint renderer_height, renderer_width;
|
||||
gtk_cell_renderer_get_fixed_size(pixbuf_renderer,
|
||||
&renderer_width, &renderer_height);
|
||||
@ -2125,7 +2150,8 @@ void ListBoxX::SetList(const char *listText, char separator, char typesep) {
|
||||
}
|
||||
}
|
||||
|
||||
void ListBoxX::SetOptions(ListOptions) {
|
||||
void ListBoxX::SetOptions(ListOptions options_) {
|
||||
imageScale = options_.imageScale;
|
||||
}
|
||||
|
||||
Menu::Menu() noexcept : mid(nullptr) {}
|
||||
|
@ -1102,6 +1102,7 @@ void ScintillaGTK::ScrollText(Sci::Line linesToMove) {
|
||||
}
|
||||
|
||||
void ScintillaGTK::SetVerticalScrollPos() {
|
||||
Editor::SetVerticalScrollPos();
|
||||
DwellEnd(true);
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustmentv), static_cast<gdouble>(topLine));
|
||||
}
|
||||
@ -2375,29 +2376,6 @@ bool ScintillaGTK::KoreanIME() {
|
||||
return lastNonCommonScript == G_UNICODE_SCRIPT_HANGUL;
|
||||
}
|
||||
|
||||
void ScintillaGTK::MoveImeCarets(Sci::Position pos) {
|
||||
// Move carets relatively by bytes
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
const Sci::Position positionInsert = sel.Range(r).Start().Position();
|
||||
sel.Range(r) = SelectionRange(positionInsert + pos);
|
||||
}
|
||||
}
|
||||
|
||||
void ScintillaGTK::DrawImeIndicator(int indicator, Sci::Position len) {
|
||||
// Emulate the visual style of IME characters with indicators.
|
||||
// Draw an indicator on the character before caret by the character bytes of len
|
||||
// so it should be called after InsertCharacter().
|
||||
// It does not affect caret positions.
|
||||
if (indicator < 8 || indicator > INDICATOR_MAX) {
|
||||
return;
|
||||
}
|
||||
pdoc->DecorationSetCurrentIndicator(indicator);
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
const Sci::Position positionInsert = sel.Range(r).Start().Position();
|
||||
pdoc->DecorationFillRange(positionInsert - len, 1, len);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<int> MapImeIndicators(PangoAttrList *attrs, const char *u8Str) {
|
||||
@ -2624,24 +2602,16 @@ bool ScintillaGTK::RetrieveSurroundingThis(GtkIMContext *context) {
|
||||
const Sci::Position startByte = pdoc->LineStart(line);
|
||||
const Sci::Position endByte = pdoc->LineEnd(line);
|
||||
|
||||
std::string utf8Text;
|
||||
gint cursorIndex; // index of the cursor inside utf8Text, in bytes
|
||||
const char *charSetBuffer;
|
||||
std::string utf8Text = UTF8FromEncoded(RangeText(startByte, endByte));
|
||||
gint cursorIndex = UTF8FromEncoded(RangeText(startByte, pos)).length();
|
||||
|
||||
if (IsUnicodeMode() || ! *(charSetBuffer = CharacterSetID())) {
|
||||
utf8Text = RangeText(startByte, endByte);
|
||||
cursorIndex = pos - startByte;
|
||||
if (pdoc->TentativeActive()) {
|
||||
// Prepare one line feed with no preedit under PreeditChangedInlineThis();
|
||||
} else {
|
||||
// Need to convert
|
||||
std::string tmpbuf = RangeText(startByte, pos);
|
||||
utf8Text = ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false);
|
||||
cursorIndex = utf8Text.length();
|
||||
if (endByte > pos) {
|
||||
tmpbuf = RangeText(pos, endByte);
|
||||
utf8Text += ConvertText(&tmpbuf[0], tmpbuf.length(), "UTF-8", charSetBuffer, false);
|
||||
}
|
||||
// reconvert key triggers CandidateBox to show up
|
||||
// when quick phrase input on fcitx (or maybe accented input on mac)
|
||||
SetCandidateWindowPos();
|
||||
}
|
||||
|
||||
gtk_im_context_set_surrounding(context, &utf8Text[0], utf8Text.length(), cursorIndex);
|
||||
|
||||
return true;
|
||||
@ -2657,6 +2627,10 @@ gboolean ScintillaGTK::RetrieveSurrounding(GtkIMContext *context, ScintillaGTK *
|
||||
|
||||
bool ScintillaGTK::DeleteSurroundingThis(GtkIMContext *, gint characterOffset, gint characterCount) {
|
||||
try {
|
||||
if (pdoc->TentativeActive()) {
|
||||
// First remove composition text so that correct surrounding text is deleted.
|
||||
pdoc->TentativeUndo();
|
||||
}
|
||||
const Sci::Position startByte = pdoc->GetRelativePosition(CurrentPosition(), characterOffset);
|
||||
if (startByte == INVALID_POSITION)
|
||||
return false;
|
||||
@ -3120,6 +3094,8 @@ void ScintillaGTK::SetDocPointer(Document *document) {
|
||||
|
||||
Editor::SetDocPointer(document);
|
||||
|
||||
ChangeScrollBars();
|
||||
|
||||
if (sciAccessible) {
|
||||
// the accessible needs have the old Document, but also the new one active
|
||||
sciAccessible->ChangeDocument(oldDoc, pdoc);
|
||||
|
@ -243,8 +243,6 @@ private:
|
||||
bool DeleteSurroundingThis(GtkIMContext *context, gint characterOffset, gint characterCount);
|
||||
static gboolean DeleteSurrounding(GtkIMContext *context, gint characterOffset, gint characterCount,
|
||||
ScintillaGTK *sciThis);
|
||||
void MoveImeCarets(Sci::Position pos);
|
||||
void DrawImeIndicator(int indicator, Sci::Position len);
|
||||
void SetCandidateWindowPos();
|
||||
|
||||
static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void *);
|
||||
|
@ -478,6 +478,8 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
|
||||
#define SCI_AUTOCGETMAXHEIGHT 2211
|
||||
#define SCI_AUTOCSETSTYLE 2109
|
||||
#define SCI_AUTOCGETSTYLE 2120
|
||||
#define SCI_AUTOCSETIMAGESCALE 2815
|
||||
#define SCI_AUTOCGETIMAGESCALE 2816
|
||||
#define SCI_SETINDENT 2122
|
||||
#define SCI_GETINDENT 2123
|
||||
#define SCI_SETUSETABS 2124
|
||||
@ -541,6 +543,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
|
||||
#define SCI_GETCHANGEHISTORY 2781
|
||||
#define SC_UNDO_SELECTION_HISTORY_DISABLED 0
|
||||
#define SC_UNDO_SELECTION_HISTORY_ENABLED 1
|
||||
#define SC_UNDO_SELECTION_HISTORY_SCROLL 2
|
||||
#define SCI_SETUNDOSELECTIONHISTORY 2782
|
||||
#define SCI_GETUNDOSELECTIONHISTORY 2783
|
||||
#define SCI_SETSELECTIONSERIALIZED 2784
|
||||
@ -567,6 +570,7 @@ typedef sptr_t (*SciFnDirectStatus)(sptr_t ptr, unsigned int iMessage, uptr_t wP
|
||||
#define SCI_LINEFROMPOSITION 2166
|
||||
#define SCI_POSITIONFROMLINE 2167
|
||||
#define SCI_LINESCROLL 2168
|
||||
#define SCI_SCROLLVERTICAL 2817
|
||||
#define SCI_SCROLLCARET 2169
|
||||
#define SCI_SCROLLRANGE 2569
|
||||
#define SCI_REPLACESEL 2170
|
||||
|
@ -1174,6 +1174,12 @@ set void AutoCSetStyle=2109(int style,)
|
||||
# Get the style number used for auto-completion and user lists fonts.
|
||||
get int AutoCGetStyle=2120(,)
|
||||
|
||||
# Set the scale factor in percent for auto-completion list images.
|
||||
set void AutoCSetImageScale=2815(int scalePercent,)
|
||||
|
||||
# Get the scale factor in percent for auto-completion list images.
|
||||
get int AutoCGetImageScale=2816(,)
|
||||
|
||||
# Set the number of spaces used for one level of indentation.
|
||||
set void SetIndent=2122(int indentSize,)
|
||||
|
||||
@ -1337,6 +1343,7 @@ get ChangeHistoryOption GetChangeHistory=2781(,)
|
||||
enu UndoSelectionHistoryOption=SC_UNDO_SELECTION_HISTORY_
|
||||
val SC_UNDO_SELECTION_HISTORY_DISABLED=0
|
||||
val SC_UNDO_SELECTION_HISTORY_ENABLED=1
|
||||
val SC_UNDO_SELECTION_HISTORY_SCROLL=2
|
||||
|
||||
# Enable or disable undo selection history.
|
||||
set void SetUndoSelectionHistory=2782(UndoSelectionHistoryOption undoSelectionHistory,)
|
||||
@ -1415,6 +1422,9 @@ fun position PositionFromLine=2167(line line,)
|
||||
# Scroll horizontally and vertically.
|
||||
fun void LineScroll=2168(position columns, line lines)
|
||||
|
||||
# Scroll vertically with allowance for wrapping.
|
||||
fun void ScrollVertical=2817(line docLine, line subLine)
|
||||
|
||||
# Ensure the caret is visible.
|
||||
fun void ScrollCaret=2169(,)
|
||||
|
||||
@ -1565,7 +1575,7 @@ fun void CallTipCancel=2201(,)
|
||||
fun bool CallTipActive=2202(,)
|
||||
|
||||
# Retrieve the position where the caret was before displaying the call tip.
|
||||
fun position CallTipPosStart=2203(,)
|
||||
get position CallTipPosStart=2203(,)
|
||||
|
||||
# Set the start position in order to change when backspacing removes the calltip.
|
||||
set void CallTipSetPosStart=2214(position posStart,)
|
||||
|
@ -324,6 +324,8 @@ public:
|
||||
int AutoCGetMaxHeight();
|
||||
void AutoCSetStyle(int style);
|
||||
int AutoCGetStyle();
|
||||
void AutoCSetImageScale(int scalePercent);
|
||||
int AutoCGetImageScale();
|
||||
void SetIndent(int indentSize);
|
||||
int Indent();
|
||||
void SetUseTabs(bool useTabs);
|
||||
@ -387,6 +389,7 @@ public:
|
||||
Line LineFromPosition(Position pos);
|
||||
Position PositionFromLine(Line line);
|
||||
void LineScroll(Position columns, Line lines);
|
||||
void ScrollVertical(Line docLine, Line subLine);
|
||||
void ScrollCaret();
|
||||
void ScrollRange(Position secondary, Position primary);
|
||||
void ReplaceSel(const char *text);
|
||||
|
@ -249,6 +249,8 @@ enum class Message {
|
||||
AutoCGetMaxHeight = 2211,
|
||||
AutoCSetStyle = 2109,
|
||||
AutoCGetStyle = 2120,
|
||||
AutoCSetImageScale = 2815,
|
||||
AutoCGetImageScale = 2816,
|
||||
SetIndent = 2122,
|
||||
GetIndent = 2123,
|
||||
SetUseTabs = 2124,
|
||||
@ -309,6 +311,7 @@ enum class Message {
|
||||
LineFromPosition = 2166,
|
||||
PositionFromLine = 2167,
|
||||
LineScroll = 2168,
|
||||
ScrollVertical = 2817,
|
||||
ScrollCaret = 2169,
|
||||
ScrollRange = 2569,
|
||||
ReplaceSel = 2170,
|
||||
|
@ -303,6 +303,7 @@ enum class ChangeHistoryOption {
|
||||
enum class UndoSelectionHistoryOption {
|
||||
Disabled = 0,
|
||||
Enabled = 1,
|
||||
Scroll = 2,
|
||||
};
|
||||
|
||||
enum class FoldLevel {
|
||||
|
@ -13,7 +13,7 @@ TEMPLATE = lib
|
||||
CONFIG += lib_bundle
|
||||
CONFIG += c++1z
|
||||
|
||||
VERSION = 5.5.6
|
||||
VERSION = 5.5.7
|
||||
|
||||
SOURCES += \
|
||||
ScintillaEdit.cpp \
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <QTextLayout>
|
||||
#include <QTextLine>
|
||||
#include <QLibrary>
|
||||
#include <QtMath>
|
||||
|
||||
using namespace Scintilla;
|
||||
|
||||
@ -994,6 +995,7 @@ private:
|
||||
bool unicodeMode{false};
|
||||
int visibleRows{5};
|
||||
QMap<int,QPixmap> images;
|
||||
float imageScale{1.0};
|
||||
};
|
||||
ListBoxImpl::ListBoxImpl() noexcept = default;
|
||||
|
||||
@ -1034,10 +1036,11 @@ void ListBoxImpl::Create(Window &parent,
|
||||
int maxIconWidth = 0;
|
||||
int maxIconHeight = 0;
|
||||
foreach (QPixmap im, images) {
|
||||
if (maxIconWidth < im.width())
|
||||
maxIconWidth = im.width();
|
||||
if (maxIconHeight < im.height())
|
||||
maxIconHeight = im.height();
|
||||
im.setDevicePixelRatio(imageScale);
|
||||
if (maxIconWidth < im.width() / im.devicePixelRatio())
|
||||
maxIconWidth = im.width() / im.devicePixelRatio();
|
||||
if (maxIconHeight < im.height() / im.devicePixelRatio())
|
||||
maxIconHeight = im.height() / im.devicePixelRatio();
|
||||
}
|
||||
list->setIconSize(QSize(maxIconWidth, maxIconHeight));
|
||||
|
||||
@ -1085,8 +1088,8 @@ int ListBoxImpl::CaretFromEdge()
|
||||
ListWidget *list = GetWidget();
|
||||
int maxIconWidth = 0;
|
||||
foreach (QPixmap im, images) {
|
||||
if (maxIconWidth < im.width())
|
||||
maxIconWidth = im.width();
|
||||
if (maxIconWidth < im.width() / im.devicePixelRatio())
|
||||
maxIconWidth = im.width() / im.devicePixelRatio();
|
||||
}
|
||||
|
||||
int extra;
|
||||
@ -1165,9 +1168,9 @@ void ListBoxImpl::RegisterQPixmapImage(int type, const QPixmap& pm)
|
||||
ListWidget *list = GetWidget();
|
||||
if (list) {
|
||||
QSize iconSize = list->iconSize();
|
||||
if (pm.width() > iconSize.width() || pm.height() > iconSize.height())
|
||||
list->setIconSize(QSize(qMax(pm.width(), iconSize.width()),
|
||||
qMax(pm.height(), iconSize.height())));
|
||||
if (pm.width() / pm.devicePixelRatio() > iconSize.width() || pm.height() / pm.devicePixelRatio() > iconSize.height())
|
||||
list->setIconSize(QSize(qMax(qFloor(pm.width() / pm.devicePixelRatio()), iconSize.width()),
|
||||
qMax(qFloor(pm.height() / pm.devicePixelRatio()), iconSize.height())));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1226,8 +1229,9 @@ void ListBoxImpl::SetList(const char *list, char separator, char typesep)
|
||||
Append(startword, numword?atoi(numword + 1):-1);
|
||||
}
|
||||
}
|
||||
void ListBoxImpl::SetOptions(ListOptions)
|
||||
void ListBoxImpl::SetOptions(ListOptions options_)
|
||||
{
|
||||
imageScale = options_.imageScale;
|
||||
}
|
||||
ListWidget *ListBoxImpl::GetWidget() const noexcept
|
||||
{
|
||||
|
@ -21,11 +21,6 @@
|
||||
#include <QScrollBar>
|
||||
#include <QTextFormat>
|
||||
|
||||
constexpr int IndicatorInput = static_cast<int>(Scintilla::IndicatorNumbers::Ime);
|
||||
constexpr int IndicatorTarget = IndicatorInput + 1;
|
||||
constexpr int IndicatorConverted = IndicatorInput + 2;
|
||||
constexpr int IndicatorUnknown = IndicatorInput + 3;
|
||||
|
||||
// Q_WS_MAC and Q_WS_X11 aren't defined in Qt5
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#ifdef Q_OS_MAC
|
||||
@ -458,31 +453,6 @@ bool ScintillaEditBase::IsHangul(const QChar qchar)
|
||||
HangulJamoExtendedA || HangulJamoExtendedB;
|
||||
}
|
||||
|
||||
void ScintillaEditBase::MoveImeCarets(Scintilla::Position offset)
|
||||
{
|
||||
// Move carets relatively by bytes
|
||||
for (size_t r=0; r < sqt->sel.Count(); r++) {
|
||||
const Sci::Position positionInsert = sqt->sel.Range(r).Start().Position();
|
||||
sqt->sel.Range(r) = SelectionRange(positionInsert + offset);
|
||||
}
|
||||
}
|
||||
|
||||
void ScintillaEditBase::DrawImeIndicator(int indicator, int len)
|
||||
{
|
||||
// Emulate the visual style of IME characters with indicators.
|
||||
// Draw an indicator on the character before caret by the character bytes of len
|
||||
// so it should be called after InsertCharacter().
|
||||
// It does not affect caret positions.
|
||||
if (indicator < INDICATOR_CONTAINER || indicator > INDICATOR_MAX) {
|
||||
return;
|
||||
}
|
||||
sqt->pdoc->DecorationSetCurrentIndicator(indicator);
|
||||
for (size_t r=0; r< sqt-> sel.Count(); r++) {
|
||||
const Sci::Position positionInsert = sqt->sel.Range(r).Start().Position();
|
||||
sqt->pdoc->DecorationFillRange(positionInsert - len, 1, len);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
int GetImeCaretPos(QInputMethodEvent *event)
|
||||
@ -613,7 +583,7 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)
|
||||
|
||||
sqt->InsertCharacter(std::string_view(oneChar.data(), oneCharLen), CharacterSource::TentativeInput);
|
||||
|
||||
DrawImeIndicator(imeIndicator[i], oneCharLen);
|
||||
sqt->DrawImeIndicator(imeIndicator[i], oneCharLen);
|
||||
i += ucWidth;
|
||||
}
|
||||
|
||||
@ -622,13 +592,13 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)
|
||||
const int imeEndToImeCaretU16 = imeCaretPos - preeditStrLen;
|
||||
const Sci::Position imeCaretPosDoc = sqt->pdoc->GetRelativePositionUTF16(sqt->CurrentPosition(), imeEndToImeCaretU16);
|
||||
|
||||
MoveImeCarets(- sqt->CurrentPosition() + imeCaretPosDoc);
|
||||
sqt->MoveImeCarets(- sqt->CurrentPosition() + imeCaretPosDoc);
|
||||
|
||||
if (IsHangul(preeditStr.at(0))) {
|
||||
#ifndef Q_OS_WIN
|
||||
if (imeCaretPos > 0) {
|
||||
int oneCharBefore = sqt->pdoc->GetRelativePosition(sqt->CurrentPosition(), -1);
|
||||
MoveImeCarets(- sqt->CurrentPosition() + oneCharBefore);
|
||||
sqt->MoveImeCarets(- sqt->CurrentPosition() + oneCharBefore);
|
||||
}
|
||||
#endif
|
||||
sqt->view.imeCaretBlockOverride = true;
|
||||
|
@ -162,8 +162,6 @@ private:
|
||||
int wheelDelta;
|
||||
|
||||
static bool IsHangul(const QChar qchar);
|
||||
void MoveImeCarets(Scintilla::Position offset);
|
||||
void DrawImeIndicator(int indicator, int len);
|
||||
static Scintilla::KeyMod ModifiersOfKeyboard();
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,7 @@ TEMPLATE = lib
|
||||
CONFIG += lib_bundle
|
||||
CONFIG += c++1z
|
||||
|
||||
VERSION = 5.5.6
|
||||
VERSION = 5.5.7
|
||||
|
||||
SOURCES += \
|
||||
PlatQt.cpp \
|
||||
|
@ -280,6 +280,7 @@ void ScintillaQt::ScrollText(Sci::Line linesToMove)
|
||||
|
||||
void ScintillaQt::SetVerticalScrollPos()
|
||||
{
|
||||
Editor::SetVerticalScrollPos();
|
||||
scrollArea->verticalScrollBar()->setValue(topLine);
|
||||
emit verticalScrolled(topLine);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// All platform headers should be included before Scintilla headers
|
||||
// and each of these groups are then divided into directory groups.
|
||||
|
||||
// Qt platform layer not handled as it doesn't define a strong ordering of headers.
|
||||
|
||||
// Base of the repository relative to this file
|
||||
|
||||
//base:..
|
||||
@ -16,8 +18,6 @@
|
||||
//source:cocoa/*.mm
|
||||
//source:cocoa/*.h
|
||||
//source:test/unit/*.cxx
|
||||
//source:lexilla/src/*.cxx
|
||||
//source:lexilla/test/*.cxx
|
||||
|
||||
// C standard library
|
||||
#include <stddef.h>
|
||||
@ -71,6 +71,7 @@
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkwayland.h>
|
||||
#include <gtk/gtk-a11y.h>
|
||||
#include <cairo/cairo-gobject.h>
|
||||
|
||||
// Windows headers
|
||||
#include <windows.h>
|
||||
|
@ -41,6 +41,7 @@ AutoComplete::AutoComplete() :
|
||||
ignoreCase(false),
|
||||
chooseSingle(false),
|
||||
options(AutoCompleteOption::Normal),
|
||||
imageScale(1.0),
|
||||
posStart(0),
|
||||
startLen(0),
|
||||
cancelAtStartPos(true),
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
bool ignoreCase;
|
||||
bool chooseSingle;
|
||||
AutoCompleteOption options;
|
||||
float imageScale;
|
||||
std::unique_ptr<ListBox> lb;
|
||||
Sci::Position posStart;
|
||||
Sci::Position startLen;
|
||||
|
@ -95,9 +95,8 @@ int CallTip::NextTabPos(int x) const noexcept {
|
||||
x -= insetX; // position relative to text
|
||||
x = (x + tabSize) / tabSize; // tab "number"
|
||||
return tabSize*x + insetX; // position of next tab
|
||||
} else {
|
||||
return x + 1; // arbitrary
|
||||
}
|
||||
return x + 1; // arbitrary
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -4072,6 +4072,10 @@ namespace {
|
||||
|
||||
enum class OtherID { oidNone, oidStart, oidContinue };
|
||||
|
||||
// Silence 'magic' number warning as these character values are not used in multiple places.
|
||||
|
||||
// NOLINTBEGIN(*-magic-numbers)
|
||||
|
||||
// Some characters are treated as valid for identifiers even
|
||||
// though most characters from their category are not.
|
||||
// Values copied from http://www.unicode.org/Public/9.0.0/ucd/PropList.txt
|
||||
@ -4161,6 +4165,8 @@ bool OmitXidContinue(int character) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTEND(*-magic-numbers)
|
||||
|
||||
}
|
||||
|
||||
// UAX #31 defines ID_Start as
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
Sci::Line LinesInDoc() const noexcept override;
|
||||
Sci::Line LinesDisplayed() const noexcept override;
|
||||
Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept override;
|
||||
Sci::Line DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept override;
|
||||
Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept override;
|
||||
Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept override;
|
||||
|
||||
@ -183,6 +184,12 @@ Sci::Line ContractionState<LINE>::DisplayFromDoc(Sci::Line lineDoc) const noexce
|
||||
}
|
||||
}
|
||||
|
||||
template <typename LINE>
|
||||
Sci::Line ContractionState<LINE>::DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept {
|
||||
return DisplayFromDoc(lineDoc) +
|
||||
std::min(lineSub, static_cast<Sci::Line>(GetHeight(lineDoc) - 1));
|
||||
}
|
||||
|
||||
template <typename LINE>
|
||||
Sci::Line ContractionState<LINE>::DisplayLastFromDoc(Sci::Line lineDoc) const noexcept {
|
||||
return DisplayFromDoc(lineDoc) + GetHeight(lineDoc) - 1;
|
||||
|
@ -21,6 +21,7 @@ public:
|
||||
virtual Sci::Line LinesInDoc() const noexcept=0;
|
||||
virtual Sci::Line LinesDisplayed() const noexcept=0;
|
||||
virtual Sci::Line DisplayFromDoc(Sci::Line lineDoc) const noexcept=0;
|
||||
virtual Sci::Line DisplayFromDocSub(Sci::Line lineDoc, Sci::Line lineSub) const noexcept=0;
|
||||
virtual Sci::Line DisplayLastFromDoc(Sci::Line lineDoc) const noexcept=0;
|
||||
virtual Sci::Line DocFromDisplay(Sci::Line lineDisplay) const noexcept=0;
|
||||
|
||||
|
@ -16,6 +16,12 @@ using namespace Scintilla::Internal;
|
||||
|
||||
namespace Scintilla::Internal {
|
||||
|
||||
// Silence 'magic' number use since the set of DBCS lead and trail bytes differ
|
||||
// between encodings and would require many constant declarations that would just
|
||||
// obscure the behaviour.
|
||||
|
||||
// NOLINTBEGIN(*-magic-numbers)
|
||||
|
||||
bool DBCSIsLeadByte(int codePage, char ch) noexcept {
|
||||
// Byte ranges found in Wikipedia articles with relevant search strings in each case
|
||||
const unsigned char uch = ch;
|
||||
@ -91,6 +97,8 @@ bool IsDBCSValidSingleByte(int codePage, int ch) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTEND(*-magic-numbers)
|
||||
|
||||
using CodePageToFoldMap = std::map<int, FoldMap>;
|
||||
CodePageToFoldMap cpToFoldMap;
|
||||
|
||||
|
@ -28,14 +28,12 @@ bool DBCSIsLeadByte(int codePage, char ch) noexcept;
|
||||
bool DBCSIsTrailByte(int codePage, char ch) noexcept;
|
||||
bool IsDBCSValidSingleByte(int codePage, int ch) noexcept;
|
||||
|
||||
// Calculate a number from a DBCS byte pair that can be used to index into an array or map.
|
||||
// Calculate a number from a DBCS byte pair that can be used to index into an array or map.
|
||||
// Should only be called with genuine DBCS character pairs which means that ch1 has top bit set.
|
||||
constexpr uint16_t DBCSIndex(char ch1, char ch2) noexcept {
|
||||
constexpr unsigned int highStart = 0x80U;
|
||||
constexpr unsigned int byteMultiply = 0x100U;
|
||||
const unsigned char uch1 = ch1;
|
||||
const unsigned char uch1 = ch1 & 0x7F;
|
||||
const unsigned char uch2 = ch2;
|
||||
return ((uch1 - highStart) * byteMultiply) + uch2;
|
||||
return (uch1 << 8) | uch2;
|
||||
}
|
||||
|
||||
struct DBCSPair {
|
||||
|
@ -120,7 +120,7 @@ void ActionDuration::AddSample(size_t numberActions, double durationOfActions) n
|
||||
// Most recent value contributes 25% to smoothed value.
|
||||
constexpr double alpha = 0.25;
|
||||
|
||||
const double durationOne = durationOfActions / numberActions;
|
||||
const double durationOne = durationOfActions / static_cast<double>(numberActions);
|
||||
duration = std::clamp(alpha * durationOne + (1.0 - alpha) * duration,
|
||||
minDuration, maxDuration);
|
||||
}
|
||||
@ -260,8 +260,7 @@ LineAnnotation *Document::EOLAnnotations() const noexcept {
|
||||
LineEndType Document::LineEndTypesSupported() const {
|
||||
if ((CpUtf8 == dbcsCodePage) && pli)
|
||||
return pli->LineEndTypesSupported();
|
||||
else
|
||||
return LineEndType::Default;
|
||||
return LineEndType::Default;
|
||||
}
|
||||
|
||||
bool Document::SetDBCSCodePage(int dbcsCodePage_) {
|
||||
@ -272,9 +271,8 @@ bool Document::SetDBCSCodePage(int dbcsCodePage_) {
|
||||
cb.SetUTF8Substance(CpUtf8 == dbcsCodePage);
|
||||
ModifiedAt(0); // Need to restyle whole document
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Document::SetLineEndTypesAllowed(LineEndType lineEndBitSet_) {
|
||||
@ -285,12 +283,9 @@ bool Document::SetLineEndTypesAllowed(LineEndType lineEndBitSet_) {
|
||||
ModifiedAt(0);
|
||||
cb.SetLineEndTypes(lineEndBitSetActive);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Document::SetSavePoint() {
|
||||
@ -453,9 +448,8 @@ int Document::AddMark(Sci::Line line, int markerNum) {
|
||||
const DocModification mh(ModificationFlags::ChangeMarker, LineStart(line), 0, 0, nullptr, line);
|
||||
NotifyModified(mh);
|
||||
return prev;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Document::AddMarkSet(Sci::Line line, int valueSet) {
|
||||
@ -632,14 +626,14 @@ constexpr bool IsSubordinate(FoldLevel levelStart, FoldLevel levelTry) noexcept
|
||||
|
||||
Sci::Line Document::GetLastChild(Sci::Line lineParent, std::optional<FoldLevel> level, Sci::Line lastLine) {
|
||||
const FoldLevel levelStart = LevelNumberPart(level ? *level : GetFoldLevel(lineParent));
|
||||
const Sci::Line maxLine = LinesTotal();
|
||||
const Sci::Line lookLastLine = (lastLine != -1) ? std::min(LinesTotal() - 1, lastLine) : -1;
|
||||
const Sci::Line maxLine = LinesTotal() - 1;
|
||||
const Sci::Line lookLastLine = (lastLine != -1) ? std::min(maxLine, lastLine) : maxLine;
|
||||
Sci::Line lineMaxSubord = lineParent;
|
||||
while (lineMaxSubord < maxLine - 1) {
|
||||
while (lineMaxSubord < maxLine) {
|
||||
EnsureStyledTo(LineStart(lineMaxSubord + 2));
|
||||
if (!IsSubordinate(levelStart, GetFoldLevel(lineMaxSubord + 1)))
|
||||
break;
|
||||
if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !LevelIsWhitespace(GetFoldLevel(lineMaxSubord)))
|
||||
if ((lineMaxSubord >= lookLastLine) && !LevelIsWhitespace(GetFoldLevel(lineMaxSubord)))
|
||||
break;
|
||||
lineMaxSubord++;
|
||||
}
|
||||
@ -763,15 +757,13 @@ int Document::LenChar(Sci::Position pos) const noexcept {
|
||||
if (utf8status & UTF8MaskInvalid) {
|
||||
// Treat as invalid and use up just one byte
|
||||
return 1;
|
||||
} else {
|
||||
return utf8status & UTF8MaskWidth;
|
||||
}
|
||||
return utf8status & UTF8MaskWidth;
|
||||
}
|
||||
if (IsDBCSLeadByteNoExcept(leadByte) && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1))) {
|
||||
return 2;
|
||||
} else {
|
||||
if (IsDBCSLeadByteNoExcept(leadByte) && IsDBCSTrailByteNoExcept(cb.CharAt(pos + 1))) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,21 +777,20 @@ bool Document::InGoodUTF8(Sci::Position pos, Sci::Position &start, Sci::Position
|
||||
const int widthCharBytes = UTF8BytesOfLead[leadByte];
|
||||
if (widthCharBytes == 1) {
|
||||
return false;
|
||||
} else {
|
||||
const int trailBytes = widthCharBytes - 1;
|
||||
const Sci::Position len = pos - start;
|
||||
if (len > trailBytes)
|
||||
// pos too far from lead
|
||||
return false;
|
||||
unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0};
|
||||
for (Sci::Position b=1; b<widthCharBytes && ((start+b) < cb.Length()); b++)
|
||||
charBytes[b] = cb.CharAt(start+b);
|
||||
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
||||
if (utf8status & UTF8MaskInvalid)
|
||||
return false;
|
||||
end = start + widthCharBytes;
|
||||
return true;
|
||||
}
|
||||
const int trailBytes = widthCharBytes - 1;
|
||||
const Sci::Position len = pos - start;
|
||||
if (len > trailBytes)
|
||||
// pos too far from lead
|
||||
return false;
|
||||
unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0};
|
||||
for (Sci::Position b=1; b<widthCharBytes && ((start+b) < cb.Length()); b++)
|
||||
charBytes[b] = cb.CharAt(start+b);
|
||||
const int utf8status = UTF8Classify(charBytes, widthCharBytes);
|
||||
if (utf8status & UTF8MaskInvalid)
|
||||
return false;
|
||||
end = start + widthCharBytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Normalise a position so that it is not part way through a multi-byte character.
|
||||
@ -958,10 +949,9 @@ bool Document::NextCharacter(Sci::Position &pos, int moveDir) const noexcept {
|
||||
Sci::Position posNext = NextPosition(pos, moveDir);
|
||||
if (posNext == pos) {
|
||||
return false;
|
||||
} else {
|
||||
pos = posNext;
|
||||
return true;
|
||||
}
|
||||
pos = posNext;
|
||||
return true;
|
||||
}
|
||||
|
||||
CharacterExtracted Document::CharacterAfter(Sci::Position position) const noexcept {
|
||||
@ -1109,6 +1099,12 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
|
||||
return IsDBCSLeadByteNoExcept(ch);
|
||||
}
|
||||
|
||||
// Silence 'magic' number use since the set of DBCS lead and trail bytes differ
|
||||
// between encodings and would require many constant declarations that would just
|
||||
// obscure the behaviour.
|
||||
|
||||
// NOLINTBEGIN(*-magic-numbers)
|
||||
|
||||
bool Document::IsDBCSLeadByteNoExcept(char ch) const noexcept {
|
||||
// Used inside core Scintilla
|
||||
// Byte ranges found in Wikipedia articles with relevant search strings in each case
|
||||
@ -1192,6 +1188,8 @@ unsigned char Document::DBCSMinTrailByte() const noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTEND(*-magic-numbers)
|
||||
|
||||
int Document::DBCSDrawBytes(std::string_view text) const noexcept {
|
||||
if (text.length() <= 1) {
|
||||
return static_cast<int>(text.length());
|
||||
@ -1218,7 +1216,8 @@ void DiscardEndFragment(std::string_view &text) noexcept {
|
||||
text.remove_suffix(1);
|
||||
} else if (UTF8IsTrailByte(text.back())) {
|
||||
// go back to the start of last character.
|
||||
const size_t maxTrail = std::max<size_t>(UTF8MaxBytes - 1, text.length());
|
||||
constexpr int UTF8MaxTrail = UTF8MaxBytes - 1;
|
||||
const size_t maxTrail = std::max<size_t>(UTF8MaxTrail, text.length());
|
||||
size_t trail = 1;
|
||||
while (trail < maxTrail && UTF8IsTrailByte(text[text.length() - trail])) {
|
||||
trail++;
|
||||
@ -1307,7 +1306,7 @@ std::string CreateIndentation(Sci::Position indent, int tabSize, bool insertSpac
|
||||
bool Scintilla::Internal::DiscardLastCombinedCharacter(std::string_view &text) noexcept {
|
||||
// Handle the simple common case where a base character may be followed by
|
||||
// accents and similar marks by discarding until start of base character.
|
||||
//
|
||||
//
|
||||
// From Grapheme_Cluster_Boundaries
|
||||
// combining character sequence = ccs-base? ccs-extend+
|
||||
// ccs-base := [\p{L}\p{N}\p{P}\p{S}\p{Zs}]
|
||||
@ -1405,10 +1404,9 @@ size_t Document::SafeSegment(std::string_view text) const noexcept {
|
||||
EncodingFamily Document::CodePageFamily() const noexcept {
|
||||
if (CpUtf8 == dbcsCodePage)
|
||||
return EncodingFamily::unicode;
|
||||
else if (dbcsCodePage)
|
||||
if (dbcsCodePage)
|
||||
return EncodingFamily::dbcs;
|
||||
else
|
||||
return EncodingFamily::eightBit;
|
||||
return EncodingFamily::eightBit;
|
||||
}
|
||||
|
||||
void Document::ModifiedAt(Sci::Position pos) noexcept {
|
||||
@ -1448,37 +1446,36 @@ bool Document::DeleteChars(Sci::Position pos, Sci::Position len) {
|
||||
CheckReadOnly();
|
||||
if (enteredModification != 0) {
|
||||
return false;
|
||||
} else {
|
||||
enteredModification++;
|
||||
if (!cb.IsReadOnly()) {
|
||||
if (cb.IsCollectingUndo() && cb.CanRedo()) {
|
||||
// Abandoning some undo actions so truncate any later selections
|
||||
TruncateUndoComments(cb.UndoCurrent());
|
||||
}
|
||||
NotifyModified(
|
||||
DocModification(
|
||||
ModificationFlags::BeforeDelete | ModificationFlags::User,
|
||||
pos, len,
|
||||
0, nullptr));
|
||||
const Sci::Line prevLinesTotal = LinesTotal();
|
||||
const bool startSavePoint = cb.IsSavePoint();
|
||||
bool startSequence = false;
|
||||
const char *text = cb.DeleteChars(pos, len, startSequence);
|
||||
if (startSavePoint && cb.IsCollectingUndo())
|
||||
NotifySavePoint(false);
|
||||
if ((pos < LengthNoExcept()) || (pos == 0))
|
||||
ModifiedAt(pos);
|
||||
else
|
||||
ModifiedAt(pos-1);
|
||||
NotifyModified(
|
||||
DocModification(
|
||||
ModificationFlags::DeleteText | ModificationFlags::User |
|
||||
(startSequence?ModificationFlags::StartAction:ModificationFlags::None),
|
||||
pos, len,
|
||||
LinesTotal() - prevLinesTotal, text));
|
||||
}
|
||||
enteredModification--;
|
||||
}
|
||||
enteredModification++;
|
||||
if (!cb.IsReadOnly()) {
|
||||
if (cb.IsCollectingUndo() && cb.CanRedo()) {
|
||||
// Abandoning some undo actions so truncate any later selections
|
||||
TruncateUndoComments(cb.UndoCurrent());
|
||||
}
|
||||
NotifyModified(
|
||||
DocModification(
|
||||
ModificationFlags::BeforeDelete | ModificationFlags::User,
|
||||
pos, len,
|
||||
0, nullptr));
|
||||
const Sci::Line prevLinesTotal = LinesTotal();
|
||||
const bool startSavePoint = cb.IsSavePoint();
|
||||
bool startSequence = false;
|
||||
const char *text = cb.DeleteChars(pos, len, startSequence);
|
||||
if (startSavePoint && cb.IsCollectingUndo())
|
||||
NotifySavePoint(false);
|
||||
if ((pos < LengthNoExcept()) || (pos == 0))
|
||||
ModifiedAt(pos);
|
||||
else
|
||||
ModifiedAt(pos-1);
|
||||
NotifyModified(
|
||||
DocModification(
|
||||
ModificationFlags::DeleteText | ModificationFlags::User |
|
||||
(startSequence?ModificationFlags::StartAction:ModificationFlags::None),
|
||||
pos, len,
|
||||
LinesTotal() - prevLinesTotal, text));
|
||||
}
|
||||
enteredModification--;
|
||||
return !cb.IsReadOnly();
|
||||
}
|
||||
|
||||
@ -2512,10 +2509,10 @@ Sci::Position Document::FindText(Sci::Position minPos, Sci::Position maxPos, con
|
||||
}
|
||||
|
||||
const char *Document::SubstituteByPosition(const char *text, Sci::Position *length) {
|
||||
if (regex)
|
||||
if (regex) {
|
||||
return regex->SubstituteByPosition(this, text, length);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LineCharacterIndexType Document::LineCharacterIndex() const noexcept {
|
||||
@ -2565,46 +2562,44 @@ void SCI_METHOD Document::StartStyling(Sci_Position position) {
|
||||
bool SCI_METHOD Document::SetStyleFor(Sci_Position length, char style) {
|
||||
if (enteredStyling != 0) {
|
||||
return false;
|
||||
} else {
|
||||
enteredStyling++;
|
||||
const Sci::Position prevEndStyled = endStyled;
|
||||
if (cb.SetStyleFor(endStyled, length, style)) {
|
||||
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
||||
prevEndStyled, length);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
endStyled += length;
|
||||
enteredStyling--;
|
||||
return true;
|
||||
}
|
||||
enteredStyling++;
|
||||
const Sci::Position prevEndStyled = endStyled;
|
||||
if (cb.SetStyleFor(endStyled, length, style)) {
|
||||
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
||||
prevEndStyled, length);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
endStyled += length;
|
||||
enteredStyling--;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SCI_METHOD Document::SetStyles(Sci_Position length, const char *styles) {
|
||||
if (enteredStyling != 0) {
|
||||
return false;
|
||||
} else {
|
||||
enteredStyling++;
|
||||
bool didChange = false;
|
||||
Sci::Position startMod = 0;
|
||||
Sci::Position endMod = 0;
|
||||
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
|
||||
PLATFORM_ASSERT(endStyled < Length());
|
||||
if (cb.SetStyleAt(endStyled, styles[iPos])) {
|
||||
if (!didChange) {
|
||||
startMod = endStyled;
|
||||
}
|
||||
didChange = true;
|
||||
endMod = endStyled;
|
||||
}
|
||||
}
|
||||
if (didChange) {
|
||||
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
||||
startMod, endMod - startMod + 1);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
enteredStyling--;
|
||||
return true;
|
||||
}
|
||||
enteredStyling++;
|
||||
bool didChange = false;
|
||||
Sci::Position startMod = 0;
|
||||
Sci::Position endMod = 0;
|
||||
for (int iPos = 0; iPos < length; iPos++, endStyled++) {
|
||||
PLATFORM_ASSERT(endStyled < Length());
|
||||
if (cb.SetStyleAt(endStyled, styles[iPos])) {
|
||||
if (!didChange) {
|
||||
startMod = endStyled;
|
||||
}
|
||||
didChange = true;
|
||||
endMod = endStyled;
|
||||
}
|
||||
}
|
||||
if (didChange) {
|
||||
const DocModification mh(ModificationFlags::ChangeStyle | ModificationFlags::User,
|
||||
startMod, endMod - startMod + 1);
|
||||
NotifyModified(mh);
|
||||
}
|
||||
enteredStyling--;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Document::EnsureStyledTo(Sci::Position pos) {
|
||||
@ -2640,7 +2635,7 @@ void Document::SetLexInterface(std::unique_ptr<LexInterface> pLexInterface) noex
|
||||
|
||||
void Document::SetViewState(void *view, ViewStateShared pVSS) {
|
||||
if (pVSS) {
|
||||
viewData[view] = pVSS;
|
||||
viewData[view] = std::move(pVSS);
|
||||
} else {
|
||||
viewData.erase(view);
|
||||
}
|
||||
@ -3027,7 +3022,7 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe
|
||||
// Avoid using MovePositionOutsideChar to check DBCS trail byte
|
||||
unsigned char maxSafeChar = 0xff;
|
||||
if (dbcsCodePage != 0 && dbcsCodePage != CpUtf8) {
|
||||
maxSafeChar = DBCSMinTrailByte() - 1;
|
||||
maxSafeChar = std::max<unsigned char>(DBCSMinTrailByte(), 1) - 1;
|
||||
}
|
||||
|
||||
while ((position >= 0) && (position < LengthNoExcept())) {
|
||||
@ -3115,10 +3110,10 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]] char CharAt(Sci::Position index) const noexcept override {
|
||||
if (index < 0 || index >= end)
|
||||
if (index < 0 || index >= end) {
|
||||
return 0;
|
||||
else
|
||||
return pdoc->CharAt(index);
|
||||
}
|
||||
return pdoc->CharAt(index);
|
||||
}
|
||||
[[nodiscard]] Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir) const noexcept override {
|
||||
return pdoc->MovePositionOutsideChar(pos, moveDir, false);
|
||||
|
@ -173,7 +173,7 @@ public:
|
||||
};
|
||||
|
||||
// Base class for view state that can be held and transferred without understanding the contents.
|
||||
// Declared here but real implementation subclass declared in EditModel
|
||||
// Declared here but real implementation subclass declared in EditModel
|
||||
struct ViewState {
|
||||
ViewState() noexcept = default;
|
||||
// Deleted so ViewState objects can not be copied
|
||||
|
@ -172,7 +172,7 @@ int EditModel::GetMark(Sci::Line line) const {
|
||||
}
|
||||
|
||||
void EditModel::EnsureModelState() {
|
||||
if (!modelState && (undoSelectionHistoryOption == UndoSelectionHistoryOption::Enabled)) {
|
||||
if (!modelState && (undoSelectionHistoryOption != UndoSelectionHistoryOption::Disabled)) {
|
||||
if (ViewStateShared vss = pdoc->GetViewState(this)) {
|
||||
modelState = std::dynamic_pointer_cast<ModelState>(vss);
|
||||
} else {
|
||||
|
@ -277,7 +277,7 @@ void EditView::DropGraphics() noexcept {
|
||||
}
|
||||
|
||||
void EditView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) {
|
||||
if (!pixmapIndentGuide) {
|
||||
if (!(pixmapIndentGuide && pixmapIndentGuideHighlight)) {
|
||||
// 1 extra pixel in height so can handle odd/even positions and so produce a continuous line
|
||||
pixmapIndentGuide = surfaceWindow->AllocatePixMap(1, vsDraw.lineHeight + 1);
|
||||
pixmapIndentGuideHighlight = surfaceWindow->AllocatePixMap(1, vsDraw.lineHeight + 1);
|
||||
@ -670,8 +670,8 @@ Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, S
|
||||
pt.y = static_cast<XYPOSITION>(subLine*vs.lineHeight);
|
||||
}
|
||||
}
|
||||
pt.y += (lineVisible - topLine) * vs.lineHeight;
|
||||
pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth;
|
||||
pt.y += static_cast<XYPOSITION>((lineVisible - topLine) * vs.lineHeight);
|
||||
pt.x += pos.VirtualSpaceWidth(vs.styles[ll->EndLineStyle()].spaceWidth);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
@ -958,7 +958,7 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle
|
||||
XYPOSITION virtualSpace = 0;
|
||||
if (lastSubLine) {
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
virtualSpace = model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)) * spaceWidth;
|
||||
virtualSpace = static_cast<XYPOSITION>(model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line))) * spaceWidth;
|
||||
}
|
||||
const XYPOSITION xEol = ll->positions[lineEnd] - subLineStart;
|
||||
|
||||
@ -977,9 +977,9 @@ void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle
|
||||
if (!portion.Empty()) {
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] -
|
||||
subLineStart+portion.start.VirtualSpace() * spaceWidth;
|
||||
subLineStart + portion.start.VirtualSpaceWidth(spaceWidth);
|
||||
rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] -
|
||||
subLineStart+portion.end.VirtualSpace() * spaceWidth;
|
||||
subLineStart + portion.end.VirtualSpaceWidth(spaceWidth);
|
||||
rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left;
|
||||
rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right;
|
||||
surface->FillRectangleAligned(rcSegment, Fill(
|
||||
@ -1149,8 +1149,8 @@ void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, con
|
||||
}
|
||||
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor(
|
||||
model.pdoc->LineEnd(line)) * spaceWidth;
|
||||
const XYPOSITION virtualSpace = static_cast<XYPOSITION>(model.sel.VirtualSpaceFor(
|
||||
model.pdoc->LineEnd(line))) * spaceWidth;
|
||||
rcSegment.left = xStart + ll->positions[ll->numCharsInLine] - subLineStart + virtualSpace + vsDraw.aveCharWidth;
|
||||
rcSegment.right = rcSegment.left + static_cast<XYPOSITION>(widthFoldDisplayText);
|
||||
|
||||
@ -1267,8 +1267,8 @@ void EditView::DrawEOLAnnotationText(Surface *surface, const EditModel &model, c
|
||||
leftBoxSpace + rightBoxSpace);
|
||||
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
const XYPOSITION virtualSpace = model.sel.VirtualSpaceFor(
|
||||
model.pdoc->LineEnd(line)) * spaceWidth;
|
||||
const XYPOSITION virtualSpace = static_cast<XYPOSITION>(model.sel.VirtualSpaceFor(
|
||||
model.pdoc->LineEnd(line))) * spaceWidth;
|
||||
rcSegment.left = xStart +
|
||||
ll->positions[ll->numCharsInLine] - subLineStart
|
||||
+ virtualSpace + vsDraw.aveCharWidth;
|
||||
@ -1518,7 +1518,7 @@ void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewSt
|
||||
}
|
||||
const int offset = static_cast<int>(posCaret.Position() - posLineStart);
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth;
|
||||
const XYPOSITION virtualOffset = posCaret.VirtualSpaceWidth(spaceWidth);
|
||||
if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) {
|
||||
XYPOSITION xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)];
|
||||
if (model.BidirectionalEnabled() && (posCaret.VirtualSpace() == 0)) {
|
||||
@ -1785,7 +1785,9 @@ void DrawTranslucentSelection(Surface *surface, const EditModel &model, const Vi
|
||||
const ColourRGBA selectionBack = SelectionBackground(
|
||||
model, vsDraw, model.sel.RangeType(r));
|
||||
const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth;
|
||||
const Interval intervalVirtual{ portion.start.VirtualSpace() * spaceWidth, portion.end.VirtualSpace() * spaceWidth };
|
||||
const Interval intervalVirtual{
|
||||
portion.start.VirtualSpaceWidth(spaceWidth),
|
||||
portion.end.VirtualSpaceWidth(spaceWidth) };
|
||||
if (model.BidirectionalEnabled()) {
|
||||
const SelectionSegment portionInSubLine = portionInLine.Subtract(lineRange.start);
|
||||
|
||||
|
@ -202,6 +202,8 @@ Editor::Editor() : durationWrapOneByte(0.000001, 0.00000001, 0.00001) {
|
||||
recordingMacro = false;
|
||||
foldAutomatic = AutomaticFold::None;
|
||||
|
||||
insideWrapScroll = false;
|
||||
|
||||
convertPastes = true;
|
||||
|
||||
SetRepresentations();
|
||||
@ -267,7 +269,7 @@ PointDocument Editor::DocumentPointFromView(Point ptView) const {
|
||||
ptDocument.y += ptOrigin.y;
|
||||
} else {
|
||||
ptDocument.x += xOffset;
|
||||
ptDocument.y += topLine * vs.lineHeight;
|
||||
ptDocument.y += static_cast<double>(topLine * vs.lineHeight);
|
||||
}
|
||||
return ptDocument;
|
||||
}
|
||||
@ -275,8 +277,7 @@ PointDocument Editor::DocumentPointFromView(Point ptView) const {
|
||||
Sci::Line Editor::TopLineOfMain() const noexcept {
|
||||
if (HasMarginWindow())
|
||||
return 0;
|
||||
else
|
||||
return topLine;
|
||||
return topLine;
|
||||
}
|
||||
|
||||
Point Editor::ClientSize() const {
|
||||
@ -310,8 +311,7 @@ Sci::Line Editor::LinesToScroll() const {
|
||||
const Sci::Line retVal = LinesOnScreen() - 1;
|
||||
if (retVal < 1)
|
||||
return 1;
|
||||
else
|
||||
return retVal;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Sci::Line Editor::MaxScrollPos() const {
|
||||
@ -325,9 +325,8 @@ Sci::Line Editor::MaxScrollPos() const {
|
||||
}
|
||||
if (retVal < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return retVal;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const {
|
||||
@ -626,7 +625,7 @@ void Editor::InvalidateWholeSelection() {
|
||||
|
||||
/* For Line selection - the anchor and caret are always
|
||||
at the beginning and end of the region lines. */
|
||||
SelectionRange Editor::LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const {
|
||||
SelectionRange Editor::LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const noexcept {
|
||||
if (currentPos_ > anchor_) {
|
||||
anchor_ = SelectionPosition(pdoc->LineStartPosition(anchor_.Position()));
|
||||
currentPos_ = SelectionPosition(pdoc->LineEndPosition(currentPos_.Position()));
|
||||
@ -743,9 +742,9 @@ void Editor::MultipleSelectAdd(AddNumber addNumber) {
|
||||
// Common case is that the selection is completely within the target but
|
||||
// may also have overlap at start or end.
|
||||
if (rangeMainSelection.end < rangeTarget.end)
|
||||
searchRanges.push_back(Range(rangeMainSelection.end, rangeTarget.end));
|
||||
searchRanges.emplace_back(rangeMainSelection.end, rangeTarget.end);
|
||||
if (rangeTarget.start < rangeMainSelection.start)
|
||||
searchRanges.push_back(Range(rangeTarget.start, rangeMainSelection.start));
|
||||
searchRanges.emplace_back(rangeTarget.start, rangeMainSelection.start);
|
||||
} else {
|
||||
// No overlap
|
||||
searchRanges.push_back(rangeTarget);
|
||||
@ -903,18 +902,17 @@ SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveD
|
||||
const Sci::Line lineDoc = pdoc->SciLineFromPosition(pos.Position());
|
||||
if (pcs->GetVisible(lineDoc)) {
|
||||
return pos;
|
||||
}
|
||||
Sci::Line lineDisplay = pcs->DisplayFromDoc(lineDoc);
|
||||
if (moveDir > 0) {
|
||||
// lineDisplay is already line before fold as lines in fold use display line of line after fold
|
||||
lineDisplay = std::clamp<Sci::Line>(lineDisplay, 0, pcs->LinesDisplayed());
|
||||
return SelectionPosition(
|
||||
pdoc->LineStart(pcs->DocFromDisplay(lineDisplay)));
|
||||
} else {
|
||||
Sci::Line lineDisplay = pcs->DisplayFromDoc(lineDoc);
|
||||
if (moveDir > 0) {
|
||||
// lineDisplay is already line before fold as lines in fold use display line of line after fold
|
||||
lineDisplay = std::clamp<Sci::Line>(lineDisplay, 0, pcs->LinesDisplayed());
|
||||
return SelectionPosition(
|
||||
pdoc->LineStart(pcs->DocFromDisplay(lineDisplay)));
|
||||
} else {
|
||||
lineDisplay = std::clamp<Sci::Line>(lineDisplay - 1, 0, pcs->LinesDisplayed());
|
||||
return SelectionPosition(
|
||||
pdoc->LineEnd(pcs->DocFromDisplay(lineDisplay)));
|
||||
}
|
||||
lineDisplay = std::clamp<Sci::Line>(lineDisplay - 1, 0, pcs->LinesDisplayed());
|
||||
return SelectionPosition(
|
||||
pdoc->LineEnd(pcs->DocFromDisplay(lineDisplay)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1113,9 +1111,9 @@ void Editor::MoveCaretInsideView(bool ensureVisible) {
|
||||
false, false, UserVirtualSpace()),
|
||||
Selection::SelTypes::none, ensureVisible);
|
||||
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
|
||||
const ptrdiff_t yOfLastLineFullyDisplayed = static_cast<ptrdiff_t>(rcClient.top) + (LinesOnScreen() - 1) * vs.lineHeight;
|
||||
const ptrdiff_t yOfLastLineFullyDisplayed = static_cast<ptrdiff_t>(rcClient.top) + ((LinesOnScreen() - 1) * vs.lineHeight);
|
||||
MovePositionTo(SPositionFromLocation(
|
||||
Point::FromInts(lastXChosen - xOffset, static_cast<int>(rcClient.top + yOfLastLineFullyDisplayed)),
|
||||
Point::FromInts(lastXChosen - xOffset, static_cast<int>(rcClient.top + static_cast<XYPOSITION>(yOfLastLineFullyDisplayed))),
|
||||
false, false, UserVirtualSpace()),
|
||||
Selection::SelTypes::none, ensureVisible);
|
||||
}
|
||||
@ -1543,7 +1541,7 @@ bool Editor::WrapBlock(Surface *surface, Sci::Line lineToWrap, Sci::Line lineToW
|
||||
|
||||
std::vector<int> linesAfterWrap(linesBeingWrapped);
|
||||
|
||||
size_t threads = std::min<size_t>({ linesBeingWrapped, view.maxLayoutThreads });
|
||||
size_t threads = std::min<size_t>(linesBeingWrapped, view.maxLayoutThreads);
|
||||
if (!surface->SupportsFeature(Supports::ThreadSafeMeasureWidths)) {
|
||||
threads = 1;
|
||||
}
|
||||
@ -1607,7 +1605,7 @@ bool Editor::WrapBlock(Surface *surface, Sci::Line lineToWrap, Sci::Line lineToW
|
||||
|
||||
// Multiply duration by number of threads to produce (near) equivalence to duration if single threaded
|
||||
const double durationShortLines = epWrapping.Duration(true);
|
||||
const double durationShortLinesThreads = durationShortLines * threads;
|
||||
const double durationShortLinesThreads = durationShortLines * static_cast<double>(threads);
|
||||
|
||||
// Wrap all the long lines in the main thread.
|
||||
// LayoutLine may then multi-thread over segments in each line.
|
||||
@ -1683,8 +1681,15 @@ bool Editor::WrapLines(WrapScope ws) {
|
||||
// Decide where to start wrapping
|
||||
Sci::Line lineToWrap = wrapPending.start;
|
||||
Sci::Line lineToWrapEnd = std::min(wrapPending.end, pdoc->LinesTotal());
|
||||
|
||||
const Sci::Line lineDocTop = pcs->DocFromDisplay(topLine);
|
||||
const Sci::Line subLineTop = topLine - pcs->DisplayFromDoc(lineDocTop);
|
||||
LineDocSub lineScrollTo;
|
||||
if (scrollToAfterWrap) {
|
||||
lineScrollTo = scrollToAfterWrap.value();
|
||||
} else {
|
||||
const Sci::Line subLineTop = topLine - pcs->DisplayFromDoc(lineDocTop);
|
||||
lineScrollTo = { lineDocTop, subLineTop };
|
||||
}
|
||||
if (ws == WrapScope::wsVisible) {
|
||||
lineToWrap = std::clamp(lineDocTop-5, wrapPending.start, pdoc->LinesTotal());
|
||||
// Priority wrap to just after visible area.
|
||||
@ -1735,21 +1740,23 @@ bool Editor::WrapLines(WrapScope ws) {
|
||||
|
||||
wrapOccurred = WrapBlock(surface, lineToWrap, lineToWrapEnd);
|
||||
|
||||
goodTopLine = pcs->DisplayFromDoc(lineDocTop) + std::min(
|
||||
subLineTop, static_cast<Sci::Line>(pcs->GetHeight(lineDocTop)-1));
|
||||
goodTopLine = pcs->DisplayFromDocSub(lineScrollTo.lineDoc, lineScrollTo.subLine);
|
||||
}
|
||||
}
|
||||
|
||||
// If wrapping is done, bring it to resting position
|
||||
if (wrapPending.start >= lineEndNeedWrap) {
|
||||
wrapPending.Reset();
|
||||
scrollToAfterWrap.reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (wrapOccurred) {
|
||||
insideWrapScroll = true;
|
||||
SetScrollBars();
|
||||
SetTopLine(std::clamp<Sci::Line>(goodTopLine, 0, MaxScrollPos()));
|
||||
SetVerticalScrollPos();
|
||||
insideWrapScroll = false;
|
||||
}
|
||||
|
||||
return wrapOccurred;
|
||||
@ -1850,15 +1857,11 @@ void Editor::PaintSelMargin(Surface *surfaceWindow, const PRectangle &rc) {
|
||||
void Editor::RefreshPixMaps(Surface *surfaceWindow) {
|
||||
view.RefreshPixMaps(surfaceWindow, vs);
|
||||
marginView.RefreshPixMaps(surfaceWindow, vs);
|
||||
if (view.bufferedDraw) {
|
||||
if (view.bufferedDraw && !(view.pixmapLine && marginView.pixmapSelMargin)) {
|
||||
const PRectangle rcClient = GetClientRectangle();
|
||||
if (!view.pixmapLine) {
|
||||
view.pixmapLine = surfaceWindow->AllocatePixMap(static_cast<int>(rcClient.Width()), vs.lineHeight);
|
||||
}
|
||||
if (!marginView.pixmapSelMargin) {
|
||||
marginView.pixmapSelMargin = surfaceWindow->AllocatePixMap(vs.fixedColumnWidth,
|
||||
static_cast<int>(rcClient.Height()));
|
||||
}
|
||||
view.pixmapLine = surfaceWindow->AllocatePixMap(static_cast<int>(rcClient.Width()), vs.lineHeight);
|
||||
marginView.pixmapSelMargin = surfaceWindow->AllocatePixMap(vs.fixedColumnWidth,
|
||||
static_cast<int>(rcClient.Height()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1872,7 +1875,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
RefreshStyleData();
|
||||
if (paintState == PaintState::abandoned)
|
||||
return; // Scroll bars may have changed so need redraw
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
|
||||
paintAbandonedByStyling = false;
|
||||
|
||||
@ -1884,7 +1886,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
|
||||
if (NotifyUpdateUI()) {
|
||||
RefreshStyleData();
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
}
|
||||
|
||||
// Wrap the visible lines if needed.
|
||||
@ -1894,9 +1895,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
|
||||
if (AbandonPaint()) {
|
||||
return;
|
||||
}
|
||||
RefreshPixMaps(surfaceWindow); // In case pixmaps invalidated by scrollbar change
|
||||
}
|
||||
|
||||
RefreshPixMaps(surfaceWindow);
|
||||
|
||||
if (!marginView.pixmapSelPattern->Initialised()) {
|
||||
// When Direct2D is used, pixmap creation may fail with D2DERR_RECREATE_TARGET so
|
||||
// abandon this paint to avoid further failures.
|
||||
@ -1990,8 +1992,13 @@ long Editor::TextWidth(uptr_t style, const char *text) {
|
||||
AutoSurface surface(this);
|
||||
if (surface) {
|
||||
return std::lround(surface->WidthText(vs.styles[style].font.get(), text));
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Editor::SetVerticalScrollPos() {
|
||||
if (!insideWrapScroll) {
|
||||
scrollToAfterWrap.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2047,11 +2054,10 @@ Sci::Position Editor::RealizeVirtualSpace(Sci::Position position, Sci::Position
|
||||
const Sci::Position indent = pdoc->GetLineIndentPosition(line);
|
||||
if (indent == position) {
|
||||
return pdoc->SetLineIndentation(line, pdoc->GetLineIndentation(line) + virtualSpace);
|
||||
} else {
|
||||
const std::string spaceText(virtualSpace, ' ');
|
||||
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText);
|
||||
position += lengthInserted;
|
||||
}
|
||||
const std::string spaceText(virtualSpace, ' ');
|
||||
const Sci::Position lengthInserted = pdoc->InsertString(position, spaceText);
|
||||
position += lengthInserted;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
@ -2409,12 +2415,14 @@ void Editor::SelectAll() {
|
||||
|
||||
void Editor::RestoreSelection(Sci::Position newPos, UndoRedo history) {
|
||||
EnsureModelState();
|
||||
if ((undoSelectionHistoryOption == UndoSelectionHistoryOption::Enabled) && modelState) {
|
||||
if (FlagSet(undoSelectionHistoryOption, UndoSelectionHistoryOption::Enabled) && modelState) {
|
||||
// Undo wants the element after the current as it just undid it
|
||||
const int index = pdoc->UndoCurrent() + (history == UndoRedo::undo ? 1 : 0);
|
||||
const SelectionWithScroll selAndLine = modelState->SelectionFromStack(index, history);
|
||||
if (!selAndLine.selection.empty()) {
|
||||
ScrollTo(selAndLine.topLine);
|
||||
if (FlagSet(undoSelectionHistoryOption, UndoSelectionHistoryOption::Scroll)) {
|
||||
ScrollTo(selAndLine.topLine);
|
||||
}
|
||||
sel = Selection(selAndLine.selection);
|
||||
if (sel.IsRectangular()) {
|
||||
const size_t mainForRectangular = sel.Main();
|
||||
@ -2654,9 +2662,8 @@ bool Editor::NotifyMarginClick(Point pt, KeyMod modifiers) {
|
||||
scn.margin = marginClicked;
|
||||
NotifyParent(scn);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Editor::NotifyMarginRightClick(Point pt, KeyMod modifiers) {
|
||||
@ -2670,9 +2677,8 @@ bool Editor::NotifyMarginRightClick(Point pt, KeyMod modifiers) {
|
||||
scn.margin = marginRightClicked;
|
||||
NotifyParent(scn);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Editor::NotifyNeedShown(Sci::Position pos, Sci::Position len) {
|
||||
@ -2746,12 +2752,10 @@ constexpr Sci::Position MovePositionForDeletion(Sci::Position position, Sci::Pos
|
||||
const Sci::Position endDeletion = startDeletion + length;
|
||||
if (position > endDeletion) {
|
||||
return position - length;
|
||||
} else {
|
||||
return startDeletion;
|
||||
}
|
||||
} else {
|
||||
return position;
|
||||
return startDeletion;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
||||
@ -2799,7 +2803,7 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
|
||||
view.llc.Invalidate(LineLayout::ValidLevel::checkTextAndStyle);
|
||||
}
|
||||
} else {
|
||||
if ((undoSelectionHistoryOption == UndoSelectionHistoryOption::Enabled) &&
|
||||
if (FlagSet(undoSelectionHistoryOption, UndoSelectionHistoryOption::Enabled) &&
|
||||
FlagSet(mh.modificationType, ModificationFlags::User)) {
|
||||
if (FlagSet(mh.modificationType, ModificationFlags::BeforeInsert | ModificationFlags::BeforeDelete)) {
|
||||
RememberSelectionForUndo(pdoc->UndoCurrent());
|
||||
@ -3366,7 +3370,7 @@ SelectionPosition Editor::PositionUpOrDown(SelectionPosition spStart, int direct
|
||||
// There is an equivalent case when moving down which skips
|
||||
// over a line.
|
||||
Point ptNew = LocationFromPosition(posNew.Position());
|
||||
while ((posNew.Position() > spStart.Position()) && (ptNew.y > newY)) {
|
||||
while ((posNew.Position() > spStart.Position()) && (ptNew.y > static_cast<XYPOSITION>(newY))) {
|
||||
posNew.Add(-1);
|
||||
posNew.SetVirtualSpace(0);
|
||||
ptNew = LocationFromPosition(posNew.Position());
|
||||
@ -3452,9 +3456,8 @@ Sci::Position Editor::StartEndDisplayLine(Sci::Position pos, bool start) {
|
||||
const Sci::Position posRet = view.StartEndDisplayLine(surface, *this, pos, start, vs);
|
||||
if (posRet == Sci::invalidPosition) {
|
||||
return pos;
|
||||
} else {
|
||||
return posRet;
|
||||
}
|
||||
return posRet;
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -3564,19 +3567,19 @@ Sci::Position Editor::HomeWrapPosition(Sci::Position position) {
|
||||
Sci::Position Editor::VCHomeDisplayPosition(Sci::Position position) {
|
||||
const Sci::Position homePos = pdoc->VCHomePosition(position);
|
||||
const Sci::Position viewLineStart = StartEndDisplayLine(position, true);
|
||||
if (viewLineStart > homePos)
|
||||
if (viewLineStart > homePos) {
|
||||
return viewLineStart;
|
||||
else
|
||||
return homePos;
|
||||
}
|
||||
return homePos;
|
||||
}
|
||||
|
||||
Sci::Position Editor::VCHomeWrapPosition(Sci::Position position) {
|
||||
const Sci::Position homePos = pdoc->VCHomePosition(position);
|
||||
const Sci::Position viewLineStart = StartEndDisplayLine(position, true);
|
||||
if ((viewLineStart < position) && (viewLineStart > homePos))
|
||||
if ((viewLineStart < position) && (viewLineStart > homePos)) {
|
||||
return viewLineStart;
|
||||
else
|
||||
return homePos;
|
||||
}
|
||||
return homePos;
|
||||
}
|
||||
|
||||
Sci::Position Editor::LineEndWrapPosition(Sci::Position position) {
|
||||
@ -3585,8 +3588,7 @@ Sci::Position Editor::LineEndWrapPosition(Sci::Position position) {
|
||||
if (endPos > realEndPos // if moved past visible EOLs
|
||||
|| position >= endPos) // if at end of display line already
|
||||
return realEndPos;
|
||||
else
|
||||
return endPos;
|
||||
return endPos;
|
||||
}
|
||||
|
||||
SelectionPosition Editor::PositionMove(Message iMessage, SelectionPosition spCaret) {
|
||||
@ -4144,11 +4146,10 @@ int Editor::KeyDownWithModifiers(Keys key, KeyMod modifiers, bool *consumed) {
|
||||
if (consumed)
|
||||
*consumed = true;
|
||||
return static_cast<int>(WndProc(msg, 0, 0));
|
||||
} else {
|
||||
if (consumed)
|
||||
*consumed = false;
|
||||
return KeyDefault(key, modifiers);
|
||||
}
|
||||
if (consumed)
|
||||
*consumed = false;
|
||||
return KeyDefault(key, modifiers);
|
||||
}
|
||||
|
||||
void Editor::Indent(bool forwards, bool lineIndent) {
|
||||
@ -4175,7 +4176,7 @@ void Editor::Indent(bool forwards, bool lineIndent) {
|
||||
sel.Range(r) = SelectionRange(caretPosition + lengthInserted);
|
||||
} else {
|
||||
int numSpaces = (pdoc->tabInChars) -
|
||||
(pdoc->GetColumn(caretPosition) % (pdoc->tabInChars));
|
||||
static_cast<int>((pdoc->GetColumn(caretPosition) % (pdoc->tabInChars)));
|
||||
if (numSpaces < 1)
|
||||
numSpaces = pdoc->tabInChars;
|
||||
const std::string spaceText(numSpaces, ' ');
|
||||
@ -4426,7 +4427,7 @@ std::string Editor::RangeText(Sci::Position start, Sci::Position end) const {
|
||||
pdoc->GetCharRange(ret.data(), start, len);
|
||||
return ret;
|
||||
}
|
||||
return std::string();
|
||||
return {};
|
||||
}
|
||||
|
||||
bool Editor::CopyLineRange(SelectionText *ss, bool allowProtected) {
|
||||
@ -4440,9 +4441,8 @@ bool Editor::CopyLineRange(SelectionText *ss, bool allowProtected) {
|
||||
ss->Copy(text, pdoc->dbcsCodePage,
|
||||
vs.styles[StyleDefault].characterSet, false, true);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
|
||||
@ -4629,7 +4629,7 @@ bool Editor::PointInSelection(Point pt) {
|
||||
}
|
||||
|
||||
ptrdiff_t Editor::SelectionFromPoint(Point pt) {
|
||||
// Prioritize checking inside non-empty selections since each character will be inside only 1
|
||||
// Prioritize checking inside non-empty selections since each character will be inside only 1
|
||||
const SelectionPosition posChar = SPositionFromLocation(pt, true, true);
|
||||
for (size_t r = 0; r < sel.Count(); r++) {
|
||||
if (sel.Range(r).ContainsCharacter(posChar)) {
|
||||
@ -4659,9 +4659,8 @@ bool Editor::PointInSelMargin(Point pt) const {
|
||||
const Point ptOrigin = GetVisibleOriginInMain();
|
||||
rcSelMargin.Move(0, -ptOrigin.y);
|
||||
return rcSelMargin.ContainsWholePixel(pt);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Window::Cursor Editor::GetMarginCursor(Point pt) const noexcept {
|
||||
@ -4911,10 +4910,9 @@ void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, KeyMod modi
|
||||
DropSelection(selectionPart);
|
||||
// Completed: don't want any more processing of this click
|
||||
return;
|
||||
} else {
|
||||
// Switch to just the click position
|
||||
SetSelection(newPos, newPos);
|
||||
}
|
||||
// Switch to just the click position
|
||||
SetSelection(newPos, newPos);
|
||||
}
|
||||
if (!sel.Range(selectionPart).Empty()) {
|
||||
inDragDrop = DragDrop::initial;
|
||||
@ -5348,10 +5346,10 @@ Sci::Position Editor::PositionAfterArea(PRectangle rcArea) const {
|
||||
// This often means that the line after a modification is restyled which helps
|
||||
// detect multiline comment additions and heals single line comments
|
||||
const Sci::Line lineAfter = TopLineOfMain() + static_cast<Sci::Line>(rcArea.bottom - 1) / vs.lineHeight + 1;
|
||||
if (lineAfter < pcs->LinesDisplayed())
|
||||
if (lineAfter < pcs->LinesDisplayed()) {
|
||||
return pdoc->LineStart(pcs->DocFromDisplay(lineAfter) + 1);
|
||||
else
|
||||
return pdoc->Length();
|
||||
}
|
||||
return pdoc->Length();
|
||||
}
|
||||
|
||||
// Style to a position within the view. If this causes a change at end of last line then
|
||||
@ -5454,9 +5452,8 @@ int Editor::SupportsFeature(Supports feature) {
|
||||
bool Editor::PaintContains(PRectangle rc) {
|
||||
if (rc.Empty()) {
|
||||
return true;
|
||||
} else {
|
||||
return rcPaint.Contains(rc);
|
||||
}
|
||||
return rcPaint.Contains(rc);
|
||||
}
|
||||
|
||||
bool Editor::PaintContainsMargin() {
|
||||
@ -5560,6 +5557,8 @@ void Editor::SetDocPointer(Document *document) {
|
||||
|
||||
SetRepresentations();
|
||||
|
||||
scrollToAfterWrap.reset();
|
||||
|
||||
// Reset the contraction state to fully shown.
|
||||
pcs->Clear();
|
||||
pcs->InsertLines(0, pdoc->LinesTotal() - 1);
|
||||
@ -5699,7 +5698,7 @@ void Editor::FoldExpand(Sci::Line line, FoldAction action, FoldLevel level) {
|
||||
Redraw();
|
||||
}
|
||||
|
||||
Sci::Line Editor::ContractedFoldNext(Sci::Line lineStart) const {
|
||||
Sci::Line Editor::ContractedFoldNext(Sci::Line lineStart) const noexcept {
|
||||
for (Sci::Line line = lineStart; line<pdoc->LinesTotal();) {
|
||||
if (!pcs->GetExpanded(line) && LevelIsHeader(pdoc->GetFoldLevel(line)))
|
||||
return line;
|
||||
@ -5950,8 +5949,7 @@ bool Editor::IsUnicodeMode() const noexcept {
|
||||
int Editor::CodePage() const noexcept {
|
||||
if (pdoc)
|
||||
return pdoc->dbcsCodePage;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<Surface> Editor::CreateMeasurementSurface() const {
|
||||
@ -5981,9 +5979,8 @@ Sci::Line Editor::WrapCount(Sci::Line line) {
|
||||
if (surface && ll) {
|
||||
view.LayoutLine(*this, surface, vs, ll.get(), wrapWidth);
|
||||
return ll->lines;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Editor::AddStyledText(const char *buffer, Sci::Position appendLength) {
|
||||
@ -6571,6 +6568,15 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
HorizontalScrollTo(xOffset + static_cast<int>(static_cast<int>(wParam) * vs.spaceWidth));
|
||||
return 1;
|
||||
|
||||
case Message::ScrollVertical:
|
||||
if (Wrapping()) {
|
||||
scrollToAfterWrap = { LineFromUPtr(wParam), lParam };
|
||||
} else {
|
||||
scrollToAfterWrap.reset();
|
||||
}
|
||||
ScrollTo(pcs->DisplayFromDocSub(LineFromUPtr(wParam), lParam));
|
||||
break;
|
||||
|
||||
case Message::SetXOffset:
|
||||
xOffset = static_cast<int>(wParam);
|
||||
ContainerNeedsUpdate(Update::HScroll);
|
||||
@ -7487,7 +7493,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
break;
|
||||
case Message::MarkerSetStrokeWidth:
|
||||
if (wParam <= MarkerMax)
|
||||
vs.markers[wParam].strokeWidth = lParam / 100.0f;
|
||||
vs.markers[wParam].strokeWidth = static_cast<XYPOSITION>(lParam) / 100.0f;
|
||||
InvalidateStyleData();
|
||||
RedrawSelMargin();
|
||||
break;
|
||||
@ -8181,7 +8187,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
|
||||
case Message::IndicSetStrokeWidth:
|
||||
if (wParam <= IndicatorMax && lParam >= 0 && lParam <= 1000) {
|
||||
vs.indicators[wParam].strokeWidth = lParam / 100.0f;
|
||||
vs.indicators[wParam].strokeWidth = static_cast<XYPOSITION>(lParam) / 100.0;
|
||||
InvalidateStyleRedraw();
|
||||
}
|
||||
break;
|
||||
@ -8452,7 +8458,8 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
|
||||
doc->Allocate(PositionFromUPtr(wParam));
|
||||
doc->SetUndoCollection(false);
|
||||
pcs = ContractionStateCreate(pdoc->IsLarge());
|
||||
return reinterpret_cast<sptr_t>(static_cast<ILoader *>(doc));
|
||||
ILoader *loader = doc;
|
||||
return reinterpret_cast<sptr_t>(loader);
|
||||
}
|
||||
|
||||
case Message::SetModEventMask:
|
||||
|
@ -283,6 +283,12 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
// Wrapping support
|
||||
WrapPending wrapPending;
|
||||
ActionDuration durationWrapOneByte;
|
||||
bool insideWrapScroll;
|
||||
struct LineDocSub {
|
||||
Scintilla::Line lineDoc = 0;
|
||||
Scintilla::Line subLine = 0;
|
||||
};
|
||||
std::optional<LineDocSub> scrollToAfterWrap;
|
||||
|
||||
bool convertPastes;
|
||||
|
||||
@ -346,7 +352,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
void ThinRectangularRange();
|
||||
void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false);
|
||||
void InvalidateWholeSelection();
|
||||
SelectionRange LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const;
|
||||
SelectionRange LineSelectionRange(SelectionPosition currentPos_, SelectionPosition anchor_) const noexcept;
|
||||
void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_);
|
||||
void SetSelection(Sci::Position currentPos_, Sci::Position anchor_);
|
||||
void SetSelection(SelectionPosition currentPos_);
|
||||
@ -417,7 +423,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
Sci::Position FormatRange(Scintilla::Message iMessage, Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
|
||||
long TextWidth(Scintilla::uptr_t style, const char *text);
|
||||
|
||||
virtual void SetVerticalScrollPos() = 0;
|
||||
virtual void SetVerticalScrollPos();
|
||||
virtual void SetHorizontalScrollPos() = 0;
|
||||
virtual bool ModifyScrollBars(Sci::Line nMax, Sci::Line nPage) = 0;
|
||||
virtual void ReconfigureScrollBars();
|
||||
@ -593,7 +599,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
void SetFoldExpanded(Sci::Line lineDoc, bool expanded);
|
||||
void FoldLine(Sci::Line line, Scintilla::FoldAction action);
|
||||
void FoldExpand(Sci::Line line, Scintilla::FoldAction action, Scintilla::FoldLevel level);
|
||||
Sci::Line ContractedFoldNext(Sci::Line lineStart) const;
|
||||
Sci::Line ContractedFoldNext(Sci::Line lineStart) const noexcept;
|
||||
void EnsureLineVisible(Sci::Line lineDoc, bool enforcePolicy);
|
||||
void FoldChanged(Sci::Line line, Scintilla::FoldLevel levelNow, Scintilla::FoldLevel levelPrev);
|
||||
void NeedShown(Sci::Position pos, Sci::Position len);
|
||||
|
@ -196,7 +196,7 @@ void LineMarker::DrawFoldingMark(Surface *surface, const PRectangle &rcWhole, Fo
|
||||
// To centre +/-, odd strokeWidth -> odd symbol width, even -> even
|
||||
const XYPOSITION widthSymbol =
|
||||
((std::lround(minDimension * pixelDivisions) % 2) == (std::lround(widthStroke * pixelDivisions) % 2)) ?
|
||||
minDimension : minDimension - 1.0f / pixelDivisions;
|
||||
minDimension : minDimension - (1.0 / static_cast<XYPOSITION>(pixelDivisions));
|
||||
|
||||
const Point centre = PixelAlign(rcWhole.Centre(), pixelDivisions);
|
||||
|
||||
@ -464,11 +464,13 @@ void LineMarker::Draw(Surface *surface, const PRectangle &rcWhole, const Font *f
|
||||
break;
|
||||
|
||||
case MarkerSymbol::DotDotDot: {
|
||||
XYPOSITION right = static_cast<XYPOSITION>(centreX - 6);
|
||||
// 3 2x2 dots with 3 pixels between, margin must be 12 wide to show all
|
||||
constexpr XYPOSITION pitchDots = 5.0;
|
||||
XYPOSITION xBlob = std::floor(centreX - (pitchDots + 1));
|
||||
for (int b = 0; b < 3; b++) {
|
||||
const PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom - 2);
|
||||
const PRectangle rcBlob(xBlob, rc.bottom - 4, xBlob + 2, rc.bottom - 2);
|
||||
surface->FillRectangle(rcBlob, fore);
|
||||
right += 5.0f;
|
||||
xBlob += pitchDots;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -516,26 +518,28 @@ void LineMarker::Draw(Surface *surface, const PRectangle &rcWhole, const Font *f
|
||||
break;
|
||||
|
||||
case MarkerSymbol::Bar: {
|
||||
// Hide cap by continuing a bit.
|
||||
constexpr XYPOSITION continueLength = 5.0;
|
||||
PRectangle rcBar = rcWhole;
|
||||
const XYPOSITION widthBar = std::floor(rcWhole.Width() / 3.0);
|
||||
const XYPOSITION widthBar = std::ceil(rcWhole.Width() / 3.0);
|
||||
rcBar.left = centreX - std::floor(widthBar / 2.0);
|
||||
rcBar.right = rcBar.left + widthBar;
|
||||
surface->SetClip(rcWhole);
|
||||
surface->SetClip(rcWhole); // Hide continued caps
|
||||
switch (part) {
|
||||
case LineMarker::FoldPart::headWithTail:
|
||||
surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth));
|
||||
break;
|
||||
case LineMarker::FoldPart::head:
|
||||
rcBar.bottom += 5;
|
||||
rcBar.bottom += continueLength;
|
||||
surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth));
|
||||
break;
|
||||
case LineMarker::FoldPart::tail:
|
||||
rcBar.top -= 5;
|
||||
rcBar.top -= continueLength;
|
||||
surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth));
|
||||
break;
|
||||
case LineMarker::FoldPart::body:
|
||||
rcBar.top -= 5;
|
||||
rcBar.bottom += 5;
|
||||
rcBar.top -= continueLength;
|
||||
rcBar.bottom += continueLength;
|
||||
surface->RectangleDraw(rcBar, FillStroke(back, fore, strokeWidth));
|
||||
break;
|
||||
default:
|
||||
|
@ -124,7 +124,7 @@ void MarginView::DropGraphics() noexcept {
|
||||
}
|
||||
|
||||
void MarginView::RefreshPixMaps(Surface *surfaceWindow, const ViewStyle &vsDraw) {
|
||||
if (!pixmapSelPattern) {
|
||||
if (!(pixmapSelPattern && pixmapSelPatternOffset1)) {
|
||||
constexpr int patternSize = 8;
|
||||
pixmapSelPattern = surfaceWindow->AllocatePixMap(patternSize, patternSize);
|
||||
pixmapSelPatternOffset1 = surfaceWindow->AllocatePixMap(patternSize, patternSize);
|
||||
@ -278,7 +278,7 @@ void MarginView::PaintOneMargin(Surface *surface, PRectangle rc, PRectangle rcOn
|
||||
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;
|
||||
XYPOSITION yposScreen = lineStartPaint * vs.lineHeight - ptOrigin.y;
|
||||
XYPOSITION yposScreen = static_cast<XYPOSITION>(lineStartPaint * vs.lineHeight) - ptOrigin.y;
|
||||
// Work out whether the top line is whitespace located after a
|
||||
// lessening of fold level which implies a 'fold tail' but which should not
|
||||
// be displayed until the last of a sequence of whitespace.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user