chore: bump scintilla and lexilla version

This commit is contained in:
2025-10-12 13:51:32 +08:00
parent 9fb3681e3a
commit db20417ce7
1093 changed files with 138943 additions and 128144 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@
# IDE stuff
CMakeLists.txt.user*
# Clangd
.cache/

View File

@ -1,143 +0,0 @@
// Scintilla source code edit control
/** @file LexMake.cxx
** Lexer for make files.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cstdarg>
#include <string>
#include <string_view>
#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"
using namespace Lexilla;
static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
}
static void ColouriseMakeLine(
const std::string &lineBuffer,
Sci_PositionU startLine,
Sci_PositionU endPos,
Accessor &styler) {
const Sci_PositionU lengthLine = lineBuffer.length();
Sci_PositionU i = 0;
Sci_Position lastNonSpace = -1;
unsigned int state = SCE_MAKE_DEFAULT;
bool bSpecial = false;
// check for a tab character in column 0 indicating a command
bool bCommand = false;
if ((lengthLine > 0) && (lineBuffer[0] == '\t'))
bCommand = true;
// Skip initial spaces
while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
i++;
}
if (i < lengthLine) {
if (lineBuffer[i] == '#') { // Comment
styler.ColourTo(endPos, SCE_MAKE_COMMENT);
return;
}
if (lineBuffer[i] == '!') { // Special directive
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return;
}
}
int varCount = 0;
while (i < lengthLine) {
if (((i + 1) < lengthLine) && (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(')) {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
if (--varCount == 0) {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
}
// skip identifier and target styling if this is a command line
if (!bSpecial && !bCommand) {
if (lineBuffer[i] == ':') {
if (((i + 1) < lengthLine) && (lineBuffer[i + 1] == '=')) {
// it's a ':=', so style as an identifier
if (lastNonSpace >= 0)
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
styler.ColourTo(startLine + i + 1, SCE_MAKE_OPERATOR);
} else {
// We should check that no colouring was made since the beginning of the line,
// to avoid colouring stuff like /OUT:file
if (lastNonSpace >= 0)
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_TARGET);
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
}
bSpecial = true; // Only react to the first ':' of the line
state = SCE_MAKE_DEFAULT;
} else if (lineBuffer[i] == '=') {
if (lastNonSpace >= 0)
styler.ColourTo(startLine + lastNonSpace, SCE_MAKE_IDENTIFIER);
styler.ColourTo(startLine + i - 1, SCE_MAKE_DEFAULT);
styler.ColourTo(startLine + i, SCE_MAKE_OPERATOR);
bSpecial = true; // Only react to the first '=' of the line
state = SCE_MAKE_DEFAULT;
}
}
if (!isspacechar(lineBuffer[i])) {
lastNonSpace = i;
}
i++;
}
if (state == SCE_MAKE_IDENTIFIER) {
styler.ColourTo(endPos, SCE_MAKE_IDEOL); // Error, variable reference not ended
} else {
styler.ColourTo(endPos, SCE_MAKE_DEFAULT);
}
}
static void ColouriseMakeDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) {
std::string lineBuffer;
styler.StartAt(startPos);
styler.StartSegment(startPos);
Sci_PositionU startLine = startPos;
for (Sci_PositionU i = startPos; i < startPos + length; i++) {
lineBuffer.push_back(styler[i]);
if (AtEOL(styler, i)) {
// End of line (or of line buffer) met, colourise it
ColouriseMakeLine(lineBuffer, startLine, i, styler);
lineBuffer.clear();
startLine = i + 1;
}
}
if (!lineBuffer.empty()) { // Last line does not have ending characters
ColouriseMakeLine(lineBuffer, startLine, startPos + length - 1, styler);
}
}
static const char *const emptyWordListDesc[] = {
nullptr
};
extern const LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", nullptr, emptyWordListDesc);

View File

@ -1,53 +0,0 @@
0 400 0 ; Enumerate all styles: 0 to 15 except for 11(comment block) which is not yet implemented.
0 400 0 ; This is not a viable source file, it just illustrates the different states in isolation.
0 400 0
0 400 0 ; comment=1
0 400 0 ; Comment
0 400 0
0 400 0 ; whitespace=0
0 400 0 ; w
0 400 0
0 400 0 ; number=2
0 400 0 11
0 400 0
0 400 0 ; string=3
0 400 0 "String"
0 400 0
0 400 0 ; operator=4
0 400 0 +
0 400 0
0 400 0 ; identifier=5
0 400 0 identifier
0 400 0
0 400 0 ; CPU instruction=6
0 400 0 add
0 400 0
0 400 0 ; math Instruction=7
0 400 0 fadd
0 400 0
0 400 0 ; register=8
0 400 0 ECX
0 400 0
0 400 0 ; directive=9
0 400 0 section
0 400 0
0 400 0 ; directive operand=10
0 400 0 rel
0 400 0
0 400 0 ; comment block=11 is for future expansion
0 400 0
0 400 0 ; character=12
0 400 0 'character'
0 400 0
0 400 0 ; string EOL=13
0 400 0 "no line end
0 400 0
0 400 0 ; extended instruction=14
0 400 0 movq
0 400 0
0 400 0 ; comment directive=15
0 400 0 comment ~ A multiple-line
0 400 0 comment directive~
0 400 0
0 400 0 ;end
0 400 0

View File

@ -1,5 +0,0 @@
<script>
/a|b/i.test("baby");
// arrow function
() => /a|b/i.test("baby");
</script>

View File

@ -1,5 +0,0 @@
{1}<script>{40}
{52}/a|b/i{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}
{1}</script>{0}

View File

@ -1,8 +0,0 @@
# encoding: utf-8
puts <<A中
#{1+2}
A中
puts <<
#{1+2}

View File

@ -1,9 +0,0 @@
0 400 0 # encoding: utf-8
2 400 0 + puts <<A中
0 401 0 | #{1+2}
0 401 0 | A中
1 400 0
2 400 0 + puts <<中
0 401 0 | #{1+2}
0 401 0 | 中
0 400 0

View File

@ -1,8 +0,0 @@
{2}# encoding: utf-8{0}
{11}puts{0} {10}<<{20}A中{22}
{10}#{{4}1{10}+{4}2{10}}{22}
{20}A中{0}
{11}puts{0} {10}<<{20}中{22}
{10}#{{4}1{10}+{4}2{10}}{22}
{20}中{0}

View File

@ -1,4 +0,0 @@
lexer.*.rb=ruby
keywords.*.rb=begin class def do end false if module return self super true unless until while \
__FILE__ __LINE__
fold=1

View File

@ -1 +0,0 @@
540

View File

@ -27,5 +27,5 @@ target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/lexilla/include
${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexlib
${CMAKE_CURRENT_SOURCE_DIR}/../scintilla552/scintilla/include
${CMAKE_CURRENT_SOURCE_DIR}/../scintilla557/scintilla/include
)

View File

@ -35,6 +35,7 @@
**.cob text
**.cmake text
**.d text
**.dart text
**.diff text
**.erl text
**.f text
@ -48,15 +49,19 @@
**.matlab text
**.ml text
**.nim text
**.nix text
**.octave text
**.p text
**.pas text
**.pl text
**.p6 text
**.ps1 text
**.r text
**.rb text
**.roff text
**.rs text
**.sql text
**.st text
**.tcl text
**.toml text
**.tsql text
@ -67,7 +72,9 @@
**.vh text
**.vhd text
**.x12 text
**.xml text
**.yaml text
**.zig text
**.md text
**.txt text
**.pch text

View File

@ -3,16 +3,24 @@ name: "Build and check Lexilla on Win32 with Visual C++"
on: [push]
jobs:
# Compile for amd64 and cross-compile for arm64. Tests run only for amd64.
build:
runs-on: windows-latest
strategy:
matrix:
arch:
- amd64
- amd64_arm64
env:
TEST: ${{ matrix.arch == 'amd64' && 'test' || '' }}
steps:
- uses: actions/checkout@v4
- name: Preparing nmake
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
arch: ${{ matrix.arch }}
- name: Install Scintilla source
run: |
pwd
@ -24,7 +32,7 @@ jobs:
- name: Unit Test
run: |
cd test/unit
nmake -f test.mak DEBUG=1 test
nmake -f test.mak DEBUG=1 $env:TEST
cd ../..
- name: Build Lexilla
run: |
@ -33,14 +41,15 @@ jobs:
cd ..
- uses: actions/upload-artifact@v4
with:
name: lexilla.dll
name: lexilla${{ matrix.arch == 'amd64_arm64' && '-arm64' || '' }}.dll
path: bin/lexilla.dll
- name: Test lexing and folding
run: |
cd test
nmake -f testlexers.mak DEBUG=1 test
nmake -f testlexers.mak DEBUG=1 $env:TEST
cd ..
- name: CheckLexilla C Example
if: matrix.arch == 'amd64'
run: |
cd examples/CheckLexilla
cl -MP CheckLexilla.c -I ../../include -Fe: CheckLexilla

View File

@ -27,12 +27,12 @@ directory conventionally called "lexilla".
To use GCC, run lexilla/src/makefile:
make
To use Clang, run lexilla/test/makefile:
To use Clang, run lexilla/src/makefile:
make CLANG=1
On macOS, CLANG is set automatically so this can just be
make
To use MSVC, run lexilla/test/lexilla.mak:
To use MSVC, run lexilla/src/lexilla.mak:
nmake -f lexilla.mak
To build a debugging version of the library, add DEBUG=1 to the command:

View File

@ -30,12 +30,12 @@
namespace {
#if defined(_WIN32)
typedef FARPROC Function;
typedef HMODULE Module;
using Function = FARPROC;
using Module = HMODULE;
constexpr const char *pathSeparator = "\\";
#else
typedef void *Function;
typedef void *Module;
using Function = void *;
using Module = void *;
constexpr const char *pathSeparator = "/";
#endif
@ -164,9 +164,10 @@ bool Lexilla::Load(std::string_view sharedLibraryPaths) {
if (fnLexerCount && fnLexerName) {
const int nLexers = fnLexerCount();
for (int i = 0; i < nLexers; i++) {
char name[100] = "";
constexpr size_t lengthName = 200;
char name[lengthName]{};
fnLexerName(i, name, sizeof(name));
lexers.push_back(name);
lexers.emplace_back(name);
}
}
CreateLexerFn fnCL = FunctionPointer<CreateLexerFn>(
@ -268,7 +269,7 @@ std::string Lexilla::NameFromID(int identifier) {
}
}
}
return std::string();
return {};
}
std::vector<std::string> Lexilla::LibraryProperties() {

View File

@ -1,6 +1,12 @@
// File to suppress cppcheck warnings for files that will not be fixed.
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
// Configured for cppcheck 2.12
// Configured for cppcheck 2.15
// Just a report of how many checkers are run
checkersReport
// This just warns that cppcheck isn't exhaustive and it still appears in exhaustive mode
normalCheckLevelMaxBranches
// Coding style is to use assignments in constructor when there are many
// members to initialize or the initialization is complex or has comments.
@ -25,12 +31,8 @@ passedByValue
missingIncludeSystem
// Passing temporary string into hidden object creator functions: they do not hold the argument
danglingTemporaryLifetime:lexilla/access/LexillaAccess.cxx
returnDanglingLifetime:lexilla/access/LexillaAccess.cxx
// cppcheck seems to believe that unique_ptr<char *[]>::get returns void* instead of char**
arithOperationsOnVoidPointer:lexilla/lexlib/WordList.cxx
// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that
// only finds one false issue in LexRuby
checkLevelNormal:lexilla/lexers/LexBash.cxx
@ -42,6 +44,9 @@ checkLevelNormal:lexilla/lexers/LexRuby.cxx
// Physically but not logically const.
constVariablePointer:lexilla/examples/CheckLexilla/CheckLexilla.c
// cppcheck appears to be incorrectly determining control flow: target_end is used after write
unreadVariable:lexilla/lexers/LexRuby.cxx
// Suppress most lexer warnings since the lexers are maintained by others
redundantCondition:lexilla/lexers/LexA68k.cxx
constParameterReference:lexilla/lexers/LexAbaqus.cxx
@ -58,21 +63,25 @@ constParameterReference:lexilla/lexers/LexBash.cxx
knownConditionTrueFalse:lexilla/lexers/LexBash.cxx
variableScope:lexilla/lexers/LexBash.cxx
constVariable:lexilla/lexers/LexBasic.cxx
constParameterReference:lexilla/lexers/LexBullant.cxx
constParameterReference:lexilla/lexers/LexCLW.cxx
knownConditionTrueFalse:lexilla/lexers/LexCLW.cxx
variableScope:lexilla/lexers/LexCmake.cxx
knownConditionTrueFalse:lexilla/lexers/LexCmake.cxx
constParameterReference:lexilla/lexers/LexCmake.cxx
constParameterReference:lexilla/lexers/LexCOBOL.cxx
constVariablePointer:lexilla/lexers/LexCOBOL.cxx
constParameterReference:lexilla/lexers/LexCoffeeScript.cxx
constParameterPointer:lexilla/lexers/LexCoffeeScript.cxx
knownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx
constVariableReference:lexilla/lexers/LexConf.cxx
constParameterReference:lexilla/lexers/LexCPP.cxx
variableScope:lexilla/lexers/LexCSS.cxx
constVariablePointer:lexilla/lexers/LexCSS.cxx
knownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx
constParameterReference:lexilla/lexers/LexDataflex.cxx
variableScope:lexilla/lexers/LexDataflex.cxx
constParameterReference:lexilla/lexers/LexDart.cxx
knownConditionTrueFalse:lexilla/lexers/LexECL.cxx
variableScope:lexilla/lexers/LexECL.cxx
constParameter:lexilla/lexers/LexEDIFACT.cxx
@ -101,6 +110,7 @@ unreadVariable:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLisp.cxx
constParameterPointer:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMarkdown.cxx
@ -110,6 +120,7 @@ unreadVariable:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMetapost.cxx
constParameterReference:lexilla/lexers/LexModula.cxx
duplicateBreak:lexilla/lexers/LexModula.cxx
variableScope:lexilla/lexers/LexModula.cxx
constParameterReference:lexilla/lexers/LexMPT.cxx
variableScope:lexilla/lexers/LexMSSQL.cxx
@ -132,6 +143,7 @@ constVariableReference:lexilla/lexers/LexPerl.cxx
knownConditionTrueFalse:lexilla/lexers/LexPerl.cxx
constParameterReference:lexilla/lexers/LexPLM.cxx
constParameterReference:lexilla/lexers/LexPO.cxx
constVariablePointer:lexilla/lexers/LexPOV.cxx
constParameterReference:lexilla/lexers/LexPython.cxx
shadowVariable:lexilla/lexers/LexPowerPro.cxx
knownConditionTrueFalse:lexilla/lexers/LexPowerPro.cxx
@ -143,6 +155,8 @@ redundantInitialization:lexilla/lexers/LexRegistry.cxx
constParameterReference:lexilla/lexers/LexRuby.cxx
constParameterReference:lexilla/lexers/LexRust.cxx
knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx
constParameterReference:lexilla/lexers/LexScriptol.cxx
constParameterPointer:lexilla/lexers/LexSmalltalk.cxx
variableScope:lexilla/lexers/LexSpecman.cxx
unreadVariable:lexilla/lexers/LexSpice.cxx
constParameterReference:lexilla/lexers/LexSpice.cxx
@ -153,6 +167,7 @@ clarifyCalculation:lexilla/lexers/LexTADS3.cxx
constParameterReference:lexilla/lexers/LexTADS3.cxx
constParameterReference:lexilla/lexers/LexTAL.cxx
constVariableReference:lexilla/lexers/LexTCL.cxx
constParameterPointer:lexilla/lexers/LexTCMD.cxx
invalidscanf:lexilla/lexers/LexTCMD.cxx
constParameterReference:lexilla/lexers/LexTeX.cxx
variableScope:lexilla/lexers/LexTeX.cxx
@ -161,6 +176,7 @@ constParameterReference:lexilla/lexers/LexVerilog.cxx
variableScope:lexilla/lexers/LexVerilog.cxx
badBitmaskCheck:lexilla/lexers/LexVerilog.cxx
uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx
duplicateCondition:lexilla/lexers/LexVerilog.cxx
constParameterReference:lexilla/lexers/LexVHDL.cxx
constVariable:lexilla/lexers/LexVHDL.cxx
shadowVariable:lexilla/lexers/LexVHDL.cxx
@ -175,7 +191,6 @@ constVariableReference:lexilla/lexers/LexX12.cxx
constParameterPointer:lexilla/lexers/LexX12.cxx
uselessCallsSubstr:lexilla/lexers/LexX12.cxx
constParameterReference:lexilla/lexers/LexYAML.cxx
constParameterPointer:lexilla/lexers/LexYAML.cxx
knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx
// These are due to Accessor::IndentAmount not declaring the callback as taking a const.
@ -186,12 +201,60 @@ constParameterCallback:lexilla/lexers/LexPython.cxx
constParameterCallback:lexilla/lexers/LexScriptol.cxx
constParameterCallback:lexilla/lexers/LexVB.cxx
constVariableReference:lexilla/lexers/LexA68k.cxx
constVariableReference:lexilla/lexers/LexAPDL.cxx
constVariableReference:lexilla/lexers/LexASY.cxx
constVariableReference:lexilla/lexers/LexAVE.cxx
constVariableReference:lexilla/lexers/LexAVS.cxx
constVariableReference:lexilla/lexers/LexAU3.cxx
constVariableReference:lexilla/lexers/LexAsn1.cxx
constVariableReference:lexilla/lexers/LexBibTeX.cxx
constVariableReference:lexilla/lexers/LexCaml.cxx
constVariableReference:lexilla/lexers/LexCLW.cxx
constVariableReference:lexilla/lexers/LexCmake.cxx
constVariableReference:lexilla/lexers/LexCOBOL.cxx
constVariableReference:lexilla/lexers/LexCoffeeScript.cxx
constVariableReference:lexilla/lexers/LexCsound.cxx
constVariableReference:lexilla/lexers/LexCSS.cxx
constVariableReference:lexilla/lexers/LexCrontab.cxx
constVariableReference:lexilla/lexers/LexDataflex.cxx
constVariableReference:lexilla/lexers/LexDMAP.cxx
constVariableReference:lexilla/lexers/LexECL.cxx
constVariableReference:lexilla/lexers/LexEiffel.cxx
constVariableReference:lexilla/lexers/LexEScript.cxx
constVariableReference:lexilla/lexers/LexErlang.cxx
constVariableReference:lexilla/lexers/LexFlagship.cxx
constVariableReference:lexilla/lexers/LexForth.cxx
constVariableReference:lexilla/lexers/LexFortran.cxx
constVariableReference:lexilla/lexers/LexGAP.cxx
constVariableReference:lexilla/lexers/LexGui4Cli.cxx
constVariableReference:lexilla/lexers/LexKix.cxx
constVariableReference:lexilla/lexers/LexKVIrc.cxx
constVariableReference:lexilla/lexers/LexLout.cxx
constVariableReference:lexilla/lexers/LexMagik.cxx
constVariableReference:lexilla/lexers/LexMatlab.cxx
constVariableReference:lexilla/lexers/LexMetapost.cxx
constVariableReference:lexilla/lexers/LexMMIXAL.cxx
constVariableReference:lexilla/lexers/LexMSSQL.cxx
constVariableReference:lexilla/lexers/LexNsis.cxx
constVariableReference:lexilla/lexers/LexOpal.cxx
constVariableReference:lexilla/lexers/LexPOV.cxx
constVariableReference:lexilla/lexers/LexPascal.cxx
constVariableReference:lexilla/lexers/LexPB.cxx
constVariableReference:lexilla/lexers/LexPowerPro.cxx
constVariableReference:lexilla/lexers/LexPS.cxx
constVariableReference:lexilla/lexers/LexRebol.cxx
constVariableReference:lexilla/lexers/LexSAS.cxx
constVariableReference:lexilla/lexers/LexSML.cxx
constVariableReference:lexilla/lexers/LexSorcus.cxx
constVariableReference:lexilla/lexers/LexSpecman.cxx
constVariableReference:lexilla/lexers/LexStata.cxx
constVariableReference:lexilla/lexers/LexTACL.cxx
constVariableReference:lexilla/lexers/LexTADS3.cxx
constVariableReference:lexilla/lexers/LexTAL.cxx
constVariableReference:lexilla/lexers/LexTCMD.cxx
constVariableReference:lexilla/lexers/LexTeX.cxx
constVariableReference:lexilla/lexers/LexVHDL.cxx
// Suppress everything in test example files
*:lexilla/test/examples/*

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="20240821" />
<meta name="Date.Modified" content="20250608" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -51,6 +51,7 @@
<title>
Lexilla
</title>
<link rel="canonical" href="https://scintilla.org/Lexilla.html" />
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0">
@ -61,8 +62,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.4.0<br />
Site last modified August 21 2024</font>
<font color="#FFCC99" size="3">Release version 5.4.5<br />
Site last modified June 8 2025</font>
</td>
<td width="20%">
&nbsp;
@ -77,11 +78,11 @@
</tr>
</table>
<ul id="versionlist">
<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>
<li>Version 5.3.0 improves Bash, HTML, and Lua.</li>
<li>Version 5.4.5 improves Dart, Makefile, Nix, TOML, and Zig.</li>
<li>Version 5.4.4 fixes a problem when building for ARM64 on Windows.</li>
<li>Version 5.4.3 improves C++, Modula 3, Pascal, Python, and Ruby.</li>
<li>Version 5.4.2 adds Nix lexer. Improves JavaScript, PHP, Rust, TOML, and Zig.</li>
<li>Version 5.4.1 adds Dart, troff, and Zig lexers. Improves C++, F#, HTML, and Smalltalk.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
@ -130,7 +131,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

@ -10,6 +10,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Lexilla Documentation</title>
<link rel="canonical" href="https://scintilla.org/LexillaDoc.html" />
<style type="text/css">
<!--

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/lexilla540.zip">
<font size="4"> <a href="https://www.scintilla.org/lexilla545.zip">
Windows</a>&nbsp;&nbsp;
<a href="https://www.scintilla.org/lexilla540.tgz">
<a href="https://www.scintilla.org/lexilla545.tgz">
GTK/Linux</a>&nbsp;&nbsp;
</font>
</td>
@ -42,7 +42,7 @@
containing very few restrictions.
</p>
<h3>
Release 5.4.0
Release 5.4.5
</h3>
<h4>
Source Code
@ -50,8 +50,8 @@
The source code package contains all of the source code for Lexilla but no binary
executable code and is available in
<ul>
<li><a href="https://www.scintilla.org/lexilla540.zip">zip format</a> (1.3M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla540.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
<li><a href="https://www.scintilla.org/lexilla545.zip">zip format</a> (1.4M) commonly used on Windows</li>
<li><a href="https://www.scintilla.org/lexilla545.tgz">tgz format</a> (1.0M) commonly used on Linux and compatible operating systems</li>
</ul>
Instructions for building on both Windows and Linux are included in the readme file.
<h4>

View File

@ -37,6 +37,7 @@
Lexilla was originally code that was part of the Scintilla project.
Thus it shares much of the history and contributors of Scintilla before it was extracted as its own project.
</p>
<a href="#Releases">Releases</a>
<h2>Contributors</h2>
<p>
Thanks to all the people that have contributed patches, bug reports and suggestions.
@ -585,9 +586,183 @@
<td>Tsuyoshi Miyake</td>
<td>Martin Schäfer</td>
<td>RainRat</td>
</tr><tr>
<td>Henrik S. Johansen</td>
<td>Ekopalypse</td>
<td>HoTschir</td>
<td>Ahmet Sait</td>
</tr>
</table>
<h2>Releases</h2>
<h2 id="Releases">Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla545.zip">Release 5.4.5</a>
</h3>
<ul>
<li>
Released 8 June 2025.
</li>
<li>
Dart: Add error state SCE_DART_STRINGEOL for unterminated string.
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
</li>
<li>
Makefile: Add a keyword list to makefile lexer to highlight GNU Make directives like 'ifdef' and 'vpath' as
SCE_MAKE_PREPROCESSOR since these are similar to NMAKE directives like '!IFDEF'.
</li>
<li>
Nix: Add error state SCE_NIX_STRINGEOL for unterminated string.
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
</li>
<li>
TOML: Add error state SCE_TOML_STRINGEOL for unterminated string.
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
</li>
<li>
Zig: Add error state SCE_ZIG_STRINGEOL for unterminated string.
<a href="https://github.com/ScintillaOrg/lexilla/pull/315">Pull request #315</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla544.zip">Release 5.4.4</a>
</h3>
<ul>
<li>
Released 2 April 2025.
</li>
<li>
Fix building for ARM64.
<a href="https://github.com/ScintillaOrg/lexilla/pull/308">Pull request #308</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla543.zip">Release 5.4.3</a>
</h3>
<ul>
<li>
Released 25 February 2025.
</li>
<li>
C++: Fix evaluation of != in preprocessor condition.
<a href="https://github.com/ScintillaOrg/lexilla/issues/299">Issue #299</a>.
</li>
<li>
Modula-3: Allow digits in uppercase identifiers.
<a href="https://github.com/ScintillaOrg/lexilla/issues/297">Issue #297</a>.
</li>
<li>
Pascal: Fix asm style extending past end.
<a href="https://github.com/ScintillaOrg/lexilla/issues/295">Issue #295</a>.
</li>
<li>
Python: Fix detection of attributes and decorators.
<a href="https://github.com/ScintillaOrg/lexilla/issues/294">Issue #294</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/302">Pull request #302</a>.
</li>
<li>
Ruby: Implement substyles for identifiers SCE_RB_IDENTIFIER.
</li>
<li>
Ruby: Recognize name as SCE_RB_DEFNAME in def when `::` used as well as `.`.
<a href="https://github.com/ScintillaOrg/lexilla/issues/300">Issue #300</a>.
</li>
</ul>
<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>
<ul>
<li>
Released 19 October 2024.
</li>
<li>
Lexer added for Dart "dart".
<a href="https://github.com/ScintillaOrg/lexilla/pull/265">Pull request #265</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/275">Pull request #275</a>.
</li>
<li>
Lexer added for troff / nroff "troff".
<a href="https://github.com/ScintillaOrg/lexilla/pull/264">Pull request #264</a>.
</li>
<li>
Lexer added for Zig "zig".
<a href="https://github.com/ScintillaOrg/lexilla/pull/267">Pull request #267</a>.
</li>
<li>
C++: Fix crash for empty documentation comment keyword where '&lt;' occurs at line end.
</li>
<li>
F#: Include EOLs in the style range of SCE_FSHARP_COMMENTLINE.
Stabilizes EOL detection when folding line comment groups.
<a href="https://github.com/ScintillaOrg/lexilla/issues/276">Issue #276</a>.
</li>
<li>
F#: Fix per-line folding in F# documents.
<a href="https://github.com/ScintillaOrg/lexilla/issues/277">Issue #277</a>.
</li>
<li>
HTML: Improve SGML/DTD lexing.
Don't terminate SGML when &gt; inside quoted string.
Lex both [ and ] as SCE_H_SGML_DEFAULT.
Nested sections handled instead of switching to SCE_H_SGML_ERROR.
<a href="https://github.com/ScintillaOrg/lexilla/issues/272">Issue #272</a>.
</li>
<li>
JavaScript: New SCE_HJ_TEMPLATELITERAL and SCE_HJA_TEMPLATELITERAL
styles for template literals when lexer is hypertext, or xml.
<a href="https://github.com/ScintillaOrg/lexilla/issues/280">Issue #280</a>.
</li>
<li>
PHP: Fix failure to recognize PHP start "&lt;?php' at end of document.
Caused by not capping retrieval range at document end causing no text to be retrieved.
<a href="https://github.com/ScintillaOrg/lexilla/issues/269">Issue #269</a>.
</li>
<li>
Smalltalk: Fix scaled decimal numbers without decimal separator.
<a href="https://github.com/ScintillaOrg/lexilla/pull/274">Pull request #274</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla540.zip">Release 5.4.0</a>
</h3>

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -27,6 +27,7 @@ style.simple.1=fore:#FF0000
#include <string.h>
#include <assert.h>
#include <string>
#include <string_view>
#include "ILexer.h"

View File

@ -145,6 +145,10 @@ val SCLEX_JULIA=133
val SCLEX_ASCIIDOC=134
val SCLEX_GDSCRIPT=135
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.
@ -175,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
@ -211,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
@ -313,6 +330,7 @@ val SCE_HJ_SINGLESTRING=49
val SCE_HJ_SYMBOLS=50
val SCE_HJ_STRINGEOL=51
val SCE_HJ_REGEX=52
val SCE_HJ_TEMPLATELITERAL=53
# ASP Javascript
val SCE_HJA_START=55
val SCE_HJA_DEFAULT=56
@ -327,6 +345,7 @@ val SCE_HJA_SINGLESTRING=64
val SCE_HJA_SYMBOLS=65
val SCE_HJA_STRINGEOL=66
val SCE_HJA_REGEX=67
val SCE_HJA_TEMPLATELITERAL=68
# Embedded VBScript
val SCE_HB_START=70
val SCE_HB_DEFAULT=71
@ -2004,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
@ -2328,3 +2349,104 @@ val SCE_TOML_TRIPLE_STRING_SQ=11
val SCE_TOML_TRIPLE_STRING_DQ=12
val SCE_TOML_ESCAPECHAR=13
val SCE_TOML_DATETIME=14
val SCE_TOML_STRINGEOL=15
# Lexical states for SCLEX_TROFF
lex troff=SCLEX_TROFF SCE_TROFF_
val SCE_TROFF_DEFAULT=0
val SCE_TROFF_REQUEST=1
val SCE_TROFF_COMMAND=2
val SCE_TROFF_NUMBER=3
val SCE_TROFF_OPERATOR=4
val SCE_TROFF_STRING=5
val SCE_TROFF_COMMENT=6
val SCE_TROFF_IGNORE=7
val SCE_TROFF_ESCAPE_STRING=8
val SCE_TROFF_ESCAPE_MACRO=9
val SCE_TROFF_ESCAPE_FONT=10
val SCE_TROFF_ESCAPE_NUMBER=11
val SCE_TROFF_ESCAPE_COLOUR=12
val SCE_TROFF_ESCAPE_GLYPH=13
val SCE_TROFF_ESCAPE_ENV=14
val SCE_TROFF_ESCAPE_SUPPRESSION=15
val SCE_TROFF_ESCAPE_SIZE=16
val SCE_TROFF_ESCAPE_TRANSPARENT=17
val SCE_TROFF_ESCAPE_ISVALID=18
val SCE_TROFF_ESCAPE_DRAW=19
val SCE_TROFF_ESCAPE_MOVE=20
val SCE_TROFF_ESCAPE_HEIGHT=21
val SCE_TROFF_ESCAPE_OVERSTRIKE=22
val SCE_TROFF_ESCAPE_SLANT=23
val SCE_TROFF_ESCAPE_WIDTH=24
val SCE_TROFF_ESCAPE_VSPACING=25
val SCE_TROFF_ESCAPE_DEVICE=26
val SCE_TROFF_ESCAPE_NOMOVE=27
# Lexical states for SCLEX_DART
lex Dart=SCLEX_DART SCE_DART_
val SCE_DART_DEFAULT=0
val SCE_DART_COMMENTLINE=1
val SCE_DART_COMMENTLINEDOC=2
val SCE_DART_COMMENTBLOCK=3
val SCE_DART_COMMENTBLOCKDOC=4
val SCE_DART_STRING_SQ=5
val SCE_DART_STRING_DQ=6
val SCE_DART_TRIPLE_STRING_SQ=7
val SCE_DART_TRIPLE_STRING_DQ=8
val SCE_DART_RAWSTRING_SQ=9
val SCE_DART_RAWSTRING_DQ=10
val SCE_DART_TRIPLE_RAWSTRING_SQ=11
val SCE_DART_TRIPLE_RAWSTRING_DQ=12
val SCE_DART_ESCAPECHAR=13
val SCE_DART_IDENTIFIER=14
val SCE_DART_IDENTIFIER_STRING=15
val SCE_DART_OPERATOR=16
val SCE_DART_OPERATOR_STRING=17
val SCE_DART_SYMBOL_IDENTIFIER=18
val SCE_DART_SYMBOL_OPERATOR=19
val SCE_DART_NUMBER=20
val SCE_DART_KEY=21
val SCE_DART_METADATA=22
val SCE_DART_KW_PRIMARY=23
val SCE_DART_KW_SECONDARY=24
val SCE_DART_KW_TERTIARY=25
val SCE_DART_KW_TYPE=26
val SCE_DART_STRINGEOL=27
# Lexical states for SCLEX_ZIG
lex Zig=SCLEX_ZIG SCE_ZIG_
val SCE_ZIG_DEFAULT=0
val SCE_ZIG_COMMENTLINE=1
val SCE_ZIG_COMMENTLINEDOC=2
val SCE_ZIG_COMMENTLINETOP=3
val SCE_ZIG_NUMBER=4
val SCE_ZIG_OPERATOR=5
val SCE_ZIG_CHARACTER=6
val SCE_ZIG_STRING=7
val SCE_ZIG_MULTISTRING=8
val SCE_ZIG_ESCAPECHAR=9
val SCE_ZIG_IDENTIFIER=10
val SCE_ZIG_FUNCTION=11
val SCE_ZIG_BUILTIN_FUNCTION=12
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
val SCE_ZIG_STRINGEOL=18
# 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
val SCE_NIX_STRINGEOL=16

View File

@ -149,6 +149,10 @@
#define SCLEX_ASCIIDOC 134
#define SCLEX_GDSCRIPT 135
#define SCLEX_TOML 136
#define SCLEX_TROFF 137
#define SCLEX_DART 138
#define SCLEX_ZIG 139
#define SCLEX_NIX 140
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
@ -199,6 +203,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
@ -289,6 +306,7 @@
#define SCE_HJ_SYMBOLS 50
#define SCE_HJ_STRINGEOL 51
#define SCE_HJ_REGEX 52
#define SCE_HJ_TEMPLATELITERAL 53
#define SCE_HJA_START 55
#define SCE_HJA_DEFAULT 56
#define SCE_HJA_COMMENT 57
@ -302,6 +320,7 @@
#define SCE_HJA_SYMBOLS 65
#define SCE_HJA_STRINGEOL 66
#define SCE_HJA_REGEX 67
#define SCE_HJA_TEMPLATELITERAL 68
#define SCE_HB_START 70
#define SCE_HB_DEFAULT 71
#define SCE_HB_COMMENTLINE 72
@ -1791,6 +1810,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
@ -2074,6 +2095,99 @@
#define SCE_TOML_TRIPLE_STRING_DQ 12
#define SCE_TOML_ESCAPECHAR 13
#define SCE_TOML_DATETIME 14
#define SCE_TOML_STRINGEOL 15
#define SCE_TROFF_DEFAULT 0
#define SCE_TROFF_REQUEST 1
#define SCE_TROFF_COMMAND 2
#define SCE_TROFF_NUMBER 3
#define SCE_TROFF_OPERATOR 4
#define SCE_TROFF_STRING 5
#define SCE_TROFF_COMMENT 6
#define SCE_TROFF_IGNORE 7
#define SCE_TROFF_ESCAPE_STRING 8
#define SCE_TROFF_ESCAPE_MACRO 9
#define SCE_TROFF_ESCAPE_FONT 10
#define SCE_TROFF_ESCAPE_NUMBER 11
#define SCE_TROFF_ESCAPE_COLOUR 12
#define SCE_TROFF_ESCAPE_GLYPH 13
#define SCE_TROFF_ESCAPE_ENV 14
#define SCE_TROFF_ESCAPE_SUPPRESSION 15
#define SCE_TROFF_ESCAPE_SIZE 16
#define SCE_TROFF_ESCAPE_TRANSPARENT 17
#define SCE_TROFF_ESCAPE_ISVALID 18
#define SCE_TROFF_ESCAPE_DRAW 19
#define SCE_TROFF_ESCAPE_MOVE 20
#define SCE_TROFF_ESCAPE_HEIGHT 21
#define SCE_TROFF_ESCAPE_OVERSTRIKE 22
#define SCE_TROFF_ESCAPE_SLANT 23
#define SCE_TROFF_ESCAPE_WIDTH 24
#define SCE_TROFF_ESCAPE_VSPACING 25
#define SCE_TROFF_ESCAPE_DEVICE 26
#define SCE_TROFF_ESCAPE_NOMOVE 27
#define SCE_DART_DEFAULT 0
#define SCE_DART_COMMENTLINE 1
#define SCE_DART_COMMENTLINEDOC 2
#define SCE_DART_COMMENTBLOCK 3
#define SCE_DART_COMMENTBLOCKDOC 4
#define SCE_DART_STRING_SQ 5
#define SCE_DART_STRING_DQ 6
#define SCE_DART_TRIPLE_STRING_SQ 7
#define SCE_DART_TRIPLE_STRING_DQ 8
#define SCE_DART_RAWSTRING_SQ 9
#define SCE_DART_RAWSTRING_DQ 10
#define SCE_DART_TRIPLE_RAWSTRING_SQ 11
#define SCE_DART_TRIPLE_RAWSTRING_DQ 12
#define SCE_DART_ESCAPECHAR 13
#define SCE_DART_IDENTIFIER 14
#define SCE_DART_IDENTIFIER_STRING 15
#define SCE_DART_OPERATOR 16
#define SCE_DART_OPERATOR_STRING 17
#define SCE_DART_SYMBOL_IDENTIFIER 18
#define SCE_DART_SYMBOL_OPERATOR 19
#define SCE_DART_NUMBER 20
#define SCE_DART_KEY 21
#define SCE_DART_METADATA 22
#define SCE_DART_KW_PRIMARY 23
#define SCE_DART_KW_SECONDARY 24
#define SCE_DART_KW_TERTIARY 25
#define SCE_DART_KW_TYPE 26
#define SCE_DART_STRINGEOL 27
#define SCE_ZIG_DEFAULT 0
#define SCE_ZIG_COMMENTLINE 1
#define SCE_ZIG_COMMENTLINEDOC 2
#define SCE_ZIG_COMMENTLINETOP 3
#define SCE_ZIG_NUMBER 4
#define SCE_ZIG_OPERATOR 5
#define SCE_ZIG_CHARACTER 6
#define SCE_ZIG_STRING 7
#define SCE_ZIG_MULTISTRING 8
#define SCE_ZIG_ESCAPECHAR 9
#define SCE_ZIG_IDENTIFIER 10
#define SCE_ZIG_FUNCTION 11
#define SCE_ZIG_BUILTIN_FUNCTION 12
#define SCE_ZIG_KW_PRIMARY 13
#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_ZIG_STRINGEOL 18
#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
#define SCE_NIX_STRINGEOL 16
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif

View File

@ -12,7 +12,6 @@
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cstdarg>
@ -40,26 +39,19 @@ using namespace Lexilla;
namespace {
bool IsAWordChar(const int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '.' ||
ch == '_' || ch == '?');
return IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == '?';
}
bool IsAWordStart(const int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.' ||
ch == '%' || ch == '@' || ch == '$' || ch == '?');
return IsAlphaNumeric(ch) || ch == '_' || ch == '.' ||
ch == '%' || ch == '@' || ch == '$' || ch == '?';
}
bool IsAsmOperator(const int ch) noexcept {
if ((ch < 0x80) && (isalnum(ch)))
if (IsAlphaNumeric(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
ch == '%' || ch == ':')
return true;
return false;
return AnyOf(ch, '*', '/', '-', '+', '(', ')', '=', '^', '[', ']', '<', '&', '>', ',', '|', '~', '%', ':');
}
constexpr bool IsStreamCommentStyle(int style) noexcept {
@ -71,26 +63,17 @@ constexpr bool IsStreamCommentStyle(int style) noexcept {
// Options used for LexerAsm
struct OptionsAsm {
std::string delimiter;
bool fold;
bool foldSyntaxBased;
bool foldCommentMultiline;
bool foldCommentExplicit;
bool fold = false;
bool foldSyntaxBased = true;
bool foldCommentMultiline = false;
bool foldCommentExplicit = false;
std::string foldExplicitStart;
std::string foldExplicitEnd;
bool foldExplicitAnywhere;
bool foldCompact;
bool foldExplicitAnywhere = false;
bool foldCompact = true;
std::string commentChar;
OptionsAsm() {
delimiter = "";
fold = false;
foldSyntaxBased = true;
foldCommentMultiline = false;
foldCommentExplicit = false;
foldExplicitStart = "";
foldExplicitEnd = "";
foldExplicitAnywhere = false;
foldCompact = true;
commentChar = "";
[[nodiscard]] char Delimiter() const noexcept {
return delimiter.empty() ? '~' : delimiter[0];
}
};
@ -153,12 +136,11 @@ class LexerAsm : public DefaultLexer {
WordList directives4foldend;
OptionsAsm options;
OptionSetAsm osAsm;
int commentChar;
char commentChar;
public:
LexerAsm(const char *languageName_, int language_, int commentChar_) : DefaultLexer(languageName_, language_) {
commentChar = commentChar_;
}
virtual ~LexerAsm() {
LexerAsm(const char *languageName_, int language_, char commentChar_) :
DefaultLexer(languageName_, language_),
commentChar(commentChar_) {
}
void SCI_METHOD Release() override {
delete this;
@ -233,6 +215,8 @@ Sci_Position SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
case 7:
wordListN = &directives4foldend;
break;
default:
break;
}
Sci_Position firstModification = -1;
if (wordListN) {
@ -255,8 +239,7 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward())
{
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart) {
switch (sc.state) {
@ -285,15 +268,20 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
}
// Determine if the current state should terminate.
if (sc.state == SCE_ASM_OPERATOR) {
switch (sc.state) {
case SCE_ASM_OPERATOR:
if (!IsAsmOperator(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_NUMBER) {
break;
case SCE_ASM_NUMBER:
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_IDENTIFIER) {
break;
case SCE_ASM_IDENTIFIER:
if (!IsAWordChar(sc.ch)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
@ -315,24 +303,26 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
}
sc.SetState(SCE_ASM_DEFAULT);
if (IsDirective && !strcmp(s, "comment")) {
const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
sc.ForwardSetState(SCE_ASM_DEFAULT);
}
if (sc.ch == delimiter) {
if (sc.ch == options.Delimiter()) {
sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
}
}
}
} else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
const char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
if (sc.ch == delimiter) {
break;
case SCE_ASM_COMMENTDIRECTIVE:
if (sc.ch == options.Delimiter()) {
while (!sc.MatchLineEnd()) {
sc.Forward();
}
sc.SetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_STRING) {
break;
case SCE_ASM_STRING:
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
@ -343,7 +333,9 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
sc.ChangeState(SCE_ASM_STRINGEOL);
sc.ForwardSetState(SCE_ASM_DEFAULT);
}
} else if (sc.state == SCE_ASM_CHARACTER) {
break;
case SCE_ASM_CHARACTER:
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
@ -354,13 +346,17 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
sc.ChangeState(SCE_ASM_STRINGEOL);
sc.ForwardSetState(SCE_ASM_DEFAULT);
}
break;
default:
break;
}
// Determine if a new state should be entered.
if (sc.state == SCE_ASM_DEFAULT) {
if (sc.ch == commentCharacter) {
sc.SetState(SCE_ASM_COMMENT);
} else if (IsASCII(sc.ch) && (isdigit(sc.ch) || (sc.ch == '.' && IsASCII(sc.chNext) && isdigit(sc.chNext)))) {
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_ASM_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_ASM_IDENTIFIER);
@ -381,32 +377,32 @@ void SCI_METHOD LexerAsm::Lex(Sci_PositionU startPos, Sci_Position length, int i
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "else".
void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {
if (!options.fold)
return;
LexAccessor styler(pAccess);
const Sci_PositionU endPos = startPos + length;
const Sci_Position startPos = static_cast<Sci_Position>(startPos_);
const Sci_Position endPos = startPos + length;
int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int styleNext = styler.StyleIndexAt(startPos);
int style = initStyle;
char word[100]{};
int wordlen = 0;
std::string word;
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (Sci_PositionU i = startPos; i < endPos; i++) {
for (Sci_Position i = startPos; i < endPos; i++) {
const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
const int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
styleNext = styler.StyleIndexAt(i + 1);
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
@ -434,38 +430,27 @@ void SCI_METHOD LexerAsm::Fold(Sci_PositionU startPos, Sci_Position length, int
}
}
if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
word[wordlen++] = MakeLowerCase(ch);
if (wordlen == 100) { // prevent overflow
word[0] = '\0';
wordlen = 1;
}
word.push_back(MakeLowerCase(ch));
if (styleNext != SCE_ASM_DIRECTIVE) { // reading directive ready
word[wordlen] = '\0';
wordlen = 0;
if (directives4foldstart.InList(word)) {
levelNext++;
} else if (directives4foldend.InList(word)) {
levelNext--;
}
word.clear();
}
}
if (!IsASpace(ch))
visibleChars++;
if (atEOL || (i == endPos-1)) {
const int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
const int lev = FoldLevelForCurrentNext(levelCurrent, levelNext) |
FoldLevelFlags(levelCurrent, levelNext, visibleChars == 0 && options.foldCompact);
styler.SetLevelIfDifferent(lineCurrent, lev);
lineCurrent++;
levelCurrent = levelNext;
if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length() - 1))) {
if (atEOL && (i == (styler.Length() - 1))) {
// There is an empty line at end of file so give it same level and empty
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
styler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);
}
visibleChars = 0;
}

View File

@ -109,7 +109,7 @@ constexpr int translateBashDigit(int ch) noexcept {
return BASH_BASE_ERROR;
}
int getBashNumberBase(char *s) noexcept {
int getBashNumberBase(const char *s) noexcept {
int i = 0;
int base = 0;
while (*s) {
@ -164,7 +164,7 @@ bool IsCommentLine(Sci_Position line, LexAccessor &styler) {
const char ch = styler[i];
if (ch == '#')
return true;
else if (ch != ' ' && ch != '\t')
if (ch != ' ' && ch != '\t')
return false;
}
return false;
@ -698,7 +698,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
identifierStyle = subStyle | insideCommand;
}
// allow keywords ending in a whitespace, meta character or command delimiter
char s2[10];
char s2[10]{};
s2[0] = static_cast<char>(sc.ch);
s2[1] = '\0';
const bool keywordEnds = IsASpace(sc.ch) || setMetaCharacter.Contains(sc.ch) || cmdDelimiter.InList(s2);
@ -1140,7 +1140,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
}
// handle command delimiters in command Start|Body|Word state, also Test if 'test' or '[]'
if (cmdState < CmdState::DoubleBracket) {
char s[10];
char s[10]{};
s[0] = static_cast<char>(sc.ch);
if (setBashOperator.Contains(sc.chNext)) {
s[1] = static_cast<char>(sc.chNext);
@ -1268,14 +1268,9 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, in
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
const int lev = levelPrev |
FoldLevelFlags(levelPrev, levelCurrent, visibleChars == 0 && options.foldCompact, visibleChars > 0);
styler.SetLevelIfDifferent(lineCurrent, lev);
lineCurrent++;
levelPrev = levelCurrent;
visibleChars = 0;

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

@ -121,7 +121,7 @@ struct BracketPair {
BracketPair FindBracketPair(Tokens &tokens) {
const Tokens::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
if (itBracket != tokens.end()) {
size_t nest = 0;
ptrdiff_t nest = 0;
for (Tokens::iterator itTok = itBracket; itTok != tokens.end(); ++itTok) {
if (*itTok == "(") {
nest++;
@ -496,7 +496,7 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
LexicalClass lexicalClasses[] = {
const LexicalClass lexicalClasses[] = {
// Lexer Cpp SCLEX_CPP SCE_C_:
0, "SCE_C_DEFAULT", "default", "White space",
1, "SCE_C_COMMENT", "comment", "Comment: /* */.",
@ -528,7 +528,7 @@ LexicalClass lexicalClasses[] = {
27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence",
};
const int sizeLexicalClasses = static_cast<int>(std::size(lexicalClasses));
constexpr int sizeLexicalClasses{ std::size(lexicalClasses) };
}
@ -1073,7 +1073,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
}
} else if ((sc.ch == '<' && sc.chNext != '/')
} else if ((sc.ch == '<' && !(IsASpace(sc.chNext) || sc.chNext == '/'))
|| (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet);
@ -1502,7 +1502,7 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
@ -1583,21 +1583,16 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
const int lev = FoldLevelForCurrentNext(levelUse, levelNext) |
FoldLevelFlags(levelUse, levelNext, visibleChars == 0 && options.foldCompact);
styler.SetLevelIfDifferent(lineCurrent, lev);
lineCurrent++;
lineStartNext = styler.LineStart(lineCurrent+1);
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) {
// There is an empty line at end of file so give it same level and empty
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
styler.SetLevel(lineCurrent, FoldLevelForCurrent(levelCurrent) | SC_FOLDLEVELWHITEFLAG);
}
visibleChars = 0;
inLineComment = false;
@ -1725,7 +1720,7 @@ void LexerCPP::EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDef
// Evaluate logical negations
for (size_t j=0; (j+1)<tokens.size();) {
if (setNegationOp.Contains(tokens[j][0])) {
if (setNegationOp.Contains(tokens[j][0]) && (tokens[j] != "!=")) {
int isTrue = atoi(tokens[j+1].c_str());
if (tokens[j] == "!")
isTrue = !isTrue;
@ -1825,7 +1820,7 @@ Tokens LexerCPP::Tokenize(const std::string &expr) const {
word += *cp;
cp++;
}
tokens.push_back(word);
tokens.push_back(std::move(word));
}
return tokens;
}

View File

@ -0,0 +1,715 @@
// Scintilla source code edit control
/** @file LexDart.cxx
** Lexer for Dart.
**/
// Based on Zufu Liu's Notepad4 Dart lexer
// Modified for 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 IsEOLChar(int ch) noexcept {
return ch == '\r' || ch == '\n';
}
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 == '_';
}
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);
}
struct EscapeSequence {
int outerState = SCE_DART_DEFAULT;
int digitsLeft = 0;
bool brace = false;
// highlight any character as escape sequence.
bool resetEscapeState(int state, int chNext) noexcept {
if (IsEOLChar(chNext)) {
return false;
}
outerState = state;
brace = false;
digitsLeft = (chNext == 'x')? 3 : ((chNext == 'u') ? 5 : 1);
return true;
}
bool atEscapeEnd(int ch) noexcept {
--digitsLeft;
return digitsLeft <= 0 || !IsAHeXDigit(ch);
}
};
constexpr bool IsDartIdentifierStart(int ch) noexcept {
return IsIdentifierStart(ch) || ch == '$';
}
constexpr bool IsDartIdentifierChar(int ch) noexcept {
return IsIdentifierChar(ch) || ch == '$';
}
constexpr bool IsDefinableOperator(int ch) noexcept {
// https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/symbol.dart
return AnyOf(ch, '+', '-', '*', '/', '%', '~', '&', '|',
'^', '<', '>', '=', '[', ']');
}
constexpr bool IsSpaceEquiv(int state) noexcept {
return state == SCE_DART_DEFAULT ||
state == SCE_DART_COMMENTLINE ||
state == SCE_DART_COMMENTLINEDOC ||
state == SCE_DART_COMMENTBLOCK ||
state == SCE_DART_COMMENTBLOCKDOC;
}
constexpr bool IsTripleString(int state) noexcept {
return state == SCE_DART_TRIPLE_STRING_SQ ||
state == SCE_DART_TRIPLE_STRING_DQ ||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
}
constexpr bool IsDoubleQuoted(int state) noexcept {
return state == SCE_DART_STRING_DQ ||
state == SCE_DART_RAWSTRING_DQ ||
state == SCE_DART_TRIPLE_STRING_DQ ||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
}
constexpr bool IsRaw(int state) noexcept {
return state == SCE_DART_RAWSTRING_SQ ||
state == SCE_DART_RAWSTRING_DQ ||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
}
constexpr int GetStringQuote(int state) noexcept {
return IsDoubleQuoted(state) ? '\"' : '\'';
}
enum {
DartLineStateMaskLineComment = 1, // line comment
DartLineStateMaskImport = (1 << 1), // import
DartLineStateMaskInterpolation = (1 << 2), // string interpolation
};
// string interpolating state
struct InterpolatingState {
int state;
int braceCount;
};
struct FoldLineState {
int lineComment;
int packageImport;
constexpr explicit FoldLineState(int lineState) noexcept:
lineComment(lineState & DartLineStateMaskLineComment),
packageImport((lineState >> 1) & 1) {
}
};
// Options used for LexerDart
struct OptionsDart {
bool fold = false;
};
const char * const dartWordListDesc[] = {
"Primary keywords",
"Secondary keywords",
"Tertiary keywords",
"Global type definitions",
nullptr
};
struct OptionSetDart : public OptionSet<OptionsDart> {
OptionSetDart() {
DefineProperty("fold", &OptionsDart::fold);
DefineWordListSets(dartWordListDesc);
}
};
LexicalClass lexicalClasses[] = {
// Lexer DART SCLEX_DART SCE_DART_:
0, "SCE_DART_DEFAULT", "default", "White space",
1, "SCE_DART_COMMENTLINE", "comment line", "Comment: //",
2, "SCE_DART_COMMENTLINEDOC", "comment line documentation", "Comment: ///",
3, "SCE_DART_COMMENTBLOCK", "comment", "Comment: /* */",
4, "SCE_DART_COMMENTBLOCKDOC", "comment documentation", "Comment: /** */",
5, "SCE_DART_STRING_SQ", "literal string", "Single quoted string",
6, "SCE_DART_STRING_DQ", "literal string", "Double quoted string",
7, "SCE_DART_TRIPLE_STRING_SQ", "literal string multiline", "Single quoted multiline string",
8, "SCE_DART_TRIPLE_STRING_DQ", "literal string multiline", "Double quoted multiline string",
9, "SCE_DART_RAWSTRING_SQ", "literal string raw", "Single quoted raw string",
10, "SCE_DART_RAWSTRING_DQ", "literal string raw", "Double quoted raw string",
11, "SCE_DART_TRIPLE_RAWSTRING_SQ", "literal string multiline raw", "Single quoted multiline raw string",
12, "SCE_DART_TRIPLE_RAWSTRING_DQ", "literal string multiline raw", "Double quoted multiline raw string",
13, "SCE_DART_ESCAPECHAR", "literal string escapesequence", "Escape sequence",
14, "SCE_DART_IDENTIFIER", "identifier", "Identifier",
15, "SCE_DART_IDENTIFIER_STRING", "identifier interpolated", "Identifier following $ inside strings",
16, "SCE_DART_OPERATOR", "operator", "Operator",
17, "SCE_DART_OPERATOR_STRING", "operator interpolated", "Braces following $ inside string",
18, "SCE_DART_SYMBOL_IDENTIFIER", "identifier symbol", "Symbol name introduced by #",
19, "SCE_DART_SYMBOL_OPERATOR", "operator symbol", "Operator introduced by #",
20, "SCE_DART_NUMBER", "literal numeric", "Number",
21, "SCE_DART_KEY", "key", "Keys preceding ':' and named parameters",
22, "SCE_DART_METADATA", "preprocessor", "Metadata introduced by @",
23, "SCE_DART_KW_PRIMARY", "keyword", "Primary keywords",
24, "SCE_DART_KW_SECONDARY", "identifier", "Secondary keywords",
25, "SCE_DART_KW_TERTIARY", "identifier", "Tertiary keywords",
26, "SCE_DART_KW_TYPE", "identifier", "Global types",
27, "SCE_DART_STRINGEOL", "error literal string", "End of line where string is not closed",
};
class LexerDart : public DefaultLexer {
WordList keywordsPrimary;
WordList keywordsSecondary;
WordList keywordsTertiary;
WordList keywordsTypes;
OptionsDart options;
OptionSetDart osDart;
public:
LexerDart(const char *languageName_, int language_) :
DefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {
}
// Deleted so LexerDart objects can not be copied.
LexerDart(const LexerDart &) = delete;
LexerDart(LexerDart &&) = delete;
void operator=(const LexerDart &) = delete;
void operator=(LexerDart &&) = delete;
~LexerDart() override = default;
void SCI_METHOD Release() override {
delete this;
}
int SCI_METHOD Version() const override {
return lvRelease5;
}
const char *SCI_METHOD PropertyNames() override {
return osDart.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) override {
return osDart.PropertyType(name);
}
const char *SCI_METHOD DescribeProperty(const char *name) override {
return osDart.DescribeProperty(name);
}
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
const char *SCI_METHOD PropertyGet(const char *key) override {
return osDart.PropertyGet(key);
}
const char *SCI_METHOD DescribeWordListSets() override {
return osDart.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);
Sci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);
static ILexer5 *LexerFactoryDart() {
return new LexerDart("dart", SCLEX_DART);
}
};
Sci_Position SCI_METHOD LexerDart::PropertySet(const char *key, const char *val) {
if (osDart.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
Sci_Position SCI_METHOD LexerDart::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 LexerDart::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);
}
}
}
Sci_PositionU LexerDart::LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite) {
do {
--startPos;
const unsigned style = styler.StyleAt(startPos);
if (!IsSpaceEquiv(style)) {
stylePrevNonWhite = style;
chPrevNonWhite = static_cast<unsigned char>(styler[startPos]);
break;
}
} while (startPos != 0);
return startPos;
}
void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, nullptr);
int lineStateLineType = 0;
int commentLevel = 0; // nested block comment level
std::vector<InterpolatingState> interpolatingStack;
int visibleChars = 0;
int chBefore = 0;
int chPrevNonWhite = 0;
EscapeSequence escSeq;
if (initStyle == SCE_DART_STRINGEOL) {
initStyle = SCE_DART_DEFAULT;
}
if (startPos != 0) {
// backtrack to the line where interpolation starts
BacktrackToStart(styler, DartLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
}
StyleContext sc(startPos, lengthDoc, initStyle, styler);
if (sc.currentLine > 0) {
const int lineState = styler.GetLineState(sc.currentLine - 1);
commentLevel = lineState >> 4;
}
if (startPos == 0) {
if (sc.Match('#', '!')) {
// Shell Shebang at beginning of file
sc.SetState(SCE_DART_COMMENTLINE);
sc.Forward();
lineStateLineType = DartLineStateMaskLineComment;
}
} else if (IsSpaceEquiv(initStyle)) {
LookbackNonWhite(styler, startPos, chPrevNonWhite, initStyle);
chBefore = chPrevNonWhite;
}
while (sc.More()) {
switch (sc.state) {
case SCE_DART_OPERATOR:
case SCE_DART_OPERATOR_STRING:
sc.SetState(SCE_DART_DEFAULT);
break;
case SCE_DART_NUMBER:
if (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_IDENTIFIER:
case SCE_DART_IDENTIFIER_STRING:
case SCE_DART_METADATA:
case SCE_DART_SYMBOL_IDENTIFIER:
if (!IsDartIdentifierChar(sc.ch) || (sc.ch == '$' && sc.state == SCE_DART_IDENTIFIER_STRING)) {
if (sc.state == SCE_DART_METADATA || sc.state == SCE_DART_SYMBOL_IDENTIFIER) {
if (sc.ch == '.') {
const int state = sc.state;
sc.SetState(SCE_DART_OPERATOR);
sc.ForwardSetState(state);
continue;
}
} else {
char s[64];
sc.GetCurrent(s, sizeof(s));
const int state = sc.state;
if (state == SCE_DART_IDENTIFIER_STRING) {
sc.SetState(escSeq.outerState);
continue;
} else if (keywordsPrimary.InList(s)) {
sc.ChangeState(SCE_DART_KW_PRIMARY);
if (strcmp(s, "import") == 0 || strcmp(s, "part") == 0) {
if (visibleChars == sc.LengthCurrent()) {
lineStateLineType = DartLineStateMaskImport;
}
}
} else if (keywordsSecondary.InList(s)) {
sc.ChangeState(SCE_DART_KW_SECONDARY);
} else if (keywordsTertiary.InList(s)) {
sc.ChangeState(SCE_DART_KW_TERTIARY);
} else if (keywordsTypes.InList(s)) {
sc.ChangeState(SCE_DART_KW_TYPE);
} else if (state == SCE_DART_IDENTIFIER && sc.ch == ':') {
if (chBefore == ',' || chBefore == '{' || chBefore == '(') {
sc.ChangeState(SCE_DART_KEY); // map key or named parameter
}
}
}
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_SYMBOL_OPERATOR:
if (!IsDefinableOperator(sc.ch)) {
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_COMMENTLINE:
case SCE_DART_COMMENTLINEDOC:
if (sc.atLineStart) {
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_COMMENTBLOCK:
case SCE_DART_COMMENTBLOCKDOC:
if (sc.Match('*', '/')) {
sc.Forward();
--commentLevel;
if (commentLevel == 0) {
sc.ForwardSetState(SCE_DART_DEFAULT);
}
} else if (sc.Match('/', '*')) {
sc.Forward();
++commentLevel;
}
break;
case SCE_DART_STRING_SQ:
case SCE_DART_STRING_DQ:
case SCE_DART_TRIPLE_STRING_SQ:
case SCE_DART_TRIPLE_STRING_DQ:
case SCE_DART_RAWSTRING_SQ:
case SCE_DART_RAWSTRING_DQ:
case SCE_DART_TRIPLE_RAWSTRING_SQ:
case SCE_DART_TRIPLE_RAWSTRING_DQ:
if (sc.atLineStart && !IsTripleString(sc.state)) {
sc.SetState(SCE_DART_DEFAULT);
} else if (sc.atLineEnd && !IsTripleString(sc.state)) {
sc.ChangeState(SCE_DART_STRINGEOL);
} else if (sc.ch == '\\' && !IsRaw(sc.state)) {
if (escSeq.resetEscapeState(sc.state, sc.chNext)) {
sc.SetState(SCE_DART_ESCAPECHAR);
sc.Forward();
if (sc.Match('u', '{')) {
escSeq.brace = true;
escSeq.digitsLeft = 7; // Unicode code point
sc.Forward();
}
}
} else if (sc.ch == '$' && !IsRaw(sc.state)) {
escSeq.outerState = sc.state;
sc.SetState(SCE_DART_OPERATOR_STRING);
sc.Forward();
if (sc.ch == '{') {
interpolatingStack.push_back({escSeq.outerState, 1});
} else if (sc.ch != '$' && IsDartIdentifierStart(sc.ch)) {
sc.SetState(SCE_DART_IDENTIFIER_STRING);
} else { // error
sc.SetState(escSeq.outerState);
continue;
}
} else if (sc.ch == GetStringQuote(sc.state) &&
(!IsTripleString(sc.state) || (sc.Match(IsDoubleQuoted(sc.state) ? R"(""")" : R"(''')")))) {
if (IsTripleString(sc.state)) {
sc.Forward(2);
}
sc.Forward();
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_STRINGEOL:
if (sc.atLineStart) {
sc.SetState(SCE_DART_DEFAULT);
}
break;
case SCE_DART_ESCAPECHAR:
if (escSeq.atEscapeEnd(sc.ch)) {
if (escSeq.brace && sc.ch == '}') {
sc.Forward();
}
sc.SetState(escSeq.outerState);
continue;
}
break;
}
if (sc.state == SCE_DART_DEFAULT) {
if (sc.ch == '/' && (sc.chNext == '/' || sc.chNext == '*')) {
const int chNext = sc.chNext;
sc.SetState((chNext == '/') ? SCE_DART_COMMENTLINE : SCE_DART_COMMENTBLOCK);
sc.Forward(2);
if (sc.ch == chNext && sc.chNext != chNext) {
if (sc.state == SCE_DART_COMMENTLINE) {
sc.ChangeState(SCE_DART_COMMENTLINEDOC);
} else {
sc.ChangeState(SCE_DART_COMMENTBLOCKDOC);
}
}
if (chNext == '/') {
if (visibleChars == 0) {
lineStateLineType = DartLineStateMaskLineComment;
}
} else {
commentLevel = 1;
}
continue;
}
if (sc.ch == 'r' && (sc.chNext == '\'' || sc.chNext == '"')) {
sc.SetState((sc.chNext == '\'') ? SCE_DART_RAWSTRING_SQ : SCE_DART_RAWSTRING_DQ);
sc.Forward(2);
if (sc.chPrev == '\'' && sc.Match('\'', '\'')) {
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_SQ);
sc.Forward(2);
} else if (sc.chPrev == '"' && sc.Match('"', '"')) {
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_DQ);
sc.Forward(2);
}
continue;
}
if (sc.ch == '"') {
if (sc.Match(R"(""")")) {
sc.SetState(SCE_DART_TRIPLE_STRING_DQ);
sc.Forward(2);
} else {
chBefore = chPrevNonWhite;
sc.SetState(SCE_DART_STRING_DQ);
}
} else if (sc.ch == '\'') {
if (sc.Match(R"(''')")) {
sc.SetState(SCE_DART_TRIPLE_STRING_SQ);
sc.Forward(2);
} else {
chBefore = chPrevNonWhite;
sc.SetState(SCE_DART_STRING_SQ);
}
} else if (IsNumberStart(sc.ch, sc.chNext)) {
sc.SetState(SCE_DART_NUMBER);
} else if ((sc.ch == '@' || sc.ch == '#') && IsDartIdentifierStart(sc.chNext)) {
sc.SetState((sc.ch == '@') ? SCE_DART_METADATA : SCE_DART_SYMBOL_IDENTIFIER);
} else if (IsDartIdentifierStart(sc.ch)) {
chBefore = chPrevNonWhite;
sc.SetState(SCE_DART_IDENTIFIER);
} else if (sc.ch == '#' && IsDefinableOperator(sc.chNext)) {
sc.SetState(SCE_DART_SYMBOL_OPERATOR);
} else if (IsAGraphic(sc.ch)) {
sc.SetState(SCE_DART_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_DART_OPERATOR_STRING);
sc.ForwardSetState(current.state);
interpolatingStack.pop_back();
continue;
}
}
}
}
}
if (!isspacechar(sc.ch)) {
visibleChars++;
if (!IsSpaceEquiv(sc.state)) {
chPrevNonWhite = sc.ch;
}
}
if (sc.atLineEnd) {
int lineState = (commentLevel << 4) | lineStateLineType;
if (!interpolatingStack.empty()) {
lineState |= DartLineStateMaskInterpolation;
}
styler.SetLineState(sc.currentLine, lineState);
lineStateLineType = 0;
visibleChars = 0;
}
sc.Forward();
}
sc.Complete();
}
void LexerDart::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 (initStyle != SCE_DART_COMMENTBLOCKDOC && initStyle != SCE_DART_COMMENTBLOCK &&
initStyle != SCE_DART_TRIPLE_RAWSTRING_SQ && initStyle != SCE_DART_TRIPLE_RAWSTRING_DQ &&
initStyle != SCE_DART_TRIPLE_STRING_SQ && initStyle != SCE_DART_TRIPLE_STRING_DQ)
break;
}
FoldLineState foldPrev(0);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) {
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
foldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));
}
int levelNext = levelCurrent;
FoldLineState foldCurrent(styler.GetLineState(lineCurrent));
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_DART_COMMENTBLOCKDOC:
case SCE_DART_COMMENTBLOCK: {
const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0);
if (level != 0) {
levelNext += level;
startPos++;
chNext = styler[startPos];
styleNext = styler.StyleIndexAt(startPos);
}
} break;
case SCE_DART_TRIPLE_RAWSTRING_SQ:
case SCE_DART_TRIPLE_RAWSTRING_DQ:
case SCE_DART_TRIPLE_STRING_SQ:
case SCE_DART_TRIPLE_STRING_DQ:
if (style != stylePrev && !AnyOf(stylePrev, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
levelNext++;
}
if (style != styleNext && !AnyOf(styleNext, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
levelNext--;
}
break;
case SCE_DART_OPERATOR:
case SCE_DART_OPERATOR_STRING:
if (ch == '{' || ch == '[' || ch == '(') {
levelNext++;
} else if (ch == '}' || ch == ']' || ch == ')') {
levelNext--;
}
break;
}
if (startPos == lineStartNext) {
const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));
levelNext = std::max(levelNext, SC_FOLDLEVELBASE);
if (foldCurrent.lineComment) {
levelNext += foldNext.lineComment - foldPrev.lineComment;
} else if (foldCurrent.packageImport) {
levelNext += foldNext.packageImport - foldPrev.packageImport;
}
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;
foldPrev = foldCurrent;
foldCurrent = foldNext;
}
}
}
} // unnamed namespace end
extern const LexerModule lmDart(SCLEX_DART, LexerDart::LexerFactoryDart, "dart", dartWordListDesc);

View File

@ -168,6 +168,7 @@ void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocume
{
posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish);
// Mark whitespace as default
if (posCurrent > 0)
styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);
if (posCurrent >= posFinish)
break;

View File

@ -3,7 +3,7 @@
* Lexer for F# 5.0
* Copyright (c) 2021 Robert Di Pardo <dipardo.r@gmail.com>
* Parts of LexerFSharp::Lex were adapted from LexCaml.cxx by Robert Roessler ("RR").
* Parts of LexerFSharp::Fold were adapted from LexCPP.cxx by Neil Hodgson and Udo Lechner.
* Parts of LexerFSharp::Fold were adapted from LexBash.cxx by Neil Hodgson and Kein-Hong Man.
* The License.txt file describes the conditions under which this software may be distributed.
*/
// clang-format off
@ -442,9 +442,13 @@ void SCI_METHOD LexerFSharp::Lex(Sci_PositionU start, Sci_Position length, int i
break;
case SCE_FSHARP_LINENUM:
case SCE_FSHARP_PREPROCESSOR:
case SCE_FSHARP_COMMENTLINE:
if (sc.MatchLineEnd()) {
state = SCE_FSHARP_DEFAULT;
}
break;
case SCE_FSHARP_COMMENTLINE:
if (sc.atLineStart) {
state = SCE_FSHARP_DEFAULT;
advance = false;
}
break;
@ -647,27 +651,26 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
}
LexAccessor styler(pAccess);
const Sci_Position startPos = static_cast<Sci_Position>(start);
Sci_Position startPos = static_cast<Sci_Position>(start);
const Sci_PositionU endPos = start + length;
Sci_Position lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
initStyle = (startPos > 0) ? styler.StyleAt(startPos - 1) : SCE_FSHARP_DEFAULT;
}
Sci_Position lineNext = lineCurrent + 1;
Sci_Position lineStartNext = styler.LineStart(lineNext);
int style = initStyle;
int styleNext = styler.StyleAt(startPos);
char chNext = styler[startPos];
int levelNext;
int levelCurrent = SC_FOLDLEVELBASE;
int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelNext = levelCurrent;
int visibleChars = 0;
if (lineCurrent > 0) {
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 0x10;
}
levelNext = levelCurrent;
for (Sci_PositionU i = start; i < endPos; i++) {
for (Sci_PositionU i = static_cast<Sci_PositionU>(startPos); i < endPos; i++) {
const Sci_Position currentPos = static_cast<Sci_Position>(i);
const bool atEOL = (currentPos == (lineStartNext - 1) || styler.SafeGetCharAt(currentPos) == '\r');
const bool atEOL = (currentPos == (lineStartNext - 1));
const bool atLineOrDocEnd = (atEOL || (i == (endPos - 1)));
const int stylePrev = style;
const char ch = chNext;
@ -708,10 +711,6 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
FoldLexicalGroup(styler, levelNext, lineCurrent, "open ", SCE_FSHARP_KEYWORD);
}
if (!IsASpace(ch)) {
visibleChars++;
}
if (atLineOrDocEnd) {
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
@ -719,7 +718,7 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
if (visibleChars == 0 && options.foldCompact) {
lev |= SC_FOLDLEVELWHITEFLAG;
}
if (levelUse < levelNext) {
if ((levelUse < levelNext) && (visibleChars > 0)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
if (lev != styler.LevelAt(lineCurrent)) {
@ -731,12 +730,14 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
lineNext = lineCurrent + 1;
lineStartNext = styler.LineStart(lineNext);
levelCurrent = levelNext;
}
if (atEOL && (currentPos == (styler.Length() - 1))) {
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
}
if (!IsASpace(ch)) {
visibleChars++;
}
}
const int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
}
bool LineContains(LexAccessor &styler, const char *word, const Sci_Position start, const int chAttr) {

View File

@ -91,7 +91,7 @@ bool Contains(const std::string &s, std::string_view search) noexcept {
return s.find(search) != std::string::npos;
}
script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) {
script_type segIsScriptingIndicator(const Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) {
const std::string s = styler.GetRangeLowered(start, end+1);
if (Contains(s, "vbs"))
return eScriptVBS;
@ -103,7 +103,7 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
return eScriptJS;
if (Contains(s, "php"))
return eScriptPHP;
if (Contains(s, "xml")) {
const size_t xml = s.find("xml");
if (xml != std::string::npos) {
for (size_t t = 0; t < xml; t++) {
@ -111,20 +111,14 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
return prevValue;
}
}
}
return eScriptXML;
}
return prevValue;
}
int PrintScriptingIndicatorOffset(Accessor &styler, Sci_PositionU start, Sci_PositionU end) {
int iResult = 0;
const std::string s = styler.GetRangeLowered(start, end+1);
if (0 == strncmp(s.c_str(), "php", 3)) {
iResult = 3;
}
return iResult;
constexpr bool IsPHPScriptState(int state) noexcept {
return (state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_OPERATOR) || (state == SCE_HPHP_COMPLEX_VARIABLE);
}
script_type ScriptOfState(int state) noexcept {
@ -132,9 +126,9 @@ script_type ScriptOfState(int state) noexcept {
return eScriptPython;
} else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) {
return eScriptVBS;
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {
return eScriptJS;
} else if ((state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_COMMENTLINE) || (state == SCE_HPHP_COMPLEX_VARIABLE)) {
} else if (IsPHPScriptState(state)) {
return eScriptPHP;
} else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
return eScriptSGML;
@ -153,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);
}
}
@ -168,7 +162,7 @@ constexpr int stateForPrintState(int StateToPrint) noexcept {
state = StateToPrint - SCE_HA_PYTHON;
} else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
state = StateToPrint - SCE_HA_VBS;
} else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) {
} else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_TEMPLATELITERAL)) {
state = StateToPrint - SCE_HA_JS;
}
@ -185,8 +179,12 @@ constexpr bool isStringState(int state) noexcept {
switch (state) {
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HJ_TEMPLATELITERAL:
case SCE_HJA_DOUBLESTRING:
case SCE_HJA_SINGLESTRING:
case SCE_HJA_REGEX:
case SCE_HJA_TEMPLATELITERAL:
case SCE_HB_STRING:
case SCE_HBA_STRING:
case SCE_HP_STRING:
@ -454,12 +452,12 @@ void classifyWordHTPHP(Sci_PositionU start, Sci_PositionU end, const WordList &k
styler.ColourTo(end, chAttr);
}
bool isWordHSGML(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, Accessor &styler) {
bool isWordHSGML(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const Accessor &styler) {
const std::string s = styler.GetRange(start, end + 1);
return keywords.InList(s);
}
bool isWordCdata(Sci_PositionU start, Sci_PositionU end, Accessor &styler) {
bool isWordCdata(Sci_PositionU start, Sci_PositionU end, const Accessor &styler) {
const std::string s = styler.GetRange(start, end + 1);
return s == "[CDATA[";
}
@ -492,9 +490,13 @@ constexpr int StateForScript(script_type scriptLanguage) noexcept {
return Result;
}
constexpr int defaultStateForSGML(script_type scriptLanguage) noexcept {
return (scriptLanguage == eScriptSGMLblock)? SCE_H_SGML_BLOCK_DEFAULT : SCE_H_SGML_DEFAULT;
}
constexpr bool issgmlwordchar(int ch) noexcept {
return !IsASCII(ch) ||
(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
}
constexpr bool IsPhpWordStart(int ch) noexcept {
@ -512,15 +514,6 @@ constexpr bool InTagState(int state) noexcept {
SCE_H_DOUBLESTRING, SCE_H_SINGLESTRING);
}
constexpr bool IsCommentState(const int state) noexcept {
return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
}
constexpr bool IsScriptCommentState(const int state) noexcept {
return AnyOf(state, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJA_COMMENT,
SCE_HJA_COMMENTLINE, SCE_HB_COMMENTLINE, SCE_HBA_COMMENTLINE);
}
constexpr bool isLineEnd(int ch) noexcept {
return ch == '\r' || ch == '\n';
}
@ -675,28 +668,41 @@ 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 <?=
Question, // <?
};
constexpr bool IsPHPEntryState(int state) noexcept {
return !(isPHPStringState(state) || IsScriptCommentState(state) || AnyOf(state, SCE_H_ASPAT, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE));
}
enum class InstructionTag {
None,
XML,
Open,// <? ?> short open tag
Echo,// <?= ?> short echo tag
PHP, // <?php ?> standard tag
};
bool IsPHPStart(AllowPHP allowPHP, Accessor &styler, Sci_PositionU start) {
if (allowPHP == AllowPHP::None) {
return false;
}
if (allowPHP == AllowPHP::PHP) {
// Require <?php or <?=
constexpr std::string_view phpTag = "<?php";
constexpr std::string_view echoTag = "<?=";
InstructionTag segIsScriptInstruction(AllowPHP allowPHP, int state, const Accessor &styler, Sci_PositionU start, bool isXml) {
constexpr std::string_view phpTag = "php";
constexpr std::string_view xmlTag = "xml";
const std::string tag = styler.GetRangeLowered(start, start + phpTag.length());
return (tag == phpTag) || (tag.substr(0, echoTag.length()) == echoTag);
if (allowPHP != AllowPHP::None) {
// Require <?php or <?=
if (tag == phpTag) {
return InstructionTag::PHP;
}
return true;
if (!tag.empty() && (tag.front() == '=')) {
return InstructionTag::Echo;
}
}
if (isXml || tag == xmlTag) {
return AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)? InstructionTag::XML : InstructionTag::None;
}
return (allowPHP == AllowPHP::Question) ? InstructionTag::Open : InstructionTag::None;
}
Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Position i, const Sci_Position lengthDoc, Accessor &styler, bool &isSimpleString) {
@ -902,7 +908,7 @@ const LexicalClass lexicalClassesHTML[] = {
50, "SCE_HJ_SYMBOLS", "client javascript operator", "JS Symbols",
51, "SCE_HJ_STRINGEOL", "client javascript error literal string", "JavaScript EOL",
52, "SCE_HJ_REGEX", "client javascript literal regex", "JavaScript RegEx",
53, "", "unused", "",
53, "SCE_HJ_TEMPLATELITERAL", "client javascript literal template", "JS Template Literal",
54, "", "unused", "",
55, "SCE_HJA_START", "server javascript default", "JS Start - allows eol filled background to not start on same line as SCRIPT tag",
56, "SCE_HJA_DEFAULT", "server javascript default", "JS Default",
@ -917,7 +923,7 @@ const LexicalClass lexicalClassesHTML[] = {
65, "SCE_HJA_SYMBOLS", "server javascript operator", "JS Symbols",
66, "SCE_HJA_STRINGEOL", "server javascript error literal string", "JavaScript EOL",
67, "SCE_HJA_REGEX", "server javascript literal regex", "JavaScript RegEx",
68, "", "unused", "",
68, "SCE_HJA_TEMPLATELITERAL", "server javascript literal template", "JS Template Literal",
69, "", "unused", "",
70, "SCE_HB_START", "client basic default", "Start",
71, "SCE_HB_DEFAULT", "client basic default", "Default",
@ -1188,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;
@ -1199,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 = 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);
@ -1250,6 +1250,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
script_type clientScript = static_cast<script_type>((lineState >> 8) & 0x0F); // 4 bits of script name
int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
bool isLanguageType = (lineState >> 20) & 1; // type or language attribute for script tag
int sgmlBlockLevel = (lineState >> 21);
script_type scriptLanguage = ScriptOfState(state);
// If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
@ -1335,7 +1336,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
case eScriptPHP:
//not currently supported case eScriptVBS:
if (!AnyOf(state, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE, SCE_HJ_REGEX, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJ_COMMENTDOC) &&
if (!AnyOf(state, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJ_COMMENTDOC) &&
!isStringState(state)) {
//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
@ -1410,7 +1411,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
((aspScript & 0x0F) << 4) |
((clientScript & 0x0F) << 8) |
((beforePreProc & 0xFF) << 12) |
((isLanguageType ? 1 : 0) << 20));
((isLanguageType ? 1 : 0) << 20) |
(sgmlBlockLevel << 21));
lineCurrent++;
lineStartVisibleChars = 0;
}
@ -1455,6 +1457,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HJ_TEMPLATELITERAL:
case SCE_HB_STRING:
case SCE_HBA_STRING:
case SCE_HP_STRING:
@ -1496,15 +1499,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
/////////////////////////////////////
// handle the start of PHP pre-processor = Non-HTML
else if ((ch == '<') && (chNext == '?') && IsPHPEntryState(state) && IsPHPStart(allowPHP, styler, i)) {
else if ((ch == '<') && (chNext == '?') && !IsPHPScriptState(state)) {
const InstructionTag tag = segIsScriptInstruction(allowPHP, state, styler, i + 2, isXml);
if (tag != InstructionTag::None) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP);
if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue;
scriptLanguage = (tag == InstructionTag::XML) ? eScriptXML : eScriptPHP;
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
i++;
visibleChars++;
i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
if (tag >= InstructionTag::Echo) {
i += (tag == InstructionTag::Echo) ? 1 : 3;
}
if (scriptLanguage == eScriptXML)
styler.ColourTo(i, SCE_H_XMLSTART);
else
@ -1522,6 +1528,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
ch = SafeGetUnsignedCharAt(styler, i);
continue;
}
}
// handle the start Mako template Python code
else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
@ -1662,16 +1669,13 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
/////////////////////////////////////
// handle the start of SGML language (DTD)
else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
else if (AnyOf(scriptLanguage, eScriptNone, eScriptXML, eScriptSGMLblock) &&
(chPrev == '<') &&
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!isStringState(StateToPrint)) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint))) {
AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
if ((state != SCE_H_SGML_BLOCK_DEFAULT) && (chNext == '-') && (chNext2 == '-')) {
state = SCE_H_COMMENT; // wait for a pending command
styler.ColourTo(i + 2, SCE_H_COMMENT);
i += 2; // follow styling after the --
@ -1687,12 +1691,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
ch = '-';
}
}
} else if (isWordCdata(i + 1, i + 7, styler)) {
} else if ((state != SCE_H_SGML_BLOCK_DEFAULT) && isWordCdata(i + 1, i + 7, styler)) {
state = SCE_H_CDATA;
} else {
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
beforeLanguage = scriptLanguage;
scriptLanguage = eScriptSGML;
state = SCE_H_SGML_COMMAND; // wait for a pending command
if ((chNext == '-') && (chNext2 == '-')) {
i += 2;
state = SCE_H_SGML_COMMENT;
} else {
state = (chNext == '[') ? SCE_H_SGML_DEFAULT : SCE_H_SGML_COMMAND; // wait for a pending command
}
}
// fold whole tag (-- when closing the tag)
if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)
@ -1763,7 +1773,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
((chNext == '>') && isPreProcessorEndTag(state, ch))) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
((scriptLanguage == eScriptSGML) && (ch == '>') && !AnyOf(state, SCE_H_SGML_COMMENT, SCE_H_SGML_DOUBLESTRING, SCE_H_SGML_SIMPLESTRING))) {
if (state == SCE_H_ASPAT) {
aspScript = segIsScriptingIndicator(styler,
styler.GetStartSegment(), i - 1, aspScript);
@ -1851,41 +1861,36 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
styler.ColourTo(i - 2, StateToPrint);
}
state = SCE_H_SGML_COMMENT;
} else if (IsUpperOrLowerCase(ch) && (chPrev == '%')) {
styler.ColourTo(i - 2, StateToPrint);
} else if (ch == '%' && IsUpperOrLowerCase(chNext)) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_ENTITY;
} else if (ch == '#') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_SPECIAL;
} else if (ch == '[') {
styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
++sgmlBlockLevel;
scriptLanguage = eScriptSGMLblock;
state = SCE_H_SGML_BLOCK_DEFAULT;
} else if (ch == ']') {
if (scriptLanguage == eScriptSGMLblock) {
styler.ColourTo(i, StateToPrint);
if (sgmlBlockLevel > 0) {
--sgmlBlockLevel;
if (sgmlBlockLevel == 0) {
beforePreProc = SCE_H_DEFAULT;
}
styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
scriptLanguage = eScriptSGML;
} else {
styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_ERROR);
}
state = SCE_H_SGML_DEFAULT;
} else if (scriptLanguage == eScriptSGMLblock) {
if ((ch == '!') && (chPrev == '<')) {
styler.ColourTo(i - 2, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
state = SCE_H_SGML_COMMAND;
} else if (ch == '>') {
styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
}
}
break;
case SCE_H_SGML_COMMAND:
if ((ch == '-') && (chPrev == '-')) {
styler.ColourTo(i - 2, StateToPrint);
state = SCE_H_SGML_COMMENT;
} else if (!issgmlwordchar(ch)) {
if (!issgmlwordchar(ch)) {
if (isWordHSGML(styler.GetStartSegment(), i - 1, keywordsSGML, styler)) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_1ST_PARAM;
@ -1897,18 +1902,10 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
case SCE_H_SGML_1ST_PARAM:
// wait for the beginning of the word
if ((ch == '-') && (chPrev == '-')) {
if (scriptLanguage == eScriptSGMLblock) {
styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT);
} else {
styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
}
state = SCE_H_SGML_1ST_PARAM_COMMENT;
} else if (issgmlwordchar(ch)) {
if (scriptLanguage == eScriptSGMLblock) {
styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
} else {
styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
}
// find the length of the word
Sci_Position size = 1;
while (setHTMLWord.Contains(SafeGetUnsignedCharAt(styler, i + size)))
@ -1917,11 +1914,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
i += size - 1;
visibleChars += size - 1;
ch = SafeGetUnsignedCharAt(styler, i);
if (scriptLanguage == eScriptSGMLblock) {
state = SCE_H_SGML_BLOCK_DEFAULT;
} else {
state = SCE_H_SGML_DEFAULT;
}
continue;
}
break;
@ -1985,12 +1978,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
}
break;
case SCE_H_SGML_ENTITY:
if (ch == ';') {
styler.ColourTo(i, StateToPrint);
state = SCE_H_SGML_DEFAULT;
} else if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.') {
styler.ColourTo(i, SCE_H_SGML_ERROR);
state = SCE_H_SGML_DEFAULT;
if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.' && ch != '_') {
styler.ColourTo(i, ((ch == ';') ? StateToPrint : SCE_H_SGML_ERROR));
state = defaultStateForSGML(scriptLanguage);
}
break;
case SCE_H_ENTITY:
@ -2203,14 +2193,11 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_WORD;
} else if (ch == '/' && chNext == '*') {
styler.ColourTo(i - 1, StateToPrint);
i++;
if (chNext2 == '*')
state = SCE_HJ_COMMENTDOC;
else
state = SCE_HJ_COMMENT;
if (chNext2 == '/') {
// Eat the * so it isn't used for the end of the comment
i++;
}
} else if (ch == '/' && chNext == '/') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE;
@ -2223,6 +2210,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} else if (ch == '\'') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_SINGLESTRING;
} else if (ch == '`') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_TEMPLATELITERAL;
} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
styler.SafeGetCharAt(i + 3) == '-') {
styler.ColourTo(i - 1, StateToPrint);
@ -2249,6 +2239,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
//styler.ColourTo(i - 1, eHTJSKeyword);
state = SCE_HJ_DEFAULT;
if (ch == '/' && chNext == '*') {
i++;
if (chNext2 == '*')
state = SCE_HJ_COMMENTDOC;
else
@ -2259,6 +2250,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_DOUBLESTRING;
} else if (ch == '\'') {
state = SCE_HJ_SINGLESTRING;
} else if (ch == '`') {
state = SCE_HJ_TEMPLATELITERAL;
} else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE;
@ -2314,6 +2307,16 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
}
}
break;
case SCE_HJ_TEMPLATELITERAL:
if (ch == '\\') {
if (chNext == '$' || chNext == '`' || chNext == '\\') {
i++;
}
} else if (ch == '`') {
styler.ColourTo(i, statePrintForState(SCE_HJ_TEMPLATELITERAL, inScriptType));
state = SCE_HJ_DEFAULT;
}
break;
case SCE_HJ_STRINGEOL:
if (!isLineEnd(ch)) {
styler.ColourTo(i - 1, StateToPrint);
@ -2334,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 == '/') {
@ -2711,7 +2715,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
}
} else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
if (ch == '/' && chNext == '*') {
if (styler.SafeGetCharAt(i + 2) == '*')
i++;
if (styler.SafeGetCharAt(i + 1) == '*')
state = SCE_HJ_COMMENTDOC;
else
state = SCE_HJ_COMMENT;
@ -2721,6 +2726,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_DOUBLESTRING;
} else if ((ch == '\'') && (nonEmptySegment)) {
state = SCE_HJ_SINGLESTRING;
} else if ((ch == '`') && (nonEmptySegment)) {
state = SCE_HJ_TEMPLATELITERAL;
} else if (IsAWordStart(ch)) {
state = SCE_HJ_WORD;
} else if (IsOperator(ch)) {

Some files were not shown because too many files have changed in this diff Show More