Update to scintilla 5.5.3 & Lexilla 5.4.1

Release 5.5.4 (https://www.scintilla.org/scintilla554.zip)

    Released 18 December 2024.
    Update to Unicode 15.1. Issue #285.
    Improve performance of SCI_BRACEMATCH. Feature #1533.
    Improve performance of DBCS text. Feature #1535.
    Fix wrapping removed lines. Bug #2456.
    Fix moving line down to empty final line and moving empty final line up. Bug #2457.
    On GTK, allow middle click to insert multiple times within a document. Geany Issue #2629.

Release 5.4.2 (https://www.scintilla.org/lexilla542.zip)

    Released 18 December 2024.
    Update to Unicode 15.1. Issue #285.
    Lexer added for Nix "nix". Pull request #282.
    JavaScript: Use correct SCE_HJA_TEMPLATELITERAL style for server-side template literals in HTML instead of client-side style. Issue #286.
    JavaScript: Use correct SCE_HJ_SYMBOLS style for '.' after regex instead of SCE_HJ_WORD. Prevent empty word assertion when non-word character after regex flag. Issue #289.
    PHP: Fix unstable lexing with substyled keyword and unterminated string. Issue #288.
    Rust: Add C string and raw C string literal styles SCE_RUST_CSTRING and SCE_RUST_CSTRINGR. Pull request #292, Issue #268.
    TOML: Don't treat keys without values as errors. Pull request #283.
    Zig: Add SCE_ZIG_IDENTIFIER_STRING for identifiers expressed as strings. Pull request #287.

Fix #15817, fix #10528, fix #15801, close #15982
This commit is contained in:
Christian Grasser 2024-12-24 08:56:50 +01:00 committed by Don Ho
parent 7544df5348
commit a6103d5de7
90 changed files with 2393 additions and 291 deletions

View File

@ -49,6 +49,7 @@
**.matlab text **.matlab text
**.ml text **.ml text
**.nim text **.nim text
**.nix text
**.octave text **.octave text
**.p text **.p text
**.pl text **.pl text

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description" <meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20241019" /> <meta name="Date.Modified" content="20241218" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css"> <style type="text/css">
.logo { .logo {
@ -61,8 +61,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font> <font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td> </td>
<td width="40%" align="right"> <td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.4.1<br /> <font color="#FFCC99" size="3">Release version 5.4.2<br />
Site last modified October 19 2024</font> Site last modified December 18 2024</font>
</td> </td>
<td width="20%"> <td width="20%">
&nbsp; &nbsp;
@ -77,11 +77,11 @@
</tr> </tr>
</table> </table>
<ul id="versionlist"> <ul id="versionlist">
<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.1 adds Dart, troff, and Zig lexers. Improves C++, F#, HTML, and Smalltalk.</li>
<li>Version 5.4.0 adds a TOML lexer.</li> <li>Version 5.4.0 adds a TOML lexer.</li>
<li>Version 5.3.3 improves HTML, JavaScript, Lua, PHP, and XML.</li> <li>Version 5.3.3 improves HTML, JavaScript, Lua, PHP, and XML.</li>
<li>Version 5.3.2 improves COBOL, HTML, Lua, Ruby, and Rust.</li> <li>Version 5.3.2 improves COBOL, HTML, Lua, Ruby, and Rust.</li>
<li>Version 5.3.1 improves Assembler, Bash, Batch, JavaScript, Python, and Ruby.</li>
</ul> </ul>
<ul id="menu"> <ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li> <li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
@ -130,7 +130,7 @@ if (!IsRemote()) { //if NOT remote...
<p> <p>
The source code can be downloaded via Git at GitHub The source code can be downloaded via Git at GitHub
<a href="https://github.com/ScintillaOrg/lexilla">Lexilla project page</a>.<br /> <a href="https://github.com/ScintillaOrg/lexilla">Lexilla project page</a>.<br />
git clone https://github.com/ScintillaOrg/lexilla <code>git clone https://github.com/ScintillaOrg/lexilla</code>
</p> </p>
<p>Current repository status:<br /> <p>Current repository status:<br />
<a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg" /></a><br /> <a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg" /></a><br />

View File

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

View File

@ -587,9 +587,53 @@
<td>RainRat</td> <td>RainRat</td>
</tr><tr> </tr><tr>
<td>Henrik S. Johansen</td> <td>Henrik S. Johansen</td>
<td>Ekopalypse</td>
</tr> </tr>
</table> </table>
<h2>Releases</h2> <h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla542.zip">Release 5.4.2</a>
</h3>
<ul>
<li>
Released 18 December 2024.
</li>
<li>
Update to Unicode 15.1.
<a href="https://github.com/ScintillaOrg/lexilla/issues/285">Issue #285</a>.
</li>
<li>
Lexer added for Nix "nix".
<a href="https://github.com/ScintillaOrg/lexilla/pull/282">Pull request #282</a>.
</li>
<li>
JavaScript: Use correct SCE_HJA_TEMPLATELITERAL style for server-side template literals in
HTML instead of client-side style.
<a href="https://github.com/ScintillaOrg/lexilla/issues/286">Issue #286</a>.
</li>
<li>
JavaScript: Use correct SCE_HJ_SYMBOLS style for '.' after regex instead of SCE_HJ_WORD.
Prevent empty word assertion when non-word character after regex flag.
<a href="https://github.com/ScintillaOrg/lexilla/issues/289">Issue #289</a>.
</li>
<li>
PHP: Fix unstable lexing with substyled keyword and unterminated string.
<a href="https://github.com/ScintillaOrg/lexilla/issues/288">Issue #288</a>.
</li>
<li>
Rust: Add C string and raw C string literal styles SCE_RUST_CSTRING and SCE_RUST_CSTRINGR.
<a href="https://github.com/ScintillaOrg/lexilla/pull/292">Pull request #292</a>,
<a href="https://github.com/ScintillaOrg/lexilla/issues/268">Issue #268</a>.
</li>
<li>
TOML: Don't treat keys without values as errors.
<a href="https://github.com/ScintillaOrg/lexilla/pull/283">Pull request #283</a>.
</li>
<li>
Zig: Add SCE_ZIG_IDENTIFIER_STRING for identifiers expressed as strings.
<a href="https://github.com/ScintillaOrg/lexilla/pull/287">Pull request #287</a>.
</li>
</ul>
<h3> <h3>
<a href="https://www.scintilla.org/lexilla541.zip">Release 5.4.1</a> <a href="https://www.scintilla.org/lexilla541.zip">Release 5.4.1</a>
</h3> </h3>

View File

@ -148,6 +148,7 @@ val SCLEX_TOML=136
val SCLEX_TROFF=137 val SCLEX_TROFF=137
val SCLEX_DART=138 val SCLEX_DART=138
val SCLEX_ZIG=139 val SCLEX_ZIG=139
val SCLEX_NIX=140
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1. # value assigned in sequence from SCLEX_AUTOMATIC+1.
@ -178,12 +179,10 @@ val SCE_P_FTRIPLEDOUBLE=19
val SCE_P_ATTRIBUTE=20 val SCE_P_ATTRIBUTE=20
# Lexical states for SCLEX_CPP # Lexical states for SCLEX_CPP
# Lexical states for SCLEX_BULLANT # Lexical states for SCLEX_BULLANT
# Lexical states for SCLEX_COBOL
# Lexical states for SCLEX_TACL # Lexical states for SCLEX_TACL
# Lexical states for SCLEX_TAL # Lexical states for SCLEX_TAL
lex Cpp=SCLEX_CPP SCE_C_ lex Cpp=SCLEX_CPP SCE_C_
lex BullAnt=SCLEX_BULLANT SCE_C_ lex BullAnt=SCLEX_BULLANT SCE_C_
lex COBOL=SCLEX_COBOL SCE_C_
lex TACL=SCLEX_TACL SCE_C_ lex TACL=SCLEX_TACL SCE_C_
lex TAL=SCLEX_TAL SCE_C_ lex TAL=SCLEX_TAL SCE_C_
val SCE_C_DEFAULT=0 val SCE_C_DEFAULT=0
@ -214,6 +213,21 @@ val SCE_C_PREPROCESSORCOMMENTDOC=24
val SCE_C_USERLITERAL=25 val SCE_C_USERLITERAL=25
val SCE_C_TASKMARKER=26 val SCE_C_TASKMARKER=26
val SCE_C_ESCAPESEQUENCE=27 val SCE_C_ESCAPESEQUENCE=27
# Lexical states for SCLEX_COBOL
lex COBOL=SCLEX_COBOL SCE_COBOL_
val SCE_COBOL_DEFAULT=0
val SCE_COBOL_COMMENT=1
val SCE_COBOL_COMMENTLINE=2
val SCE_COBOL_COMMENTDOC=3
val SCE_COBOL_NUMBER=4
val SCE_COBOL_WORD=5
val SCE_COBOL_STRING=6
val SCE_COBOL_CHARACTER=7
val SCE_COBOL_WORD3=8
val SCE_COBOL_PREPROCESSOR=9
val SCE_COBOL_OPERATOR=10
val SCE_COBOL_IDENTIFIER=11
val SCE_COBOL_WORD2=16
# Lexical states for SCLEX_D # Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_ lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0 val SCE_D_DEFAULT=0
@ -2009,6 +2023,8 @@ val SCE_RUST_LEXERROR=20
val SCE_RUST_BYTESTRING=21 val SCE_RUST_BYTESTRING=21
val SCE_RUST_BYTESTRINGR=22 val SCE_RUST_BYTESTRINGR=22
val SCE_RUST_BYTECHARACTER=23 val SCE_RUST_BYTECHARACTER=23
val SCE_RUST_CSTRING=24
val SCE_RUST_CSTRINGR=25
# Lexical states for SCLEX_DMAP # Lexical states for SCLEX_DMAP
lex DMAP=SCLEX_DMAP SCE_DMAP_ lex DMAP=SCLEX_DMAP SCE_DMAP_
val SCE_DMAP_DEFAULT=0 val SCE_DMAP_DEFAULT=0
@ -2411,3 +2427,22 @@ val SCE_ZIG_KW_PRIMARY=13
val SCE_ZIG_KW_SECONDARY=14 val SCE_ZIG_KW_SECONDARY=14
val SCE_ZIG_KW_TERTIARY=15 val SCE_ZIG_KW_TERTIARY=15
val SCE_ZIG_KW_TYPE=16 val SCE_ZIG_KW_TYPE=16
val SCE_ZIG_IDENTIFIER_STRING=17
# Lexical states for SCLEX_NIX
lex Nix=SCLEX_NIX SCE_NIX_
val SCE_NIX_DEFAULT=0
val SCE_NIX_COMMENTLINE=1
val SCE_NIX_COMMENTBLOCK=2
val SCE_NIX_STRING=3
val SCE_NIX_STRING_MULTILINE=4
val SCE_NIX_ESCAPECHAR=5
val SCE_NIX_IDENTIFIER=6
val SCE_NIX_OPERATOR=7
val SCE_NIX_OPERATOR_STRING=8
val SCE_NIX_NUMBER=9
val SCE_NIX_KEY=10
val SCE_NIX_PATH=11
val SCE_NIX_KEYWORD1=12
val SCE_NIX_KEYWORD2=13
val SCE_NIX_KEYWORD3=14
val SCE_NIX_KEYWORD4=15

View File

@ -152,6 +152,7 @@
#define SCLEX_TROFF 137 #define SCLEX_TROFF 137
#define SCLEX_DART 138 #define SCLEX_DART 138
#define SCLEX_ZIG 139 #define SCLEX_ZIG 139
#define SCLEX_NIX 140
#define SCLEX_SEARCHRESULT 150 #define SCLEX_SEARCHRESULT 150
#define SCLEX_OBJC 151 #define SCLEX_OBJC 151
#define SCLEX_USER 152 #define SCLEX_USER 152
@ -205,6 +206,19 @@
#define SCE_C_USERLITERAL 25 #define SCE_C_USERLITERAL 25
#define SCE_C_TASKMARKER 26 #define SCE_C_TASKMARKER 26
#define SCE_C_ESCAPESEQUENCE 27 #define SCE_C_ESCAPESEQUENCE 27
#define SCE_COBOL_DEFAULT 0
#define SCE_COBOL_COMMENT 1
#define SCE_COBOL_COMMENTLINE 2
#define SCE_COBOL_COMMENTDOC 3
#define SCE_COBOL_NUMBER 4
#define SCE_COBOL_WORD 5
#define SCE_COBOL_STRING 6
#define SCE_COBOL_CHARACTER 7
#define SCE_COBOL_WORD3 8
#define SCE_COBOL_PREPROCESSOR 9
#define SCE_COBOL_OPERATOR 10
#define SCE_COBOL_IDENTIFIER 11
#define SCE_COBOL_WORD2 16
#define SCE_D_DEFAULT 0 #define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1 #define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2 #define SCE_D_COMMENTLINE 2
@ -1799,6 +1813,8 @@
#define SCE_RUST_BYTESTRING 21 #define SCE_RUST_BYTESTRING 21
#define SCE_RUST_BYTESTRINGR 22 #define SCE_RUST_BYTESTRINGR 22
#define SCE_RUST_BYTECHARACTER 23 #define SCE_RUST_BYTECHARACTER 23
#define SCE_RUST_CSTRING 24
#define SCE_RUST_CSTRINGR 25
#define SCE_DMAP_DEFAULT 0 #define SCE_DMAP_DEFAULT 0
#define SCE_DMAP_COMMENT 1 #define SCE_DMAP_COMMENT 1
#define SCE_DMAP_NUMBER 2 #define SCE_DMAP_NUMBER 2
@ -2154,6 +2170,23 @@
#define SCE_ZIG_KW_SECONDARY 14 #define SCE_ZIG_KW_SECONDARY 14
#define SCE_ZIG_KW_TERTIARY 15 #define SCE_ZIG_KW_TERTIARY 15
#define SCE_ZIG_KW_TYPE 16 #define SCE_ZIG_KW_TYPE 16
#define SCE_ZIG_IDENTIFIER_STRING 17
#define SCE_NIX_DEFAULT 0
#define SCE_NIX_COMMENTLINE 1
#define SCE_NIX_COMMENTBLOCK 2
#define SCE_NIX_STRING 3
#define SCE_NIX_STRING_MULTILINE 4
#define SCE_NIX_ESCAPECHAR 5
#define SCE_NIX_IDENTIFIER 6
#define SCE_NIX_OPERATOR 7
#define SCE_NIX_OPERATOR_STRING 8
#define SCE_NIX_NUMBER 9
#define SCE_NIX_KEY 10
#define SCE_NIX_PATH 11
#define SCE_NIX_KEYWORD1 12
#define SCE_NIX_KEYWORD2 13
#define SCE_NIX_KEYWORD3 14
#define SCE_NIX_KEYWORD4 15
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */

View File

@ -8,12 +8,11 @@
** Updated by Rod Falck, Aug 2006 Converted to COBOL ** Updated by Rod Falck, Aug 2006 Converted to COBOL
**/ **/
#include <stdlib.h> #include <cstdlib>
#include <string.h> #include <cassert>
#include <stdio.h> #include <cstring>
#include <stdarg.h> #include <cctype>
#include <assert.h> #include <cstdio>
#include <ctype.h>
#include <string> #include <string>
#include <string_view> #include <string_view>
@ -38,23 +37,25 @@ using namespace Lexilla;
#define IN_FLAGS 0xF #define IN_FLAGS 0xF
#define NOT_HEADER 0x10 #define NOT_HEADER 0x10
inline bool isCOBOLoperator(char ch) namespace {
bool isCOBOLoperator(char ch)
{ {
return isoperator(ch); return isoperator(ch);
} }
inline bool isCOBOLwordchar(char ch) bool isCOBOLwordchar(char ch)
{ {
return IsASCII(ch) && (isalnum(ch) || ch == '-'); return IsASCII(ch) && (isalnum(ch) || ch == '-');
} }
inline bool isCOBOLwordstart(char ch) bool isCOBOLwordstart(char ch)
{ {
return IsASCII(ch) && isalnum(ch); return IsASCII(ch) && isalnum(ch);
} }
static int CountBits(int nBits) int CountBits(int nBits)
{ {
int count = 0; int count = 0;
for (int i = 0; i < 32; ++i) for (int i = 0; i < 32; ++i)
@ -65,7 +66,7 @@ static int CountBits(int nBits)
return count; return count;
} }
static void getRange(Sci_PositionU start, void getRange(Sci_PositionU start,
Sci_PositionU end, Sci_PositionU end,
Accessor &styler, Accessor &styler,
char *s, char *s,
@ -78,12 +79,12 @@ static void getRange(Sci_PositionU start,
s[i] = '\0'; s[i] = '\0';
} }
static void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) { void ColourTo(Accessor &styler, Sci_PositionU end, unsigned int attr) {
styler.ColourTo(end, attr); styler.ColourTo(end, attr);
} }
static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) { int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList &keywords*/WordList *keywordlists[], Accessor &styler, int nContainment, bool *bAarea) {
int ret = 0; int ret = 0;
char s[100]; char s[100];
@ -91,31 +92,31 @@ static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList
s[1] = '\0'; s[1] = '\0';
getRange(start, end, styler, s, sizeof(s)); getRange(start, end, styler, s, sizeof(s));
int chAttr = SCE_C_IDENTIFIER; int chAttr = SCE_COBOL_IDENTIFIER;
if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) { if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
chAttr = SCE_C_NUMBER; chAttr = SCE_COBOL_NUMBER;
char *p = s + 1; char *p = s + 1;
while (*p) { while (*p) {
if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) { if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
chAttr = SCE_C_IDENTIFIER; chAttr = SCE_COBOL_IDENTIFIER;
break; break;
} }
++p; ++p;
} }
} }
if (chAttr == SCE_C_IDENTIFIER) { if (chAttr == SCE_COBOL_IDENTIFIER) {
WordList& a_keywords = *keywordlists[0]; WordList& a_keywords = *keywordlists[0];
WordList& b_keywords = *keywordlists[1]; WordList& b_keywords = *keywordlists[1];
WordList& c_keywords = *keywordlists[2]; WordList& c_keywords = *keywordlists[2];
if (a_keywords.InList(s)) { if (a_keywords.InList(s)) {
chAttr = SCE_C_WORD; chAttr = SCE_COBOL_WORD;
} }
else if (b_keywords.InList(s)) { else if (b_keywords.InList(s)) {
chAttr = SCE_C_WORD2; chAttr = SCE_COBOL_WORD2;
} }
else if (c_keywords.InList(s)) { else if (c_keywords.InList(s)) {
chAttr = SCE_C_UUID; chAttr = SCE_COBOL_WORD3;
} }
} }
if (*bAarea) { if (*bAarea) {
@ -143,14 +144,14 @@ static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList
return ret; return ret;
} }
static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
Accessor &styler) { Accessor &styler) {
styler.StartAt(startPos); styler.StartAt(startPos);
int state = initStyle; int state = initStyle;
if (state == SCE_C_CHARACTER) // Does not leak onto next line if (state == SCE_COBOL_CHARACTER) // Does not leak onto next line
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
char chPrev = ' '; char chPrev = ' ';
char chNext = styler[startPos]; char chNext = styler[startPos];
Sci_PositionU lengthDoc = startPos + length; Sci_PositionU lengthDoc = startPos + length;
@ -189,9 +190,9 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
// Avoid triggering two times on Dos/Win // Avoid triggering two times on Dos/Win
// End of line // End of line
if (state == SCE_C_CHARACTER) { if (state == SCE_COBOL_CHARACTER) {
ColourTo(styler, i, state); ColourTo(styler, i, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
styler.SetLineState(currentLine, nContainment); styler.SetLineState(currentLine, nContainment);
currentLine++; currentLine++;
@ -207,44 +208,44 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i
continue; continue;
} }
if (state == SCE_C_DEFAULT) { if (state == SCE_COBOL_DEFAULT) {
if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) { if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER; state = SCE_COBOL_IDENTIFIER;
} else if (column == 6 && (ch == '*' || ch == '/')) { } else if (column == 6 && (ch == '*' || ch == '/')) {
// Cobol comment line: asterisk in column 7. // Cobol comment line: asterisk in column 7.
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE; state = SCE_COBOL_COMMENTLINE;
} else if (ch == '*' && chNext == '>') { } else if (ch == '*' && chNext == '>') {
// Cobol inline comment: asterisk, followed by greater than. // Cobol inline comment: asterisk, followed by greater than.
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE; state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext != '*') { } else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE; state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '/' && chNext != '*') { } else if (column == 0 && ch == '/' && chNext != '*') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE; state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext == '*') { } else if (column == 0 && ch == '*' && chNext == '*') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC; state = SCE_COBOL_COMMENTDOC;
} else if (column == 0 && ch == '/' && chNext == '*') { } else if (column == 0 && ch == '/' && chNext == '*') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC; state = SCE_COBOL_COMMENTDOC;
} else if (ch == '"') { } else if (ch == '"') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_STRING; state = SCE_COBOL_STRING;
} else if (ch == '\'') { } else if (ch == '\'') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_CHARACTER; state = SCE_COBOL_CHARACTER;
} else if (ch == '?' && column == 0) { } else if (ch == '?' && column == 0) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_PREPROCESSOR; state = SCE_COBOL_PREPROCESSOR;
} else if (isCOBOLoperator(ch)) { } else if (isCOBOLoperator(ch)) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
ColourTo(styler, i, SCE_C_OPERATOR); ColourTo(styler, i, SCE_COBOL_OPERATOR);
} }
} else if (state == SCE_C_IDENTIFIER) { } else if (state == SCE_COBOL_IDENTIFIER) {
if (!isCOBOLwordchar(ch)) { if (!isCOBOLwordchar(ch)) {
int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea); int lStateChange = classifyWordCOBOL(styler.GetStartSegment(), i - 1, keywordlists, styler, nContainment, &bAarea);
@ -253,55 +254,55 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i
nContainment = lStateChange; nContainment = lStateChange;
} }
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
if (column == 6 && (ch == '*' || ch == '/')) { if (column == 6 && (ch == '*' || ch == '/')) {
state = SCE_C_COMMENTLINE; state = SCE_COBOL_COMMENTLINE;
} else if (ch == '"') { } else if (ch == '"') {
state = SCE_C_STRING; state = SCE_COBOL_STRING;
} else if (ch == '\'') { } else if (ch == '\'') {
state = SCE_C_CHARACTER; state = SCE_COBOL_CHARACTER;
} else if (isCOBOLoperator(ch)) { } else if (isCOBOLoperator(ch)) {
ColourTo(styler, i, SCE_C_OPERATOR); ColourTo(styler, i, SCE_COBOL_OPERATOR);
} }
} }
} else { } else {
if (state == SCE_C_PREPROCESSOR) { if (state == SCE_COBOL_PREPROCESSOR) {
if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) { if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} else if (state == SCE_C_COMMENT) { } else if (state == SCE_COBOL_COMMENT) {
if (ch == '\r' || ch == '\n') { if (ch == '\r' || ch == '\n') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} else if (state == SCE_C_COMMENTDOC) { } else if (state == SCE_COBOL_COMMENTDOC) {
if (ch == '\r' || ch == '\n') { if (ch == '\r' || ch == '\n') {
if (((i > styler.GetStartSegment() + 2) || ( if (((i > styler.GetStartSegment() + 2) || (
(initStyle == SCE_C_COMMENTDOC) && (initStyle == SCE_COBOL_COMMENTDOC) &&
(styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) { (styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} }
} else if (state == SCE_C_COMMENTLINE) { } else if (state == SCE_COBOL_COMMENTLINE) {
if (ch == '\r' || ch == '\n') { if (ch == '\r' || ch == '\n') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} else if (state == SCE_C_STRING) { } else if (state == SCE_COBOL_STRING) {
if (ch == '"') { if (ch == '"') {
ColourTo(styler, i, state); ColourTo(styler, i, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} else if (ch == '\r' || ch == '\n') { } else if (ch == '\r' || ch == '\n') {
ColourTo(styler, i-1, state); ColourTo(styler, i-1, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} else if (state == SCE_C_CHARACTER) { } else if (state == SCE_COBOL_CHARACTER) {
if (ch == '\'') { if (ch == '\'') {
ColourTo(styler, i, state); ColourTo(styler, i, state);
state = SCE_C_DEFAULT; state = SCE_COBOL_DEFAULT;
} }
} }
} }
@ -315,7 +316,7 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i
ColourTo(styler, lengthDoc - 1, state); ColourTo(styler, lengthDoc - 1, state);
} }
static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
Accessor &styler) { Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
Sci_PositionU endPos = startPos + length; Sci_PositionU endPos = startPos + length;
@ -377,11 +378,13 @@ static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordL
styler.SetLevel(lineCurrent, levelPrev | flagsNext); styler.SetLevel(lineCurrent, levelPrev | flagsNext);
} }
static const char * const COBOLWordListDesc[] = { const char * const COBOLWordListDesc[] = {
"A Keywords", "A Keywords",
"B Keywords", "B Keywords",
"Extended Keywords", "Extended Keywords",
0 nullptr
}; };
}
extern const LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc); extern const LexerModule lmCOBOL(SCLEX_COBOL, ColouriseCOBOLDoc, "COBOL", FoldCOBOLDoc, COBOLWordListDesc);

View File

@ -147,7 +147,7 @@ constexpr int statePrintForState(int state, script_mode inScriptType) noexcept {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
} else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
} }
} }
@ -668,6 +668,10 @@ constexpr bool isPHPStringState(int state) noexcept {
(state == SCE_HPHP_COMPLEX_VARIABLE); (state == SCE_HPHP_COMPLEX_VARIABLE);
} }
constexpr bool StyleNeedsBacktrack(int state) noexcept {
return InTagState(state) || isPHPStringState(state);
}
enum class AllowPHP : int { enum class AllowPHP : int {
None, // No PHP None, // No PHP
PHP, // <?php and <?= PHP, // <?php and <?=
@ -1190,7 +1194,6 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
if (isPHPScript && (startPos == 0)) { if (isPHPScript && (startPos == 0)) {
initStyle = SCE_HPHP_DEFAULT; initStyle = SCE_HPHP_DEFAULT;
} }
styler.StartAt(startPos);
std::string lastTag; std::string lastTag;
std::string prevWord; std::string prevWord;
PhpNumberState phpNumber; PhpNumberState phpNumber;
@ -1201,23 +1204,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
int makoComment = 0; int makoComment = 0;
std::string djangoBlockType; std::string djangoBlockType;
// If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen // If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen
if (InTagState(state)) { // PHP string can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
while ((startPos > 0) && (InTagState(styler.StyleIndexAt(startPos - 1)))) { if (StyleNeedsBacktrack(state)) {
while ((startPos > 0) && (StyleNeedsBacktrack(styler.StyleIndexAt(startPos - 1)))) {
const Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1)); const Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1));
length += startPos - backLineStart; length += startPos - backLineStart;
startPos = backLineStart; startPos = backLineStart;
} }
state = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : SCE_H_DEFAULT; if (startPos > 0) {
state = styler.StyleIndexAt(startPos - 1);
} else {
state = isPHPScript ? SCE_HPHP_DEFAULT : SCE_H_DEFAULT;
} }
// String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
if (isPHPStringState(state)) {
while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
startPos--;
length++;
state = styler.StyleIndexAt(startPos);
}
if (startPos == 0)
state = SCE_H_DEFAULT;
} }
styler.StartAt(startPos); styler.StartAt(startPos);
@ -2339,6 +2337,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} }
styler.ColourTo(i, StateToPrint); styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT; state = SCE_HJ_DEFAULT;
continue;
} else if (ch == '\\') { } else if (ch == '\\') {
// Gobble up the quoted character // Gobble up the quoted character
if (chNext == '\\' || chNext == '/') { if (chNext == '\\' || chNext == '/') {

527
lexilla/lexers/LexNix.cxx Normal file
View File

@ -0,0 +1,527 @@
// Scintilla source code edit control
/** @file LexNix.cxx
** Lexer for Nix.
**/
// Based on Zufu Liu's Notepad4 Dart lexer
// Modified for Nix and Scintilla by Jiri Techet, 2024
// The License.txt file describes the conditions under which this software may be distributed.
#include <cassert>
#include <cstring>
#include <string>
#include <string_view>
#include <vector>
#include <map>
#include <algorithm>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#include "OptionSet.h"
#include "DefaultLexer.h"
using namespace Scintilla;
using namespace Lexilla;
namespace {
// Use an unnamed namespace to protect the functions and classes from name conflicts
constexpr bool IsAGraphic(int ch) noexcept {
// excludes C0 control characters and whitespace
return ch > 32 && ch < 127;
}
constexpr bool IsIdentifierChar(int ch) noexcept {
return IsAlphaNumeric(ch) || ch == '_' || ch == '\'' || ch == '-';
}
constexpr bool IsIdentifierStart(int ch) noexcept {
return IsUpperOrLowerCase(ch) || ch == '_';
}
constexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {
return ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))
|| (ch == '.' && chNext != '.');
}
constexpr bool IsNumberStart(int ch, int chNext) noexcept {
return IsADigit(ch) || (ch == '.' && IsADigit(chNext));
}
constexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {
return IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);
}
constexpr bool IsNixIdentifierStart(int ch) noexcept {
return IsIdentifierStart(ch);
}
constexpr bool IsNixIdentifierChar(int ch) noexcept {
return IsIdentifierChar(ch);
}
constexpr bool IsPathTerminator(int ch) noexcept {
return isspacechar(ch) || AnyOf(ch, ';', ',', ']', '}', ')');
}
bool IsKey(LexAccessor &styler, Sci_Position start) {
for (Sci_Position i = 0; i < 50; i++) {
char curr = styler.SafeGetCharAt(start+i, '\0');
char next = styler.SafeGetCharAt(start+i+1, '\0');
bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n') || (curr == '\0');
if (curr == '=') {
return true;
} else if (!isspacechar(curr) || atEOL) {
return false;
}
}
return false;
}
bool IsPath(LexAccessor &styler, Sci_Position start) {
for (Sci_Position i = 0; i < 50; i++) {
char curr = styler.SafeGetCharAt(start+i, '\0');
char next = styler.SafeGetCharAt(start+i+1, '\0');
bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n') || (curr == '\0');
if (curr == '/') {
return true;
} else if (IsPathTerminator(curr) || curr == '$' || atEOL) {
return false;
}
}
return false;
}
enum {
NixLineStateMaskInterpolation = 1, // string interpolation
};
// string interpolating state
struct InterpolatingState {
int state;
int braceCount;
};
// Options used for LexerNix
struct OptionsNix {
bool fold = false;
};
const char * const nixWordListDesc[] = {
"Keywords 1",
"Keywords 2",
"Keywords 3",
"Keywords 4",
nullptr
};
struct OptionSetNix : public OptionSet<OptionsNix> {
OptionSetNix() {
DefineProperty("fold", &OptionsNix::fold);
DefineWordListSets(nixWordListDesc);
}
};
LexicalClass lexicalClasses[] = {
// Lexer NIX SCLEX_NIX SCE_NIX_:
0, "SCE_NIX_DEFAULT", "default", "White space",
1, "SCE_NIX_COMMENTLINE", "comment line", "Comment: //",
2, "SCE_NIX_COMMENTBLOCK", "comment", "Comment: /* */",
3, "SCE_NIX_STRING", "literal string", "Double quoted string",
4, "SCE_NIX_STRING_MULTILINE", "literal string multiline", "Single quoted multiline string",
5, "SCE_NIX_ESCAPECHAR", "literal string escapesequence", "Escape sequence",
6, "SCE_NIX_IDENTIFIER", "identifier", "Identifier",
7, "SCE_NIX_OPERATOR", "operator", "Operator",
8, "SCE_NIX_OPERATOR_STRING", "operator interpolated", "Braces following $ inside string",
9, "SCE_NIX_NUMBER", "literal numeric", "Number",
10, "SCE_NIX_KEY", "key", "Keys preceding '='",
11, "SCE_NIX_PATH", "identifier", "Path literal",
12, "SCE_NIX_KEYWORD1", "keyword", "Primary keywords",
13, "SCE_NIX_KEYWORD2", "identifier", "Keywords 2",
14, "SCE_NIX_KEYWORD3", "identifier", "Keywords 3",
15, "SCE_NIX_KEYWORD4", "identifier", "Keywords 4",
};
class LexerNix : public DefaultLexer {
WordList keywordsPrimary;
WordList keywordsSecondary;
WordList keywordsTertiary;
WordList keywordsTypes;
OptionsNix options;
OptionSetNix osNix;
public:
LexerNix(const char *languageName_, int language_) :
DefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {
}
// Deleted so LexerNix objects can not be copied.
LexerNix(const LexerNix &) = delete;
LexerNix(LexerNix &&) = delete;
void operator=(const LexerNix &) = delete;
void operator=(LexerNix &&) = delete;
~LexerNix() override = default;
void SCI_METHOD Release() override {
delete this;
}
int SCI_METHOD Version() const override {
return lvRelease5;
}
const char *SCI_METHOD PropertyNames() override {
return osNix.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) override {
return osNix.PropertyType(name);
}
const char *SCI_METHOD DescribeProperty(const char *name) override {
return osNix.DescribeProperty(name);
}
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
const char *SCI_METHOD PropertyGet(const char *key) override {
return osNix.PropertyGet(key);
}
const char *SCI_METHOD DescribeWordListSets() override {
return osNix.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 {
return nullptr;
}
void BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);
static ILexer5 *LexerFactoryNix() {
return new LexerNix("nix", SCLEX_NIX);
}
};
Sci_Position SCI_METHOD LexerNix::PropertySet(const char *key, const char *val) {
if (osNix.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
Sci_Position SCI_METHOD LexerNix::WordListSet(int n, const char *wl) {
WordList *wordListN = nullptr;
switch (n) {
case 0:
wordListN = &keywordsPrimary;
break;
case 1:
wordListN = &keywordsSecondary;
break;
case 2:
wordListN = &keywordsTertiary;
break;
case 3:
wordListN = &keywordsTypes;
break;
default:
break;
}
Sci_Position firstModification = -1;
if (wordListN && wordListN->Set(wl/*, false*/)) {
firstModification = 0;
}
return firstModification;
}
void LexerNix::BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle) {
const Sci_Position currentLine = styler.GetLine(startPos);
if (currentLine != 0) {
Sci_Position line = currentLine - 1;
int lineState = styler.GetLineState(line);
while ((lineState & stateMask) != 0 && line != 0) {
--line;
lineState = styler.GetLineState(line);
}
if ((lineState & stateMask) == 0) {
++line;
}
if (line != currentLine) {
const Sci_PositionU endPos = startPos + lengthDoc;
startPos = (line == 0) ? 0 : styler.LineStart(line);
lengthDoc = endPos - startPos;
initStyle = (startPos == 0) ? 0 : styler.StyleAt(startPos - 1);
}
}
}
void LexerNix::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, nullptr);
std::vector<InterpolatingState> interpolatingStack;
if (startPos != 0) {
// backtrack to the line where interpolation starts
BacktrackToStart(styler, NixLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
}
StyleContext sc(startPos, lengthDoc, initStyle, styler);
while (sc.More()) {
switch (sc.state) {
case SCE_NIX_OPERATOR:
case SCE_NIX_OPERATOR_STRING:
sc.SetState(SCE_NIX_DEFAULT);
break;
case SCE_NIX_NUMBER:
if (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {
sc.SetState(SCE_NIX_DEFAULT);
}
break;
case SCE_NIX_IDENTIFIER:
if (sc.state == SCE_NIX_IDENTIFIER && !IsNixIdentifierChar(sc.ch)) {
char s[64];
sc.GetCurrent(s, sizeof(s));
if (IsKey(styler, sc.currentPos)) {
sc.ChangeState(SCE_NIX_KEY);
} else if (keywordsPrimary.InList(s)) {
sc.ChangeState(SCE_NIX_KEYWORD1);
} else if (keywordsSecondary.InList(s)) {
sc.ChangeState(SCE_NIX_KEYWORD2);
} else if (keywordsTertiary.InList(s)) {
sc.ChangeState(SCE_NIX_KEYWORD3);
} else if (keywordsTypes.InList(s)) {
sc.ChangeState(SCE_NIX_KEYWORD4);
}
sc.SetState(SCE_NIX_DEFAULT);
}
break;
case SCE_NIX_COMMENTLINE:
if (sc.atLineStart) {
sc.SetState(SCE_NIX_DEFAULT);
}
break;
case SCE_NIX_COMMENTBLOCK:
if (sc.Match('*', '/')) {
sc.Forward(2);
sc.SetState(SCE_NIX_DEFAULT);
continue;
}
break;
case SCE_NIX_STRING:
if (sc.atLineStart) {
sc.SetState(SCE_NIX_DEFAULT);
} else if (sc.ch == '\\' && AnyOf(sc.chNext, '"', '\\', 'n', 'r', 't', '$')) {
sc.SetState(SCE_NIX_STRING);
sc.ChangeState(SCE_NIX_ESCAPECHAR);
sc.Forward(2);
sc.SetState(SCE_NIX_STRING);
continue;
} else if (sc.ch == '\"') {
sc.Forward();
sc.SetState(SCE_NIX_DEFAULT);
continue;
} else if (sc.Match('$','$')) {
sc.Forward();
continue;
}
break;
case SCE_NIX_PATH:
if (sc.atLineStart) {
sc.SetState(SCE_NIX_DEFAULT);
} else if (sc.ch == '>') {
sc.Forward();
sc.SetState(SCE_NIX_DEFAULT);
continue;
} else if (IsPathTerminator(sc.ch)) {
sc.SetState(SCE_NIX_DEFAULT);
}
break;
case SCE_NIX_STRING_MULTILINE:
if (sc.ch == '\'' && sc.chNext == '\'') {
if (AnyOf(styler.SafeGetCharAt(sc.currentPos+2, '\0'), '$', '\'', '\\')) {
sc.SetState(SCE_NIX_ESCAPECHAR);
sc.Forward(2);
if (sc.ch == '$' || sc.ch == '\'') {
sc.Forward();
} else if (sc.ch == '\\') {
sc.Forward(2);
}
sc.SetState(SCE_NIX_STRING_MULTILINE);
continue;
} else {
sc.Forward(2);
sc.SetState(SCE_NIX_DEFAULT);
continue;
}
} else if (sc.Match('$','$')) {
sc.Forward();
continue;
}
break;
}
if (sc.state == SCE_NIX_DEFAULT)
{
if (sc.ch == '/' && sc.chNext == '*') {
sc.SetState(SCE_NIX_COMMENTBLOCK);
sc.Forward();
continue;
} else if (sc.ch == '#') {
sc.SetState(SCE_NIX_COMMENTLINE);
} else if (sc.ch == '"') {
sc.SetState(SCE_NIX_STRING);
} else if (sc.ch == '\'' && sc.chNext == '\'') {
sc.SetState(SCE_NIX_STRING_MULTILINE);
sc.Forward();
continue;
} else if (IsNumberStart(sc.ch, sc.chNext)) {
sc.SetState(SCE_NIX_NUMBER);
} else if (sc.ch == '<') {
sc.SetState(SCE_NIX_PATH);
} else if ((IsNixIdentifierStart(sc.ch) || AnyOf(sc.ch, '~', '.', '/')) &&
IsPath(styler, sc.currentPos)) {
sc.SetState(SCE_NIX_PATH);
} else if (IsNixIdentifierStart(sc.ch)) {
sc.SetState(SCE_NIX_IDENTIFIER);
} else if (IsAGraphic(sc.ch) && sc.ch != '$') {
sc.SetState(SCE_NIX_OPERATOR);
if (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {
InterpolatingState &current = interpolatingStack.back();
if (sc.ch == '{') {
current.braceCount += 1;
} else {
current.braceCount -= 1;
if (current.braceCount == 0) {
sc.ChangeState(SCE_NIX_OPERATOR_STRING);
sc.ForwardSetState(current.state);
interpolatingStack.pop_back();
continue;
}
}
}
}
}
// string interpolations
if (AnyOf(sc.state, SCE_NIX_DEFAULT, SCE_NIX_STRING, SCE_NIX_STRING_MULTILINE, SCE_NIX_PATH)) {
if (sc.Match('$','{')) {
interpolatingStack.push_back({sc.state, 1});
sc.SetState(SCE_NIX_OPERATOR_STRING);
sc.Forward();
}
}
if (sc.atLineEnd) {
int lineState = 0;
if (!interpolatingStack.empty()) {
lineState |= NixLineStateMaskInterpolation;
}
styler.SetLineState(sc.currentLine, lineState);
}
sc.Forward();
}
sc.Complete();
}
void LexerNix::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
if (!options.fold)
return;
Accessor styler(pAccess, nullptr);
const Sci_PositionU endPos = startPos + lengthDoc;
Sci_Position lineCurrent = styler.GetLine(startPos);
while (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;
if (!AnyOf(initStyle, SCE_NIX_COMMENTBLOCK, SCE_NIX_STRING_MULTILINE)) {
break;
}
}
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) {
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
}
int levelNext = levelCurrent;
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);
lineStartNext = std::min(lineStartNext, endPos);
char chNext = styler[startPos];
int styleNext = styler.StyleIndexAt(startPos);
int style = initStyle;
while (startPos < endPos) {
const char ch = chNext;
const int stylePrev = style;
style = styleNext;
chNext = styler[++startPos];
styleNext = styler.StyleIndexAt(startPos);
switch (style) {
case SCE_NIX_COMMENTBLOCK:
if (style != stylePrev) {
levelNext++;
}
if (style != styleNext) {
levelNext--;
}
break;
case SCE_NIX_STRING_MULTILINE:
if (style != stylePrev && !AnyOf(stylePrev, SCE_NIX_ESCAPECHAR, SCE_NIX_OPERATOR_STRING)) {
levelNext++;
}
if (style != styleNext && !AnyOf(styleNext, SCE_NIX_ESCAPECHAR, SCE_NIX_OPERATOR_STRING)) {
levelNext--;
}
break;
case SCE_NIX_OPERATOR:
case SCE_NIX_OPERATOR_STRING:
if (ch == '{' || ch == '[' || ch == '(') {
levelNext++;
} else if (ch == '}' || ch == ']' || ch == ')') {
levelNext--;
}
break;
}
if (startPos == lineStartNext) {
levelNext = std::max(levelNext, SC_FOLDLEVELBASE);
const int levelUse = levelCurrent;
int lev = levelUse | (levelNext << 16);
if (levelUse < levelNext) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
lineStartNext = styler.LineStart(lineCurrent + 1);
lineStartNext = std::min(lineStartNext, endPos);
levelCurrent = levelNext;
}
}
}
} // unnamed namespace end
extern const LexerModule lmNix(SCLEX_NIX, LexerNix::LexerFactoryNix, "nix", nixWordListDesc);

View File

@ -36,10 +36,23 @@
using namespace Scintilla; using namespace Scintilla;
using namespace Lexilla; using namespace Lexilla;
static const int NUM_RUST_KEYWORD_LISTS = 7; namespace {
static const int MAX_RUST_IDENT_CHARS = 1023;
static bool IsStreamCommentStyle(int style) { constexpr int NUM_RUST_KEYWORD_LISTS = 7;
constexpr int MAX_RUST_IDENT_CHARS = 1023;
enum class StringType : int {
STRING = SCE_RUST_STRING,
BYTESTRING = SCE_RUST_BYTESTRING,
CSTRING = SCE_RUST_CSTRING,
RAW_STRING = SCE_RUST_STRINGR,
RAW_BYTESTRING = SCE_RUST_BYTESTRINGR,
RAW_CSTRING = SCE_RUST_CSTRINGR
};
static bool IsStreamCommentStyle(int style) noexcept {
return style == SCE_RUST_COMMENTBLOCK || return style == SCE_RUST_COMMENTBLOCK ||
style == SCE_RUST_COMMENTBLOCKDOC; style == SCE_RUST_COMMENTBLOCKDOC;
} }
@ -208,7 +221,7 @@ static void GrabString(char* s, Accessor& styler, Sci_Position start, Sci_Positi
} }
static void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) { static void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) {
Sci_Position start = pos; const Sci_Position start = pos;
while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0'))) while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0')))
pos++; pos++;
@ -226,7 +239,7 @@ static void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) {
} }
static void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywords) { static void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywords) {
Sci_Position start = pos; const Sci_Position start = pos;
while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0'))) while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0')))
pos++; pos++;
@ -254,9 +267,9 @@ static void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywor
/* Scans a sequence of digits, returning true if it found any. */ /* Scans a sequence of digits, returning true if it found any. */
static bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) { static bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) {
Sci_Position old_pos = pos; const Sci_Position old_pos = pos;
for (;;) { for (;;) {
int c = styler.SafeGetCharAt(pos, '\0'); const int c = styler.SafeGetCharAt(pos, '\0');
if (IsADigit(c, base) || c == '_') if (IsADigit(c, base) || c == '_')
pos++; pos++;
else else
@ -397,7 +410,7 @@ static bool IsValidStringEscape(int c) {
static bool ScanNumericEscape(Accessor &styler, Sci_Position& pos, Sci_Position num_digits, bool stop_asap) { static bool ScanNumericEscape(Accessor &styler, Sci_Position& pos, Sci_Position num_digits, bool stop_asap) {
for (;;) { for (;;) {
int c = styler.SafeGetCharAt(pos, '\0'); const int c = styler.SafeGetCharAt(pos, '\0');
if (!IsADigit(c, 16)) if (!IsADigit(c, 16))
break; break;
num_digits--; num_digits--;
@ -508,7 +521,7 @@ static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position
int c = styler.SafeGetCharAt(pos, '\0'); int c = styler.SafeGetCharAt(pos, '\0');
bool maybe_doc_comment = false; bool maybe_doc_comment = false;
if (c == '*') { if (c == '*') {
int n = styler.SafeGetCharAt(pos + 1, '\0'); const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (n != '*' && n != '/') { if (n != '*' && n != '/') {
maybe_doc_comment = true; maybe_doc_comment = true;
} }
@ -517,7 +530,7 @@ static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position
} }
for (;;) { for (;;) {
int n = styler.SafeGetCharAt(pos + 1, '\0'); const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (pos == styler.LineEnd(styler.GetLine(pos))) if (pos == styler.LineEnd(styler.GetLine(pos)))
styler.SetLineState(styler.GetLine(pos), level); styler.SetLineState(styler.GetLine(pos), level);
if (c == '*') { if (c == '*') {
@ -585,7 +598,7 @@ static void ResumeLineComment(Accessor &styler, Sci_Position& pos, Sci_Position
static void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max) { static void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max) {
pos++; pos++;
int c = styler.SafeGetCharAt(pos, '\0'); const int c = styler.SafeGetCharAt(pos, '\0');
pos++; pos++;
if (c == '/') if (c == '/')
ResumeLineComment(styler, pos, max, UnknownComment); ResumeLineComment(styler, pos, max, UnknownComment);
@ -593,7 +606,7 @@ static void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max)
ResumeBlockComment(styler, pos, max, UnknownComment, 1); ResumeBlockComment(styler, pos, max, UnknownComment, 1);
} }
static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max, StringType string_type) {
int c = styler.SafeGetCharAt(pos, '\0'); int c = styler.SafeGetCharAt(pos, '\0');
bool error = false; bool error = false;
while (c != '"' && !error) { while (c != '"' && !error) {
@ -604,13 +617,13 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
if (pos == styler.LineEnd(styler.GetLine(pos))) if (pos == styler.LineEnd(styler.GetLine(pos)))
styler.SetLineState(styler.GetLine(pos), 0); styler.SetLineState(styler.GetLine(pos), 0);
if (c == '\\') { if (c == '\\') {
int n = styler.SafeGetCharAt(pos + 1, '\0'); const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (IsValidStringEscape(n)) { if (IsValidStringEscape(n)) {
pos += 2; pos += 2;
} else if (n == 'x') { } else if (n == 'x') {
pos += 2; pos += 2;
error = !ScanNumericEscape(styler, pos, 2, true); error = !ScanNumericEscape(styler, pos, 2, true);
} else if (n == 'u' && !ascii_only) { } else if (n == 'u' && (string_type != StringType::BYTESTRING)) {
pos += 2; pos += 2;
if (styler.SafeGetCharAt(pos, '\0') != '{') { if (styler.SafeGetCharAt(pos, '\0') != '{') {
// old-style // old-style
@ -624,7 +637,7 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
else else
error = true; error = true;
} }
} else if (n == 'U' && !ascii_only) { } else if (n == 'U' && (string_type != StringType::BYTESTRING)) {
pos += 2; pos += 2;
error = !ScanNumericEscape(styler, pos, 8, true); error = !ScanNumericEscape(styler, pos, 8, true);
} else { } else {
@ -632,7 +645,7 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
error = true; error = true;
} }
} else { } else {
if (ascii_only && !IsASCII((char)c)) if (string_type == StringType::BYTESTRING && !IsASCII((char)c))
error = true; error = true;
else else
pos++; pos++;
@ -641,15 +654,16 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
} }
if (!error) if (!error)
pos++; pos++;
styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRING : SCE_RUST_STRING);
styler.ColourTo(pos - 1, static_cast<int>(string_type));
} }
static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, int num_hashes, bool ascii_only) { static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, int num_hashes, StringType string_type) {
for (;;) { for (;;) {
if (pos == styler.LineEnd(styler.GetLine(pos))) if (pos == styler.LineEnd(styler.GetLine(pos)))
styler.SetLineState(styler.GetLine(pos), num_hashes); styler.SetLineState(styler.GetLine(pos), num_hashes);
int c = styler.SafeGetCharAt(pos, '\0'); const int c = styler.SafeGetCharAt(pos, '\0');
if (c == '"') { if (c == '"') {
pos++; pos++;
int trailing_num_hashes = 0; int trailing_num_hashes = 0;
@ -664,15 +678,16 @@ static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position ma
} else if (pos >= max) { } else if (pos >= max) {
break; break;
} else { } else {
if (ascii_only && !IsASCII((char)c)) if ((string_type == StringType::RAW_BYTESTRING) && !IsASCII((char)c))
break; break;
pos++; pos++;
} }
} }
styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRINGR : SCE_RUST_STRINGR);
styler.ColourTo(pos - 1, static_cast<int>(string_type));
} }
static void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { static void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, StringType string_type) {
pos++; pos++;
int num_hashes = 0; int num_hashes = 0;
while (styler.SafeGetCharAt(pos, '\0') == '#') { while (styler.SafeGetCharAt(pos, '\0') == '#') {
@ -683,7 +698,7 @@ static void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max,
styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); styler.ColourTo(pos - 1, SCE_RUST_LEXERROR);
} else { } else {
pos++; pos++;
ResumeRawString(styler, pos, max, num_hashes, ascii_only); ResumeRawString(styler, pos, max, num_hashes, string_type);
} }
} }
@ -691,7 +706,7 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
PropSetSimple props; PropSetSimple props;
Accessor styler(pAccess, &props); Accessor styler(pAccess, &props);
Sci_Position pos = startPos; Sci_Position pos = startPos;
Sci_Position max = pos + length; const Sci_Position max = pos + length;
styler.StartAt(pos); styler.StartAt(pos);
styler.StartSegment(pos); styler.StartSegment(pos);
@ -701,19 +716,22 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
} else if (initStyle == SCE_RUST_COMMENTLINE || initStyle == SCE_RUST_COMMENTLINEDOC) { } else if (initStyle == SCE_RUST_COMMENTLINE || initStyle == SCE_RUST_COMMENTLINEDOC) {
ResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment); ResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment);
} else if (initStyle == SCE_RUST_STRING) { } else if (initStyle == SCE_RUST_STRING) {
ResumeString(styler, pos, max, false); ResumeString(styler, pos, max, StringType::STRING);
} else if (initStyle == SCE_RUST_BYTESTRING) { } else if (initStyle == SCE_RUST_BYTESTRING) {
ResumeString(styler, pos, max, true); ResumeString(styler, pos, max, StringType::BYTESTRING);
} else if (initStyle == SCE_RUST_STRINGR) { } else if (initStyle == SCE_RUST_STRINGR) {
ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), false); ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_STRING);
} else if (initStyle == SCE_RUST_BYTESTRINGR) { } else if (initStyle == SCE_RUST_BYTESTRINGR) {
ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), true); ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_BYTESTRING);
} else if (initStyle == SCE_RUST_CSTRING) {
ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::CSTRING);
} else if (initStyle == SCE_RUST_CSTRINGR) {
ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), StringType::RAW_CSTRING);
} }
while (pos < max) { while (pos < max) {
int c = styler.SafeGetCharAt(pos, '\0'); const int c = styler.SafeGetCharAt(pos, '\0');
int n = styler.SafeGetCharAt(pos + 1, '\0'); const int n = styler.SafeGetCharAt(pos + 1, '\0');
int n2 = styler.SafeGetCharAt(pos + 2, '\0'); const int n2 = styler.SafeGetCharAt(pos + 2, '\0');
if (pos == 0 && c == '#' && n == '!' && n2 != '[') { if (pos == 0 && c == '#' && n == '!' && n2 != '[') {
pos += 2; pos += 2;
@ -726,13 +744,19 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
pos += 2; pos += 2;
ScanRawIdentifier(styler, pos); ScanRawIdentifier(styler, pos);
} else if (c == 'r' && (n == '#' || n == '"')) { } else if (c == 'r' && (n == '#' || n == '"')) {
ScanRawString(styler, pos, max, false); ScanRawString(styler, pos, max, StringType::RAW_STRING);
} else if (c == 'b' && n == 'r' && (n2 == '#' || n2 == '"')) { } else if (c == 'b' && n == 'r' && (n2 == '#' || n2 == '"')) {
pos++; pos++;
ScanRawString(styler, pos, max, true); ScanRawString(styler, pos, max, StringType::RAW_BYTESTRING);
} else if (c == 'b' && n == '"') { } else if (c == 'b' && n == '"') {
pos += 2; pos += 2;
ResumeString(styler, pos, max, true); ResumeString(styler, pos, max, StringType::BYTESTRING);
} else if (c == 'c' && n == 'r' && (n2 == '#' || n2 == '"')) {
pos++;
ScanRawString(styler, pos, max, StringType::RAW_CSTRING);
} else if (c == 'c' && n == '"') {
pos += 2;
ResumeString(styler, pos, max, StringType::CSTRING);
} else if (c == 'b' && n == '\'') { } else if (c == 'b' && n == '\'') {
pos++; pos++;
ScanCharacterLiteralOrLifetime(styler, pos, true); ScanCharacterLiteralOrLifetime(styler, pos, true);
@ -753,7 +777,7 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
ScanCharacterLiteralOrLifetime(styler, pos, false); ScanCharacterLiteralOrLifetime(styler, pos, false);
} else if (c == '"') { } else if (c == '"') {
pos++; pos++;
ResumeString(styler, pos, max, false); ResumeString(styler, pos, max, StringType::STRING);
} else { } else {
pos++; pos++;
styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); styler.ColourTo(pos - 1, SCE_RUST_LEXERROR);
@ -770,7 +794,7 @@ void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int
LexAccessor styler(pAccess); LexAccessor styler(pAccess);
Sci_PositionU endPos = startPos + length; const Sci_PositionU endPos = startPos + length;
int visibleChars = 0; int visibleChars = 0;
bool inLineComment = false; bool inLineComment = false;
Sci_Position lineCurrent = styler.GetLine(startPos); Sci_Position lineCurrent = styler.GetLine(startPos);
@ -785,12 +809,12 @@ void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int
int style = initStyle; int style = initStyle;
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (Sci_PositionU i = startPos; i < endPos; i++) { for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext; const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1); chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style; const int stylePrev = style;
style = styleNext; style = styleNext;
styleNext = styler.StyleAt(i + 1); styleNext = styler.StyleAt(i + 1);
bool atEOL = i == (lineStartNext-1); const bool atEOL = i == (lineStartNext-1);
if ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC)) if ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC))
inLineComment = true; inLineComment = true;
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) { if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) {
@ -810,7 +834,7 @@ void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int
} }
} else { } else {
if ((ch == '/') && (chNext == '/')) { if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2); const char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') { if (chNext2 == '{') {
levelNext++; levelNext++;
} else if (chNext2 == '}') { } else if (chNext2 == '}') {
@ -860,4 +884,6 @@ void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int
} }
} }
}
extern const LexerModule lmRust(SCLEX_RUST, LexerRust::LexerFactoryRust, "rust", rustWordLists); extern const LexerModule lmRust(SCLEX_RUST, LexerRust::LexerFactoryRust, "rust", rustWordLists);

View File

@ -259,12 +259,9 @@ void ColouriseTOMLDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt
} }
} else if (sc.state == SCE_TOML_KEY && !IsTOMLUnquotedKey(sc.ch)) { } else if (sc.state == SCE_TOML_KEY && !IsTOMLUnquotedKey(sc.ch)) {
const int chNext = GetLineNextChar(sc); const int chNext = GetLineNextChar(sc);
if (chNext == '=') { if (chNext == '=' || (chNext != '.' && chPrevNonWhite != '.')) {
keyState = TOMLKeyState::End; keyState = TOMLKeyState::End;
sc.SetState(SCE_TOML_DEFAULT); sc.SetState(SCE_TOML_DEFAULT);
} else if (chNext != '.' && chPrevNonWhite != '.') {
sc.ChangeState(SCE_TOML_ERROR);
continue;
} }
} }
} }

View File

@ -162,6 +162,7 @@ LexicalClass lexicalClasses[] = {
14, "SCE_ZIG_KW_SECONDARY", "identifier", "Secondary keywords", 14, "SCE_ZIG_KW_SECONDARY", "identifier", "Secondary keywords",
15, "SCE_ZIG_KW_TERTIARY", "identifier", "Tertiary keywords", 15, "SCE_ZIG_KW_TERTIARY", "identifier", "Tertiary keywords",
16, "SCE_ZIG_KW_TYPE", "identifier", "Global types", 16, "SCE_ZIG_KW_TYPE", "identifier", "Global types",
17, "SCE_ZIG_IDENTIFIER_STRING", "identifier", "Identifier using @\"\" syntax",
}; };
class LexerZig : public DefaultLexer { class LexerZig : public DefaultLexer {
@ -307,6 +308,7 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
case SCE_ZIG_CHARACTER: case SCE_ZIG_CHARACTER:
case SCE_ZIG_STRING: case SCE_ZIG_STRING:
case SCE_ZIG_MULTISTRING: case SCE_ZIG_MULTISTRING:
case SCE_ZIG_IDENTIFIER_STRING:
if (sc.atLineStart) { if (sc.atLineStart) {
sc.SetState(SCE_ZIG_DEFAULT); sc.SetState(SCE_ZIG_DEFAULT);
} else if (sc.ch == '\\' && sc.state != SCE_ZIG_MULTISTRING) { } else if (sc.ch == '\\' && sc.state != SCE_ZIG_MULTISTRING) {
@ -318,16 +320,9 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
escSeq.digitsLeft = 9; escSeq.digitsLeft = 9;
sc.Forward(); sc.Forward();
} }
} else if ((sc.ch == '\'' && sc.state == SCE_ZIG_CHARACTER) || (sc.ch == '\"' && sc.state == SCE_ZIG_STRING)) { } else if ((sc.ch == '\'' && sc.state == SCE_ZIG_CHARACTER) ||
(sc.ch == '\"' && (sc.state == SCE_ZIG_STRING || sc.state == SCE_ZIG_IDENTIFIER_STRING))) {
sc.ForwardSetState(SCE_ZIG_DEFAULT); sc.ForwardSetState(SCE_ZIG_DEFAULT);
} else if (sc.state != SCE_ZIG_CHARACTER) {
if (sc.ch == '{' || sc.ch == '}') {
if (sc.ch == sc.chNext) {
escSeq.resetEscapeState(sc.state);
sc.SetState(SCE_ZIG_ESCAPECHAR);
sc.Forward();
}
}
} }
break; break;
@ -373,6 +368,9 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
sc.SetState(SCE_ZIG_NUMBER); sc.SetState(SCE_ZIG_NUMBER);
} else if ((sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) || IsIdentifierStartEx(sc.ch)) { } else if ((sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) || IsIdentifierStartEx(sc.ch)) {
sc.SetState((sc.ch == '@') ? SCE_ZIG_BUILTIN_FUNCTION : SCE_ZIG_IDENTIFIER); sc.SetState((sc.ch == '@') ? SCE_ZIG_BUILTIN_FUNCTION : SCE_ZIG_IDENTIFIER);
} else if (sc.ch == '@' && sc.chNext == '"') {
sc.SetState(SCE_ZIG_IDENTIFIER_STRING);
sc.Forward();
} else if (IsAGraphic(sc.ch)) { } else if (IsAGraphic(sc.ch)) {
sc.SetState(SCE_ZIG_OPERATOR); sc.SetState(SCE_ZIG_OPERATOR);
} }

View File

@ -20,7 +20,7 @@ namespace {
const int catRanges[] = { const int catRanges[] = {
//++Autogenerated -- start of section automatically generated //++Autogenerated -- start of section automatically generated
// Created with Python 3.12.0, Unicode 15.0.0 // Created with Python 3.13.0, Unicode 15.1.0
25, 25,
1046, 1046,
1073, 1073,
@ -2255,7 +2255,6 @@ const int catRanges[] = {
385045, 385045,
391901, 391901,
392725, 392725,
393117,
393238, 393238,
393265, 393265,
393365, 393365,
@ -2319,6 +2318,7 @@ const int catRanges[] = {
406532, 406532,
407573, 407573,
408733, 408733,
409077,
409092, 409092,
409621, 409621,
410621, 410621,
@ -4012,6 +4012,8 @@ const int catRanges[] = {
5887069, 5887069,
5887492, 5887492,
6126653, 6126653,
6127108,
6147037,
6225924, 6225924,
6243293, 6243293,
6291460, 6291460,

View File

@ -108,6 +108,7 @@ extern const LexerModule lmMSSQL;
extern const LexerModule lmMySQL; extern const LexerModule lmMySQL;
extern const LexerModule lmNim; extern const LexerModule lmNim;
extern const LexerModule lmNimrod; extern const LexerModule lmNimrod;
extern const LexerModule lmNix;
extern const LexerModule lmNncrontab; extern const LexerModule lmNncrontab;
extern const LexerModule lmNsis; extern const LexerModule lmNsis;
extern const LexerModule lmNull; extern const LexerModule lmNull;
@ -263,6 +264,7 @@ void AddEachLexer() {
&lmMySQL, &lmMySQL,
&lmNim, &lmNim,
&lmNimrod, &lmNimrod,
&lmNix,
&lmNncrontab, &lmNncrontab,
&lmNsis, &lmNsis,
&lmNull, &lmNull,

View File

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

View File

@ -160,6 +160,7 @@
14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */ = {isa = PBXBuildFile; fileRef = D2EF4913B8F91656C787F584 /* LexTroff.cxx */; }; 14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */ = {isa = PBXBuildFile; fileRef = D2EF4913B8F91656C787F584 /* LexTroff.cxx */; };
0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1F274010A7943C43BA265511 /* LexDart.cxx */; }; 0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1F274010A7943C43BA265511 /* LexDart.cxx */; };
CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 71684CF6BCC80369BCE2F893 /* LexZig.cxx */; }; CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 71684CF6BCC80369BCE2F893 /* LexZig.cxx */; };
4A444CF5A75E52E2C5537328 /* LexNix.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@ -318,6 +319,7 @@
D2EF4913B8F91656C787F584 /* LexTroff.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTroff.cxx; path = ../../lexers/LexTroff.cxx; sourceTree = SOURCE_ROOT; }; D2EF4913B8F91656C787F584 /* LexTroff.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTroff.cxx; path = ../../lexers/LexTroff.cxx; sourceTree = SOURCE_ROOT; };
1F274010A7943C43BA265511 /* LexDart.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDart.cxx; path = ../../lexers/LexDart.cxx; sourceTree = SOURCE_ROOT; }; 1F274010A7943C43BA265511 /* LexDart.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDart.cxx; path = ../../lexers/LexDart.cxx; sourceTree = SOURCE_ROOT; };
71684CF6BCC80369BCE2F893 /* LexZig.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexZig.cxx; path = ../../lexers/LexZig.cxx; sourceTree = SOURCE_ROOT; }; 71684CF6BCC80369BCE2F893 /* LexZig.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexZig.cxx; path = ../../lexers/LexZig.cxx; sourceTree = SOURCE_ROOT; };
81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexNix.cxx; path = ../../lexers/LexNix.cxx; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -436,6 +438,7 @@
28BA72E124E34D9200272C2D /* LexMySQL.cxx */, 28BA72E124E34D9200272C2D /* LexMySQL.cxx */,
28BA72D324E34D9200272C2D /* LexNim.cxx */, 28BA72D324E34D9200272C2D /* LexNim.cxx */,
28BA733624E34D9700272C2D /* LexNimrod.cxx */, 28BA733624E34D9700272C2D /* LexNimrod.cxx */,
81E2488CB0A0DC6B67AA08DD /* LexNix.cxx */,
28BA72F424E34D9300272C2D /* LexNsis.cxx */, 28BA72F424E34D9300272C2D /* LexNsis.cxx */,
28BA731424E34D9500272C2D /* LexNull.cxx */, 28BA731424E34D9500272C2D /* LexNull.cxx */,
28BA731824E34D9500272C2D /* LexOpal.cxx */, 28BA731824E34D9500272C2D /* LexOpal.cxx */,
@ -745,6 +748,7 @@
14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */, 14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */,
0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */, 0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */,
CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */, CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */,
4A444CF5A75E52E2C5537328 /* LexNix.cxx in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -872,7 +876,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.4.1; CURRENT_PROJECT_VERSION = 5.4.2;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E; DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;
@ -900,7 +904,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.4.1; CURRENT_PROJECT_VERSION = 5.4.2;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E; DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_COMPATIBILITY_VERSION = 1;

View File

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

View File

@ -1034,6 +1034,20 @@ $(DIR_O)/LexNimrod.o: \
../lexlib/StyleContext.h \ ../lexlib/StyleContext.h \
../lexlib/CharacterSet.h \ ../lexlib/CharacterSet.h \
../lexlib/LexerModule.h ../lexlib/LexerModule.h
$(DIR_O)/LexNix.o: \
../lexers/LexNix.cxx \
../../scintilla/include/ILexer.h \
../../scintilla/include/Sci_Position.h \
../../scintilla/include/Scintilla.h \
../include/SciLexer.h \
../lexlib/WordList.h \
../lexlib/LexAccessor.h \
../lexlib/Accessor.h \
../lexlib/StyleContext.h \
../lexlib/CharacterSet.h \
../lexlib/LexerModule.h \
../lexlib/OptionSet.h \
../lexlib/DefaultLexer.h
$(DIR_O)/LexNsis.o: \ $(DIR_O)/LexNsis.o: \
../lexers/LexNsis.cxx \ ../lexers/LexNsis.cxx \
../../scintilla/include/ILexer.h \ ../../scintilla/include/ILexer.h \

View File

@ -158,6 +158,7 @@ LEX_OBJS=\
$(DIR_O)\LexMySQL.obj \ $(DIR_O)\LexMySQL.obj \
$(DIR_O)\LexNim.obj \ $(DIR_O)\LexNim.obj \
$(DIR_O)\LexNimrod.obj \ $(DIR_O)\LexNimrod.obj \
$(DIR_O)\LexNix.obj \
$(DIR_O)\LexNsis.obj \ $(DIR_O)\LexNsis.obj \
$(DIR_O)\LexNull.obj \ $(DIR_O)\LexNull.obj \
$(DIR_O)\LexOpal.obj \ $(DIR_O)\LexOpal.obj \

View File

@ -1034,6 +1034,20 @@ $(DIR_O)/LexNimrod.obj: \
../lexlib/StyleContext.h \ ../lexlib/StyleContext.h \
../lexlib/CharacterSet.h \ ../lexlib/CharacterSet.h \
../lexlib/LexerModule.h ../lexlib/LexerModule.h
$(DIR_O)/LexNix.obj: \
../lexers/LexNix.cxx \
../../scintilla/include/ILexer.h \
../../scintilla/include/Sci_Position.h \
../../scintilla/include/Scintilla.h \
../include/SciLexer.h \
../lexlib/WordList.h \
../lexlib/LexAccessor.h \
../lexlib/Accessor.h \
../lexlib/StyleContext.h \
../lexlib/CharacterSet.h \
../lexlib/LexerModule.h \
../lexlib/OptionSet.h \
../lexlib/DefaultLexer.h
$(DIR_O)/LexNsis.obj: \ $(DIR_O)/LexNsis.obj: \
../lexers/LexNsis.cxx \ ../lexers/LexNsis.cxx \
../../scintilla/include/ILexer.h \ ../../scintilla/include/ILexer.h \

View File

@ -2,4 +2,9 @@
/a|b/i.test("baby"); /a|b/i.test("baby");
// arrow function // arrow function
() => /a|b/i.test("baby"); () => /a|b/i.test("baby");
// Issue 289
/a/g.test('a');
/a/gm.test('a');
'a'.replace(/a/g, 'b');
'a'.replace(/a/gm, 'b');
</script> </script>

View File

@ -2,5 +2,10 @@
0 401 0 | /a|b/i.test("baby"); 0 401 0 | /a|b/i.test("baby");
0 401 0 | // arrow function 0 401 0 | // arrow function
0 401 0 | () => /a|b/i.test("baby"); 0 401 0 | () => /a|b/i.test("baby");
0 401 0 | // Issue 289
0 401 0 | /a/g.test('a');
0 401 0 | /a/gm.test('a');
0 401 0 | 'a'.replace(/a/g, 'b');
0 401 0 | 'a'.replace(/a/gm, 'b');
0 401 0 | </script> 0 401 0 | </script>
0 400 0 0 400 0

View File

@ -1,5 +1,10 @@
{1}<script>{40} {1}<script>{40}
{52}/a|b/i{46}.test{50}({48}"baby"{50});{41} {52}/a|b/i{50}.{46}test{50}({48}"baby"{50});{41}
{43}// arrow function{41} {43}// arrow function{41}
{50}(){41} {50}=>{41} {52}/a|b/i{46}.test{50}({48}"baby"{50});{41} {50}(){41} {50}=>{41} {52}/a|b/i{50}.{46}test{50}({48}"baby"{50});{41}
{43}// Issue 289{41}
{52}/a/g{50}.{46}test{50}({49}'a'{50});{41}
{52}/a/gm{50}.{46}test{50}({49}'a'{50});{41}
{49}'a'{50}.{46}replace{50}({52}/a/g{50},{41} {49}'b'{50});{41}
{49}'a'{50}.{46}replace{50}({52}/a/gm{50},{41} {49}'b'{50});{41}
{1}</script>{0} {1}</script>{0}

View File

@ -0,0 +1,4 @@
<?
nl2br("\n); // unterminated string
?>
")

View File

@ -0,0 +1,5 @@
2 400 0 + <?
0 401 0 | nl2br("\n); // unterminated string
0 401 0 | ?>
0 401 0 | ")
0 401 0 |

View File

@ -0,0 +1,4 @@
{18}<?{118}
{198}nl2br{127}({119}"\n); // unterminated string
?>
"{127}){118}

View File

@ -33,7 +33,7 @@ substyles.hypertext.96=1
substylewords.96.1.*=parse substylewords.96.1.*=parse
# PHP # PHP
substyles.hypertext.121=1 substyles.hypertext.121=1
substylewords.121.1.*=decrypt substylewords.121.1.*=decrypt nl2br
fold=1 fold=1
fold.html=1 fold.html=1

View File

@ -15,5 +15,6 @@ Start
<%var x=3;//comment%> <%var x=3;//comment%>
<%x=3;//comment ?> %> <%x=3;//comment ?> %>
<%Response.Write(x)%> <%Response.Write(x)%>
<%Response.Write(`template ${2+2}`)%>
End End
</html> </html>

View File

@ -15,6 +15,7 @@
0 401 0 | <%var x=3;//comment%> 0 401 0 | <%var x=3;//comment%>
0 401 0 | <%x=3;//comment ?> %> 0 401 0 | <%x=3;//comment ?> %>
0 401 0 | <%Response.Write(x)%> 0 401 0 | <%Response.Write(x)%>
0 401 0 | <%Response.Write(`template ${2+2}`)%>
0 401 0 | End 0 401 0 | End
0 401 0 | </html> 0 401 0 | </html>
0 400 0 0 400 0

View File

@ -15,5 +15,6 @@ Start
{15}<%{62}var{56} {61}x{65}={60}3{65};{58}//comment{15}%>{0} {15}<%{62}var{56} {61}x{65}={60}3{65};{58}//comment{15}%>{0}
{15}<%{61}x{65}={60}3{65};{58}//comment ?> {15}%>{0} {15}<%{61}x{65}={60}3{65};{58}//comment ?> {15}%>{0}
{15}<%{61}Response.Write{65}({61}x{65}){15}%>{0} {15}<%{61}Response.Write{65}({61}x{65}){15}%>{0}
{15}<%{61}Response.Write{65}({68}`template ${2+2}`{65}){15}%>{0}
End End
{1}</html>{0} {1}</html>{0}

View File

@ -1,7 +1,7 @@
{12}<?{1}xml{8} {3}version{8}={6}"1.0"{8} {3}encoding{8}={6}"UTF-8"{13}?>{0} {12}<?{1}xml{8} {3}version{8}={6}"1.0"{8} {3}encoding{8}={6}"UTF-8"{13}?>{0}
{1}<html{8} {3}xmlns{8}={6}"http://www.w3.org/1999/xhtml"{1}>{0} {1}<html{8} {3}xmlns{8}={6}"http://www.w3.org/1999/xhtml"{1}>{0}
{1}<script{8} {3}type{8}={6}"text/javascript"{1}>{40} {1}<script{8} {3}type{8}={6}"text/javascript"{1}>{40}
{47}var{41} {46}b{41} {50}={41} {52}/abc/i{46}.test{50}({49}'abc'{50});{41} {47}var{41} {46}b{41} {50}={41} {52}/abc/i{50}.{46}test{50}({49}'abc'{50});{41}
{194}let{41} {46}b{41} {50}={41} {45}1{50};{41} {194}let{41} {46}b{41} {50}={41} {45}1{50};{41}
{49}'x\ {49}'x\
</t>'{41} </t>'{41}

View File

@ -0,0 +1,349 @@
# coding:utf-8
1 + 2
let
x = 1;
y = 2;
in x + y
let x=1;y=2;in x+y
{
string = "hello";
integer = 1;
float = 3.141;
bool = true;
null = null;
list = [ 1 "two" false ];
attribute-set = {
a = "hello";
b = 2;
c = 2.718;
d = false;
}; # comments are supported
}
rec {
one = 1;
two = one + 1;
three = two + 1;
}
{ one = 1; three = 3; two = 2; }
let
a = 1;
in
a + a
let
b = a + 1;
a = 1;
in
a + b
{
a = let x = 1; in x;
b = x;
}
let
attrset = { x = 1; };
in
attrset.x
let
attrset = { a = { b = { c = 1; }; }; };
in
attrset.a.b.c
{ a.b.c = 1; }
let
a = {
x = 1;
y = 2;
z = 3;
};
in
with a; [ x y z ]
let
x = 1;
y = 2;
in
{
inherit x y;
}
let
a = { x = 1; y = 2; };
in
{
inherit (a) x y;
}
let
inherit ({ x = 1; y = 2; }) x y;
in [ x y ]
let
name = "Nix${}";
in
"hello ${name}"
graphviz = (import ../tools/graphics/graphviz) {
inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
inherit (xorg) libXaw;
};
let negate = x: !x;
concat = x: y: x + y;
in if negate true then concat "foo" "bar" else ""
# A number
# Equals 1 + 1
# asd
/* /*
Block comments
can span multiple lines.
*/ "hello"
"hello"
/* /* nope */ 1
map (concat "foo") [ "bar" "bla" "abc" ]
{ localServer ? false
, httpServer ? false
, sslSupport ? false
, pythonBindings ? false
, javaSwigBindings ? false
, javahlBindings ? false
, stdenv, fetchurl
, openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
}:
assert localServer -> db4 != null;
assert httpServer -> httpd != null && httpd.expat == expat;
assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);
assert pythonBindings -> swig != null && swig.pythonSupport;
assert javaSwigBindings -> swig != null && swig.javaSupport;
assert javahlBindings -> j2sdk != null;
stdenv.mkDerivation {
name = "subversion-1.1.1";
openssl = if sslSupport then openssl else null;
}
configureFlags = ''
-system-zlib -system-libpng -system-libjpeg
${if openglSupport then ''-dlopen-opengl
-L${mesa}/lib -I${mesa}/include
-L${libXmu}/lib -I${libXmu}/include'' else ""}
${if threadSupport then "-thread" else "-no-thread"}
'';
let
a = "no";
a.b.c.d = "foo"
in
"${a + " ${a + " ${a}"}"}"
let
out = "Nix";
in
"echo ${out} > $out"
<nixpkgs/lib>
''
multi
''${}
'''
line
''\n
string
''
''
one
two
three
''
x: x + 1
x: y: x + y
{ a, b }: a + b
{ a, b ? 0 }: a + b
{ a, b, ...}: a + b
args@{ a, b, ... }: a + b + args.c
{ a, b, ... }@args: a + b + args.c
let
f = x: x + 1;
in f
let
f = x: x + 1;
in f 1
let
f = x: x.a;
v = { a = 1; };
in
f v
(x: x + 1) 1
let
f = x: x + 1;
a = 1;
in [ (f a) ]
let
f = x: x + 1;
a = 1;
in [ f a ]
let
f = x: y: x + y;
in
f 1 2
{a, b}: a + b
let
f = {a, b}: a + b;
in
f { a = 1; b = 2; }
let
f = {a, b}: a + b;
in
f { a = 1; b = 2; c = 3; }
let
f = {a, b ? 0}: a + b;
in
f { a = 1; }
let
f = {a ? 0, b ? 0}: a + b;
in
f { } # empty attribute set
let
f = {a, b, ...}: a + b;
in
f { a = 1; b = 2; c = 3; }
{a, b, ...}@args: a + b + args.c
args@{a, b, ...}: a + b + args.c
let
f = {a, b, ...}@args: a + b + args.c;
in
f { a = 1; b = 2; c = 3; }
{ pkgs ? import <nixpkgs> {} }:
let
message = "hello world";
in
pkgs.mkShellNoCC {
packages = with pkgs; [ cowsay ];
shellHook = ''
cowsay ${message}
'';
}
{ config, pkgs, ... }: {
imports = [ ./hardware-configuration.nix ];
environment.systemPackages = with pkgs; [ git ];
# ...
}
{ lib, stdenv, fetchurl }:
stdenv.mkDerivation rec {
pname = "hello";
version = "2.12";
src = fetchurl {
url = "mirror://gnu/${pname}/${pname}-${version}.tar.gz";
sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g";
};
meta = with lib; {
license = licenses.gpl3Plus;
};
}
{
baseName = baseNameOf name;
pullImage =
let
fixName = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
in
{ imageName
# To find the digest of an image, you can use skopeo:
# see doc/functions.xml
, imageDigest
, sha256
, os ? "linux"
, # Image architecture, defaults to the architecture of the `hostPlatform` when unset
arch ? defaultArchitecture
# This is used to set name to the pulled image
, finalImageName ? imageName
# This used to set a tag to the pulled image
, finalImageTag ? "latest"
# This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks
, tlsVerify ? true
, name ? fixName "docker-image-${finalImageName}-${finalImageTag}.tar"
}:
runCommand name
{
inherit imageDigest;
imageName = finalImageName;
imageTag = finalImageTag;
impureEnvVars = lib.fetchers.proxyImpureEnvVars;
outputHashMode = "flat";
outputHashAlgo = "sha256";
outputHash = sha256;
nativeBuildInputs = [ skopeo ];
SSL_CERT_FILE = "${cacert.out}/etc/ssl/certs/ca-bundle.crt";
sourceURL = "docker://${imageName}@${imageDigest}";
destNameTag = "${finalImageName}:${finalImageTag}";
} ''
skopeo \
--insecure-policy \
--tmpdir=$TMPDIR \
--override-os ${os} \
--override-arch ${arch} \
copy \
--src-tls-verify=${lib.boolToString tlsVerify} \
"$sourceURL" "docker-archive://$out:$destNameTag" \
| cat # pipe through cat to force-disable progress bar
'';
}

View File

@ -0,0 +1,350 @@
0 400 400 # coding:utf-8
0 400 400
0 400 400 1 + 2
0 400 400
0 400 400 let
0 400 400 x = 1;
0 400 400 y = 2;
0 400 400 in x + y
0 400 400
0 400 400 let x=1;y=2;in x+y
0 400 400
2 400 401 + {
0 401 401 | string = "hello";
0 401 401 | integer = 1;
0 401 401 | float = 3.141;
0 401 401 | bool = true;
0 401 401 | null = null;
0 401 401 | list = [ 1 "two" false ];
2 401 402 + attribute-set = {
0 402 402 | a = "hello";
0 402 402 | b = 2;
0 402 402 | c = 2.718;
0 402 402 | d = false;
0 402 401 | }; # comments are supported
0 401 400 | }
0 400 400
2 400 401 + rec {
0 401 401 | one = 1;
0 401 401 | two = one + 1;
0 401 401 | three = two + 1;
0 401 400 | }
0 400 400
0 400 400 { one = 1; three = 3; two = 2; }
0 400 400
0 400 400 let
0 400 400 a = 1;
0 400 400 in
0 400 400 a + a
0 400 400
0 400 400 let
0 400 400 b = a + 1;
0 400 400 a = 1;
0 400 400 in
0 400 400 a + b
0 400 400
2 400 401 + {
0 401 401 | a = let x = 1; in x;
0 401 401 | b = x;
0 401 400 | }
0 400 400
0 400 400 let
0 400 400 attrset = { x = 1; };
0 400 400 in
0 400 400 attrset.x
0 400 400
0 400 400 let
0 400 400 attrset = { a = { b = { c = 1; }; }; };
0 400 400 in
0 400 400 attrset.a.b.c
0 400 400
0 400 400 { a.b.c = 1; }
0 400 400
0 400 400 let
2 400 401 + a = {
0 401 401 | x = 1;
0 401 401 | y = 2;
0 401 401 | z = 3;
0 401 400 | };
0 400 400 in
0 400 400 with a; [ x y z ]
0 400 400
0 400 400 let
0 400 400 x = 1;
0 400 400 y = 2;
0 400 400 in
2 400 401 + {
0 401 401 | inherit x y;
0 401 400 | }
0 400 400
0 400 400 let
0 400 400 a = { x = 1; y = 2; };
0 400 400 in
2 400 401 + {
0 401 401 | inherit (a) x y;
0 401 400 | }
0 400 400
0 400 400 let
0 400 400 inherit ({ x = 1; y = 2; }) x y;
0 400 400 in [ x y ]
0 400 400
0 400 400 let
0 400 400 name = "Nix${}";
0 400 400 in
0 400 400 "hello ${name}"
0 400 400
2 400 401 + graphviz = (import ../tools/graphics/graphviz) {
0 401 401 | inherit fetchurl stdenv libpng libjpeg expat x11 yacc;
0 401 401 | inherit (xorg) libXaw;
0 401 400 | };
0 400 400
0 400 400 let negate = x: !x;
0 400 400 concat = x: y: x + y;
0 400 400 in if negate true then concat "foo" "bar" else ""
0 400 400
0 400 400 # A number
0 400 400 # Equals 1 + 1
0 400 400 # asd
0 400 400
2 400 401 + /* /*
0 401 401 | Block comments
0 401 401 | can span multiple lines.
0 401 400 | */ "hello"
0 400 400 "hello"
0 400 400
0 400 400 /* /* nope */ 1
0 400 400
0 400 400 map (concat "foo") [ "bar" "bla" "abc" ]
0 400 400
2 400 401 + { localServer ? false
0 401 401 | , httpServer ? false
0 401 401 | , sslSupport ? false
0 401 401 | , pythonBindings ? false
0 401 401 | , javaSwigBindings ? false
0 401 401 | , javahlBindings ? false
0 401 401 | , stdenv, fetchurl
0 401 401 | , openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null
0 401 400 | }:
0 400 400
0 400 400 assert localServer -> db4 != null;
0 400 400 assert httpServer -> httpd != null && httpd.expat == expat;
0 400 400 assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl);
0 400 400 assert pythonBindings -> swig != null && swig.pythonSupport;
0 400 400 assert javaSwigBindings -> swig != null && swig.javaSupport;
0 400 400 assert javahlBindings -> j2sdk != null;
0 400 400
2 400 401 + stdenv.mkDerivation {
0 401 401 | name = "subversion-1.1.1";
0 401 401 | openssl = if sslSupport then openssl else null;
0 401 400 | }
0 400 400
2 400 401 + configureFlags = ''
0 401 401 | -system-zlib -system-libpng -system-libjpeg
2 401 403 + ${if openglSupport then ''-dlopen-opengl
0 403 403 | -L${mesa}/lib -I${mesa}/include
0 403 401 | -L${libXmu}/lib -I${libXmu}/include'' else ""}
0 401 401 | ${if threadSupport then "-thread" else "-no-thread"}
0 401 400 | '';
0 400 400
0 400 400 let
0 400 400 a = "no";
0 400 400 a.b.c.d = "foo"
0 400 400 in
0 400 400 "${a + " ${a + " ${a}"}"}"
0 400 400
0 400 400 let
0 400 400 out = "Nix";
0 400 400 in
0 400 400 "echo ${out} > $out"
0 400 400
0 400 400 <nixpkgs/lib>
0 400 400
2 400 401 + ''
0 401 401 | multi
0 401 401 | ''${}
0 401 401 | '''
0 401 401 | line
0 401 401 | ''\n
0 401 401 | string
0 401 400 | ''
0 400 400
2 400 401 + ''
0 401 401 | one
0 401 401 | two
0 401 401 | three
0 401 400 | ''
0 400 400
0 400 400 x: x + 1
0 400 400
0 400 400 x: y: x + y
0 400 400
0 400 400 { a, b }: a + b
0 400 400
0 400 400 { a, b ? 0 }: a + b
0 400 400
0 400 400 { a, b, ...}: a + b
0 400 400
0 400 400 args@{ a, b, ... }: a + b + args.c
0 400 400
0 400 400 { a, b, ... }@args: a + b + args.c
0 400 400
0 400 400 let
0 400 400 f = x: x + 1;
0 400 400 in f
0 400 400
0 400 400 let
0 400 400 f = x: x + 1;
0 400 400 in f 1
0 400 400
0 400 400 let
0 400 400 f = x: x.a;
0 400 400 v = { a = 1; };
0 400 400 in
0 400 400 f v
0 400 400
0 400 400 (x: x + 1) 1
0 400 400
0 400 400 let
0 400 400 f = x: x + 1;
0 400 400 a = 1;
0 400 400 in [ (f a) ]
0 400 400
0 400 400 let
0 400 400 f = x: x + 1;
0 400 400 a = 1;
0 400 400 in [ f a ]
0 400 400
0 400 400 let
0 400 400 f = x: y: x + y;
0 400 400 in
0 400 400 f 1 2
0 400 400
0 400 400 {a, b}: a + b
0 400 400
0 400 400 let
0 400 400 f = {a, b}: a + b;
0 400 400 in
0 400 400 f { a = 1; b = 2; }
0 400 400
0 400 400 let
0 400 400 f = {a, b}: a + b;
0 400 400 in
0 400 400 f { a = 1; b = 2; c = 3; }
0 400 400
0 400 400 let
0 400 400 f = {a, b ? 0}: a + b;
0 400 400 in
0 400 400 f { a = 1; }
0 400 400
0 400 400 let
0 400 400 f = {a ? 0, b ? 0}: a + b;
0 400 400 in
0 400 400 f { } # empty attribute set
0 400 400
0 400 400 let
0 400 400 f = {a, b, ...}: a + b;
0 400 400 in
0 400 400 f { a = 1; b = 2; c = 3; }
0 400 400
0 400 400 {a, b, ...}@args: a + b + args.c
0 400 400
0 400 400 args@{a, b, ...}: a + b + args.c
0 400 400
0 400 400 let
0 400 400 f = {a, b, ...}@args: a + b + args.c;
0 400 400 in
0 400 400 f { a = 1; b = 2; c = 3; }
0 400 400
0 400 400 { pkgs ? import <nixpkgs> {} }:
0 400 400 let
0 400 400 message = "hello world";
0 400 400 in
2 400 401 + pkgs.mkShellNoCC {
0 401 401 | packages = with pkgs; [ cowsay ];
2 401 402 + shellHook = ''
0 402 402 | cowsay ${message}
0 402 401 | '';
0 401 400 | }
0 400 400
2 400 401 + { config, pkgs, ... }: {
0 401 401 |
0 401 401 | imports = [ ./hardware-configuration.nix ];
0 401 401 |
0 401 401 | environment.systemPackages = with pkgs; [ git ];
0 401 401 |
0 401 401 | # ...
0 401 400 | }
0 400 400
0 400 400 { lib, stdenv, fetchurl }:
0 400 400
2 400 401 + stdenv.mkDerivation rec {
0 401 401 |
0 401 401 | pname = "hello";
0 401 401 |
0 401 401 | version = "2.12";
0 401 401 |
2 401 402 + src = fetchurl {
0 402 402 | url = "mirror://gnu/${pname}/${pname}-${version}.tar.gz";
0 402 402 | sha256 = "1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g";
0 402 401 | };
0 401 401 |
2 401 402 + meta = with lib; {
0 402 402 | license = licenses.gpl3Plus;
0 402 401 | };
0 401 401 |
0 401 400 | }
0 400 400
2 400 401 + {
0 401 401 | baseName = baseNameOf name;
0 401 401 |
0 401 401 | pullImage =
0 401 401 | let
0 401 401 | fixName = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
0 401 401 | in
2 401 402 + { imageName
0 402 402 | # To find the digest of an image, you can use skopeo:
0 402 402 | # see doc/functions.xml
0 402 402 | , imageDigest
0 402 402 | , sha256
0 402 402 | , os ? "linux"
0 402 402 | , # Image architecture, defaults to the architecture of the `hostPlatform` when unset
0 402 402 | arch ? defaultArchitecture
0 402 402 | # This is used to set name to the pulled image
0 402 402 | , finalImageName ? imageName
0 402 402 | # This used to set a tag to the pulled image
0 402 402 | , finalImageTag ? "latest"
0 402 402 | # This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks
0 402 402 | , tlsVerify ? true
0 402 402 |
0 402 402 | , name ? fixName "docker-image-${finalImageName}-${finalImageTag}.tar"
0 402 401 | }:
0 401 401 |
0 401 401 | runCommand name
2 401 402 + {
0 402 402 | inherit imageDigest;
0 402 402 | imageName = finalImageName;
0 402 402 | imageTag = finalImageTag;
0 402 402 | impureEnvVars = lib.fetchers.proxyImpureEnvVars;
0 402 402 | outputHashMode = "flat";
0 402 402 | outputHashAlgo = "sha256";
0 402 402 | outputHash = sha256;
0 402 402 |
0 402 402 | nativeBuildInputs = [ skopeo ];
0 402 402 | SSL_CERT_FILE = "${cacert.out}/etc/ssl/certs/ca-bundle.crt";
0 402 402 |
0 402 402 | sourceURL = "docker://${imageName}@${imageDigest}";
0 402 402 | destNameTag = "${finalImageName}:${finalImageTag}";
0 402 402 | } ''
0 402 402 | skopeo \
0 402 402 | --insecure-policy \
0 402 402 | --tmpdir=$TMPDIR \
0 402 402 | --override-os ${os} \
0 402 402 | --override-arch ${arch} \
0 402 402 | copy \
0 402 402 | --src-tls-verify=${lib.boolToString tlsVerify} \
0 402 402 | "$sourceURL" "docker-archive://$out:$destNameTag" \
0 402 402 | | cat # pipe through cat to force-disable progress bar
0 402 401 | '';
0 401 401 |
0 401 400 | }
0 400 0

View File

@ -0,0 +1,349 @@
{1}# coding:utf-8
{0}
{9}1{0} {7}+{0} {9}2{0}
{12}let{0}
{10}x{0} {7}={0} {9}1{7};{0}
{10}y{0} {7}={0} {9}2{7};{0}
{12}in{0} {6}x{0} {7}+{0} {6}y{0}
{12}let{0} {10}x{7}={9}1{7};{10}y{7}={9}2{7};{12}in{0} {6}x{7}+{6}y{0}
{7}{{0}
{10}string{0} {7}={0} {3}"hello"{7};{0}
{10}integer{0} {7}={0} {9}1{7};{0}
{10}float{0} {7}={0} {9}3.141{7};{0}
{10}bool{0} {7}={0} {13}true{7};{0}
{10}null{0} {7}={0} {13}null{7};{0}
{10}list{0} {7}={0} {7}[{0} {9}1{0} {3}"two"{0} {13}false{0} {7}];{0}
{10}attribute-set{0} {7}={0} {7}{{0}
{10}a{0} {7}={0} {3}"hello"{7};{0}
{10}b{0} {7}={0} {9}2{7};{0}
{10}c{0} {7}={0} {9}2.718{7};{0}
{10}d{0} {7}={0} {13}false{7};{0}
{7}};{0} {1}# comments are supported
{7}}{0}
{12}rec{0} {7}{{0}
{10}one{0} {7}={0} {9}1{7};{0}
{10}two{0} {7}={0} {6}one{0} {7}+{0} {9}1{7};{0}
{10}three{0} {7}={0} {6}two{0} {7}+{0} {9}1{7};{0}
{7}}{0}
{7}{{0} {10}one{0} {7}={0} {9}1{7};{0} {10}three{0} {7}={0} {9}3{7};{0} {10}two{0} {7}={0} {9}2{7};{0} {7}}{0}
{12}let{0}
{10}a{0} {7}={0} {9}1{7};{0}
{12}in{0}
{6}a{0} {7}+{0} {6}a{0}
{12}let{0}
{10}b{0} {7}={0} {6}a{0} {7}+{0} {9}1{7};{0}
{10}a{0} {7}={0} {9}1{7};{0}
{12}in{0}
{6}a{0} {7}+{0} {6}b{0}
{7}{{0}
{10}a{0} {7}={0} {12}let{0} {10}x{0} {7}={0} {9}1{7};{0} {12}in{0} {6}x{7};{0}
{10}b{0} {7}={0} {6}x{7};{0}
{7}}{0}
{12}let{0}
{10}attrset{0} {7}={0} {7}{{0} {10}x{0} {7}={0} {9}1{7};{0} {7}};{0}
{12}in{0}
{6}attrset{7}.{6}x{0}
{12}let{0}
{10}attrset{0} {7}={0} {7}{{0} {10}a{0} {7}={0} {7}{{0} {10}b{0} {7}={0} {7}{{0} {10}c{0} {7}={0} {9}1{7};{0} {7}};{0} {7}};{0} {7}};{0}
{12}in{0}
{6}attrset{7}.{6}a{7}.{6}b{7}.{6}c{0}
{7}{{0} {6}a{7}.{6}b{7}.{10}c{0} {7}={0} {9}1{7};{0} {7}}{0}
{12}let{0}
{10}a{0} {7}={0} {7}{{0}
{10}x{0} {7}={0} {9}1{7};{0}
{10}y{0} {7}={0} {9}2{7};{0}
{10}z{0} {7}={0} {9}3{7};{0}
{7}};{0}
{12}in{0}
{12}with{0} {6}a{7};{0} {7}[{0} {6}x{0} {6}y{0} {6}z{0} {7}]{0}
{12}let{0}
{10}x{0} {7}={0} {9}1{7};{0}
{10}y{0} {7}={0} {9}2{7};{0}
{12}in{0}
{7}{{0}
{12}inherit{0} {6}x{0} {6}y{7};{0}
{7}}{0}
{12}let{0}
{10}a{0} {7}={0} {7}{{0} {10}x{0} {7}={0} {9}1{7};{0} {10}y{0} {7}={0} {9}2{7};{0} {7}};{0}
{12}in{0}
{7}{{0}
{12}inherit{0} {7}({6}a{7}){0} {6}x{0} {6}y{7};{0}
{7}}{0}
{12}let{0}
{12}inherit{0} {7}({{0} {10}x{0} {7}={0} {9}1{7};{0} {10}y{0} {7}={0} {9}2{7};{0} {7}}){0} {6}x{0} {6}y{7};{0}
{12}in{0} {7}[{0} {6}x{0} {6}y{0} {7}]{0}
{12}let{0}
{10}name{0} {7}={0} {3}"Nix{8}${}{3}"{7};{0}
{12}in{0}
{3}"hello {8}${{6}name{8}}{3}"{0}
{10}graphviz{0} {7}={0} {7}({14}import{0} {11}../tools/graphics/graphviz{7}){0} {7}{{0}
{12}inherit{0} {14}fetchurl{0} {6}stdenv{0} {6}libpng{0} {6}libjpeg{0} {6}expat{0} {6}x11{0} {6}yacc{7};{0}
{12}inherit{0} {7}({6}xorg{7}){0} {6}libXaw{7};{0}
{7}};{0}
{12}let{0} {10}negate{0} {7}={0} {6}x{7}:{0} {7}!{6}x{7};{0}
{10}concat{0} {7}={0} {6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{7};{0}
{12}in{0} {12}if{0} {6}negate{0} {13}true{0} {12}then{0} {6}concat{0} {3}"foo"{0} {3}"bar"{0} {12}else{0} {3}""{0}
{1}# A number
# Equals 1 + 1
# asd
{0}
{2}/* /*
Block comments
can span multiple lines.
*/{0} {3}"hello"{0}
{3}"hello"{0}
{2}/* /* nope */{0} {9}1{0}
{14}map{0} {7}({6}concat{0} {3}"foo"{7}){0} {7}[{0} {3}"bar"{0} {3}"bla"{0} {3}"abc"{0} {7}]{0}
{7}{{0} {6}localServer{0} {7}?{0} {13}false{0}
{7},{0} {6}httpServer{0} {7}?{0} {13}false{0}
{7},{0} {6}sslSupport{0} {7}?{0} {13}false{0}
{7},{0} {6}pythonBindings{0} {7}?{0} {13}false{0}
{7},{0} {6}javaSwigBindings{0} {7}?{0} {13}false{0}
{7},{0} {6}javahlBindings{0} {7}?{0} {13}false{0}
{7},{0} {6}stdenv{7},{0} {14}fetchurl{0}
{7},{0} {6}openssl{0} {7}?{0} {13}null{7},{0} {6}httpd{0} {7}?{0} {13}null{7},{0} {6}db4{0} {7}?{0} {13}null{7},{0} {6}expat{7},{0} {6}swig{0} {7}?{0} {13}null{7},{0} {6}j2sdk{0} {7}?{0} {13}null{0}
{7}}:{0}
{12}assert{0} {6}localServer{0} {7}->{0} {6}db4{0} {7}!={0} {13}null{7};{0}
{12}assert{0} {6}httpServer{0} {7}->{0} {6}httpd{0} {7}!={0} {13}null{0} {7}&&{0} {6}httpd{7}.{10}expat{0} {7}=={0} {6}expat{7};{0}
{12}assert{0} {6}sslSupport{0} {7}->{0} {6}openssl{0} {7}!={0} {13}null{0} {7}&&{0} {7}({6}httpServer{0} {7}->{0} {6}httpd{7}.{10}openssl{0} {7}=={0} {6}openssl{7});{0}
{12}assert{0} {6}pythonBindings{0} {7}->{0} {6}swig{0} {7}!={0} {13}null{0} {7}&&{0} {6}swig{7}.{6}pythonSupport{7};{0}
{12}assert{0} {6}javaSwigBindings{0} {7}->{0} {6}swig{0} {7}!={0} {13}null{0} {7}&&{0} {6}swig{7}.{6}javaSupport{7};{0}
{12}assert{0} {6}javahlBindings{0} {7}->{0} {6}j2sdk{0} {7}!={0} {13}null{7};{0}
{6}stdenv{7}.{6}mkDerivation{0} {7}{{0}
{10}name{0} {7}={0} {3}"subversion-1.1.1"{7};{0}
{10}openssl{0} {7}={0} {12}if{0} {6}sslSupport{0} {12}then{0} {6}openssl{0} {12}else{0} {13}null{7};{0}
{7}}{0}
{10}configureFlags{0} {7}={0} {4}''
-system-zlib -system-libpng -system-libjpeg
{8}${{12}if{0} {6}openglSupport{0} {12}then{0} {4}''-dlopen-opengl
-L{8}${{6}mesa{8}}{4}/lib -I{8}${{6}mesa{8}}{4}/include
-L{8}${{6}libXmu{8}}{4}/lib -I{8}${{6}libXmu{8}}{4}/include''{0} {12}else{0} {3}""{8}}{4}
{8}${{12}if{0} {6}threadSupport{0} {12}then{0} {3}"-thread"{0} {12}else{0} {3}"-no-thread"{8}}{4}
''{7};{0}
{12}let{0}
{10}a{0} {7}={0} {3}"no"{7};{0}
{6}a{7}.{6}b{7}.{6}c{7}.{10}d{0} {7}={0} {3}"foo"{0}
{12}in{0}
{3}"{8}${{6}a{0} {7}+{0} {3}" {8}${{6}a{0} {7}+{0} {3}" {8}${{6}a{8}}{3}"{8}}{3}"{8}}{3}"{0}
{12}let{0}
{10}out{0} {7}={0} {3}"Nix"{7};{0}
{12}in{0}
{3}"echo {8}${{6}out{8}}{3} > $out"{0}
{11}<nixpkgs/lib>{0}
{4}''
multi
{5}''${4}{}
{5}'''{4}
line
{5}''\n{4}
string
''{0}
{4}''
one
two
three
''{0}
{6}x{7}:{0} {6}x{0} {7}+{0} {9}1{0}
{6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{0}
{7}{{0} {6}a{7},{0} {6}b{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0}
{7}{{0} {6}a{7},{0} {6}b{0} {7}?{0} {9}0{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0}
{7}{{0} {6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{0}
{6}args{7}@{{0} {6}a{7},{0} {6}b{7},{0} {7}...{0} {7}}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}
{7}{{0} {6}a{7},{0} {6}b{7},{0} {7}...{0} {7}}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}
{12}in{0} {6}f{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}
{12}in{0} {6}f{0} {9}1{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}x{7}.{6}a{7};{0}
{10}v{0} {7}={0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {7}};{0}
{12}in{0}
{6}f{0} {6}v{0}
{7}({6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7}){0} {9}1{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}
{10}a{0} {7}={0} {9}1{7};{0}
{12}in{0} {7}[{0} {7}({6}f{0} {6}a{7}){0} {7}]{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}x{0} {7}+{0} {9}1{7};{0}
{10}a{0} {7}={0} {9}1{7};{0}
{12}in{0} {7}[{0} {6}f{0} {6}a{0} {7}]{0}
{12}let{0}
{10}f{0} {7}={0} {6}x{7}:{0} {6}y{7}:{0} {6}x{0} {7}+{0} {6}y{7};{0}
{12}in{0}
{6}f{0} {9}1{0} {9}2{0}
{7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {7}}{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{0} {7}?{0} {9}0{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {7}}{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{0} {7}?{0} {9}0{7},{0} {6}b{0} {7}?{0} {9}0{7}}:{0} {6}a{0} {7}+{0} {6}b{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {7}}{0} {1}# empty attribute set
{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}
{7}{{6}a{7},{0} {6}b{7},{0} {7}...}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}
{6}args{7}@{{6}a{7},{0} {6}b{7},{0} {7}...}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{0}
{12}let{0}
{10}f{0} {7}={0} {7}{{6}a{7},{0} {6}b{7},{0} {7}...}@{6}args{7}:{0} {6}a{0} {7}+{0} {6}b{0} {7}+{0} {6}args{7}.{6}c{7};{0}
{12}in{0}
{6}f{0} {7}{{0} {10}a{0} {7}={0} {9}1{7};{0} {10}b{0} {7}={0} {9}2{7};{0} {10}c{0} {7}={0} {9}3{7};{0} {7}}{0}
{7}{{0} {6}pkgs{0} {7}?{0} {14}import{0} {11}<nixpkgs>{0} {7}{}{0} {7}}:{0}
{12}let{0}
{10}message{0} {7}={0} {3}"hello world"{7};{0}
{12}in{0}
{6}pkgs{7}.{6}mkShellNoCC{0} {7}{{0}
{10}packages{0} {7}={0} {12}with{0} {6}pkgs{7};{0} {7}[{0} {6}cowsay{0} {7}];{0}
{10}shellHook{0} {7}={0} {4}''
cowsay {8}${{6}message{8}}{4}
''{7};{0}
{7}}{0}
{7}{{0} {6}config{7},{0} {6}pkgs{7},{0} {7}...{0} {7}}:{0} {7}{{0}
{10}imports{0} {7}={0} {7}[{0} {11}./hardware-configuration.nix{0} {7}];{0}
{6}environment{7}.{10}systemPackages{0} {7}={0} {12}with{0} {6}pkgs{7};{0} {7}[{0} {6}git{0} {7}];{0}
{1}# ...
{7}}{0}
{7}{{0} {6}lib{7},{0} {6}stdenv{7},{0} {14}fetchurl{0} {7}}:{0}
{6}stdenv{7}.{6}mkDerivation{0} {12}rec{0} {7}{{0}
{10}pname{0} {7}={0} {3}"hello"{7};{0}
{10}version{0} {7}={0} {3}"2.12"{7};{0}
{10}src{0} {7}={0} {14}fetchurl{0} {7}{{0}
{10}url{0} {7}={0} {3}"mirror://gnu/{8}${{6}pname{8}}{3}/{8}${{6}pname{8}}{3}-{8}${{6}version{8}}{3}.tar.gz"{7};{0}
{10}sha256{0} {7}={0} {3}"1ayhp9v4m4rdhjmnl2bq3cibrbqqkgjbl3s7yk2nhlh8vj3ay16g"{7};{0}
{7}};{0}
{10}meta{0} {7}={0} {12}with{0} {6}lib{7};{0} {7}{{0}
{10}license{0} {7}={0} {6}licenses{7}.{6}gpl3Plus{7};{0}
{7}};{0}
{7}}{0}
{7}{{0}
{10}baseName{0} {7}={0} {14}baseNameOf{0} {6}name{7};{0}
{10}pullImage{0} {7}={0}
{12}let{0}
{10}fixName{0} {7}={0} {6}name{7}:{0} {14}builtins{7}.{14}replaceStrings{0} {7}[{0} {3}"/"{0} {3}":"{0} {7}]{0} {7}[{0} {3}"-"{0} {3}"-"{0} {7}]{0} {6}name{7};{0}
{12}in{0}
{7}{{0} {6}imageName{0}
{1}# To find the digest of an image, you can use skopeo:
{0} {1}# see doc/functions.xml
{0} {7},{0} {6}imageDigest{0}
{7},{0} {6}sha256{0}
{7},{0} {6}os{0} {7}?{0} {3}"linux"{0}
{7},{0} {1}# Image architecture, defaults to the architecture of the `hostPlatform` when unset
{0} {6}arch{0} {7}?{0} {6}defaultArchitecture{0}
{1}# This is used to set name to the pulled image
{0} {7},{0} {6}finalImageName{0} {7}?{0} {6}imageName{0}
{1}# This used to set a tag to the pulled image
{0} {7},{0} {6}finalImageTag{0} {7}?{0} {3}"latest"{0}
{1}# This is used to disable TLS certificate verification, allowing access to http registries on (hopefully) trusted networks
{0} {7},{0} {6}tlsVerify{0} {7}?{0} {13}true{0}
{7},{0} {6}name{0} {7}?{0} {6}fixName{0} {3}"docker-image-{8}${{6}finalImageName{8}}{3}-{8}${{6}finalImageTag{8}}{3}.tar"{0}
{7}}:{0}
{15}runCommand{0} {6}name{0}
{7}{{0}
{12}inherit{0} {6}imageDigest{7};{0}
{10}imageName{0} {7}={0} {6}finalImageName{7};{0}
{10}imageTag{0} {7}={0} {6}finalImageTag{7};{0}
{10}impureEnvVars{0} {7}={0} {6}lib{7}.{6}fetchers{7}.{6}proxyImpureEnvVars{7};{0}
{10}outputHashMode{0} {7}={0} {3}"flat"{7};{0}
{10}outputHashAlgo{0} {7}={0} {3}"sha256"{7};{0}
{10}outputHash{0} {7}={0} {6}sha256{7};{0}
{10}nativeBuildInputs{0} {7}={0} {7}[{0} {6}skopeo{0} {7}];{0}
{10}SSL_CERT_FILE{0} {7}={0} {3}"{8}${{6}cacert{7}.{6}out{8}}{3}/etc/ssl/certs/ca-bundle.crt"{7};{0}
{10}sourceURL{0} {7}={0} {3}"docker://{8}${{6}imageName{8}}{3}@{8}${{6}imageDigest{8}}{3}"{7};{0}
{10}destNameTag{0} {7}={0} {3}"{8}${{6}finalImageName{8}}{3}:{8}${{6}finalImageTag{8}}{3}"{7};{0}
{7}}{0} {4}''
skopeo \
--insecure-policy \
--tmpdir=$TMPDIR \
--override-os {8}${{6}os{8}}{4} \
--override-arch {8}${{6}arch{8}}{4} \
copy \
--src-tls-verify={8}${{6}lib{7}.{6}boolToString{0} {6}tlsVerify{8}}{4} \
"$sourceURL" "docker-archive://$out:$destNameTag" \
| cat # pipe through cat to force-disable progress bar
''{7};{0}
{7}}{0}

View File

@ -0,0 +1,7 @@
lexer.*.nix=nix
fold=1
keywords.*.nix=assert else if in inherit let or rec then with
keywords2.*.nix=false null true
keywords3.*.nix=abort add addDrvOutputDependencies all any attrNames attrValues baseNameOf bitAnd bitOr bitXor break builtins catAttrs ceil compareVersions concatLists concatMap concatStringsSep convertHash currentSystem currentTime deepSeq derivation dirOf div elem elemAt fetchClosure fetchGit fetchTarball fetchTree fetchurl filter filterSource findFile flakeRefToString floor foldl' fromJSON fromTOML functionArgs genList genericClosure getAttr getContext getEnv getFlake groupBy hasAttr hasContext hashFile hashString head import intersectAttrs isAttrs isBool isFloat isFunction isInt isList isNull isPath isString langVersion length lessThan listToAttrs map mapAttrs match mul nixPath nixVersion outputOf parseDrvName parseFlakeRef partition path pathExists placeholder readDir readFile readFileType removeAttrs replaceStrings seq sort split splitVersion storeDir storePath stringLength sub substring tail throw toFile toJSON toPath toString toXML trace traceVerbose tryEval typeOf unsafeDiscardOutputDependency unsafeDiscardStringContext warn zipAttrsWith
keywords4.*.nix=runCommand

View File

@ -0,0 +1,36 @@
// coding: utf-8
b"foo"; br"foo" // foo
b"\"foo\""; br#""foo""#; // "foo"
b"foo #\"# bar";
br##"foo #"# bar"##; // foo #"# bar
b"\x52"; b"R"; br"R" // R
b"\\x52"; br"\x52" // \x52
c"æ" // LATIN SMALL LETTER AE (U+00E6)
c"\u{00E6}";
c"\xC3\xA6";
c"foo"; cr"foo" // foo
c"\"foo\""; cr#""foo""#; // "foo"
c"foo #\"# bar";
cr##"foo #"# bar"##; // foo #"# bar
c"\x52"; c"R"; cr"R" // R
c"\\x52"; cr"\x52" // \x52
"foo"; r"foo" // foo
"\"foo\""; r#""foo""#; // "foo"
"foo #\"# bar";
r##"foo #"# bar"##; // foo #"# bar
"\x52"; "R"; r"R" // R
"\\x52"; r"\x52" // \x52
"æ" // LATIN SMALL LETTER AE (U+00E6)
"\u{00E6}";
"\xC3\xA6";

View File

@ -0,0 +1,36 @@
0 400 400 // coding: utf-8
1 400 400
0 400 400 b"foo"; br"foo" // foo
0 400 400 b"\"foo\""; br#""foo""#; // "foo"
1 400 400
0 400 400 b"foo #\"# bar";
0 400 400 br##"foo #"# bar"##; // foo #"# bar
1 400 400
0 400 400 b"\x52"; b"R"; br"R" // R
0 400 400 b"\\x52"; br"\x52" // \x52
1 400 400
0 400 400 c"æ" // LATIN SMALL LETTER AE (U+00E6)
0 400 400 c"\u{00E6}";
0 400 400 c"\xC3\xA6";
1 400 400
0 400 400 c"foo"; cr"foo" // foo
0 400 400 c"\"foo\""; cr#""foo""#; // "foo"
1 400 400
0 400 400 c"foo #\"# bar";
0 400 400 cr##"foo #"# bar"##; // foo #"# bar
1 400 400
0 400 400 c"\x52"; c"R"; cr"R" // R
0 400 400 c"\\x52"; cr"\x52" // \x52
1 400 400
0 400 400 "foo"; r"foo" // foo
0 400 400 "\"foo\""; r#""foo""#; // "foo"
1 400 400
0 400 400 "foo #\"# bar";
0 400 400 r##"foo #"# bar"##; // foo #"# bar
1 400 400
0 400 400 "\x52"; "R"; r"R" // R
0 400 400 "\\x52"; r"\x52" // \x52
1 400 400
0 400 400 "æ" // LATIN SMALL LETTER AE (U+00E6)
0 400 400 "\u{00E6}";
0 400 400 "\xC3\xA6";

View File

@ -0,0 +1,36 @@
{2}// coding: utf-8{0}
{21}b"foo"{16};{0} {22}br"foo"{0} {2}// foo{0}
{21}b"\"foo\""{16};{0} {22}br#""foo""#{16};{0} {2}// "foo"{0}
{21}b"foo #\"# bar"{16};{0}
{22}br##"foo #"# bar"##{16};{0} {2}// foo #"# bar{0}
{21}b"\x52"{16};{0} {21}b"R"{16};{0} {22}br"R"{0} {2}// R{0}
{21}b"\\x52"{16};{0} {22}br"\x52"{0} {2}// \x52{0}
{24}c"æ"{0} {2}// LATIN SMALL LETTER AE (U+00E6){0}
{24}c"\u{00E6}"{16};{0}
{24}c"\xC3\xA6"{16};{0}
{24}c"foo"{16};{0} {25}cr"foo"{0} {2}// foo{0}
{24}c"\"foo\""{16};{0} {25}cr#""foo""#{16};{0} {2}// "foo"{0}
{24}c"foo #\"# bar"{16};{0}
{25}cr##"foo #"# bar"##{16};{0} {2}// foo #"# bar{0}
{24}c"\x52"{16};{0} {24}c"R"{16};{0} {25}cr"R"{0} {2}// R{0}
{24}c"\\x52"{16};{0} {25}cr"\x52"{0} {2}// \x52{0}
{13}"foo"{16};{0} {14}r"foo"{0} {2}// foo{0}
{13}"\"foo\""{16};{0} {14}r#""foo""#{16};{0} {2}// "foo"{0}
{13}"foo #\"# bar"{16};{0}
{14}r##"foo #"# bar"##{16};{0} {2}// foo #"# bar{0}
{13}"\x52"{16};{0} {13}"R"{16};{0} {14}r"R"{0} {2}// R{0}
{13}"\\x52"{16};{0} {14}r"\x52"{0} {2}// \x52{0}
{13}"æ"{0} {2}// LATIN SMALL LETTER AE (U+00E6){0}
{13}"\u{00E6}"{16};{0}
{13}"\xC3\xA6"{16};

View File

@ -186,5 +186,6 @@ points = [ { x = 1, y = 2, z = 3 },
{ x = 7, y = 8, z = 9 }, { x = 7, y = 8, z = 9 },
{ x = 2, y = 4, z = 8 } ] { x = 2, y = 4, z = 8 } ]
~~~~ = true # invalid character in key
invalid # invalid, missing value invalid # invalid, missing value
key = identifier # also invalid, identifier must be one of true, false, inf, nan key = identifier # also invalid, identifier must be one of true, false, inf, nan

View File

@ -186,6 +186,7 @@
0 401 0 | { x = 7, y = 8, z = 9 }, 0 401 0 | { x = 7, y = 8, z = 9 },
0 401 0 | { x = 2, y = 4, z = 8 } ] 0 401 0 | { x = 2, y = 4, z = 8 } ]
0 401 0 | 0 401 0 |
0 401 0 | ~~~~ = true # invalid character in key
0 401 0 | invalid # invalid, missing value 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 = identifier # also invalid, identifier must be one of true, false, inf, nan
0 401 0 | 0 401 0 |

View File

@ -186,5 +186,6 @@ trimmed in raw strings.
{8}{{0} {6}x{0} {8}={0} {4}7{8},{0} {6}y{0} {8}={0} {4}8{8},{0} {6}z{0} {8}={0} {4}9{0} {8}},{0} {8}{{0} {6}x{0} {8}={0} {4}7{8},{0} {6}y{0} {8}={0} {4}8{8},{0} {6}z{0} {8}={0} {4}9{0} {8}},{0}
{8}{{0} {6}x{0} {8}={0} {4}2{8},{0} {6}y{0} {8}={0} {4}4{8},{0} {6}z{0} {8}={0} {4}8{0} {8}}{0} {8}]{0} {8}{{0} {6}x{0} {8}={0} {4}2{8},{0} {6}y{0} {8}={0} {4}4{8},{0} {6}z{0} {8}={0} {4}8{0} {8}}{0} {8}]{0}
{7}invalid {1}# invalid, missing value {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} {2}identifier{0} {1}# also invalid, identifier must be one of true, false, inf, nan

View File

@ -275,3 +275,16 @@ const optional_value: ?i32 = null;
//! This module provides functions for retrieving the current date and //! This module provides functions for retrieving the current date and
//! time with varying degrees of precision and accuracy. It does not //! time with varying degrees of precision and accuracy. It does not
//! depend on libc, but will use functions from it if available. //! depend on libc, but will use functions from it if available.
const @"identifier with spaces in it" = 0xff;
const @"1SmallStep4Man" = 112358;
const c = @import("std").c;
pub extern "c" fn @"error"() void;
pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
const Color = enum {
red,
@"really red",
};
const color: Color = .@"really red";

View File

@ -275,4 +275,17 @@
2 400 401 + //! This module provides functions for retrieving the current date and 2 400 401 + //! This module provides functions for retrieving the current date and
0 401 401 | //! time with varying degrees of precision and accuracy. It does not 0 401 401 | //! time with varying degrees of precision and accuracy. It does not
0 401 400 | //! depend on libc, but will use functions from it if available. 0 401 400 | //! depend on libc, but will use functions from it if available.
0 400 400
0 400 400 const @"identifier with spaces in it" = 0xff;
0 400 400 const @"1SmallStep4Man" = 112358;
0 400 400
0 400 400 const c = @import("std").c;
0 400 400 pub extern "c" fn @"error"() void;
0 400 400 pub extern "c" fn @"fstat$INODE64"(fd: c.fd_t, buf: *c.Stat) c_int;
0 400 400
2 400 401 + const Color = enum {
0 401 401 | red,
0 401 401 | @"really red",
0 401 400 | };
0 400 400 const color: Color = .@"really red";
0 400 0 0 400 0

View File

@ -275,3 +275,16 @@
{3}//! This module provides functions for retrieving the current date and {3}//! This module provides functions for retrieving the current date and
//! time with varying degrees of precision and accuracy. It does not //! time with varying degrees of precision and accuracy. It does not
//! depend on libc, but will use functions from it if available. //! depend on libc, but will use functions from it if available.
{0}
{13}const{0} {17}@"identifier with spaces in it"{0} {5}={0} {4}0xff{5};{0}
{13}const{0} {17}@"1SmallStep4Man"{0} {5}={0} {4}112358{5};{0}
{13}const{0} {10}c{0} {5}={0} {12}@import{5}({7}"std"{5}).{10}c{5};{0}
{13}pub{0} {13}extern{0} {7}"c"{0} {13}fn{0} {17}@"error"{5}(){0} {11}void{5};{0}
{13}pub{0} {13}extern{0} {7}"c"{0} {13}fn{0} {17}@"fstat$INODE64"{5}({11}fd{5}:{0} {10}c{5}.{10}fd_t{5},{0} {10}buf{5}:{0} {5}*{10}c{5}.{10}Stat{5}){0} {10}c_int{5};{0}
{13}const{0} {10}Color{0} {5}={0} {13}enum{0} {5}{{0}
{10}red{5},{0}
{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}

View File

@ -1 +1 @@
541 542

View File

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

View File

@ -586,7 +586,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.5.3; CURRENT_PROJECT_VERSION = 5.5.4;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -650,7 +650,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.5.3; CURRENT_PROJECT_VERSION = 5.5.4;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
@ -682,7 +682,7 @@
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.5.3; CURRENT_PROJECT_VERSION = 5.5.4;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";
@ -717,7 +717,7 @@
CODE_SIGN_IDENTITY = "-"; CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.5.3; CURRENT_PROJECT_VERSION = 5.5.4;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES; DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = "";

View File

@ -60,7 +60,4 @@ xcodebuild clean
xcodebuild xcodebuild
cd .. cd ..
cd ScintillaEditPy
python2 sepbuild.py
cd ..
cd ../.. cd ../..

View File

@ -130,7 +130,7 @@
<h1>Scintilla Documentation</h1> <h1>Scintilla Documentation</h1>
<p>Last edited 22 March 2024 NH</p> <p>Last edited 26 October 2024 NH</p>
<p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new <p style="background:#90F0C0">Scintilla 5 has moved the lexers from Scintilla into a new
<a href="Lexilla.html">Lexilla</a> project.<br /> <a href="Lexilla.html">Lexilla</a> project.<br />
@ -8654,7 +8654,7 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
<p>If the value argument is 0 then the length that should be allocated to store the value is returned; <p>If the value argument is 0 then the length that should be allocated to store the value is returned;
again, the terminating 0 is not included.</p> again, the terminating 0 is not included.</p>
<p><b id="SCI_GETPROPERTYEXPANDED">SCI_GETPROPERTYEXPANDED(const char *key, char *value) &rarr; int</b><br /> <p><b id="SCI_GETPROPERTYEXPANDED">SCI_GETPROPERTYEXPANDED(const char *key, char *value NUL-terminated) &rarr; int</b><br />
This is now the same as <a class="message" href="#SCI_GETPROPERTY"><code>SCI_GETPROPERTY</code></a> This is now the same as <a class="message" href="#SCI_GETPROPERTY"><code>SCI_GETPROPERTY</code></a>
- no expansion is performed.</p> - no expansion is performed.</p>
@ -8742,13 +8742,13 @@ sptr_t CallScintilla(unsigned int iMessage, uptr_t wParam, sptr_t lParam){
<p><b id="SCI_GETNAMEDSTYLES">SCI_GETNAMEDSTYLES &rarr; int</b><br /> <p><b id="SCI_GETNAMEDSTYLES">SCI_GETNAMEDSTYLES &rarr; int</b><br />
Retrieve the number of named styles for the lexer.</p> Retrieve the number of named styles for the lexer.</p>
<p><b id="SCI_NAMEOFSTYLE">SCI_NAMEOFSTYLE(int style, char *name) &rarr; int</b><br /> <p><b id="SCI_NAMEOFSTYLE">SCI_NAMEOFSTYLE(int style, char *name NUL-terminated) &rarr; int</b><br />
Retrieve the name of a style. This is a C preprocessor symbol like "SCE_C_COMMENTDOC".</p> Retrieve the name of a style. This is a C preprocessor symbol like "SCE_C_COMMENTDOC".</p>
<p><b id="SCI_TAGSOFSTYLE">SCI_TAGSOFSTYLE(int style, char *tags) &rarr; int</b><br /> <p><b id="SCI_TAGSOFSTYLE">SCI_TAGSOFSTYLE(int style, char *tags NUL-terminated) &rarr; int</b><br />
Retrieve the tags of a style. This is a space-separated set of words like "comment documentation".</p> Retrieve the tags of a style. This is a space-separated set of words like "comment documentation".</p>
<p><b id="SCI_DESCRIPTIONOFSTYLE">SCI_DESCRIPTIONOFSTYLE(int style, char *description) &rarr; int</b><br /> <p><b id="SCI_DESCRIPTIONOFSTYLE">SCI_DESCRIPTIONOFSTYLE(int style, char *description NUL-terminated) &rarr; int</b><br />
Retrieve an English-language description of a style which may be suitable for display in a user interface. Retrieve an English-language description of a style which may be suitable for display in a user interface.
This looks like "Doc comment: block comments beginning with /** or /*!".</p> This looks like "Doc comment: block comments beginning with /** or /*!".</p>
@ -9516,6 +9516,16 @@ struct SCNotification {
<td><code>line</code></td> <td><code>line</code></td>
</tr> </tr>
<tr>
<td align="left"><code id="SC_MOD_CHANGEEOLANNOTATION">SC_MOD_CHANGEEOLANNOTATION</code></td>
<td align="right">0x400000</td>
<td>An EOL annotation has changed.</td>
<td><code>line</code></td>
</tr>
<tr> <tr>
<td align="left"><code id="SC_MOD_INSERTCHECK">SC_MOD_INSERTCHECK</code></td> <td align="left"><code id="SC_MOD_INSERTCHECK">SC_MOD_INSERTCHECK</code></td>
@ -9568,7 +9578,7 @@ struct SCNotification {
<tr> <tr>
<td align="left"><code>SC_MODEVENTMASKALL</code></td> <td align="left"><code>SC_MODEVENTMASKALL</code></td>
<td align="right">0x1FFFFF</td> <td align="right">0x7FFFFF</td>
<td>This is a mask for all valid flags. This is the default mask state set by <a <td>This is a mask for all valid flags. This is the default mask state set by <a
class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</td> class="message" href="#SCI_SETMODEVENTMASK"><code>SCI_SETMODEVENTMASK</code></a>.</td>

View File

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

View File

@ -582,9 +582,43 @@
<td>Gary James</td> <td>Gary James</td>
<td>Tsuyoshi Miyake</td> <td>Tsuyoshi Miyake</td>
<td>Martijn Laan</td> <td>Martijn Laan</td>
</tr><tr>
<td>Pawel Z Wronek</td>
</tr> </tr>
</table> </table>
<h2>Releases</h2> <h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla554.zip">Release 5.5.4</a>
</h3>
<ul>
<li>
Released 18 December 2024.
</li>
<li>
Update to Unicode 15.1.
<a href="https://github.com/ScintillaOrg/lexilla/issues/285">Issue #285</a>.
</li>
<li>
Improve performance of SCI_BRACEMATCH.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1533/">Feature #1533</a>.
</li>
<li>
Improve performance of DBCS text.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1535/">Feature #1535</a>.
</li>
<li>
Fix wrapping removed lines.
<a href="https://sourceforge.net/p/scintilla/bugs/2456/">Bug #2456</a>.
</li>
<li>
Fix moving line down to empty final line and moving empty final line up.
<a href="https://sourceforge.net/p/scintilla/bugs/2457/">Bug #2457</a>.
</li>
<li>
On GTK, allow middle click to insert multiple times within a document.
<a href="https://github.com/geany/geany/issues/2629">Geany Issue #2629</a>.
</li>
</ul>
<h3> <h3>
<a href="https://www.scintilla.org/scintilla553.zip">Release 5.5.3</a> <a href="https://www.scintilla.org/scintilla553.zip">Release 5.5.3</a>
</h3> </h3>

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description" <meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20241019" /> <meta name="Date.Modified" content="20241218" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css"> <style type="text/css">
.logo { .logo {
@ -61,8 +61,8 @@
GTK, and macOS</font> GTK, and macOS</font>
</td> </td>
<td width="40%" align="right"> <td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 5.5.3<br /> <font color="#FFCC99" size="3"> Release version 5.5.4<br />
Site last modified October 19 2024</font> Site last modified December 18 2024</font>
</td> </td>
<td width="20%"> <td width="20%">
&nbsp; &nbsp;
@ -77,11 +77,11 @@
</tr> </tr>
</table> </table>
<ul id="versionlist"> <ul id="versionlist">
<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.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> <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>
<li>Version 5.5.1 adds SCI_CUTALLOWLINE and fixes a Win32 bug that caused the cursor to flicker.</li> <li>Version 5.5.1 adds SCI_CUTALLOWLINE and fixes a Win32 bug that caused the cursor to flicker.</li>
<li>Version 5.5.0 adds elements for inactive additional selections.</li> <li>Version 5.5.0 adds elements for inactive additional selections.</li>
<li>Version 5.4.3 fixes a redo bug.</li>
</ul> </ul>
<ul id="menu"> <ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li> <li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -5,6 +5,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cmath> #include <cmath>

View File

@ -1502,8 +1502,8 @@ void ScintillaGTK::PrimaryClearSelection(GtkClipboard *clip, gpointer pSci) {
void ScintillaGTK::ClaimSelection() { void ScintillaGTK::ClaimSelection() {
// X Windows has a 'primary selection' as well as the clipboard. // X Windows has a 'primary selection' as well as the clipboard.
// Whenever the user selects some text, we become the primary selection // Whenever the user selects some text, we become the primary selection
ClearPrimarySelection();
if (!sel.Empty()) { if (!sel.Empty()) {
ClearPrimarySelection();
if (gtk_clipboard_set_with_data( if (gtk_clipboard_set_with_data(
gtk_clipboard_get(GDK_SELECTION_PRIMARY), gtk_clipboard_get(GDK_SELECTION_PRIMARY),
clipboardCopyTargets, nClipboardCopyTargets, clipboardCopyTargets, nClipboardCopyTargets,

View File

@ -1399,7 +1399,7 @@ struct Sci_RangeToFormatFull {
#ifndef __cplusplus #ifndef __cplusplus
/* For the GTK+ platform, g-ir-scanner needs to have these typedefs. This /* For the GTK+ platform, g-ir-scanner needs to have these typedefs. This
* is not required in C++ code and actually seems to break ScintillaEditPy */ * is not required in C++ code and has caused problems in the past. */
typedef struct Sci_NotifyHeader Sci_NotifyHeader; typedef struct Sci_NotifyHeader Sci_NotifyHeader;
typedef struct SCNotification SCNotification; typedef struct SCNotification SCNotification;
#endif #endif

View File

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

View File

@ -12,6 +12,7 @@
#define PLATQT_H #define PLATQT_H
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <string> #include <string>
#include <string_view> #include <string_view>

View File

@ -13,6 +13,7 @@
#define SCINTILLAEDITBASE_H #define SCINTILLAEDITBASE_H
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <string> #include <string>
#include <string_view> #include <string_view>

View File

@ -13,7 +13,7 @@ TEMPLATE = lib
CONFIG += lib_bundle CONFIG += lib_bundle
CONFIG += c++1z CONFIG += c++1z
VERSION = 5.5.3 VERSION = 5.5.4
SOURCES += \ SOURCES += \
PlatQt.cpp \ PlatQt.cpp \

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
@ -92,7 +93,7 @@ bool AutoComplete::IsFillUpChar(char ch) const noexcept {
return ch && (fillUpChars.find(ch) != std::string::npos); return ch && (fillUpChars.find(ch) != std::string::npos);
} }
void AutoComplete::SetSeparator(char separator_) { void AutoComplete::SetSeparator(char separator_) noexcept {
separator = separator_; separator = separator_;
} }
@ -100,7 +101,7 @@ char AutoComplete::GetSeparator() const noexcept {
return separator; return separator;
} }
void AutoComplete::SetTypesep(char separator_) { void AutoComplete::SetTypesep(char separator_) noexcept {
typesep = separator_; typesep = separator_;
} }
@ -108,28 +109,32 @@ char AutoComplete::GetTypesep() const noexcept {
return typesep; return typesep;
} }
namespace {
struct Sorter { struct Sorter {
AutoComplete *ac; const bool ignoreCase;
const char *list; const char *list;
std::vector<int> indices; std::vector<int> indices;
Sorter(AutoComplete *ac_, const char *list_) : ac(ac_), list(list_) { Sorter(const AutoComplete *ac, const char *list_) : ignoreCase(ac->ignoreCase), list(list_) {
int i = 0; int i = 0;
if (!list[i]) { if (!list[i]) {
// Empty list has a single empty member // Empty list has a single empty member
indices.push_back(i); // word start indices.push_back(i); // word start
indices.push_back(i); // word end indices.push_back(i); // word end
} }
const char separator = ac->GetSeparator();
const char typesep = ac->GetTypesep();
while (list[i]) { while (list[i]) {
indices.push_back(i); // word start indices.push_back(i); // word start
while (list[i] != ac->GetTypesep() && list[i] != ac->GetSeparator() && list[i]) while (list[i] != typesep && list[i] != separator && list[i])
++i; ++i;
indices.push_back(i); // word end indices.push_back(i); // word end
if (list[i] == ac->GetTypesep()) { if (list[i] == typesep) {
while (list[i] != ac->GetSeparator() && list[i]) while (list[i] != separator && list[i])
++i; ++i;
} }
if (list[i] == ac->GetSeparator()) { if (list[i] == separator) {
++i; ++i;
// preserve trailing separator as blank entry // preserve trailing separator as blank entry
if (!list[i]) { if (!list[i]) {
@ -141,34 +146,41 @@ struct Sorter {
indices.push_back(i); // index of last position indices.push_back(i); // index of last position
} }
bool operator()(int a, int b) noexcept { bool operator()(int a, int b) const noexcept {
const int lenA = indices[a * 2 + 1] - indices[a * 2]; const unsigned indexA = a * 2;
const int lenB = indices[b * 2 + 1] - indices[b * 2]; const unsigned indexB = b * 2;
const int lenA = indices[indexA + 1] - indices[indexA];
const int lenB = indices[indexB + 1] - indices[indexB];
const int len = std::min(lenA, lenB); const int len = std::min(lenA, lenB);
int cmp; int cmp;
if (ac->ignoreCase) if (ignoreCase)
cmp = CompareNCaseInsensitive(list + indices[a * 2], list + indices[b * 2], len); cmp = CompareNCaseInsensitive(list + indices[indexA], list + indices[indexB], len);
else else
cmp = strncmp(list + indices[a * 2], list + indices[b * 2], len); cmp = strncmp(list + indices[indexA], list + indices[indexB], len);
if (cmp == 0) if (cmp == 0)
cmp = lenA - lenB; cmp = lenA - lenB;
return cmp < 0; return cmp < 0;
} }
}; };
void FillSortMatrix(std::vector<int> &sortMatrix, int itemCount) {
sortMatrix.clear();
for (int i = 0; i < itemCount; i++) {
sortMatrix.push_back(i);
}
}
}
void AutoComplete::SetList(const char *list) { void AutoComplete::SetList(const char *list) {
if (autoSort == Ordering::PreSorted) { if (autoSort == Ordering::PreSorted) {
lb->SetList(list, separator, typesep); lb->SetList(list, separator, typesep);
sortMatrix.clear(); FillSortMatrix(sortMatrix, lb->Length());
for (int i = 0; i < lb->Length(); ++i)
sortMatrix.push_back(i);
return; return;
} }
Sorter IndexSort(this, list); const Sorter IndexSort(this, list);
sortMatrix.clear(); FillSortMatrix(sortMatrix, static_cast<int>(IndexSort.indices.size() / 2));
for (int i = 0; i < static_cast<int>(IndexSort.indices.size()) / 2; ++i)
sortMatrix.push_back(i);
std::sort(sortMatrix.begin(), sortMatrix.end(), IndexSort); std::sort(sortMatrix.begin(), sortMatrix.end(), IndexSort);
if (autoSort == Ordering::Custom || sortMatrix.size() < 2) { if (autoSort == Ordering::Custom || sortMatrix.size() < 2) {
lb->SetList(list, separator, typesep); lb->SetList(list, separator, typesep);
@ -177,28 +189,25 @@ void AutoComplete::SetList(const char *list) {
} }
std::string sortedList; std::string sortedList;
char item[maxItemLen];
for (size_t i = 0; i < sortMatrix.size(); ++i) { for (size_t i = 0; i < sortMatrix.size(); ++i) {
int wordLen = IndexSort.indices[sortMatrix[i] * 2 + 2] - IndexSort.indices[sortMatrix[i] * 2]; const unsigned index = sortMatrix[i] * 2;
if (wordLen > maxItemLen-2) sortMatrix[i] = static_cast<int>(i);
wordLen = maxItemLen - 2; // word length include trailing typesep and separator
memcpy(item, list + IndexSort.indices[sortMatrix[i] * 2], wordLen); const int wordLen = IndexSort.indices[index + 2] - IndexSort.indices[index];
const std::string_view item(list + IndexSort.indices[index], wordLen);
sortedList += item;
if ((i + 1) == sortMatrix.size()) { if ((i + 1) == sortMatrix.size()) {
// Last item so remove separator if present // Last item so remove separator if present
if ((wordLen > 0) && (item[wordLen-1] == separator)) if (!item.empty() && item.back() == separator) {
wordLen--; sortedList.pop_back();
}
} else { } else {
// Item before last needs a separator // Item before last needs a separator
if ((wordLen == 0) || (item[wordLen-1] != separator)) { if (item.empty() || item.back() != separator) {
item[wordLen] = separator; sortedList += separator;
wordLen++;
} }
} }
item[wordLen] = '\0';
sortedList += item;
} }
for (int i = 0; i < static_cast<int>(sortMatrix.size()); ++i)
sortMatrix[i] = i;
lb->SetList(sortedList.c_str(), separator, typesep); lb->SetList(sortedList.c_str(), separator, typesep);
} }
@ -290,7 +299,7 @@ void AutoComplete::Select(const char *word) {
if (autoSort == Ordering::Custom) { if (autoSort == Ordering::Custom) {
// Check for a logically earlier match // Check for a logically earlier match
for (int i = location + 1; i <= end; ++i) { for (int i = location + 1; i <= end; ++i) {
std::string item = lb->GetValue(sortMatrix[i]); const std::string item = lb->GetValue(sortMatrix[i]);
if (CompareNCaseInsensitive(word, item.c_str(), lenWord)) if (CompareNCaseInsensitive(word, item.c_str(), lenWord))
break; break;
if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item.c_str(), lenWord)) if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item.c_str(), lenWord))

View File

@ -18,7 +18,6 @@ class AutoComplete {
std::string fillUpChars; std::string fillUpChars;
char separator; char separator;
char typesep; // Type separator char typesep; // Type separator
enum { maxItemLen=1000 };
std::vector<int> sortMatrix; std::vector<int> sortMatrix;
public: public:
@ -67,11 +66,11 @@ public:
bool IsFillUpChar(char ch) const noexcept; bool IsFillUpChar(char ch) const noexcept;
/// The separator character is used when interpreting the list in SetList /// The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_); void SetSeparator(char separator_) noexcept;
char GetSeparator() const noexcept; char GetSeparator() const noexcept;
/// The typesep character is used for separating the word from the type /// The typesep character is used for separating the word from the type
void SetTypesep(char separator_); void SetTypesep(char separator_) noexcept;
char GetTypesep() const noexcept; char GetTypesep() const noexcept;
/// The list string contains a sequence of words separated by the separator character /// The list string contains a sequence of words separated by the separator character

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cassert> #include <cassert>
#include <stdexcept> #include <stdexcept>

View File

@ -22,7 +22,7 @@ namespace {
const int catRanges[] = { const int catRanges[] = {
//++Autogenerated -- start of section automatically generated //++Autogenerated -- start of section automatically generated
// Created with Python 3.12.0, Unicode 15.0.0 // Created with Python 3.13.0, Unicode 15.1.0
25, 25,
1046, 1046,
1073, 1073,
@ -2257,7 +2257,6 @@ const int catRanges[] = {
385045, 385045,
391901, 391901,
392725, 392725,
393117,
393238, 393238,
393265, 393265,
393365, 393365,
@ -2321,6 +2320,7 @@ const int catRanges[] = {
406532, 406532,
407573, 407573,
408733, 408733,
409077,
409092, 409092,
409621, 409621,
410621, 410621,
@ -4014,6 +4014,8 @@ const int catRanges[] = {
5887069, 5887069,
5887492, 5887492,
6126653, 6126653,
6127108,
6147037,
6225924, 6225924,
6243293, 6243293,
6291460, 6291460,

View File

@ -6,6 +6,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cstdarg> #include <cstdarg>

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
@ -832,15 +833,9 @@ Sci::Position Document::MovePositionOutsideChar(Sci::Position pos, Sci::Position
// Else invalid UTF-8 so return position of isolated trail byte // Else invalid UTF-8 so return position of isolated trail byte
} }
} else { } else {
// Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte.
const Sci::Position posStartLine = LineStartPosition(pos);
if (pos == posStartLine)
return pos;
// Step back until a non-lead-byte is found. // Step back until a non-lead-byte is found.
Sci::Position posCheck = pos; Sci::Position posCheck = pos;
while ((posCheck > posStartLine) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1))) while ((posCheck > 0) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1)))
posCheck--; posCheck--;
// Check from known start of character. // Check from known start of character.
@ -915,14 +910,11 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc
if (pos > cb.Length()) if (pos > cb.Length())
pos = cb.Length(); pos = cb.Length();
} else { } else {
// Anchor DBCS calculations at start of line because start of line can // How to Go Backward in a DBCS String
// not be a DBCS trail byte. // https://msdn.microsoft.com/en-us/library/cc194792.aspx
const Sci::Position posStartLine = LineStartPosition(pos); // DBCS-Enabled Programs vs. Non-DBCS-Enabled Programs
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx // https://msdn.microsoft.com/en-us/library/cc194790.aspx
// http://msdn.microsoft.com/en-us/library/cc194790.aspx if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) {
if ((pos - 1) <= posStartLine) {
return pos - 1;
} else if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) {
// Should actually be trail byte // Should actually be trail byte
if (IsDBCSDualByteAt(pos - 2)) { if (IsDBCSDualByteAt(pos - 2)) {
return pos - 2; return pos - 2;
@ -933,7 +925,7 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc
} else { } else {
// Otherwise, step back until a non-lead-byte is found. // Otherwise, step back until a non-lead-byte is found.
Sci::Position posTemp = pos - 1; Sci::Position posTemp = pos - 1;
while (posStartLine <= --posTemp && IsDBCSLeadByteNoExcept(cb.CharAt(posTemp))) while (--posTemp >= 0 && IsDBCSLeadByteNoExcept(cb.CharAt(posTemp)))
; ;
// Now posTemp+1 must point to the beginning of a character, // Now posTemp+1 must point to the beginning of a character,
// so figure out whether we went back an even or an odd // so figure out whether we went back an even or an odd
@ -1170,6 +1162,29 @@ bool Document::IsDBCSTrailByteNoExcept(char ch) const noexcept {
return false; return false;
} }
unsigned char Document::DBCSMinTrailByte() const noexcept {
switch (dbcsCodePage) {
case 932:
// Shift_jis
return 0x40;
case 936:
// GBK
return 0x40;
case 949:
// Korean Wansung KS C-5601-1987
return 0x41;
case 950:
// Big5
return 0x40;
case 1361:
// Korean Johab KS C-5601-1992
return 0x31;
default:
// UTF-8 or single byte, should not occur as not DBCS
return 0;
}
}
int Document::DBCSDrawBytes(std::string_view text) const noexcept { int Document::DBCSDrawBytes(std::string_view text) const noexcept {
if (text.length() <= 1) { if (text.length() <= 1) {
return static_cast<int>(text.length()); return static_cast<int>(text.length());
@ -2828,8 +2843,8 @@ static char BraceOpposite(char ch) noexcept {
// TODO: should be able to extend styled region to find matching brace // TODO: should be able to extend styled region to find matching brace
Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/, Sci::Position startPos, bool useStartPos) noexcept { Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxReStyle*/, Sci::Position startPos, bool useStartPos) noexcept {
const char chBrace = CharAt(position); const unsigned char chBrace = CharAt(position);
const char chSeek = BraceOpposite(chBrace); const unsigned char chSeek = BraceOpposite(chBrace);
if (chSeek == '\0') if (chSeek == '\0')
return -1; return -1;
const int styBrace = StyleIndexAt(position); const int styBrace = StyleIndexAt(position);
@ -2837,22 +2852,25 @@ Sci::Position Document::BraceMatch(Sci::Position position, Sci::Position /*maxRe
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1; direction = 1;
int depth = 1; int depth = 1;
position = useStartPos ? startPos : NextPosition(position, direction); position = useStartPos ? startPos : position + direction;
// Avoid using MovePositionOutsideChar to check DBCS trail byte
unsigned char maxSafeChar = 0xff;
if (dbcsCodePage != 0 && dbcsCodePage != CpUtf8) {
maxSafeChar = DBCSMinTrailByte() - 1;
}
while ((position >= 0) && (position < LengthNoExcept())) { while ((position >= 0) && (position < LengthNoExcept())) {
const char chAtPos = CharAt(position); const unsigned char chAtPos = CharAt(position);
const int styAtPos = StyleIndexAt(position); if (chAtPos == chBrace || chAtPos == chSeek) {
if ((position > GetEndStyled()) || (styAtPos == styBrace)) { if (((position > GetEndStyled()) || (StyleIndexAt(position) == styBrace)) &&
if (chAtPos == chBrace) (chAtPos <= maxSafeChar || position == MovePositionOutsideChar(position, direction, false))) {
depth++; depth += (chAtPos == chBrace) ? 1 : -1;
if (chAtPos == chSeek)
depth--;
if (depth == 0) if (depth == 0)
return position; return position;
} }
const Sci::Position positionBeforeMove = position; }
position = NextPosition(position, direction); position += direction;
if (position == positionBeforeMove)
break;
} }
return -1; return -1;
} }
@ -2882,14 +2900,13 @@ namespace {
*/ */
class RESearchRange { class RESearchRange {
public: public:
const Document *doc;
int increment; int increment;
Sci::Position startPos; Sci::Position startPos;
Sci::Position endPos; Sci::Position endPos;
Sci::Line lineRangeStart; Sci::Line lineRangeStart;
Sci::Line lineRangeEnd; Sci::Line lineRangeEnd;
Sci::Line lineRangeBreak; Sci::Line lineRangeBreak;
RESearchRange(const Document *doc_, Sci::Position minPos, Sci::Position maxPos) noexcept : doc(doc_) { RESearchRange(const Document *doc, Sci::Position minPos, Sci::Position maxPos) noexcept {
increment = (minPos <= maxPos) ? 1 : -1; increment = (minPos <= maxPos) ? 1 : -1;
// Range endpoints should not be inside DBCS characters or between a CR and LF, // Range endpoints should not be inside DBCS characters or between a CR and LF,

View File

@ -369,6 +369,7 @@ public:
bool SCI_METHOD IsDBCSLeadByte(char ch) const override; bool SCI_METHOD IsDBCSLeadByte(char ch) const override;
bool IsDBCSLeadByteNoExcept(char ch) const noexcept; bool IsDBCSLeadByteNoExcept(char ch) const noexcept;
bool IsDBCSTrailByteNoExcept(char ch) const noexcept; bool IsDBCSTrailByteNoExcept(char ch) const noexcept;
unsigned char DBCSMinTrailByte() const noexcept;
int DBCSDrawBytes(std::string_view text) const noexcept; int DBCSDrawBytes(std::string_view text) const noexcept;
bool IsDBCSDualByteAt(Sci::Position pos) const noexcept; bool IsDBCSDualByteAt(Sci::Position pos) const noexcept;
size_t SafeSegment(std::string_view text) const noexcept; size_t SafeSegment(std::string_view text) const noexcept;

View File

@ -516,10 +516,14 @@ void Editor::RedrawSelMargin(Sci::Line line, bool allAfter) {
} }
PRectangle Editor::RectangleFromRange(Range r, int overlap) { PRectangle Editor::RectangleFromRange(Range r, int overlap) {
const Sci::Line minLine = pcs->DisplayFromDoc( const Sci::Line docLineFirst = pdoc->SciLineFromPosition(r.First());
pdoc->SciLineFromPosition(r.First())); const Sci::Line minLine = pcs->DisplayFromDoc(docLineFirst);
const Sci::Line maxLine = pcs->DisplayLastFromDoc( Sci::Line docLineLast = docLineFirst; // Common case where range is wholly in one document line
pdoc->SciLineFromPosition(r.Last())); if (r.Last() >= pdoc->LineStart(docLineFirst + 1)) {
// Range covers multiple lines so need last line
docLineLast = pdoc->SciLineFromPosition(r.Last());
}
const Sci::Line maxLine = pcs->DisplayLastFromDoc(docLineLast);
const PRectangle rcClientDrawing = GetClientDrawingRectangle(); const PRectangle rcClientDrawing = GetClientDrawingRectangle();
PRectangle rc; PRectangle rc;
const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0; const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0;
@ -999,21 +1003,25 @@ void Editor::MoveSelectedLines(int lineDelta) {
// if selection doesn't end at the beginning of a line greater than that of the start, // if selection doesn't end at the beginning of a line greater than that of the start,
// then set it at the beginning of the next one // then set it at the beginning of the next one
Sci::Position selectionEnd = SelectionEnd().Position(); Sci::Position selectionEnd = SelectionEnd().Position();
const Sci::Line endLine = pdoc->SciLineFromPosition(selectionEnd); Sci::Line endLine = pdoc->SciLineFromPosition(selectionEnd);
const Sci::Position beginningOfEndLine = pdoc->LineStart(endLine); const Sci::Position beginningOfEndLine = pdoc->LineStart(endLine);
bool appendEol = false; bool appendEol = false;
if (selectionEnd > beginningOfEndLine if (selectionEnd > beginningOfEndLine
|| selectionStart == selectionEnd) { || selectionStart == selectionEnd) {
selectionEnd = pdoc->LineStart(endLine + 1); selectionEnd = pdoc->LineStart(endLine + 1);
appendEol = (selectionEnd == pdoc->Length() && pdoc->SciLineFromPosition(selectionEnd) == endLine); appendEol = (selectionEnd == pdoc->Length() && pdoc->SciLineFromPosition(selectionEnd) == endLine);
endLine = pdoc->SciLineFromPosition(selectionEnd);
} }
// if there's nowhere for the selection to move // if there's nowhere for the selection to move
// (i.e. at the beginning going up or at the end going down), // (i.e. at the beginning going up or at the end going down),
// stop it right there! // stop it right there!
const bool docEndLineEmpty = pdoc->LineStart(endLine) == pdoc->Length();
if ((selectionStart == 0 && lineDelta < 0) if ((selectionStart == 0 && lineDelta < 0)
|| (selectionEnd == pdoc->Length() && lineDelta > 0) || (selectionEnd == pdoc->Length() && lineDelta > 0
|| selectionStart == selectionEnd) { && !docEndLineEmpty) // allow moving when end line of document is empty
|| ((selectionStart == selectionEnd)
&& !(lineDelta < 0 && docEndLineEmpty && selectionEnd == pdoc->Length()))) { // allow moving-up last empty line
return; return;
} }
@ -2634,6 +2642,12 @@ void Editor::CheckModificationForWrap(DocModification mh) {
const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position); const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position);
const Sci::Line lines = std::max(static_cast<Sci::Line>(0), mh.linesAdded); const Sci::Line lines = std::max(static_cast<Sci::Line>(0), mh.linesAdded);
if (Wrapping()) { if (Wrapping()) {
// Check if this modification crosses any of the wrap points
if (wrapPending.NeedsWrap()) {
if (lineDoc < wrapPending.end) { // Inserted/deleted before or inside wrap range
wrapPending.end += mh.linesAdded;
}
}
NeedWrapping(lineDoc, lineDoc + lines + 1); NeedWrapping(lineDoc, lineDoc + lines + 1);
} }
RefreshStyleData(); RefreshStyleData();

View File

@ -5,6 +5,7 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdint>
#include <cmath> #include <cmath>
#include <stdexcept> #include <stdexcept>

View File

@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string_view>

View File

@ -5,6 +5,7 @@
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdint>
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>

View File

@ -182,7 +182,7 @@ public:
T upper = Partitions(); T upper = Partitions();
do { do {
const T middle = (upper + lower + 1) / 2; // Round high const T middle = (upper + lower + 1) / 2; // Round high
T posMiddle = body.ValueAt(middle); T posMiddle = body[middle];
if (middle > stepPartition) if (middle > stepPartition)
posMiddle += stepLength; posMiddle += stepLength;
if (pos < posMiddle) { if (pos < posMiddle) {

View File

@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>

View File

@ -80,8 +80,6 @@ void RunStyles<DISTANCE, STYLE>::RemoveRunIfSameAsPrevious(DISTANCE run) {
template <typename DISTANCE, typename STYLE> template <typename DISTANCE, typename STYLE>
RunStyles<DISTANCE, STYLE>::RunStyles() { RunStyles<DISTANCE, STYLE>::RunStyles() {
starts = Partitioning<DISTANCE>(8);
styles = SplitVector<STYLE>();
styles.InsertValue(0, 2, 0); styles.InsertValue(0, 2, 0);
} }
@ -136,7 +134,8 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
return resultNoChange; return resultNoChange;
} }
DISTANCE runEnd = RunFromPosition(end); DISTANCE runEnd = RunFromPosition(end);
if (styles.ValueAt(runEnd) == value) { const STYLE valueCurrent = styles.ValueAt(runEnd);
if (valueCurrent == value) {
// End already has value so trim range. // End already has value so trim range.
end = starts.PositionFromPartition(runEnd); end = starts.PositionFromPartition(runEnd);
if (position >= end) { if (position >= end) {
@ -145,6 +144,22 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
} }
fillLength = end - position; fillLength = end - position;
} else { } else {
const DISTANCE startRun = starts.PositionFromPartition(runEnd);
if (position > startRun) {
const DISTANCE runNext = runEnd + 1;
const DISTANCE endRun = starts.PositionFromPartition(runNext);
if (end < endRun) {
// New piece is completely inside a run with a different value so its a simple
// insertion of two points [ (position, value), (end, valueCurrent) ]
const DISTANCE range[] { position, end};
starts.InsertPartitions(runEnd + 1, range, 2);
// Temporary runEndIndex silences non-useful arithmetic overflow warnings
const ptrdiff_t runEndIndex = runEnd;
styles.Insert(runEndIndex + 1, value);
styles.Insert(runEndIndex + 2, valueCurrent);
return { true, position, fillLength };
}
}
runEnd = SplitRun(end); runEnd = SplitRun(end);
} }
DISTANCE runStart = RunFromPosition(position); DISTANCE runStart = RunFromPosition(position);
@ -172,9 +187,8 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
runEnd = RunFromPosition(end); runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd); RemoveRunIfEmpty(runEnd);
return result; return result;
} else {
return resultNoChange;
} }
return resultNoChange;
} }
template <typename DISTANCE, typename STYLE> template <typename DISTANCE, typename STYLE>
@ -213,7 +227,7 @@ void RunStyles<DISTANCE, STYLE>::InsertSpace(DISTANCE position, DISTANCE insertL
template <typename DISTANCE, typename STYLE> template <typename DISTANCE, typename STYLE>
void RunStyles<DISTANCE, STYLE>::DeleteAll() { void RunStyles<DISTANCE, STYLE>::DeleteAll() {
starts = Partitioning<DISTANCE>(8); starts = Partitioning<DISTANCE>();
styles = SplitVector<STYLE>(); styles = SplitVector<STYLE>();
styles.InsertValue(0, 2, 0); styles.InsertValue(0, 2, 0);
} }

View File

@ -27,8 +27,6 @@ private:
} }
public: public:
SparseVector() : empty() { SparseVector() : empty() {
starts = Partitioning<Sci::Position>(8);
values = SplitVector<T>();
values.InsertEmpty(0, 2); values.InsertEmpty(0, 2);
} }
Sci::Position Length() const noexcept { Sci::Position Length() const noexcept {
@ -158,7 +156,7 @@ public:
Check(); Check();
} }
void DeleteAll() { void DeleteAll() {
starts = Partitioning<Sci::Position>(8); starts = Partitioning<Sci::Position>();
values = SplitVector<T>(); values = SplitVector<T>();
values.InsertEmpty(0, 2); values.InsertEmpty(0, 2);
} }

View File

@ -5,6 +5,8 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdint>
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string_view>
#include <vector> #include <vector>

View File

@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <cmath> #include <cmath>

View File

@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cstring> #include <cstring>
#include <climits> #include <climits>

View File

@ -3,6 +3,7 @@
**/ **/
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>

View File

@ -3,6 +3,7 @@
**/ **/
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string_view>
@ -728,6 +729,55 @@ TEST_CASE("Document") {
REQUIRE(substituted == "\ta\n"); REQUIRE(substituted == "\ta\n");
} }
SECTION("BraceMatch") {
DocPlus doc("{}(()())[]", CpUtf8);
constexpr Sci::Position maxReStyle = 0; // unused parameter
Sci::Position pos = doc.document.BraceMatch(0, maxReStyle, 0, false);
REQUIRE(pos == 1);
pos = doc.document.BraceMatch(1, maxReStyle, 0, false);
REQUIRE(pos == 0);
pos = doc.document.BraceMatch(8, maxReStyle, 0, false);
REQUIRE(pos == 9);
pos = doc.document.BraceMatch(9, maxReStyle, 0, false);
REQUIRE(pos == 8);
pos = doc.document.BraceMatch(2, maxReStyle, 0, false);
REQUIRE(pos == 7);
pos = doc.document.BraceMatch(7, maxReStyle, 0, false);
REQUIRE(pos == 2);
// BraceMatchNext()
pos = doc.document.BraceMatch(2, maxReStyle, 3, true);
REQUIRE(pos == 7);
pos = doc.document.BraceMatch(2, maxReStyle, 4, true);
REQUIRE(pos == 4);
pos = doc.document.BraceMatch(2, maxReStyle, 5, true);
REQUIRE(pos == 7);
pos = doc.document.BraceMatch(2, maxReStyle, 6, true);
REQUIRE(pos == 6);
pos = doc.document.BraceMatch(2, maxReStyle, 7, true);
REQUIRE(pos == 7);
pos = doc.document.BraceMatch(7, maxReStyle, 6, true);
REQUIRE(pos == 2);
pos = doc.document.BraceMatch(7, maxReStyle, 5, true);
REQUIRE(pos == 5);
pos = doc.document.BraceMatch(7, maxReStyle, 4, true);
REQUIRE(pos == 2);
pos = doc.document.BraceMatch(7, maxReStyle, 3, true);
REQUIRE(pos == 3);
pos = doc.document.BraceMatch(7, maxReStyle, 2, true);
REQUIRE(pos == 2);
}
SECTION("BraceMatch DBCS") {
DocPlus doc("{\x81}\x81{}", 932); // { U+00B1 U+FF0B }
constexpr Sci::Position maxReStyle = 0; // unused parameter
Sci::Position pos = doc.document.BraceMatch(0, maxReStyle, 0, false);
REQUIRE(pos == 5);
pos = doc.document.BraceMatch(5, maxReStyle, 0, false);
REQUIRE(pos == 0);
}
} }
TEST_CASE("DocumentUndo") { TEST_CASE("DocumentUndo") {

View File

@ -3,6 +3,7 @@
**/ **/
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <string_view> #include <string_view>

View File

@ -3,6 +3,7 @@
**/ **/
#include <cstddef> #include <cstddef>
#include <cstdint>
#include <cstring> #include <cstring>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>

View File

@ -1 +1 @@
553 554

View File

@ -7,6 +7,7 @@
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstdint>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
#include <cstdarg> #include <cstdarg>

View File

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

View File

@ -5,6 +5,8 @@
// Copyright 1998-2018 by Neil Hodgson <neilh@scintilla.org> // Copyright 1998-2018 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed. // The License.txt file describes the conditions under which this software may be distributed.
#include <cstdint>
#undef _WIN32_WINNT #undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500 #define _WIN32_WINNT 0x0500
#undef WINVER #undef WINVER

View File

@ -303,7 +303,7 @@ public:
return ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, nullptr, 0); return ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, nullptr, 0);
} }
std::vector<BYTE> GetImeAttributes() { std::vector<BYTE> GetImeAttributes() const {
const int attrLen = ::ImmGetCompositionStringW(hIMC, GCS_COMPATTR, nullptr, 0); const int attrLen = ::ImmGetCompositionStringW(hIMC, GCS_COMPATTR, nullptr, 0);
std::vector<BYTE> attr(attrLen, 0); std::vector<BYTE> attr(attrLen, 0);
::ImmGetCompositionStringW(hIMC, GCS_COMPATTR, &attr[0], static_cast<DWORD>(attr.size())); ::ImmGetCompositionStringW(hIMC, GCS_COMPATTR, &attr[0], static_cast<DWORD>(attr.size()));
@ -315,7 +315,7 @@ public:
return byteLen / sizeof(wchar_t); return byteLen / sizeof(wchar_t);
} }
std::wstring GetCompositionString(DWORD dwIndex) { std::wstring GetCompositionString(DWORD dwIndex) const {
const LONG byteLen = ::ImmGetCompositionStringW(hIMC, dwIndex, nullptr, 0); const LONG byteLen = ::ImmGetCompositionStringW(hIMC, dwIndex, nullptr, 0);
std::wstring wcs(byteLen / 2, 0); std::wstring wcs(byteLen / 2, 0);
::ImmGetCompositionStringW(hIMC, dwIndex, &wcs[0], byteLen); ::ImmGetCompositionStringW(hIMC, dwIndex, &wcs[0], byteLen);