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
**.ml text
**.nim text
**.nix text
**.octave text
**.p text
**.pl text

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20241019" />
<meta name="Date.Modified" content="20241218" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -61,8 +61,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.4.1<br />
Site last modified October 19 2024</font>
<font color="#FFCC99" size="3">Release version 5.4.2<br />
Site last modified December 18 2024</font>
</td>
<td width="20%">
&nbsp;
@ -77,11 +77,11 @@
</tr>
</table>
<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.0 adds a TOML lexer.</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.1 improves Assembler, Bash, Batch, JavaScript, Python, and Ruby.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
@ -130,7 +130,7 @@ if (!IsRemote()) { //if NOT remote...
<p>
The source code can be downloaded via Git at GitHub
<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>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 />

View File

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

View File

@ -587,9 +587,53 @@
<td>RainRat</td>
</tr><tr>
<td>Henrik S. Johansen</td>
<td>Ekopalypse</td>
</tr>
</table>
<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>
<a href="https://www.scintilla.org/lexilla541.zip">Release 5.4.1</a>
</h3>

View File

@ -148,6 +148,7 @@ val SCLEX_TOML=136
val SCLEX_TROFF=137
val SCLEX_DART=138
val SCLEX_ZIG=139
val SCLEX_NIX=140
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1.
@ -178,12 +179,10 @@ val SCE_P_FTRIPLEDOUBLE=19
val SCE_P_ATTRIBUTE=20
# Lexical states for SCLEX_CPP
# Lexical states for SCLEX_BULLANT
# Lexical states for SCLEX_COBOL
# Lexical states for SCLEX_TACL
# Lexical states for SCLEX_TAL
lex Cpp=SCLEX_CPP SCE_C_
lex BullAnt=SCLEX_BULLANT SCE_C_
lex COBOL=SCLEX_COBOL SCE_C_
lex TACL=SCLEX_TACL SCE_C_
lex TAL=SCLEX_TAL SCE_C_
val SCE_C_DEFAULT=0
@ -214,6 +213,21 @@ val SCE_C_PREPROCESSORCOMMENTDOC=24
val SCE_C_USERLITERAL=25
val SCE_C_TASKMARKER=26
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
lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0
@ -2009,6 +2023,8 @@ val SCE_RUST_LEXERROR=20
val SCE_RUST_BYTESTRING=21
val SCE_RUST_BYTESTRINGR=22
val SCE_RUST_BYTECHARACTER=23
val SCE_RUST_CSTRING=24
val SCE_RUST_CSTRINGR=25
# Lexical states for SCLEX_DMAP
lex DMAP=SCLEX_DMAP SCE_DMAP_
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_TERTIARY=15
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_DART 138
#define SCLEX_ZIG 139
#define SCLEX_NIX 140
#define SCLEX_SEARCHRESULT 150
#define SCLEX_OBJC 151
#define SCLEX_USER 152
@ -205,6 +206,19 @@
#define SCE_C_USERLITERAL 25
#define SCE_C_TASKMARKER 26
#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_COMMENT 1
#define SCE_D_COMMENTLINE 2
@ -1799,6 +1813,8 @@
#define SCE_RUST_BYTESTRING 21
#define SCE_RUST_BYTESTRINGR 22
#define SCE_RUST_BYTECHARACTER 23
#define SCE_RUST_CSTRING 24
#define SCE_RUST_CSTRINGR 25
#define SCE_DMAP_DEFAULT 0
#define SCE_DMAP_COMMENT 1
#define SCE_DMAP_NUMBER 2
@ -2154,6 +2170,23 @@
#define SCE_ZIG_KW_SECONDARY 14
#define SCE_ZIG_KW_TERTIARY 15
#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 */

View File

@ -8,12 +8,11 @@
** Updated by Rod Falck, Aug 2006 Converted to COBOL
**/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <string>
#include <string_view>
@ -38,23 +37,25 @@ using namespace Lexilla;
#define IN_FLAGS 0xF
#define NOT_HEADER 0x10
inline bool isCOBOLoperator(char ch)
namespace {
bool isCOBOLoperator(char ch)
{
return isoperator(ch);
}
inline bool isCOBOLwordchar(char ch)
bool isCOBOLwordchar(char ch)
{
return IsASCII(ch) && (isalnum(ch) || ch == '-');
}
inline bool isCOBOLwordstart(char ch)
bool isCOBOLwordstart(char ch)
{
return IsASCII(ch) && isalnum(ch);
}
static int CountBits(int nBits)
int CountBits(int nBits)
{
int count = 0;
for (int i = 0; i < 32; ++i)
@ -65,7 +66,7 @@ static int CountBits(int nBits)
return count;
}
static void getRange(Sci_PositionU start,
void getRange(Sci_PositionU start,
Sci_PositionU end,
Accessor &styler,
char *s,
@ -78,12 +79,12 @@ static void getRange(Sci_PositionU start,
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);
}
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;
char s[100];
@ -91,31 +92,31 @@ static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList
s[1] = '\0';
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')) {
chAttr = SCE_C_NUMBER;
chAttr = SCE_COBOL_NUMBER;
char *p = s + 1;
while (*p) {
if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
chAttr = SCE_C_IDENTIFIER;
chAttr = SCE_COBOL_IDENTIFIER;
break;
}
++p;
}
}
if (chAttr == SCE_C_IDENTIFIER) {
if (chAttr == SCE_COBOL_IDENTIFIER) {
WordList& a_keywords = *keywordlists[0];
WordList& b_keywords = *keywordlists[1];
WordList& c_keywords = *keywordlists[2];
if (a_keywords.InList(s)) {
chAttr = SCE_C_WORD;
chAttr = SCE_COBOL_WORD;
}
else if (b_keywords.InList(s)) {
chAttr = SCE_C_WORD2;
chAttr = SCE_COBOL_WORD2;
}
else if (c_keywords.InList(s)) {
chAttr = SCE_C_UUID;
chAttr = SCE_COBOL_WORD3;
}
}
if (*bAarea) {
@ -143,14 +144,14 @@ static int classifyWordCOBOL(Sci_PositionU start, Sci_PositionU end, /*WordList
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) {
styler.StartAt(startPos);
int state = initStyle;
if (state == SCE_C_CHARACTER) // Does not leak onto next line
state = SCE_C_DEFAULT;
if (state == SCE_COBOL_CHARACTER) // Does not leak onto next line
state = SCE_COBOL_DEFAULT;
char chPrev = ' ';
char chNext = styler[startPos];
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)
// Avoid triggering two times on Dos/Win
// End of line
if (state == SCE_C_CHARACTER) {
if (state == SCE_COBOL_CHARACTER) {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
state = SCE_COBOL_DEFAULT;
}
styler.SetLineState(currentLine, nContainment);
currentLine++;
@ -207,44 +208,44 @@ static void ColouriseCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int i
continue;
}
if (state == SCE_C_DEFAULT) {
if (state == SCE_COBOL_DEFAULT) {
if (isCOBOLwordstart(ch) || (ch == '$' && IsASCII(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER;
state = SCE_COBOL_IDENTIFIER;
} else if (column == 6 && (ch == '*' || ch == '/')) {
// Cobol comment line: asterisk in column 7.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
state = SCE_COBOL_COMMENTLINE;
} else if (ch == '*' && chNext == '>') {
// Cobol inline comment: asterisk, followed by greater than.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '/' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
state = SCE_COBOL_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext == '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC;
state = SCE_COBOL_COMMENTDOC;
} else if (column == 0 && ch == '/' && chNext == '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTDOC;
state = SCE_COBOL_COMMENTDOC;
} else if (ch == '"') {
ColourTo(styler, i-1, state);
state = SCE_C_STRING;
state = SCE_COBOL_STRING;
} else if (ch == '\'') {
ColourTo(styler, i-1, state);
state = SCE_C_CHARACTER;
state = SCE_COBOL_CHARACTER;
} else if (ch == '?' && column == 0) {
ColourTo(styler, i-1, state);
state = SCE_C_PREPROCESSOR;
state = SCE_COBOL_PREPROCESSOR;
} else if (isCOBOLoperator(ch)) {
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)) {
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;
}
state = SCE_C_DEFAULT;
state = SCE_COBOL_DEFAULT;
chNext = styler.SafeGetCharAt(i + 1);
if (column == 6 && (ch == '*' || ch == '/')) {
state = SCE_C_COMMENTLINE;
state = SCE_COBOL_COMMENTLINE;
} else if (ch == '"') {
state = SCE_C_STRING;
state = SCE_COBOL_STRING;
} else if (ch == '\'') {
state = SCE_C_CHARACTER;
state = SCE_COBOL_CHARACTER;
} else if (isCOBOLoperator(ch)) {
ColourTo(styler, i, SCE_C_OPERATOR);
ColourTo(styler, i, SCE_COBOL_OPERATOR);
}
}
} else {
if (state == SCE_C_PREPROCESSOR) {
if (state == SCE_COBOL_PREPROCESSOR) {
if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
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') {
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 (((i > styler.GetStartSegment() + 2) || (
(initStyle == SCE_C_COMMENTDOC) &&
(initStyle == SCE_COBOL_COMMENTDOC) &&
(styler.GetStartSegment() == static_cast<Sci_PositionU>(startPos))))) {
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') {
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 == '"') {
ColourTo(styler, i, state);
state = SCE_C_DEFAULT;
state = SCE_COBOL_DEFAULT;
} else if (ch == '\r' || ch == '\n') {
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 == '\'') {
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);
}
static void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
void FoldCOBOLDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
Accessor &styler) {
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
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);
}
static const char * const COBOLWordListDesc[] = {
const char * const COBOLWordListDesc[] = {
"A Keywords",
"B Keywords",
"Extended Keywords",
0
nullptr
};
}
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);
} else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
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);
}
}
@ -668,6 +668,10 @@ constexpr bool isPHPStringState(int state) noexcept {
(state == SCE_HPHP_COMPLEX_VARIABLE);
}
constexpr bool StyleNeedsBacktrack(int state) noexcept {
return InTagState(state) || isPHPStringState(state);
}
enum class AllowPHP : int {
None, // No PHP
PHP, // <?php and <?=
@ -1190,7 +1194,6 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
if (isPHPScript && (startPos == 0)) {
initStyle = SCE_HPHP_DEFAULT;
}
styler.StartAt(startPos);
std::string lastTag;
std::string prevWord;
PhpNumberState phpNumber;
@ -1201,23 +1204,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
int makoComment = 0;
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 (InTagState(state)) {
while ((startPos > 0) && (InTagState(styler.StyleIndexAt(startPos - 1)))) {
// PHP string can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
if (StyleNeedsBacktrack(state)) {
while ((startPos > 0) && (StyleNeedsBacktrack(styler.StyleIndexAt(startPos - 1)))) {
const Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1));
length += 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);
@ -2339,6 +2337,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
}
styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT;
continue;
} else if (ch == '\\') {
// Gobble up the quoted character
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 Lexilla;
static const int NUM_RUST_KEYWORD_LISTS = 7;
static const int MAX_RUST_IDENT_CHARS = 1023;
namespace {
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 ||
style == SCE_RUST_COMMENTBLOCKDOC;
}
@ -81,7 +94,7 @@ static const char * const rustWordLists[NUM_RUST_KEYWORD_LISTS + 1] = {
"Keywords 6",
"Keywords 7",
0,
};
};
struct OptionSetRust : public OptionSet<OptionsRust> {
OptionSetRust() {
@ -208,7 +221,7 @@ static void GrabString(char* s, Accessor& styler, Sci_Position start, Sci_Positi
}
static void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) {
Sci_Position start = pos;
const Sci_Position start = pos;
while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0')))
pos++;
@ -226,7 +239,7 @@ static void ScanRawIdentifier(Accessor& styler, Sci_Position& pos) {
}
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')))
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. */
static bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) {
Sci_Position old_pos = pos;
const Sci_Position old_pos = pos;
for (;;) {
int c = styler.SafeGetCharAt(pos, '\0');
const int c = styler.SafeGetCharAt(pos, '\0');
if (IsADigit(c, base) || c == '_')
pos++;
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) {
for (;;) {
int c = styler.SafeGetCharAt(pos, '\0');
const int c = styler.SafeGetCharAt(pos, '\0');
if (!IsADigit(c, 16))
break;
num_digits--;
@ -508,7 +521,7 @@ static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position
int c = styler.SafeGetCharAt(pos, '\0');
bool maybe_doc_comment = false;
if (c == '*') {
int n = styler.SafeGetCharAt(pos + 1, '\0');
const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (n != '*' && n != '/') {
maybe_doc_comment = true;
}
@ -517,7 +530,7 @@ static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position
}
for (;;) {
int n = styler.SafeGetCharAt(pos + 1, '\0');
const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (pos == styler.LineEnd(styler.GetLine(pos)))
styler.SetLineState(styler.GetLine(pos), level);
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) {
pos++;
int c = styler.SafeGetCharAt(pos, '\0');
const int c = styler.SafeGetCharAt(pos, '\0');
pos++;
if (c == '/')
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);
}
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');
bool error = false;
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)))
styler.SetLineState(styler.GetLine(pos), 0);
if (c == '\\') {
int n = styler.SafeGetCharAt(pos + 1, '\0');
const int n = styler.SafeGetCharAt(pos + 1, '\0');
if (IsValidStringEscape(n)) {
pos += 2;
} else if (n == 'x') {
pos += 2;
error = !ScanNumericEscape(styler, pos, 2, true);
} else if (n == 'u' && !ascii_only) {
} else if (n == 'u' && (string_type != StringType::BYTESTRING)) {
pos += 2;
if (styler.SafeGetCharAt(pos, '\0') != '{') {
// old-style
@ -624,7 +637,7 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
else
error = true;
}
} else if (n == 'U' && !ascii_only) {
} else if (n == 'U' && (string_type != StringType::BYTESTRING)) {
pos += 2;
error = !ScanNumericEscape(styler, pos, 8, true);
} else {
@ -632,7 +645,7 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
error = true;
}
} else {
if (ascii_only && !IsASCII((char)c))
if (string_type == StringType::BYTESTRING && !IsASCII((char)c))
error = true;
else
pos++;
@ -641,15 +654,16 @@ static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max,
}
if (!error)
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 (;;) {
if (pos == styler.LineEnd(styler.GetLine(pos)))
styler.SetLineState(styler.GetLine(pos), num_hashes);
int c = styler.SafeGetCharAt(pos, '\0');
const int c = styler.SafeGetCharAt(pos, '\0');
if (c == '"') {
pos++;
int trailing_num_hashes = 0;
@ -664,15 +678,16 @@ static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position ma
} else if (pos >= max) {
break;
} else {
if (ascii_only && !IsASCII((char)c))
if ((string_type == StringType::RAW_BYTESTRING) && !IsASCII((char)c))
break;
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++;
int num_hashes = 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);
} else {
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;
Accessor styler(pAccess, &props);
Sci_Position pos = startPos;
Sci_Position max = pos + length;
const Sci_Position max = pos + length;
styler.StartAt(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) {
ResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment);
} else if (initStyle == SCE_RUST_STRING) {
ResumeString(styler, pos, max, false);
ResumeString(styler, pos, max, StringType::STRING);
} else if (initStyle == SCE_RUST_BYTESTRING) {
ResumeString(styler, pos, max, true);
ResumeString(styler, pos, max, StringType::BYTESTRING);
} 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) {
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) {
int c = styler.SafeGetCharAt(pos, '\0');
int n = styler.SafeGetCharAt(pos + 1, '\0');
int n2 = styler.SafeGetCharAt(pos + 2, '\0');
const int c = styler.SafeGetCharAt(pos, '\0');
const int n = styler.SafeGetCharAt(pos + 1, '\0');
const int n2 = styler.SafeGetCharAt(pos + 2, '\0');
if (pos == 0 && c == '#' && n == '!' && n2 != '[') {
pos += 2;
@ -726,13 +744,19 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
pos += 2;
ScanRawIdentifier(styler, pos);
} 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 == '"')) {
pos++;
ScanRawString(styler, pos, max, true);
ScanRawString(styler, pos, max, StringType::RAW_BYTESTRING);
} else if (c == 'b' && n == '"') {
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 == '\'') {
pos++;
ScanCharacterLiteralOrLifetime(styler, pos, true);
@ -753,7 +777,7 @@ void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int
ScanCharacterLiteralOrLifetime(styler, pos, false);
} else if (c == '"') {
pos++;
ResumeString(styler, pos, max, false);
ResumeString(styler, pos, max, StringType::STRING);
} else {
pos++;
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);
Sci_PositionU endPos = startPos + length;
const Sci_PositionU endPos = startPos + length;
int visibleChars = 0;
bool inLineComment = false;
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;
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext;
const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
const int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = i == (lineStartNext-1);
const bool atEOL = i == (lineStartNext-1);
if ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC))
inLineComment = true;
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 {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
const char chNext2 = styler.SafeGetCharAt(i + 2);
if (chNext2 == '{') {
levelNext++;
} 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);

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)) {
const int chNext = GetLineNextChar(sc);
if (chNext == '=') {
if (chNext == '=' || (chNext != '.' && chPrevNonWhite != '.')) {
keyState = TOMLKeyState::End;
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",
15, "SCE_ZIG_KW_TERTIARY", "identifier", "Tertiary keywords",
16, "SCE_ZIG_KW_TYPE", "identifier", "Global types",
17, "SCE_ZIG_IDENTIFIER_STRING", "identifier", "Identifier using @\"\" syntax",
};
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_STRING:
case SCE_ZIG_MULTISTRING:
case SCE_ZIG_IDENTIFIER_STRING:
if (sc.atLineStart) {
sc.SetState(SCE_ZIG_DEFAULT);
} 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;
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);
} 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;
@ -373,6 +368,9 @@ void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle
sc.SetState(SCE_ZIG_NUMBER);
} else if ((sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) || IsIdentifierStartEx(sc.ch)) {
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)) {
sc.SetState(SCE_ZIG_OPERATOR);
}

View File

@ -20,7 +20,7 @@ namespace {
const int catRanges[] = {
//++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,
1046,
1073,
@ -2255,7 +2255,6 @@ const int catRanges[] = {
385045,
391901,
392725,
393117,
393238,
393265,
393365,
@ -2319,6 +2318,7 @@ const int catRanges[] = {
406532,
407573,
408733,
409077,
409092,
409621,
410621,
@ -4012,6 +4012,8 @@ const int catRanges[] = {
5887069,
5887492,
6126653,
6127108,
6147037,
6225924,
6243293,
6291460,

View File

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

View File

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

View File

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

View File

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

View File

@ -1034,6 +1034,20 @@ $(DIR_O)/LexNimrod.o: \
../lexlib/StyleContext.h \
../lexlib/CharacterSet.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: \
../lexers/LexNsis.cxx \
../../scintilla/include/ILexer.h \

View File

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

View File

@ -1034,6 +1034,20 @@ $(DIR_O)/LexNimrod.obj: \
../lexlib/StyleContext.h \
../lexlib/CharacterSet.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: \
../lexers/LexNsis.cxx \
../../scintilla/include/ILexer.h \

View File

@ -2,4 +2,9 @@
/a|b/i.test("baby");
// arrow function
() => /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>

View File

@ -2,5 +2,10 @@
0 401 0 | /a|b/i.test("baby");
0 401 0 | // arrow function
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 400 0

View File

@ -1,5 +1,10 @@
{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}
{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}

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
# PHP
substyles.hypertext.121=1
substylewords.121.1.*=decrypt
substylewords.121.1.*=decrypt nl2br
fold=1
fold.html=1

View File

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

View File

@ -15,6 +15,7 @@
0 401 0 | <%var x=3;//comment%>
0 401 0 | <%x=3;//comment ?> %>
0 401 0 | <%Response.Write(x)%>
0 401 0 | <%Response.Write(`template ${2+2}`)%>
0 401 0 | End
0 401 0 | </html>
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}<%{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}({68}`template ${2+2}`{65}){15}%>{0}
End
{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}
{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}
{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}
{49}'x\
</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 = 2, y = 4, z = 8 } ]
~~~~ = true # invalid character in key
invalid # invalid, missing value
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 = 2, y = 4, z = 8 } ]
0 401 0 |
0 401 0 | ~~~~ = true # invalid character in key
0 401 0 | invalid # invalid, missing value
0 401 0 | key = identifier # also invalid, identifier must be one of true, false, inf, nan
0 401 0 |

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}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

View File

@ -275,3 +275,16 @@ const optional_value: ?i32 = null;
//! This module provides functions for retrieving the current date and
//! time with varying degrees of precision and accuracy. It does not
//! 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
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 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

View File

@ -275,3 +275,16 @@
{3}//! This module provides functions for retrieving the current date and
//! time with varying degrees of precision and accuracy. It does not
//! 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>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>5.5.3</string>
<string>5.5.4</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>

View File

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

View File

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

View File

@ -130,7 +130,7 @@
<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
<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;
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>
- 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 />
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>
<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>
<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.
This looks like "Doc comment: block comments beginning with /** or /*!".</p>
@ -9516,6 +9516,16 @@ struct SCNotification {
<td><code>line</code></td>
</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>
<td align="left"><code id="SC_MOD_INSERTCHECK">SC_MOD_INSERTCHECK</code></td>
@ -9568,7 +9578,7 @@ struct SCNotification {
<tr>
<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
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">
<tr>
<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;
<a href="https://www.scintilla.org/scintilla553.tgz">
<a href="https://www.scintilla.org/scintilla554.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.5.3
Release 5.5.4
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Scintilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/scintilla553.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.zip">zip format</a> (1.8M) commonly used on Windows</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>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -582,9 +582,43 @@
<td>Gary James</td>
<td>Tsuyoshi Miyake</td>
<td>Martijn Laan</td>
</tr><tr>
<td>Pawel Z Wronek</td>
</tr>
</table>
<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>
<a href="https://www.scintilla.org/scintilla553.zip">Release 5.5.3</a>
</h3>

View File

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

View File

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

View File

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

View File

@ -1399,7 +1399,7 @@ struct Sci_RangeToFormatFull {
#ifndef __cplusplus
/* 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 SCNotification SCNotification;
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ namespace {
const int catRanges[] = {
//++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,
1046,
1073,
@ -2257,7 +2257,6 @@ const int catRanges[] = {
385045,
391901,
392725,
393117,
393238,
393265,
393365,
@ -2321,6 +2320,7 @@ const int catRanges[] = {
406532,
407573,
408733,
409077,
409092,
409621,
410621,
@ -4014,6 +4014,8 @@ const int catRanges[] = {
5887069,
5887492,
6126653,
6127108,
6147037,
6225924,
6243293,
6291460,

View File

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

View File

@ -7,6 +7,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstdint>
#include <cassert>
#include <cstring>
#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 {
// 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.
Sci::Position posCheck = pos;
while ((posCheck > posStartLine) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1)))
while ((posCheck > 0) && IsDBCSLeadByteNoExcept(cb.CharAt(posCheck-1)))
posCheck--;
// 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())
pos = cb.Length();
} 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);
// See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
// http://msdn.microsoft.com/en-us/library/cc194790.aspx
if ((pos - 1) <= posStartLine) {
return pos - 1;
} else if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) {
// How to Go Backward in a DBCS String
// https://msdn.microsoft.com/en-us/library/cc194792.aspx
// DBCS-Enabled Programs vs. Non-DBCS-Enabled Programs
// https://msdn.microsoft.com/en-us/library/cc194790.aspx
if (IsDBCSLeadByteNoExcept(cb.CharAt(pos - 1))) {
// Should actually be trail byte
if (IsDBCSDualByteAt(pos - 2)) {
return pos - 2;
@ -933,7 +925,7 @@ Sci::Position Document::NextPosition(Sci::Position pos, int moveDir) const noexc
} else {
// Otherwise, step back until a non-lead-byte is found.
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,
// 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;
}
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 {
if (text.length() <= 1) {
return static_cast<int>(text.length());
@ -2828,33 +2843,36 @@ static char BraceOpposite(char ch) noexcept {
// 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 {
const char chBrace = CharAt(position);
const char chSeek = BraceOpposite(chBrace);
const unsigned char chBrace = CharAt(position);
const unsigned char chSeek = BraceOpposite(chBrace);
if (chSeek == '\0')
return - 1;
return -1;
const int styBrace = StyleIndexAt(position);
int direction = -1;
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 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())) {
const char chAtPos = CharAt(position);
const int styAtPos = StyleIndexAt(position);
if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
if (chAtPos == chBrace)
depth++;
if (chAtPos == chSeek)
depth--;
const unsigned char chAtPos = CharAt(position);
if (chAtPos == chBrace || chAtPos == chSeek) {
if (((position > GetEndStyled()) || (StyleIndexAt(position) == styBrace)) &&
(chAtPos <= maxSafeChar || position == MovePositionOutsideChar(position, direction, false))) {
depth += (chAtPos == chBrace) ? 1 : -1;
if (depth == 0)
return position;
}
const Sci::Position positionBeforeMove = position;
position = NextPosition(position, direction);
if (position == positionBeforeMove)
break;
}
return - 1;
position += direction;
}
return -1;
}
/**
@ -2882,14 +2900,13 @@ namespace {
*/
class RESearchRange {
public:
const Document *doc;
int increment;
Sci::Position startPos;
Sci::Position endPos;
Sci::Line lineRangeStart;
Sci::Line lineRangeEnd;
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;
// 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 IsDBCSLeadByteNoExcept(char ch) const noexcept;
bool IsDBCSTrailByteNoExcept(char ch) const noexcept;
unsigned char DBCSMinTrailByte() const noexcept;
int DBCSDrawBytes(std::string_view text) const noexcept;
bool IsDBCSDualByteAt(Sci::Position pos) 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) {
const Sci::Line minLine = pcs->DisplayFromDoc(
pdoc->SciLineFromPosition(r.First()));
const Sci::Line maxLine = pcs->DisplayLastFromDoc(
pdoc->SciLineFromPosition(r.Last()));
const Sci::Line docLineFirst = pdoc->SciLineFromPosition(r.First());
const Sci::Line minLine = pcs->DisplayFromDoc(docLineFirst);
Sci::Line docLineLast = docLineFirst; // Common case where range is wholly in one document line
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();
PRectangle rc;
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,
// then set it at the beginning of the next one
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);
bool appendEol = false;
if (selectionEnd > beginningOfEndLine
|| selectionStart == selectionEnd) {
selectionEnd = pdoc->LineStart(endLine + 1);
appendEol = (selectionEnd == pdoc->Length() && pdoc->SciLineFromPosition(selectionEnd) == endLine);
endLine = pdoc->SciLineFromPosition(selectionEnd);
}
// if there's nowhere for the selection to move
// (i.e. at the beginning going up or at the end going down),
// stop it right there!
const bool docEndLineEmpty = pdoc->LineStart(endLine) == pdoc->Length();
if ((selectionStart == 0 && lineDelta < 0)
|| (selectionEnd == pdoc->Length() && lineDelta > 0)
|| selectionStart == selectionEnd) {
|| (selectionEnd == pdoc->Length() && lineDelta > 0
&& !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;
}
@ -2634,6 +2642,12 @@ void Editor::CheckModificationForWrap(DocModification mh) {
const Sci::Line lineDoc = pdoc->SciLineFromPosition(mh.position);
const Sci::Line lines = std::max(static_cast<Sci::Line>(0), mh.linesAdded);
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);
}
RefreshStyleData();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,8 +80,6 @@ void RunStyles<DISTANCE, STYLE>::RemoveRunIfSameAsPrevious(DISTANCE run) {
template <typename DISTANCE, typename STYLE>
RunStyles<DISTANCE, STYLE>::RunStyles() {
starts = Partitioning<DISTANCE>(8);
styles = SplitVector<STYLE>();
styles.InsertValue(0, 2, 0);
}
@ -136,7 +134,8 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
return resultNoChange;
}
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 = starts.PositionFromPartition(runEnd);
if (position >= end) {
@ -145,6 +144,22 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
}
fillLength = end - position;
} 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);
}
DISTANCE runStart = RunFromPosition(position);
@ -172,9 +187,8 @@ FillResult<DISTANCE> RunStyles<DISTANCE, STYLE>::FillRange(DISTANCE position, ST
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return result;
} else {
return resultNoChange;
}
return resultNoChange;
}
template <typename DISTANCE, typename STYLE>
@ -213,7 +227,7 @@ void RunStyles<DISTANCE, STYLE>::InsertSpace(DISTANCE position, DISTANCE insertL
template <typename DISTANCE, typename STYLE>
void RunStyles<DISTANCE, STYLE>::DeleteAll() {
starts = Partitioning<DISTANCE>(8);
starts = Partitioning<DISTANCE>();
styles = SplitVector<STYLE>();
styles.InsertValue(0, 2, 0);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
**/
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <stdexcept>
#include <string_view>
@ -728,6 +729,55 @@ TEST_CASE("Document") {
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") {

View File

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

View File

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

View File

@ -1 +1 @@
553
554

View File

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

View File

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

View File

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

View File

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