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 # IDE stuff
CMakeLists.txt.user* 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 PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/lexilla/include ${CMAKE_CURRENT_SOURCE_DIR}/lexilla/include
${CMAKE_CURRENT_SOURCE_DIR}/lexilla/lexlib ${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 **.cob text
**.cmake text **.cmake text
**.d text **.d text
**.dart text
**.diff text **.diff text
**.erl text **.erl text
**.f text **.f text
@ -48,15 +49,19 @@
**.matlab text **.matlab text
**.ml text **.ml text
**.nim text **.nim text
**.nix text
**.octave text **.octave text
**.p text **.p text
**.pas text
**.pl text **.pl text
**.p6 text **.p6 text
**.ps1 text **.ps1 text
**.r text **.r text
**.rb text **.rb text
**.roff text
**.rs text **.rs text
**.sql text **.sql text
**.st text
**.tcl text **.tcl text
**.toml text **.toml text
**.tsql text **.tsql text
@ -67,7 +72,9 @@
**.vh text **.vh text
**.vhd text **.vhd text
**.x12 text **.x12 text
**.xml text
**.yaml text **.yaml text
**.zig text
**.md text **.md text
**.txt text **.txt text
**.pch text **.pch text

View File

@ -3,16 +3,24 @@ name: "Build and check Lexilla on Win32 with Visual C++"
on: [push] on: [push]
jobs: jobs:
# Compile for amd64 and cross-compile for arm64. Tests run only for amd64.
build: build:
runs-on: windows-latest runs-on: windows-latest
strategy:
matrix:
arch:
- amd64
- amd64_arm64
env:
TEST: ${{ matrix.arch == 'amd64' && 'test' || '' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Preparing nmake - name: Preparing nmake
uses: ilammy/msvc-dev-cmd@v1 uses: ilammy/msvc-dev-cmd@v1
with: with:
arch: x64 arch: ${{ matrix.arch }}
- name: Install Scintilla source - name: Install Scintilla source
run: | run: |
pwd pwd
@ -24,7 +32,7 @@ jobs:
- name: Unit Test - name: Unit Test
run: | run: |
cd test/unit cd test/unit
nmake -f test.mak DEBUG=1 test nmake -f test.mak DEBUG=1 $env:TEST
cd ../.. cd ../..
- name: Build Lexilla - name: Build Lexilla
run: | run: |
@ -33,14 +41,15 @@ jobs:
cd .. cd ..
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: lexilla.dll name: lexilla${{ matrix.arch == 'amd64_arm64' && '-arm64' || '' }}.dll
path: bin/lexilla.dll path: bin/lexilla.dll
- name: Test lexing and folding - name: Test lexing and folding
run: | run: |
cd test cd test
nmake -f testlexers.mak DEBUG=1 test nmake -f testlexers.mak DEBUG=1 $env:TEST
cd .. cd ..
- name: CheckLexilla C Example - name: CheckLexilla C Example
if: matrix.arch == 'amd64'
run: | run: |
cd examples/CheckLexilla cd examples/CheckLexilla
cl -MP CheckLexilla.c -I ../../include -Fe: 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: To use GCC, run lexilla/src/makefile:
make make
To use Clang, run lexilla/test/makefile: To use Clang, run lexilla/src/makefile:
make CLANG=1 make CLANG=1
On macOS, CLANG is set automatically so this can just be On macOS, CLANG is set automatically so this can just be
make make
To use MSVC, run lexilla/test/lexilla.mak: To use MSVC, run lexilla/src/lexilla.mak:
nmake -f lexilla.mak nmake -f lexilla.mak
To build a debugging version of the library, add DEBUG=1 to the command: To build a debugging version of the library, add DEBUG=1 to the command:

View File

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

View File

@ -1,6 +1,12 @@
// File to suppress cppcheck warnings for files that will not be fixed. // 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. // 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 // Coding style is to use assignments in constructor when there are many
// members to initialize or the initialization is complex or has comments. // members to initialize or the initialization is complex or has comments.
@ -25,12 +31,8 @@ passedByValue
missingIncludeSystem missingIncludeSystem
// Passing temporary string into hidden object creator functions: they do not hold the argument // Passing temporary string into hidden object creator functions: they do not hold the argument
danglingTemporaryLifetime:lexilla/access/LexillaAccess.cxx
returnDanglingLifetime: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 // cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that
// only finds one false issue in LexRuby // only finds one false issue in LexRuby
checkLevelNormal:lexilla/lexers/LexBash.cxx checkLevelNormal:lexilla/lexers/LexBash.cxx
@ -42,6 +44,9 @@ checkLevelNormal:lexilla/lexers/LexRuby.cxx
// Physically but not logically const. // Physically but not logically const.
constVariablePointer:lexilla/examples/CheckLexilla/CheckLexilla.c 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 // Suppress most lexer warnings since the lexers are maintained by others
redundantCondition:lexilla/lexers/LexA68k.cxx redundantCondition:lexilla/lexers/LexA68k.cxx
constParameterReference:lexilla/lexers/LexAbaqus.cxx constParameterReference:lexilla/lexers/LexAbaqus.cxx
@ -58,21 +63,25 @@ constParameterReference:lexilla/lexers/LexBash.cxx
knownConditionTrueFalse:lexilla/lexers/LexBash.cxx knownConditionTrueFalse:lexilla/lexers/LexBash.cxx
variableScope:lexilla/lexers/LexBash.cxx variableScope:lexilla/lexers/LexBash.cxx
constVariable:lexilla/lexers/LexBasic.cxx constVariable:lexilla/lexers/LexBasic.cxx
constParameterReference:lexilla/lexers/LexBullant.cxx
constParameterReference:lexilla/lexers/LexCLW.cxx constParameterReference:lexilla/lexers/LexCLW.cxx
knownConditionTrueFalse:lexilla/lexers/LexCLW.cxx knownConditionTrueFalse:lexilla/lexers/LexCLW.cxx
variableScope:lexilla/lexers/LexCmake.cxx variableScope:lexilla/lexers/LexCmake.cxx
knownConditionTrueFalse:lexilla/lexers/LexCmake.cxx knownConditionTrueFalse:lexilla/lexers/LexCmake.cxx
constParameterReference:lexilla/lexers/LexCmake.cxx constParameterReference:lexilla/lexers/LexCmake.cxx
constParameterReference:lexilla/lexers/LexCOBOL.cxx constParameterReference:lexilla/lexers/LexCOBOL.cxx
constVariablePointer:lexilla/lexers/LexCOBOL.cxx
constParameterReference:lexilla/lexers/LexCoffeeScript.cxx constParameterReference:lexilla/lexers/LexCoffeeScript.cxx
constParameterPointer:lexilla/lexers/LexCoffeeScript.cxx constParameterPointer:lexilla/lexers/LexCoffeeScript.cxx
knownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx knownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx
constVariableReference:lexilla/lexers/LexConf.cxx constVariableReference:lexilla/lexers/LexConf.cxx
constParameterReference:lexilla/lexers/LexCPP.cxx constParameterReference:lexilla/lexers/LexCPP.cxx
variableScope:lexilla/lexers/LexCSS.cxx variableScope:lexilla/lexers/LexCSS.cxx
constVariablePointer:lexilla/lexers/LexCSS.cxx
knownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx knownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx
constParameterReference:lexilla/lexers/LexDataflex.cxx constParameterReference:lexilla/lexers/LexDataflex.cxx
variableScope:lexilla/lexers/LexDataflex.cxx variableScope:lexilla/lexers/LexDataflex.cxx
constParameterReference:lexilla/lexers/LexDart.cxx
knownConditionTrueFalse:lexilla/lexers/LexECL.cxx knownConditionTrueFalse:lexilla/lexers/LexECL.cxx
variableScope:lexilla/lexers/LexECL.cxx variableScope:lexilla/lexers/LexECL.cxx
constParameter:lexilla/lexers/LexEDIFACT.cxx constParameter:lexilla/lexers/LexEDIFACT.cxx
@ -101,6 +110,7 @@ unreadVariable:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexJulia.cxx variableScope:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexLaTeX.cxx variableScope:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLaTeX.cxx constParameterReference:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexLisp.cxx
constParameterPointer:lexilla/lexers/LexMagik.cxx constParameterPointer:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMagik.cxx constParameterReference:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMarkdown.cxx constParameterReference:lexilla/lexers/LexMarkdown.cxx
@ -110,6 +120,7 @@ unreadVariable:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMatlab.cxx variableScope:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMetapost.cxx variableScope:lexilla/lexers/LexMetapost.cxx
constParameterReference:lexilla/lexers/LexModula.cxx constParameterReference:lexilla/lexers/LexModula.cxx
duplicateBreak:lexilla/lexers/LexModula.cxx
variableScope:lexilla/lexers/LexModula.cxx variableScope:lexilla/lexers/LexModula.cxx
constParameterReference:lexilla/lexers/LexMPT.cxx constParameterReference:lexilla/lexers/LexMPT.cxx
variableScope:lexilla/lexers/LexMSSQL.cxx variableScope:lexilla/lexers/LexMSSQL.cxx
@ -132,6 +143,7 @@ constVariableReference:lexilla/lexers/LexPerl.cxx
knownConditionTrueFalse:lexilla/lexers/LexPerl.cxx knownConditionTrueFalse:lexilla/lexers/LexPerl.cxx
constParameterReference:lexilla/lexers/LexPLM.cxx constParameterReference:lexilla/lexers/LexPLM.cxx
constParameterReference:lexilla/lexers/LexPO.cxx constParameterReference:lexilla/lexers/LexPO.cxx
constVariablePointer:lexilla/lexers/LexPOV.cxx
constParameterReference:lexilla/lexers/LexPython.cxx constParameterReference:lexilla/lexers/LexPython.cxx
shadowVariable:lexilla/lexers/LexPowerPro.cxx shadowVariable:lexilla/lexers/LexPowerPro.cxx
knownConditionTrueFalse: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/LexRuby.cxx
constParameterReference:lexilla/lexers/LexRust.cxx constParameterReference:lexilla/lexers/LexRust.cxx
knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx
constParameterReference:lexilla/lexers/LexScriptol.cxx
constParameterPointer:lexilla/lexers/LexSmalltalk.cxx
variableScope:lexilla/lexers/LexSpecman.cxx variableScope:lexilla/lexers/LexSpecman.cxx
unreadVariable:lexilla/lexers/LexSpice.cxx unreadVariable:lexilla/lexers/LexSpice.cxx
constParameterReference: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/LexTADS3.cxx
constParameterReference:lexilla/lexers/LexTAL.cxx constParameterReference:lexilla/lexers/LexTAL.cxx
constVariableReference:lexilla/lexers/LexTCL.cxx constVariableReference:lexilla/lexers/LexTCL.cxx
constParameterPointer:lexilla/lexers/LexTCMD.cxx
invalidscanf:lexilla/lexers/LexTCMD.cxx invalidscanf:lexilla/lexers/LexTCMD.cxx
constParameterReference:lexilla/lexers/LexTeX.cxx constParameterReference:lexilla/lexers/LexTeX.cxx
variableScope:lexilla/lexers/LexTeX.cxx variableScope:lexilla/lexers/LexTeX.cxx
@ -161,6 +176,7 @@ constParameterReference:lexilla/lexers/LexVerilog.cxx
variableScope:lexilla/lexers/LexVerilog.cxx variableScope:lexilla/lexers/LexVerilog.cxx
badBitmaskCheck:lexilla/lexers/LexVerilog.cxx badBitmaskCheck:lexilla/lexers/LexVerilog.cxx
uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx
duplicateCondition:lexilla/lexers/LexVerilog.cxx
constParameterReference:lexilla/lexers/LexVHDL.cxx constParameterReference:lexilla/lexers/LexVHDL.cxx
constVariable:lexilla/lexers/LexVHDL.cxx constVariable:lexilla/lexers/LexVHDL.cxx
shadowVariable:lexilla/lexers/LexVHDL.cxx shadowVariable:lexilla/lexers/LexVHDL.cxx
@ -175,7 +191,6 @@ constVariableReference:lexilla/lexers/LexX12.cxx
constParameterPointer:lexilla/lexers/LexX12.cxx constParameterPointer:lexilla/lexers/LexX12.cxx
uselessCallsSubstr:lexilla/lexers/LexX12.cxx uselessCallsSubstr:lexilla/lexers/LexX12.cxx
constParameterReference:lexilla/lexers/LexYAML.cxx constParameterReference:lexilla/lexers/LexYAML.cxx
constParameterPointer:lexilla/lexers/LexYAML.cxx
knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx
// These are due to Accessor::IndentAmount not declaring the callback as taking a const. // 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/LexScriptol.cxx
constParameterCallback:lexilla/lexers/LexVB.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/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/LexCSS.cxx
constVariableReference:lexilla/lexers/LexCrontab.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/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/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/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 // Suppress everything in test example files
*:lexilla/test/examples/* *:lexilla/test/examples/*

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" /> <meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description" <meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." /> content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20240821" /> <meta name="Date.Modified" content="20250608" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css"> <style type="text/css">
.logo { .logo {
@ -51,6 +51,7 @@
<title> <title>
Lexilla Lexilla
</title> </title>
<link rel="canonical" href="https://scintilla.org/Lexilla.html" />
</head> </head>
<body bgcolor="#FFFFFF" text="#000000"> <body bgcolor="#FFFFFF" text="#000000">
<table bgcolor="#000000" width="100%" cellspacing="0" cellpadding="0" border="0"> <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> <font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td> </td>
<td width="40%" align="right"> <td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.4.0<br /> <font color="#FFCC99" size="3">Release version 5.4.5<br />
Site last modified August 21 2024</font> Site last modified June 8 2025</font>
</td> </td>
<td width="20%"> <td width="20%">
&nbsp; &nbsp;
@ -77,11 +78,11 @@
</tr> </tr>
</table> </table>
<ul id="versionlist"> <ul id="versionlist">
<li>Version 5.4.0 adds a TOML lexer.</li> <li>Version 5.4.5 improves Dart, Makefile, Nix, TOML, and Zig.</li>
<li>Version 5.3.3 improves HTML, JavaScript, Lua, PHP, and XML.</li> <li>Version 5.4.4 fixes a problem when building for ARM64 on Windows.</li>
<li>Version 5.3.2 improves COBOL, HTML, Lua, Ruby, and Rust.</li> <li>Version 5.4.3 improves C++, Modula 3, Pascal, Python, and Ruby.</li>
<li>Version 5.3.1 improves Assembler, Bash, Batch, JavaScript, Python, and Ruby.</li> <li>Version 5.4.2 adds Nix lexer. Improves JavaScript, PHP, Rust, TOML, and Zig.</li>
<li>Version 5.3.0 improves Bash, HTML, and Lua.</li> <li>Version 5.4.1 adds Dart, troff, and Zig lexers. Improves C++, F#, HTML, and Smalltalk.</li>
</ul> </ul>
<ul id="menu"> <ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li> <li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
@ -130,7 +131,7 @@ if (!IsRemote()) { //if NOT remote...
<p> <p>
The source code can be downloaded via Git at GitHub The source code can be downloaded via Git at GitHub
<a href="https://github.com/ScintillaOrg/lexilla">Lexilla project page</a>.<br /> <a href="https://github.com/ScintillaOrg/lexilla">Lexilla project page</a>.<br />
git clone https://github.com/ScintillaOrg/lexilla <code>git clone https://github.com/ScintillaOrg/lexilla</code>
</p> </p>
<p>Current repository status:<br /> <p>Current repository status:<br />
<a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg" /></a><br /> <a href="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml"><img src="https://github.com/ScintillaOrg/lexilla/actions/workflows/build-check.yml/badge.svg" /></a><br />

View File

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

View File

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

View File

@ -37,6 +37,7 @@
Lexilla was originally code that was part of the Scintilla project. 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. Thus it shares much of the history and contributors of Scintilla before it was extracted as its own project.
</p> </p>
<a href="#Releases">Releases</a>
<h2>Contributors</h2> <h2>Contributors</h2>
<p> <p>
Thanks to all the people that have contributed patches, bug reports and suggestions. Thanks to all the people that have contributed patches, bug reports and suggestions.
@ -585,9 +586,183 @@
<td>Tsuyoshi Miyake</td> <td>Tsuyoshi Miyake</td>
<td>Martin Schäfer</td> <td>Martin Schäfer</td>
<td>RainRat</td> <td>RainRat</td>
</tr><tr>
<td>Henrik S. Johansen</td>
<td>Ekopalypse</td>
<td>HoTschir</td>
<td>Ahmet Sait</td>
</tr> </tr>
</table> </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> <h3>
<a href="https://www.scintilla.org/lexilla540.zip">Release 5.4.0</a> <a href="https://www.scintilla.org/lexilla540.zip">Release 5.4.0</a>
</h3> </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 <string.h>
#include <assert.h> #include <assert.h>
#include <string>
#include <string_view> #include <string_view>
#include "ILexer.h" #include "ILexer.h"

View File

@ -145,6 +145,10 @@ val SCLEX_JULIA=133
val SCLEX_ASCIIDOC=134 val SCLEX_ASCIIDOC=134
val SCLEX_GDSCRIPT=135 val SCLEX_GDSCRIPT=135
val SCLEX_TOML=136 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 # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1. # value assigned in sequence from SCLEX_AUTOMATIC+1.
@ -175,12 +179,10 @@ val SCE_P_FTRIPLEDOUBLE=19
val SCE_P_ATTRIBUTE=20 val SCE_P_ATTRIBUTE=20
# Lexical states for SCLEX_CPP # Lexical states for SCLEX_CPP
# Lexical states for SCLEX_BULLANT # Lexical states for SCLEX_BULLANT
# Lexical states for SCLEX_COBOL
# Lexical states for SCLEX_TACL # Lexical states for SCLEX_TACL
# Lexical states for SCLEX_TAL # Lexical states for SCLEX_TAL
lex Cpp=SCLEX_CPP SCE_C_ lex Cpp=SCLEX_CPP SCE_C_
lex BullAnt=SCLEX_BULLANT SCE_C_ lex BullAnt=SCLEX_BULLANT SCE_C_
lex COBOL=SCLEX_COBOL SCE_C_
lex TACL=SCLEX_TACL SCE_C_ lex TACL=SCLEX_TACL SCE_C_
lex TAL=SCLEX_TAL SCE_C_ lex TAL=SCLEX_TAL SCE_C_
val SCE_C_DEFAULT=0 val SCE_C_DEFAULT=0
@ -211,6 +213,21 @@ val SCE_C_PREPROCESSORCOMMENTDOC=24
val SCE_C_USERLITERAL=25 val SCE_C_USERLITERAL=25
val SCE_C_TASKMARKER=26 val SCE_C_TASKMARKER=26
val SCE_C_ESCAPESEQUENCE=27 val SCE_C_ESCAPESEQUENCE=27
# Lexical states for SCLEX_COBOL
lex COBOL=SCLEX_COBOL SCE_COBOL_
val SCE_COBOL_DEFAULT=0
val SCE_COBOL_COMMENT=1
val SCE_COBOL_COMMENTLINE=2
val SCE_COBOL_COMMENTDOC=3
val SCE_COBOL_NUMBER=4
val SCE_COBOL_WORD=5
val SCE_COBOL_STRING=6
val SCE_COBOL_CHARACTER=7
val SCE_COBOL_WORD3=8
val SCE_COBOL_PREPROCESSOR=9
val SCE_COBOL_OPERATOR=10
val SCE_COBOL_IDENTIFIER=11
val SCE_COBOL_WORD2=16
# Lexical states for SCLEX_D # Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_ lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0 val SCE_D_DEFAULT=0
@ -313,6 +330,7 @@ val SCE_HJ_SINGLESTRING=49
val SCE_HJ_SYMBOLS=50 val SCE_HJ_SYMBOLS=50
val SCE_HJ_STRINGEOL=51 val SCE_HJ_STRINGEOL=51
val SCE_HJ_REGEX=52 val SCE_HJ_REGEX=52
val SCE_HJ_TEMPLATELITERAL=53
# ASP Javascript # ASP Javascript
val SCE_HJA_START=55 val SCE_HJA_START=55
val SCE_HJA_DEFAULT=56 val SCE_HJA_DEFAULT=56
@ -327,6 +345,7 @@ val SCE_HJA_SINGLESTRING=64
val SCE_HJA_SYMBOLS=65 val SCE_HJA_SYMBOLS=65
val SCE_HJA_STRINGEOL=66 val SCE_HJA_STRINGEOL=66
val SCE_HJA_REGEX=67 val SCE_HJA_REGEX=67
val SCE_HJA_TEMPLATELITERAL=68
# Embedded VBScript # Embedded VBScript
val SCE_HB_START=70 val SCE_HB_START=70
val SCE_HB_DEFAULT=71 val SCE_HB_DEFAULT=71
@ -2004,6 +2023,8 @@ val SCE_RUST_LEXERROR=20
val SCE_RUST_BYTESTRING=21 val SCE_RUST_BYTESTRING=21
val SCE_RUST_BYTESTRINGR=22 val SCE_RUST_BYTESTRINGR=22
val SCE_RUST_BYTECHARACTER=23 val SCE_RUST_BYTECHARACTER=23
val SCE_RUST_CSTRING=24
val SCE_RUST_CSTRINGR=25
# Lexical states for SCLEX_DMAP # Lexical states for SCLEX_DMAP
lex DMAP=SCLEX_DMAP SCE_DMAP_ lex DMAP=SCLEX_DMAP SCE_DMAP_
val SCE_DMAP_DEFAULT=0 val SCE_DMAP_DEFAULT=0
@ -2328,3 +2349,104 @@ val SCE_TOML_TRIPLE_STRING_SQ=11
val SCE_TOML_TRIPLE_STRING_DQ=12 val SCE_TOML_TRIPLE_STRING_DQ=12
val SCE_TOML_ESCAPECHAR=13 val SCE_TOML_ESCAPECHAR=13
val SCE_TOML_DATETIME=14 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_ASCIIDOC 134
#define SCLEX_GDSCRIPT 135 #define SCLEX_GDSCRIPT 135
#define SCLEX_TOML 136 #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 SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0 #define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1 #define SCE_P_COMMENTLINE 1
@ -199,6 +203,19 @@
#define SCE_C_USERLITERAL 25 #define SCE_C_USERLITERAL 25
#define SCE_C_TASKMARKER 26 #define SCE_C_TASKMARKER 26
#define SCE_C_ESCAPESEQUENCE 27 #define SCE_C_ESCAPESEQUENCE 27
#define SCE_COBOL_DEFAULT 0
#define SCE_COBOL_COMMENT 1
#define SCE_COBOL_COMMENTLINE 2
#define SCE_COBOL_COMMENTDOC 3
#define SCE_COBOL_NUMBER 4
#define SCE_COBOL_WORD 5
#define SCE_COBOL_STRING 6
#define SCE_COBOL_CHARACTER 7
#define SCE_COBOL_WORD3 8
#define SCE_COBOL_PREPROCESSOR 9
#define SCE_COBOL_OPERATOR 10
#define SCE_COBOL_IDENTIFIER 11
#define SCE_COBOL_WORD2 16
#define SCE_D_DEFAULT 0 #define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1 #define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2 #define SCE_D_COMMENTLINE 2
@ -289,6 +306,7 @@
#define SCE_HJ_SYMBOLS 50 #define SCE_HJ_SYMBOLS 50
#define SCE_HJ_STRINGEOL 51 #define SCE_HJ_STRINGEOL 51
#define SCE_HJ_REGEX 52 #define SCE_HJ_REGEX 52
#define SCE_HJ_TEMPLATELITERAL 53
#define SCE_HJA_START 55 #define SCE_HJA_START 55
#define SCE_HJA_DEFAULT 56 #define SCE_HJA_DEFAULT 56
#define SCE_HJA_COMMENT 57 #define SCE_HJA_COMMENT 57
@ -302,6 +320,7 @@
#define SCE_HJA_SYMBOLS 65 #define SCE_HJA_SYMBOLS 65
#define SCE_HJA_STRINGEOL 66 #define SCE_HJA_STRINGEOL 66
#define SCE_HJA_REGEX 67 #define SCE_HJA_REGEX 67
#define SCE_HJA_TEMPLATELITERAL 68
#define SCE_HB_START 70 #define SCE_HB_START 70
#define SCE_HB_DEFAULT 71 #define SCE_HB_DEFAULT 71
#define SCE_HB_COMMENTLINE 72 #define SCE_HB_COMMENTLINE 72
@ -1791,6 +1810,8 @@
#define SCE_RUST_BYTESTRING 21 #define SCE_RUST_BYTESTRING 21
#define SCE_RUST_BYTESTRINGR 22 #define SCE_RUST_BYTESTRINGR 22
#define SCE_RUST_BYTECHARACTER 23 #define SCE_RUST_BYTECHARACTER 23
#define SCE_RUST_CSTRING 24
#define SCE_RUST_CSTRINGR 25
#define SCE_DMAP_DEFAULT 0 #define SCE_DMAP_DEFAULT 0
#define SCE_DMAP_COMMENT 1 #define SCE_DMAP_COMMENT 1
#define SCE_DMAP_NUMBER 2 #define SCE_DMAP_NUMBER 2
@ -2074,6 +2095,99 @@
#define SCE_TOML_TRIPLE_STRING_DQ 12 #define SCE_TOML_TRIPLE_STRING_DQ 12
#define SCE_TOML_ESCAPECHAR 13 #define SCE_TOML_ESCAPECHAR 13
#define SCE_TOML_DATETIME 14 #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 */ /* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif #endif

View File

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

View File

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

View File

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

View File

@ -121,7 +121,7 @@ struct BracketPair {
BracketPair FindBracketPair(Tokens &tokens) { BracketPair FindBracketPair(Tokens &tokens) {
const Tokens::iterator itBracket = std::find(tokens.begin(), tokens.end(), "("); const Tokens::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
if (itBracket != tokens.end()) { if (itBracket != tokens.end()) {
size_t nest = 0; ptrdiff_t nest = 0;
for (Tokens::iterator itTok = itBracket; itTok != tokens.end(); ++itTok) { for (Tokens::iterator itTok = itBracket; itTok != tokens.end(); ++itTok) {
if (*itTok == "(") { if (*itTok == "(") {
nest++; nest++;
@ -496,7 +496,7 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0}; const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
LexicalClass lexicalClasses[] = { const LexicalClass lexicalClasses[] = {
// Lexer Cpp SCLEX_CPP SCE_C_: // Lexer Cpp SCLEX_CPP SCE_C_:
0, "SCE_C_DEFAULT", "default", "White space", 0, "SCE_C_DEFAULT", "default", "White space",
1, "SCE_C_COMMENT", "comment", "Comment: /* */.", 1, "SCE_C_COMMENT", "comment", "Comment: /* */.",
@ -528,7 +528,7 @@ LexicalClass lexicalClasses[] = {
27, "SCE_C_ESCAPESEQUENCE", "literal string escapesequence", "Escape sequence", 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; styleBeforeDCKeyword = SCE_C_COMMENTDOC;
sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); 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 || (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style
styleBeforeDCKeyword = SCE_C_COMMENTDOC; styleBeforeDCKeyword = SCE_C_COMMENTDOC;
sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet); 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); Sci_Position lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE; int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0) if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; levelCurrent = FoldLevelStart(styler.LevelAt(lineCurrent-1));
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1); Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1);
int levelMinCurrent = levelCurrent; int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent; int levelNext = levelCurrent;
@ -1583,21 +1583,16 @@ void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int
) { ) {
levelUse = levelMinCurrent; levelUse = levelMinCurrent;
} }
int lev = levelUse | levelNext << 16; const int lev = FoldLevelForCurrentNext(levelUse, levelNext) |
if (visibleChars == 0 && options.foldCompact) FoldLevelFlags(levelUse, levelNext, visibleChars == 0 && options.foldCompact);
lev |= SC_FOLDLEVELWHITEFLAG; styler.SetLevelIfDifferent(lineCurrent, lev);
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++; lineCurrent++;
lineStartNext = styler.LineStart(lineCurrent+1); lineStartNext = styler.LineStart(lineCurrent+1);
levelCurrent = levelNext; levelCurrent = levelNext;
levelMinCurrent = levelCurrent; levelMinCurrent = levelCurrent;
if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) { 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 // 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; visibleChars = 0;
inLineComment = false; inLineComment = false;
@ -1725,7 +1720,7 @@ void LexerCPP::EvaluateTokens(Tokens &tokens, const SymbolTable &preprocessorDef
// Evaluate logical negations // Evaluate logical negations
for (size_t j=0; (j+1)<tokens.size();) { 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()); int isTrue = atoi(tokens[j+1].c_str());
if (tokens[j] == "!") if (tokens[j] == "!")
isTrue = !isTrue; isTrue = !isTrue;
@ -1825,7 +1820,7 @@ Tokens LexerCPP::Tokenize(const std::string &expr) const {
word += *cp; word += *cp;
cp++; cp++;
} }
tokens.push_back(word); tokens.push_back(std::move(word));
} }
return tokens; 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,7 +168,8 @@ void LexerEDIFACT::Lex(Sci_PositionU startPos, Sci_Position length, int, IDocume
{ {
posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish); posCurrent = ForwardPastWhitespace(pAccess, posCurrent, posFinish);
// Mark whitespace as default // Mark whitespace as default
styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT); if (posCurrent > 0)
styler.ColourTo(posCurrent - 1, SCE_EDI_DEFAULT);
if (posCurrent >= posFinish) if (posCurrent >= posFinish)
break; break;

View File

@ -3,7 +3,7 @@
* Lexer for F# 5.0 * Lexer for F# 5.0
* Copyright (c) 2021 Robert Di Pardo <dipardo.r@gmail.com> * 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::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. * The License.txt file describes the conditions under which this software may be distributed.
*/ */
// clang-format off // clang-format off
@ -442,9 +442,13 @@ void SCI_METHOD LexerFSharp::Lex(Sci_PositionU start, Sci_Position length, int i
break; break;
case SCE_FSHARP_LINENUM: case SCE_FSHARP_LINENUM:
case SCE_FSHARP_PREPROCESSOR: case SCE_FSHARP_PREPROCESSOR:
case SCE_FSHARP_COMMENTLINE:
if (sc.MatchLineEnd()) { if (sc.MatchLineEnd()) {
state = SCE_FSHARP_DEFAULT; state = SCE_FSHARP_DEFAULT;
}
break;
case SCE_FSHARP_COMMENTLINE:
if (sc.atLineStart) {
state = SCE_FSHARP_DEFAULT;
advance = false; advance = false;
} }
break; break;
@ -647,27 +651,26 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
} }
LexAccessor styler(pAccess); 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; const Sci_PositionU endPos = start + length;
Sci_Position lineCurrent = styler.GetLine(startPos); 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 lineNext = lineCurrent + 1;
Sci_Position lineStartNext = styler.LineStart(lineNext); Sci_Position lineStartNext = styler.LineStart(lineNext);
int style = initStyle; int style = initStyle;
int styleNext = styler.StyleAt(startPos); int styleNext = styler.StyleAt(startPos);
char chNext = styler[startPos]; char chNext = styler[startPos];
int levelNext; int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = SC_FOLDLEVELBASE; int levelNext = levelCurrent;
int visibleChars = 0; int visibleChars = 0;
if (lineCurrent > 0) { for (Sci_PositionU i = static_cast<Sci_PositionU>(startPos); i < endPos; i++) {
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 0x10;
}
levelNext = levelCurrent;
for (Sci_PositionU i = start; i < endPos; i++) {
const Sci_Position currentPos = static_cast<Sci_Position>(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 bool atLineOrDocEnd = (atEOL || (i == (endPos - 1)));
const int stylePrev = style; const int stylePrev = style;
const char ch = chNext; 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); FoldLexicalGroup(styler, levelNext, lineCurrent, "open ", SCE_FSHARP_KEYWORD);
} }
if (!IsASpace(ch)) {
visibleChars++;
}
if (atLineOrDocEnd) { if (atLineOrDocEnd) {
int levelUse = levelCurrent; int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16; 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) { if (visibleChars == 0 && options.foldCompact) {
lev |= SC_FOLDLEVELWHITEFLAG; lev |= SC_FOLDLEVELWHITEFLAG;
} }
if (levelUse < levelNext) { if ((levelUse < levelNext) && (visibleChars > 0)) {
lev |= SC_FOLDLEVELHEADERFLAG; lev |= SC_FOLDLEVELHEADERFLAG;
} }
if (lev != styler.LevelAt(lineCurrent)) { if (lev != styler.LevelAt(lineCurrent)) {
@ -731,12 +730,14 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
lineNext = lineCurrent + 1; lineNext = lineCurrent + 1;
lineStartNext = styler.LineStart(lineNext); lineStartNext = styler.LineStart(lineNext);
levelCurrent = levelNext; levelCurrent = levelNext;
}
if (atEOL && (currentPos == (styler.Length() - 1))) { if (!IsASpace(ch)) {
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); 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) { 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; 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); const std::string s = styler.GetRangeLowered(start, end+1);
if (Contains(s, "vbs")) if (Contains(s, "vbs"))
return eScriptVBS; return eScriptVBS;
@ -103,13 +103,12 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
return eScriptJS; return eScriptJS;
if (Contains(s, "php")) if (Contains(s, "php"))
return eScriptPHP; return eScriptPHP;
if (Contains(s, "xml")) {
const size_t xml = s.find("xml"); const size_t xml = s.find("xml");
if (xml != std::string::npos) { if (xml != std::string::npos) {
for (size_t t = 0; t < xml; t++) { for (size_t t = 0; t < xml; t++) {
if (!IsASpace(s[t])) { if (!IsASpace(s[t])) {
return prevValue; return prevValue;
}
} }
} }
return eScriptXML; return eScriptXML;
@ -118,13 +117,8 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
return prevValue; return prevValue;
} }
int PrintScriptingIndicatorOffset(Accessor &styler, Sci_PositionU start, Sci_PositionU end) { constexpr bool IsPHPScriptState(int state) noexcept {
int iResult = 0; return (state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_OPERATOR) || (state == SCE_HPHP_COMPLEX_VARIABLE);
const std::string s = styler.GetRangeLowered(start, end+1);
if (0 == strncmp(s.c_str(), "php", 3)) {
iResult = 3;
}
return iResult;
} }
script_type ScriptOfState(int state) noexcept { script_type ScriptOfState(int state) noexcept {
@ -132,9 +126,9 @@ script_type ScriptOfState(int state) noexcept {
return eScriptPython; return eScriptPython;
} else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) { } else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) {
return eScriptVBS; return eScriptVBS;
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {
return eScriptJS; return eScriptJS;
} else if ((state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_COMMENTLINE) || (state == SCE_HPHP_COMPLEX_VARIABLE)) { } else if (IsPHPScriptState(state)) {
return eScriptPHP; return eScriptPHP;
} else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) { } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
return eScriptSGML; return eScriptSGML;
@ -153,7 +147,7 @@ constexpr int statePrintForState(int state, script_mode inScriptType) noexcept {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON);
} else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS);
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {
StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS);
} }
} }
@ -168,7 +162,7 @@ constexpr int stateForPrintState(int StateToPrint) noexcept {
state = StateToPrint - SCE_HA_PYTHON; state = StateToPrint - SCE_HA_PYTHON;
} else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) { } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
state = StateToPrint - SCE_HA_VBS; 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; state = StateToPrint - SCE_HA_JS;
} }
@ -185,8 +179,12 @@ constexpr bool isStringState(int state) noexcept {
switch (state) { switch (state) {
case SCE_HJ_DOUBLESTRING: case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING: case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX:
case SCE_HJ_TEMPLATELITERAL:
case SCE_HJA_DOUBLESTRING: case SCE_HJA_DOUBLESTRING:
case SCE_HJA_SINGLESTRING: case SCE_HJA_SINGLESTRING:
case SCE_HJA_REGEX:
case SCE_HJA_TEMPLATELITERAL:
case SCE_HB_STRING: case SCE_HB_STRING:
case SCE_HBA_STRING: case SCE_HBA_STRING:
case SCE_HP_STRING: case SCE_HP_STRING:
@ -454,12 +452,12 @@ void classifyWordHTPHP(Sci_PositionU start, Sci_PositionU end, const WordList &k
styler.ColourTo(end, chAttr); 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); const std::string s = styler.GetRange(start, end + 1);
return keywords.InList(s); 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); const std::string s = styler.GetRange(start, end + 1);
return s == "[CDATA["; return s == "[CDATA[";
} }
@ -492,9 +490,13 @@ constexpr int StateForScript(script_type scriptLanguage) noexcept {
return Result; 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 { constexpr bool issgmlwordchar(int ch) noexcept {
return !IsASCII(ch) || return !IsASCII(ch) ||
(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '['); (IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
} }
constexpr bool IsPhpWordStart(int ch) noexcept { constexpr bool IsPhpWordStart(int ch) noexcept {
@ -512,15 +514,6 @@ constexpr bool InTagState(int state) noexcept {
SCE_H_DOUBLESTRING, SCE_H_SINGLESTRING); 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 { constexpr bool isLineEnd(int ch) noexcept {
return ch == '\r' || ch == '\n'; return ch == '\r' || ch == '\n';
} }
@ -675,28 +668,41 @@ constexpr bool isPHPStringState(int state) noexcept {
(state == SCE_HPHP_COMPLEX_VARIABLE); (state == SCE_HPHP_COMPLEX_VARIABLE);
} }
constexpr bool StyleNeedsBacktrack(int state) noexcept {
return InTagState(state) || isPHPStringState(state);
}
enum class AllowPHP : int { enum class AllowPHP : int {
None, // No PHP None, // No PHP
PHP, // <?php and <?= PHP, // <?php and <?=
Question, // <? Question, // <?
}; };
constexpr bool IsPHPEntryState(int state) noexcept { enum class InstructionTag {
return !(isPHPStringState(state) || IsScriptCommentState(state) || AnyOf(state, SCE_H_ASPAT, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE)); None,
} XML,
Open,// <? ?> short open tag
Echo,// <?= ?> short echo tag
PHP, // <?php ?> standard tag
};
bool IsPHPStart(AllowPHP allowPHP, Accessor &styler, Sci_PositionU start) { InstructionTag segIsScriptInstruction(AllowPHP allowPHP, int state, const Accessor &styler, Sci_PositionU start, bool isXml) {
if (allowPHP == AllowPHP::None) { constexpr std::string_view phpTag = "php";
return false; constexpr std::string_view xmlTag = "xml";
} const std::string tag = styler.GetRangeLowered(start, start + phpTag.length());
if (allowPHP == AllowPHP::PHP) { if (allowPHP != AllowPHP::None) {
// Require <?php or <?= // Require <?php or <?=
constexpr std::string_view phpTag = "<?php"; if (tag == phpTag) {
constexpr std::string_view echoTag = "<?="; return InstructionTag::PHP;
const std::string tag = styler.GetRangeLowered(start, start + phpTag.length()); }
return (tag == phpTag) || (tag.substr(0, echoTag.length()) == echoTag); if (!tag.empty() && (tag.front() == '=')) {
return InstructionTag::Echo;
}
} }
return true; 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) { 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", 50, "SCE_HJ_SYMBOLS", "client javascript operator", "JS Symbols",
51, "SCE_HJ_STRINGEOL", "client javascript error literal string", "JavaScript EOL", 51, "SCE_HJ_STRINGEOL", "client javascript error literal string", "JavaScript EOL",
52, "SCE_HJ_REGEX", "client javascript literal regex", "JavaScript RegEx", 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", "", 54, "", "unused", "",
55, "SCE_HJA_START", "server javascript default", "JS Start - allows eol filled background to not start on same line as SCRIPT tag", 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", 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", 65, "SCE_HJA_SYMBOLS", "server javascript operator", "JS Symbols",
66, "SCE_HJA_STRINGEOL", "server javascript error literal string", "JavaScript EOL", 66, "SCE_HJA_STRINGEOL", "server javascript error literal string", "JavaScript EOL",
67, "SCE_HJA_REGEX", "server javascript literal regex", "JavaScript RegEx", 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", "", 69, "", "unused", "",
70, "SCE_HB_START", "client basic default", "Start", 70, "SCE_HB_START", "client basic default", "Start",
71, "SCE_HB_DEFAULT", "client basic default", "Default", 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)) { if (isPHPScript && (startPos == 0)) {
initStyle = SCE_HPHP_DEFAULT; initStyle = SCE_HPHP_DEFAULT;
} }
styler.StartAt(startPos);
std::string lastTag; std::string lastTag;
std::string prevWord; std::string prevWord;
PhpNumberState phpNumber; PhpNumberState phpNumber;
@ -1199,23 +1204,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
int makoComment = 0; int makoComment = 0;
std::string djangoBlockType; std::string djangoBlockType;
// If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen // If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen
if (InTagState(state)) { // PHP string can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
while ((startPos > 0) && (InTagState(styler.StyleIndexAt(startPos - 1)))) { if (StyleNeedsBacktrack(state)) {
while ((startPos > 0) && (StyleNeedsBacktrack(styler.StyleIndexAt(startPos - 1)))) {
const Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1)); const Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1));
length += startPos - backLineStart; length += startPos - backLineStart;
startPos = backLineStart; startPos = backLineStart;
} }
state = SCE_H_DEFAULT; if (startPos > 0) {
} state = styler.StyleIndexAt(startPos - 1);
// String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState } else {
if (isPHPStringState(state)) { state = isPHPScript ? SCE_HPHP_DEFAULT : SCE_H_DEFAULT;
while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) {
startPos--;
length++;
state = styler.StyleIndexAt(startPos);
} }
if (startPos == 0)
state = SCE_H_DEFAULT;
} }
styler.StartAt(startPos); styler.StartAt(startPos);
@ -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 script_type clientScript = static_cast<script_type>((lineState >> 8) & 0x0F); // 4 bits of script name
int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
bool isLanguageType = (lineState >> 20) & 1; // type or language attribute for script tag bool isLanguageType = (lineState >> 20) & 1; // type or language attribute for script tag
int sgmlBlockLevel = (lineState >> 21);
script_type scriptLanguage = ScriptOfState(state); script_type scriptLanguage = ScriptOfState(state);
// If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment // 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: case eScriptPHP:
//not currently supported case eScriptVBS: //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)) { !isStringState(state)) {
//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle); //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)) { //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) | ((aspScript & 0x0F) << 4) |
((clientScript & 0x0F) << 8) | ((clientScript & 0x0F) << 8) |
((beforePreProc & 0xFF) << 12) | ((beforePreProc & 0xFF) << 12) |
((isLanguageType ? 1 : 0) << 20)); ((isLanguageType ? 1 : 0) << 20) |
(sgmlBlockLevel << 21));
lineCurrent++; lineCurrent++;
lineStartVisibleChars = 0; 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_DOUBLESTRING:
case SCE_HJ_SINGLESTRING: case SCE_HJ_SINGLESTRING:
case SCE_HJ_REGEX: case SCE_HJ_REGEX:
case SCE_HJ_TEMPLATELITERAL:
case SCE_HB_STRING: case SCE_HB_STRING:
case SCE_HBA_STRING: case SCE_HBA_STRING:
case SCE_HP_STRING: case SCE_HP_STRING:
@ -1496,31 +1499,35 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
///////////////////////////////////// /////////////////////////////////////
// handle the start of PHP pre-processor = Non-HTML // 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)) {
beforeLanguage = scriptLanguage; const InstructionTag tag = segIsScriptInstruction(allowPHP, state, styler, i + 2, isXml);
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP); if (tag != InstructionTag::None) {
if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue; beforeLanguage = scriptLanguage;
styler.ColourTo(i - 1, StateToPrint); scriptLanguage = (tag == InstructionTag::XML) ? eScriptXML : eScriptPHP;
beforePreProc = state; styler.ColourTo(i - 1, StateToPrint);
i++; beforePreProc = state;
visibleChars++; i++;
i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6); visibleChars++;
if (scriptLanguage == eScriptXML) if (tag >= InstructionTag::Echo) {
styler.ColourTo(i, SCE_H_XMLSTART); i += (tag == InstructionTag::Echo) ? 1 : 3;
else }
styler.ColourTo(i, SCE_H_QUESTION); if (scriptLanguage == eScriptXML)
state = StateForScript(scriptLanguage); styler.ColourTo(i, SCE_H_XMLSTART);
if (inScriptType == eNonHtmlScript) else
inScriptType = eNonHtmlScriptPreProc; styler.ColourTo(i, SCE_H_QUESTION);
else state = StateForScript(scriptLanguage);
inScriptType = eNonHtmlPreProc; if (inScriptType == eNonHtmlScript)
// Fold whole script, but not if the XML first tag (all XML-like tags in this case) inScriptType = eNonHtmlScriptPreProc;
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { else
levelCurrent++; inScriptType = eNonHtmlPreProc;
// Fold whole script, but not if the XML first tag (all XML-like tags in this case)
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent++;
}
// should be better
ch = SafeGetUnsignedCharAt(styler, i);
continue;
} }
// should be better
ch = SafeGetUnsignedCharAt(styler, i);
continue;
} }
// handle the start Mako template Python code // handle the start Mako template Python code
@ -1662,16 +1669,13 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
///////////////////////////////////// /////////////////////////////////////
// handle the start of SGML language (DTD) // handle the start of SGML language (DTD)
else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) && else if (AnyOf(scriptLanguage, eScriptNone, eScriptXML, eScriptSGMLblock) &&
(chPrev == '<') && (chPrev == '<') &&
(ch == '!') && (ch == '!') &&
(StateToPrint != SCE_H_CDATA) && AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)) {
(!isStringState(StateToPrint)) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint))) {
beforePreProc = state; beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint); 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 state = SCE_H_COMMENT; // wait for a pending command
styler.ColourTo(i + 2, SCE_H_COMMENT); styler.ColourTo(i + 2, SCE_H_COMMENT);
i += 2; // follow styling after the -- i += 2; // follow styling after the --
@ -1687,12 +1691,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
ch = '-'; 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; state = SCE_H_CDATA;
} else { } else {
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
beforeLanguage = scriptLanguage;
scriptLanguage = eScriptSGML; 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) // fold whole tag (-- when closing the tag)
if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA) 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)) && else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) && (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
((chNext == '>') && isPreProcessorEndTag(state, ch))) || ((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) { if (state == SCE_H_ASPAT) {
aspScript = segIsScriptingIndicator(styler, aspScript = segIsScriptingIndicator(styler,
styler.GetStartSegment(), i - 1, aspScript); 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); styler.ColourTo(i - 2, StateToPrint);
} }
state = SCE_H_SGML_COMMENT; state = SCE_H_SGML_COMMENT;
} else if (IsUpperOrLowerCase(ch) && (chPrev == '%')) { } else if (ch == '%' && IsUpperOrLowerCase(chNext)) {
styler.ColourTo(i - 2, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_ENTITY; state = SCE_H_SGML_ENTITY;
} else if (ch == '#') { } else if (ch == '#') {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_SPECIAL; state = SCE_H_SGML_SPECIAL;
} else if (ch == '[') { } else if (ch == '[') {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
++sgmlBlockLevel;
scriptLanguage = eScriptSGMLblock; scriptLanguage = eScriptSGMLblock;
state = SCE_H_SGML_BLOCK_DEFAULT; state = SCE_H_SGML_BLOCK_DEFAULT;
} else if (ch == ']') { } else if (ch == ']') {
if (scriptLanguage == eScriptSGMLblock) { if (sgmlBlockLevel > 0) {
styler.ColourTo(i, StateToPrint); --sgmlBlockLevel;
if (sgmlBlockLevel == 0) {
beforePreProc = SCE_H_DEFAULT;
}
styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
scriptLanguage = eScriptSGML; scriptLanguage = eScriptSGML;
} else { } else {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
styler.ColourTo(i, SCE_H_SGML_ERROR); styler.ColourTo(i, SCE_H_SGML_ERROR);
} }
state = SCE_H_SGML_DEFAULT; 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; break;
case SCE_H_SGML_COMMAND: case SCE_H_SGML_COMMAND:
if ((ch == '-') && (chPrev == '-')) { if (!issgmlwordchar(ch)) {
styler.ColourTo(i - 2, StateToPrint);
state = SCE_H_SGML_COMMENT;
} else if (!issgmlwordchar(ch)) {
if (isWordHSGML(styler.GetStartSegment(), i - 1, keywordsSGML, styler)) { if (isWordHSGML(styler.GetStartSegment(), i - 1, keywordsSGML, styler)) {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_H_SGML_1ST_PARAM; 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: case SCE_H_SGML_1ST_PARAM:
// wait for the beginning of the word // wait for the beginning of the word
if ((ch == '-') && (chPrev == '-')) { if ((ch == '-') && (chPrev == '-')) {
if (scriptLanguage == eScriptSGMLblock) { styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
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; state = SCE_H_SGML_1ST_PARAM_COMMENT;
} else if (issgmlwordchar(ch)) { } else if (issgmlwordchar(ch)) {
if (scriptLanguage == eScriptSGMLblock) { styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
} else {
styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
}
// find the length of the word // find the length of the word
Sci_Position size = 1; Sci_Position size = 1;
while (setHTMLWord.Contains(SafeGetUnsignedCharAt(styler, i + size))) 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; i += size - 1;
visibleChars += size - 1; visibleChars += size - 1;
ch = SafeGetUnsignedCharAt(styler, i); ch = SafeGetUnsignedCharAt(styler, i);
if (scriptLanguage == eScriptSGMLblock) { state = SCE_H_SGML_DEFAULT;
state = SCE_H_SGML_BLOCK_DEFAULT;
} else {
state = SCE_H_SGML_DEFAULT;
}
continue; continue;
} }
break; break;
@ -1985,12 +1978,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} }
break; break;
case SCE_H_SGML_ENTITY: case SCE_H_SGML_ENTITY:
if (ch == ';') { if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.' && ch != '_') {
styler.ColourTo(i, StateToPrint); styler.ColourTo(i, ((ch == ';') ? StateToPrint : SCE_H_SGML_ERROR));
state = SCE_H_SGML_DEFAULT; state = defaultStateForSGML(scriptLanguage);
} else if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.') {
styler.ColourTo(i, SCE_H_SGML_ERROR);
state = SCE_H_SGML_DEFAULT;
} }
break; break;
case SCE_H_ENTITY: case SCE_H_ENTITY:
@ -2203,14 +2193,11 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_WORD; state = SCE_HJ_WORD;
} else if (ch == '/' && chNext == '*') { } else if (ch == '/' && chNext == '*') {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
i++;
if (chNext2 == '*') if (chNext2 == '*')
state = SCE_HJ_COMMENTDOC; state = SCE_HJ_COMMENTDOC;
else else
state = SCE_HJ_COMMENT; state = SCE_HJ_COMMENT;
if (chNext2 == '/') {
// Eat the * so it isn't used for the end of the comment
i++;
}
} else if (ch == '/' && chNext == '/') { } else if (ch == '/' && chNext == '/') {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE; state = SCE_HJ_COMMENTLINE;
@ -2223,6 +2210,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} else if (ch == '\'') { } else if (ch == '\'') {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_SINGLESTRING; state = SCE_HJ_SINGLESTRING;
} else if (ch == '`') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_TEMPLATELITERAL;
} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
styler.SafeGetCharAt(i + 3) == '-') { styler.SafeGetCharAt(i + 3) == '-') {
styler.ColourTo(i - 1, StateToPrint); 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); //styler.ColourTo(i - 1, eHTJSKeyword);
state = SCE_HJ_DEFAULT; state = SCE_HJ_DEFAULT;
if (ch == '/' && chNext == '*') { if (ch == '/' && chNext == '*') {
i++;
if (chNext2 == '*') if (chNext2 == '*')
state = SCE_HJ_COMMENTDOC; state = SCE_HJ_COMMENTDOC;
else else
@ -2259,6 +2250,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_DOUBLESTRING; state = SCE_HJ_DOUBLESTRING;
} else if (ch == '\'') { } else if (ch == '\'') {
state = SCE_HJ_SINGLESTRING; state = SCE_HJ_SINGLESTRING;
} else if (ch == '`') {
state = SCE_HJ_TEMPLATELITERAL;
} else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
styler.ColourTo(i - 1, StateToPrint); styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE; state = SCE_HJ_COMMENTLINE;
@ -2314,6 +2307,16 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
} }
} }
break; 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: case SCE_HJ_STRINGEOL:
if (!isLineEnd(ch)) { if (!isLineEnd(ch)) {
styler.ColourTo(i - 1, StateToPrint); 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); styler.ColourTo(i, StateToPrint);
state = SCE_HJ_DEFAULT; state = SCE_HJ_DEFAULT;
continue;
} else if (ch == '\\') { } else if (ch == '\\') {
// Gobble up the quoted character // Gobble up the quoted character
if (chNext == '\\' || chNext == '/') { if (chNext == '\\' || chNext == '/') {
@ -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 } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
if (ch == '/' && chNext == '*') { if (ch == '/' && chNext == '*') {
if (styler.SafeGetCharAt(i + 2) == '*') i++;
if (styler.SafeGetCharAt(i + 1) == '*')
state = SCE_HJ_COMMENTDOC; state = SCE_HJ_COMMENTDOC;
else else
state = SCE_HJ_COMMENT; state = SCE_HJ_COMMENT;
@ -2721,6 +2726,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
state = SCE_HJ_DOUBLESTRING; state = SCE_HJ_DOUBLESTRING;
} else if ((ch == '\'') && (nonEmptySegment)) { } else if ((ch == '\'') && (nonEmptySegment)) {
state = SCE_HJ_SINGLESTRING; state = SCE_HJ_SINGLESTRING;
} else if ((ch == '`') && (nonEmptySegment)) {
state = SCE_HJ_TEMPLATELITERAL;
} else if (IsAWordStart(ch)) { } else if (IsAWordStart(ch)) {
state = SCE_HJ_WORD; state = SCE_HJ_WORD;
} else if (IsOperator(ch)) { } else if (IsOperator(ch)) {

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