Update: Scintilla 5.3.6 and Lexilla 5.2.6

update to Scinitlla Release 5.3.6 (https://www.scintilla.org/scintilla536.zip)

    Released 26 July 2023.
    Redraw calltip after showing as didn't update when size of new text exactly same as previous. Feature #1486.
    On Win32 fix reverse arrow cursor when scaled. Bug #2382.
    On Win32 hide cursor when typing if that system preference has been chosen. Bug #2333.
    On Win32 and Qt, stop aligning IME candidate window to target. It is now always aligned to start of composition string. This undoes part of feature #1300. Feature #1488, Bug #2391, Feature #1300.
    On Qt, for IMEs, update micro focus when selection changes. This may move the location of IME popups to align with the caret.
    On Qt, implement replacement for IMEs which may help with actions like reconversion. This is similar to delete-surrounding on GTK.

and Lexilla Release 5.2.6 (https://www.scintilla.org/lexilla526.zip)

    Released 26 July 2023.
    Include empty word list names in value returned by DescribeWordListSets and SCI_DESCRIBEKEYWORDSETS. Issue #175, Pull request #176.
    Bash: style here-doc end delimiters as SCE_SH_HERE_DELIM instead of SCE_SH_HERE_Q. Issue #177.
    Bash: allow '$' as last character in string. Issue #180, Pull request #181.
    Bash: fix state after expansion. Highlight all numeric and file test operators. Don't highlight dash in long option as operator. Issue #182, Pull request #183.
    Bash: strict checking of special parameters ($*, $@, $$, ...) with property lexer.bash.special.parameter to specify valid parameters. Issue #184, Pull request #186.
    Bash: recognize keyword before redirection operators (< and >). Issue #188, Pull request #189.
    Errorlist: recognize Bash diagnostic messages.
    HTML: allow ASP block to terminate inside line comment. Issue #185.
    HTML: fix folding with JSP/ASP.NET <%-- comment. Issue #191.
    HTML: fix incremental styling of multi-line ASP.NET directive. Issue #191.
    Matlab: improve arguments blocks. Add support for multiple arguments blocks. Prevent "arguments" from being keyword in function declaration line. Fix semicolon handling. Pull request #179.
    Visual Prolog: add support for embedded syntax with SCE_VISUALPROLOG_EMBEDDED and SCE_VISUALPROLOG_PLACEHOLDER.
    Styling of string literals changed with no differentiation between literals with quotes and those that are prefixed with "@". Quote characters are in a separate style (SCE_VISUALPROLOG_STRING_QUOTE) to contents (SCE_VISUALPROLOG_STRING).
    SCE_VISUALPROLOG_CHARACTER, SCE_VISUALPROLOG_CHARACTER_TOO_MANY, SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR, SCE_VISUALPROLOG_STRING_EOL_OPEN, and SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL were removed (replaced with SCE_VISUALPROLOG_UNUSED[1-5]). Pull request #178.

Fix #13901, fix #13911, fix #13943, close #13940
This commit is contained in:
Christian Grasser 2023-07-27 19:57:12 +02:00 committed by Don Ho
parent 50a15f2e59
commit cc1a3c826b
101 changed files with 1885 additions and 759 deletions

View File

@ -25,6 +25,7 @@
**.folded text
**.adoc text
**.asp text
**.aspx text
**.php text
**.vb text
**.cmake text

View File

@ -1,5 +1,6 @@
// File to suppress cppcheck warnings for files that will not be fixed.
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
// Configured for cppcheck 2.11
// Coding style is to use assignments in constructor when there are many
// members to initialize or the initialization is complex or has comments.
@ -17,103 +18,140 @@ noExplicitConstructor
// code legibility.
passedByValue
// cppcheck 2.11 can't find system headers on Win32.
missingIncludeSystem
// cppcheck seems to believe that unique_ptr<char *[]>::get returns void* instead of char**
arithOperationsOnVoidPointer:lexilla/lexlib/WordList.cxx
// This could be fixed but it should be rewritten to use string_view which doesn't have resize
uselessCallsSubstr:lexilla/lexers/LexCPP.cxx
// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that
// only finds one false issue in LexRuby
checkLevelNormal:lexilla/lexers/LexBash.cxx
checkLevelNormal:lexilla/lexers/LexCPP.cxx
checkLevelNormal:lexilla/lexers/LexHTML.cxx
checkLevelNormal:lexilla/lexers/LexPerl.cxx
checkLevelNormal:lexilla/lexers/LexRuby.cxx
// Cppcheck wrongly assumes string_view::remove_prefix can not empty the view
knownConditionTrueFalse:lexilla/test/TestLexers.cxx
// Suppress most lexer warnings since the lexers are maintained by others
redundantCondition:lexilla/lexers/LexA68k.cxx
constParameter:lexilla/lexers/LexAbaqus.cxx
constParameterReference:lexilla/lexers/LexAbaqus.cxx
constParameterReference:lexilla/lexers/LexAsciidoc.cxx
constParameterCallback:lexilla/lexers/LexAsn1.cxx
knownConditionTrueFalse:lexilla/lexers/LexAU3.cxx
shadowVariable:lexilla/lexers/LexAU3.cxx
constParameter:lexilla/lexers/LexBaan.cxx
constParameterReference:lexilla/lexers/LexBaan.cxx
unreadVariable:lexilla/lexers/LexBaan.cxx
constParameter:lexilla/lexers/LexBash.cxx
variableScope:lexilla/lexers/LexBaan.cxx
constParameterPointer:lexilla/lexers/LexBaan.cxx
constParameterReference:lexilla/lexers/LexBash.cxx
variableScope:lexilla/lexers/LexBash.cxx
constVariable:lexilla/lexers/LexBasic.cxx
variableScope:lexilla/lexers/LexCmake.cxx
knownConditionTrueFalse:lexilla/lexers/LexCmake.cxx
constParameter:lexilla/lexers/LexCLW.cxx
constParameterReference:lexilla/lexers/LexCLW.cxx
knownConditionTrueFalse:lexilla/lexers/LexCLW.cxx
constParameter:lexilla/lexers/LexCoffeeScript.cxx
constParameterReference:lexilla/lexers/LexCoffeeScript.cxx
constParameterPointer:lexilla/lexers/LexCoffeeScript.cxx
knownConditionTrueFalse:lexilla/lexers/LexCoffeeScript.cxx
constParameter:lexilla/lexers/LexCPP.cxx
constParameterReference:lexilla/lexers/LexCPP.cxx
variableScope:lexilla/lexers/LexCSS.cxx
variableScope:lexilla/lexers/LexDataflex.cxx
knownConditionTrueFalse:lexilla/lexers/LexECL.cxx
variableScope:lexilla/lexers/LexECL.cxx
constParameterPointer:lexilla/lexers/LexEDIFACT.cxx
knownConditionTrueFalse:lexilla/lexers/LexEiffel.cxx
variableScope:lexilla/lexers/LexErlang.cxx
knownConditionTrueFalse:lexilla/lexers/LexErrorList.cxx
knownConditionTrueFalse:lexilla/lexers/LexEScript.cxx
constParameter:lexilla/lexers/LexFortran.cxx
constParameterReference:lexilla/lexers/LexFortran.cxx
redundantContinue:lexilla/lexers/LexFortran.cxx
knownConditionTrueFalse:lexilla/lexers/LexFSharp.cxx
constParameter:lexilla/lexers/LexGDScript.cxx
constParameterReference:lexilla/lexers/LexGDScript.cxx
variableScope:lexilla/lexers/LexGui4Cli.cxx
constParameter:lexilla/lexers/LexHaskell.cxx
constParameter:lexilla/lexers/LexHex.cxx
constParameterReference:lexilla/lexers/LexHaskell.cxx
constParameterReference:lexilla/lexers/LexHex.cxx
knownConditionTrueFalse:lexilla/lexers/LexHex.cxx
constParameter:lexilla/lexers/LexHTML.cxx
constParameterReference:lexilla/lexers/LexHTML.cxx
constVariable:lexilla/lexers/LexHollywood.cxx
variableScope:lexilla/lexers/LexInno.cxx
constParameter:lexilla/lexers/LexJulia.cxx
constParameterReference:lexilla/lexers/LexJulia.cxx
knownConditionTrueFalse:lexilla/lexers/LexJulia.cxx
unreadVariable:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexJulia.cxx
variableScope:lexilla/lexers/LexLaTeX.cxx
constParameter:lexilla/lexers/LexLaTeX.cxx
constParameter:lexilla/lexers/LexMagik.cxx
constParameter:lexilla/lexers/LexMatlab.cxx
constParameterReference:lexilla/lexers/LexLaTeX.cxx
constParameterReference:lexilla/lexers/LexMagik.cxx
constParameterReference:lexilla/lexers/LexMarkdown.cxx
constParameterReference:lexilla/lexers/LexMatlab.cxx
unreadVariable:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMatlab.cxx
variableScope:lexilla/lexers/LexMetapost.cxx
constParameter:lexilla/lexers/LexModula.cxx
constParameterReference:lexilla/lexers/LexModula.cxx
variableScope:lexilla/lexers/LexModula.cxx
constParameterReference:lexilla/lexers/LexMPT.cxx
variableScope:lexilla/lexers/LexMSSQL.cxx
shadowArgument:lexilla/lexers/LexMySQL.cxx
constParameter:lexilla/lexers/LexNim.cxx
constParameter:lexilla/lexers/LexNimrod.cxx
constParameterReference:lexilla/lexers/LexNim.cxx
constParameterReference:lexilla/lexers/LexNimrod.cxx
knownConditionTrueFalse:lexilla/lexers/LexNimrod.cxx
variableScope:lexilla/lexers/LexNimrod.cxx
variableScope:lexilla/lexers/LexNsis.cxx
knownConditionTrueFalse:lexilla/lexers/LexNsis.cxx
variableScope:lexilla/lexers/LexOpal.cxx
constParameter:lexilla/lexers/LexOScript.cxx
knownConditionTrueFalse:lexilla/lexers/LexOpal.cxx
constParameterReference:lexilla/lexers/LexOScript.cxx
variableScope:lexilla/lexers/LexPB.cxx
constParameter:lexilla/lexers/LexPerl.cxx
constParameterReference:lexilla/lexers/LexPerl.cxx
knownConditionTrueFalse:lexilla/lexers/LexPerl.cxx
constParameter:lexilla/lexers/LexPython.cxx
constParameterReference:lexilla/lexers/LexPO.cxx
constParameterReference:lexilla/lexers/LexPython.cxx
shadowVariable:lexilla/lexers/LexPowerPro.cxx
knownConditionTrueFalse:lexilla/lexers/LexPowerPro.cxx
variableScope:lexilla/lexers/LexProgress.cxx
constParameter:lexilla/lexers/LexRaku.cxx
constParameterReference:lexilla/lexers/LexRaku.cxx
variableScope:lexilla/lexers/LexRaku.cxx
redundantInitialization:lexilla/lexers/LexRegistry.cxx
constParameter:lexilla/lexers/LexRuby.cxx
knownConditionTrueFalse:lexilla/lexers/LexRuby.cxx
constParameter:lexilla/lexers/LexRust.cxx
constParameterReference:lexilla/lexers/LexRuby.cxx
constParameterReference:lexilla/lexers/LexRust.cxx
knownConditionTrueFalse:lexilla/lexers/LexScriptol.cxx
variableScope:lexilla/lexers/LexSpecman.cxx
unreadVariable:lexilla/lexers/LexSpice.cxx
constParameter:lexilla/lexers/LexSTTXT.cxx
constParameterReference:lexilla/lexers/LexSTTXT.cxx
knownConditionTrueFalse:lexilla/lexers/LexTACL.cxx
clarifyCalculation:lexilla/lexers/LexTADS3.cxx
constParameter:lexilla/lexers/LexTADS3.cxx
constParameterReference:lexilla/lexers/LexTADS3.cxx
unreadVariable:lexilla/lexers/LexTCL.cxx
invalidscanf:lexilla/lexers/LexTCMD.cxx
constParameter:lexilla/lexers/LexTeX.cxx
constParameterPointer:lexilla/lexers/LexTCMD.cxx
constParameterReference:lexilla/lexers/LexTeX.cxx
variableScope:lexilla/lexers/LexTeX.cxx
knownConditionTrueFalse:lexilla/lexers/LexTxt2tags.cxx
knownConditionTrueFalse:lexilla/lexers/LexVB.cxx
constParameter:lexilla/lexers/LexVerilog.cxx
constParameterReference:lexilla/lexers/LexVerilog.cxx
variableScope:lexilla/lexers/LexVerilog.cxx
badBitmaskCheck:lexilla/lexers/LexVerilog.cxx
uselessCallsSubstr:lexilla/lexers/LexVerilog.cxx
constParameter:lexilla/lexers/LexVHDL.cxx
constParameterReference:lexilla/lexers/LexVHDL.cxx
constVariable:lexilla/lexers/LexVHDL.cxx
shadowVariable:lexilla/lexers/LexVHDL.cxx
unreadVariable:lexilla/lexers/LexVHDL.cxx
variableScope:lexilla/lexers/LexVHDL.cxx
unreadVariable:lexilla/lexers/LexVisualProlog.cxx
variableScope:lexilla/lexers/LexVisualProlog.cxx
shiftTooManyBitsSigned:lexilla/lexers/LexVisualProlog.cxx
unreadVariable:lexilla/lexers/LexX12.cxx
constVariable:lexilla/lexers/LexX12.cxx
constVariableReference:lexilla/lexers/LexX12.cxx
constParameterPointer:lexilla/lexers/LexX12.cxx
uselessCallsSubstr:lexilla/lexers/LexX12.cxx
constParameter:lexilla/lexers/LexYAML.cxx
constParameterReference:lexilla/lexers/LexYAML.cxx
constParameterPointer:lexilla/lexers/LexYAML.cxx
knownConditionTrueFalse:lexilla/lexers/LexYAML.cxx
// These are due to Accessor::IndentAmount not declaring the callback as taking a const.
@ -124,15 +162,12 @@ constParameterCallback:lexilla/lexers/LexPython.cxx
constParameterCallback:lexilla/lexers/LexScriptol.cxx
constParameterCallback:lexilla/lexers/LexVB.cxx
constVariable:lexilla/lexers/LexCSS.cxx
constVariable:lexilla/lexers/LexCrontab.cxx
constVariable:lexilla/lexers/LexGui4Cli.cxx
constVariable:lexilla/lexers/LexKix.cxx
constVariable:lexilla/lexers/LexMetapost.cxx
constVariable:lexilla/lexers/LexOpal.cxx
// cppcheck appears wrong as atKeyPath must be remembered between loops
variableScope:lexilla/lexers/LexRegistry.cxx
constVariableReference:lexilla/lexers/LexCSS.cxx
constVariableReference:lexilla/lexers/LexCrontab.cxx
constVariableReference:lexilla/lexers/LexGui4Cli.cxx
constVariableReference:lexilla/lexers/LexKix.cxx
constVariableReference:lexilla/lexers/LexMetapost.cxx
constVariableReference:lexilla/lexers/LexOpal.cxx
// Suppress everything in test example files
*:lexilla/test/examples/*

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20230531" />
<meta name="Date.Modified" content="20230726" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -61,8 +61,8 @@
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3">Release version 5.2.5<br />
Site last modified May 31 2023</font>
<font color="#FFCC99" size="3">Release version 5.2.6<br />
Site last modified July 26 2023</font>
</td>
<td width="20%">
&nbsp;
@ -77,12 +77,11 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.2.6 improves Bash, Errorlist, HTML, Matlab, and Visual Prolog.</li>
<li>Version 5.2.5 improves Bash, Batch, F#, and VB.</li>
<li>Version 5.2.4 improves C++ and GDScript.</li>
<li>Version 5.2.3 improves Makefile, Ruby, and YAML.</li>
<li>Version 5.2.2 improves C++, Matlab, Modula-3, Python, and X12.</li>
<li>Version 5.2.1 improves Batch, F#, Markdown, and PowerShell.</li>
<li>Version 5.2.0 improves PowerShell and R.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -99,7 +99,7 @@
<code>void <span class="name">SetLibraryProperty</span>(const char *key, const char *value)</code><br />
<code>const char *<span class="name">GetNameSpace</span>()</code>
</p>
<p><span class="name">ILexer5</span> is defined by Scintilla in include/ILexer.h as the interface provided by lexers which is called by Scintilla.
Many clients do not actually need to call methods on <span class="name">ILexer5</span> - they just take the return from CreateLexer and plug it
straight into Scintilla so it can be treated as a machine pointer (void *).
@ -109,22 +109,22 @@
<code>ILexer5 *(*LexerFactoryFunction)()</code> but this can be ignored by most client code.
</p>
<p>The Lexilla protocol is a superset of the earlier external lexer protocol that defined the first 3 functions
<p>The Lexilla protocol is a superset of the earlier external lexer protocol that defined the first 3 functions
(<span class="name">GetLexerCount</span>, <span class="name">GetLexerName</span>, <span class="name">GetLexerFactory</span>)
so Lexilla can be loaded by applications that support that protocol.
<span class="name">GetLexerFactory</span> will rarely be used now as it is easier to call <span class="name">CreateLexer</span>.
</p>
<p><span class="name">CreateLexer</span> is the main call that will create a lexer for a particular language. The returned lexer can then be
set as the current lexer in Scintilla by calling
<a class="seealso" href="ScintillaDoc.html#SCI_SETILEXER">SCI_SETILEXER</a>.</p>
<p><span class="name">LexerNameFromID</span> is an optional function that returns the name for a lexer identifier.
<code>LexerNameFromID(SCLEX_CPP) &rarr; "cpp"</code>.
This is a temporary affordance to make it easier to convert applications to using Lexilla.
Applications should move to using lexer names instead of IDs.
This function is deprecated, showing warnings with some compilers, and will be removed in a future version of Lexilla.</p>
<p><span class="name">SetLibraryProperty</span> and <span class="name">GetLibraryPropertyNames</span>
are optional functions that can be
defined if a library requires initialisation before calling other methods.
@ -134,12 +134,12 @@
If a library implements SetLibraryProperty then it may also provide a set of valid property names with
GetLibraryPropertyNames that can then be used by the application to define configuration file property
names or user interface elements for options dialogs.</p>
<p><span class="name">GetNameSpace</span> is an optional function that returns a namespace string
that can be used to disambiguate lexers with the same name from different providers.
If Lexilla and XMLLexers both provide a "cpp" lexer than a request for "cpp" may be satisfied by either but "xmllexers.cpp"
unambiguously refers to the "cpp" lexer from XMLLexers.</p>
<h2>Building Lexilla</h2>
<p>Before using Lexilla it must be built or downloaded.</p>
@ -161,7 +161,7 @@
a difference between the actual and expected result:<br>
<code>C:\u\hg\lexilla\test\examples\python\x.py:1: is different</code>
</div>
<p>There are also RunTest.sh / RunTest.bat scripts in the scripts directory to build Lexilla and then build and run the tests.
These both use gcc/clang, not MSVC.</p>
@ -170,7 +170,7 @@
There is also test/TestLexers.vcxproj to build the tests with Visual C++.</p>
<h2>Using Lexilla</h2>
<p>Definitions for using Lexilla from C and C++ are included in lexilla/include/Lexilla.h.
For C++, scintilla/include/ILexer.h should be included before Lexilla.h as the
<code>ILexer5</code> type is used.
@ -227,7 +227,7 @@
and configuration files.</p>
<h2>Modifying or adding lexers</h2>
<p>Lexilla can be modified or a new library created that can be used to replace or augment Lexilla.</p>
<p>Lexer libraries that provide the same functions as Lexilla may provide lexers for use by Scintilla,

View File

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

View File

@ -585,6 +585,80 @@
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/lexilla526.zip">Release 5.2.6</a>
</h3>
<ul>
<li>
Released 26 July 2023.
</li>
<li>
Include empty word list names in value returned by DescribeWordListSets and SCI_DESCRIBEKEYWORDSETS.
<a href="https://github.com/ScintillaOrg/lexilla/issues/175">Issue #175</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/176">Pull request #176</a>.
</li>
<li>
Bash: style here-doc end delimiters as SCE_SH_HERE_DELIM instead of SCE_SH_HERE_Q.
<a href="https://github.com/ScintillaOrg/lexilla/issues/177">Issue #177</a>.
</li>
<li>
Bash: allow '$' as last character in string.
<a href="https://github.com/ScintillaOrg/lexilla/issues/180">Issue #180</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/181">Pull request #181</a>.
</li>
<li>
Bash: fix state after expansion. Highlight all numeric and file test operators.
Don't highlight dash in long option as operator.
<a href="https://github.com/ScintillaOrg/lexilla/issues/182">Issue #182</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/183">Pull request #183</a>.
</li>
<li>
Bash: strict checking of special parameters ($*, $@, $$, ...) with property lexer.bash.special.parameter to specify
valid parameters.
<a href="https://github.com/ScintillaOrg/lexilla/issues/184">Issue #184</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/186">Pull request #186</a>.
</li>
<li>
Bash: recognize keyword before redirection operators (&lt; and &gt;).
<a href="https://github.com/ScintillaOrg/lexilla/issues/188">Issue #188</a>,
<a href="https://github.com/ScintillaOrg/lexilla/pull/189">Pull request #189</a>.
</li>
<li>
Errorlist: recognize Bash diagnostic messages.
</li>
<li>
HTML: allow ASP block to terminate inside line comment.
<a href="https://github.com/ScintillaOrg/lexilla/issues/185">Issue #185</a>.
</li>
<li>
HTML: fix folding with JSP/ASP.NET &lt;%-- comment.
<a href="https://github.com/ScintillaOrg/lexilla/issues/191">Issue #191</a>.
</li>
<li>
HTML: fix incremental styling of multi-line ASP.NET directive.
<a href="https://github.com/ScintillaOrg/lexilla/issues/191">Issue #191</a>.
</li>
<li>
Matlab: improve arguments blocks.
Add support for multiple arguments blocks.
Prevent "arguments" from being keyword in function declaration line.
Fix semicolon handling.
<a href="https://github.com/ScintillaOrg/lexilla/pull/179">Pull request #179</a>.
</li>
<li>
Visual Prolog: add support for embedded syntax with SCE_VISUALPROLOG_EMBEDDED
and SCE_VISUALPROLOG_PLACEHOLDER.<br />
Styling of string literals changed with no differentiation between literals with quotes and those
that are prefixed with "@".
Quote characters are in a separate style (SCE_VISUALPROLOG_STRING_QUOTE)
to contents (SCE_VISUALPROLOG_STRING).<br />
SCE_VISUALPROLOG_CHARACTER, SCE_VISUALPROLOG_CHARACTER_TOO_MANY,
SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR, SCE_VISUALPROLOG_STRING_EOL_OPEN,
and SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL were removed (replaced with
SCE_VISUALPROLOG_UNUSED[1-5]).
<a href="https://github.com/ScintillaOrg/lexilla/pull/178">Pull request #178</a>.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/lexilla525.zip">Release 5.2.5</a>
</h3>

View File

@ -284,7 +284,7 @@ val SCE_H_CDATA=17
val SCE_H_QUESTION=18
# More HTML
val SCE_H_VALUE=19
# X-Code
# X-Code, ASP.NET, JSP
val SCE_H_XCCOMMENT=20
# SGML
val SCE_H_SGML_DEFAULT=21
@ -576,6 +576,7 @@ val SCE_ERR_GCC_INCLUDED_FROM=22
val SCE_ERR_ESCSEQ=23
val SCE_ERR_ESCSEQ_UNKNOWN=24
val SCE_ERR_GCC_EXCERPT=25
val SCE_ERR_BASH=26
val SCE_ERR_ES_BLACK=40
val SCE_ERR_ES_RED=41
val SCE_ERR_ES_GREEN=42
@ -1928,16 +1929,18 @@ val SCE_VISUALPROLOG_VARIABLE=9
val SCE_VISUALPROLOG_ANONYMOUS=10
val SCE_VISUALPROLOG_NUMBER=11
val SCE_VISUALPROLOG_OPERATOR=12
val SCE_VISUALPROLOG_CHARACTER=13
val SCE_VISUALPROLOG_CHARACTER_TOO_MANY=14
val SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR=15
val SCE_VISUALPROLOG_STRING=16
val SCE_VISUALPROLOG_UNUSED1=13
val SCE_VISUALPROLOG_UNUSED2=14
val SCE_VISUALPROLOG_UNUSED3=15
val SCE_VISUALPROLOG_STRING_QUOTE=16
val SCE_VISUALPROLOG_STRING_ESCAPE=17
val SCE_VISUALPROLOG_STRING_ESCAPE_ERROR=18
val SCE_VISUALPROLOG_STRING_EOL_OPEN=19
val SCE_VISUALPROLOG_STRING_VERBATIM=20
val SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL=21
val SCE_VISUALPROLOG_STRING_VERBATIM_EOL=22
val SCE_VISUALPROLOG_UNUSED4=19
val SCE_VISUALPROLOG_STRING=20
val SCE_VISUALPROLOG_UNUSED5=21
val SCE_VISUALPROLOG_STRING_EOL=22
val SCE_VISUALPROLOG_EMBEDDED=23
val SCE_VISUALPROLOG_PLACEHOLDER=24
# Lexical states for SCLEX_STTXT
lex StructuredText=SCLEX_STTXT SCE_STTXT_
val SCE_STTXT_DEFAULT=0

View File

@ -652,6 +652,7 @@
#define SCE_ERR_ESCSEQ 23
#define SCE_ERR_ESCSEQ_UNKNOWN 24
#define SCE_ERR_GCC_EXCERPT 25
#define SCE_ERR_BASH 26
#define SCE_ERR_ES_BLACK 40
#define SCE_ERR_ES_RED 41
#define SCE_ERR_ES_GREEN 42
@ -1847,16 +1848,18 @@
#define SCE_VISUALPROLOG_ANONYMOUS 10
#define SCE_VISUALPROLOG_NUMBER 11
#define SCE_VISUALPROLOG_OPERATOR 12
#define SCE_VISUALPROLOG_CHARACTER 13
#define SCE_VISUALPROLOG_CHARACTER_TOO_MANY 14
#define SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR 15
#define SCE_VISUALPROLOG_STRING 16
#define SCE_VISUALPROLOG_UNUSED1 13
#define SCE_VISUALPROLOG_UNUSED2 14
#define SCE_VISUALPROLOG_UNUSED3 15
#define SCE_VISUALPROLOG_STRING_QUOTE 16
#define SCE_VISUALPROLOG_STRING_ESCAPE 17
#define SCE_VISUALPROLOG_STRING_ESCAPE_ERROR 18
#define SCE_VISUALPROLOG_STRING_EOL_OPEN 19
#define SCE_VISUALPROLOG_STRING_VERBATIM 20
#define SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL 21
#define SCE_VISUALPROLOG_STRING_VERBATIM_EOL 22
#define SCE_VISUALPROLOG_UNUSED4 19
#define SCE_VISUALPROLOG_STRING 20
#define SCE_VISUALPROLOG_UNUSED5 21
#define SCE_VISUALPROLOG_STRING_EOL 22
#define SCE_VISUALPROLOG_EMBEDDED 23
#define SCE_VISUALPROLOG_PLACEHOLDER 24
#define SCE_STTXT_DEFAULT 0
#define SCE_STTXT_COMMENT 1
#define SCE_STTXT_COMMENTLINE 2

View File

@ -89,6 +89,7 @@ enum class QuoteStyle {
};
#define BASH_QUOTE_STACK_MAX 7
#define BASH_SPECIAL_PARAMETER "*@#?-$!"
constexpr int commandSubstitutionFlag = 0x40;
constexpr int MaskCommand(int state) noexcept {
@ -180,6 +181,7 @@ struct OptionsBash {
bool stylingInsideParameter = false;
bool stylingInsideHeredoc = false;
int commandSubstitution = static_cast<int>(CommandSubstitution::Backtick);
std::string specialParameter = BASH_SPECIAL_PARAMETER;
[[nodiscard]] bool stylingInside(int state) const noexcept {
switch (state) {
@ -228,6 +230,9 @@ struct OptionSetBash : public OptionSet<OptionsBash> {
"1 highlighted inside. "
"2 highlighted inside with extra scope tracking.");
DefineProperty("lexer.bash.special.parameter", &OptionsBash::specialParameter,
"Set shell (default is Bash) special parameters.");
DefineWordListSets(bashWordListDesc);
}
};
@ -239,19 +244,22 @@ public:
int Down = '\0';
QuoteStyle Style = QuoteStyle::Literal;
int Outer = SCE_SH_DEFAULT;
CmdState State = CmdState::Body;
void Clear() noexcept {
Count = 0;
Up = '\0';
Down = '\0';
Style = QuoteStyle::Literal;
Outer = SCE_SH_DEFAULT;
State = CmdState::Body;
}
void Start(int u, QuoteStyle s, int outer) noexcept {
void Start(int u, QuoteStyle s, int outer, CmdState state) noexcept {
Count = 1;
Up = u;
Down = opposite(Up);
Style = s;
Outer = outer;
State = state;
}
};
@ -263,23 +271,25 @@ public:
int insideCommand = 0;
QuoteCls Current;
QuoteCls Stack[BASH_QUOTE_STACK_MAX];
const CharacterSet &setParamStart;
QuoteStackCls(const CharacterSet &setParamStart_) noexcept : setParamStart{setParamStart_} {}
[[nodiscard]] bool Empty() const noexcept {
return Current.Up == '\0';
}
void Start(int u, QuoteStyle s, int outer) noexcept {
void Start(int u, QuoteStyle s, int outer, CmdState state) noexcept {
if (Empty()) {
Current.Start(u, s, outer);
Current.Start(u, s, outer, state);
} else {
Push(u, s, outer);
Push(u, s, outer, state);
}
}
void Push(int u, QuoteStyle s, int outer) noexcept {
void Push(int u, QuoteStyle s, int outer, CmdState state) noexcept {
if (Depth >= BASH_QUOTE_STACK_MAX) {
return;
}
Stack[Depth] = Current;
Depth++;
Current.Start(u, s, outer);
Current.Start(u, s, outer, state);
}
void Pop() noexcept {
if (Depth == 0) {
@ -311,7 +321,7 @@ public:
sc.Forward();
}
if (Current.Count == 0) {
cmdState = CmdState::Body;
cmdState = Current.State;
const int outer = Current.Outer;
Pop();
sc.ForwardSetState(outer | insideCommand);
@ -320,6 +330,7 @@ public:
return false;
}
void Expand(StyleContext &sc, CmdState &cmdState, bool stylingInside) {
const CmdState current = cmdState;
const int state = sc.state;
QuoteStyle style = QuoteStyle::Literal;
State = state;
@ -352,7 +363,7 @@ public:
sc.ChangeState(SCE_SH_BACKTICKS);
}
}
if (sc.Match('(', '(') && state == SCE_SH_DEFAULT && Depth == 0) {
if (current == CmdState::Body && sc.Match('(', '(') && state == SCE_SH_DEFAULT && Depth == 0) {
// optimized to avoid track nested delimiter pairs
style = QuoteStyle::Literal;
}
@ -361,6 +372,9 @@ public:
sc.ChangeState(SCE_SH_BACKTICKS);
} else {
// scalar has no delimiter pair
if (!setParamStart.Contains(sc.ch)) {
stylingInside = false; // not scalar
}
}
if (!stylingInside) {
sc.ChangeState(state);
@ -368,7 +382,7 @@ public:
sc.ChangeState(sc.state | insideCommand);
}
if (style != QuoteStyle::Literal) {
Start(sc.ch, style, state);
Start(sc.ch, style, state, current);
sc.Forward();
}
}
@ -401,17 +415,21 @@ class LexerBash final : public DefaultLexer {
WordList cmdDelimiter;
WordList bashStruct;
WordList bashStruct_in;
WordList testOperator;
OptionsBash options;
OptionSetBash osBash;
CharacterSet setParamStart;
enum { ssIdentifier, ssScalar };
SubStyles subStyles;
public:
LexerBash() :
DefaultLexer("bash", SCLEX_BASH, lexicalClasses, ELEMENTS(lexicalClasses)),
setParamStart(CharacterSet::setAlphaNum, "_" BASH_SPECIAL_PARAMETER),
subStyles(styleSubable, 0x80, 0x40, 0) {
cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
bashStruct.Set("if elif fi while until else then do done esac eval");
bashStruct_in.Set("for case select");
testOperator.Set("eq ge gt le lt ne ef nt ot");
}
void SCI_METHOD Release() override {
delete this;
@ -437,7 +455,7 @@ public:
}
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 Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) override;
void * SCI_METHOD PrivateCall(int, void *) override {
return nullptr;
@ -472,6 +490,11 @@ public:
return styleSubable;
}
bool IsTestOperator(const char *s, const CharacterSet &setSingleCharOp) const noexcept {
return (s[2] == '\0' && setSingleCharOp.Contains(s[1]))
|| testOperator.InList(s + 1);
}
static ILexer5 *LexerFactoryBash() {
return new LexerBash();
}
@ -479,6 +502,10 @@ public:
Sci_Position SCI_METHOD LexerBash::PropertySet(const char *key, const char *val) {
if (osBash.PropertySet(&options, key, val)) {
if (strcmp(key, "lexer.bash.special.parameter") == 0) {
setParamStart = CharacterSet(CharacterSet::setAlphaNum, "_");
setParamStart.AddString(options.specialParameter.empty() ? BASH_SPECIAL_PARAMETER : options.specialParameter.c_str());
}
return 0;
}
return -1;
@ -532,7 +559,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
};
HereDocCls HereDoc;
QuoteStackCls QuoteStack;
QuoteStackCls QuoteStack(setParamStart);
QuoteStack.commandSubstitution = static_cast<CommandSubstitution>(options.commandSubstitution);
const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_SH_IDENTIFIER);
@ -614,11 +641,11 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
if (subStyle >= 0) {
identifierStyle = subStyle | insideCommand;
}
// allow keywords ending in a whitespace or command delimiter
// allow keywords ending in a whitespace, meta character or command delimiter
char s2[10];
s2[0] = static_cast<char>(sc.ch);
s2[1] = '\0';
const bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2);
const bool keywordEnds = IsASpace(sc.ch) || setMetaCharacter.Contains(sc.ch) || cmdDelimiter.InList(s2);
// 'in' or 'do' may be construct keywords
if (cmdState == CmdState::Word) {
if (strcmp(s, "in") == 0 && keywordEnds)
@ -654,7 +681,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
}
// disambiguate option items and file test operators
else if (s[0] == '-') {
if (cmdState != CmdState::Test)
if (cmdState != CmdState::Test || !IsTestOperator(s, setSingleCharOp))
sc.ChangeState(identifierStyle);
}
// disambiguate keywords and identifiers
@ -807,7 +834,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
sc.ChangeState(subStyle | insideCommand);
}
if (sc.LengthCurrent() == 1) {
// Special variable: $(, $_ etc.
// Special variable
sc.Forward();
}
sc.SetState(QuoteStack.State | insideCommand);
@ -825,8 +852,11 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
}
if ((static_cast<Sci_Position>(sc.currentPos + HereDoc.DelimiterLength) == sc.lineEnd) &&
(HereDoc.DelimiterLength == 0 || sc.Match(HereDoc.Delimiter))) {
while (!sc.MatchLineEnd()) {
sc.Forward();
if (HereDoc.DelimiterLength != 0) {
sc.SetState(SCE_SH_HERE_DELIM | insideCommand);
while (!sc.MatchLineEnd()) {
sc.Forward();
}
}
QuoteStack.Pop();
sc.SetState(SCE_SH_DEFAULT | QuoteStack.insideCommand);
@ -857,11 +887,11 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
) { // do nesting for "string", $"locale-string", heredoc
const bool stylingInside = options.stylingInside(MaskCommand(sc.state));
if (sc.ch == '`') {
QuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state);
QuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state, cmdState);
if (stylingInside) {
sc.SetState(SCE_SH_BACKTICKS | insideCommand);
}
} else if (sc.ch == '$') {
} else if (sc.ch == '$' && !AnyOf(sc.chNext, '\"', '\'')) {
QuoteStack.Expand(sc, cmdState, stylingInside);
continue;
}
@ -875,15 +905,15 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
QuoteStack.State = sc.state;
sc.SetState(SCE_SH_CHARACTER | insideCommand);
} else {
QuoteStack.Push(sc.ch, QuoteStyle::Literal, sc.state);
QuoteStack.Push(sc.ch, QuoteStyle::Literal, sc.state, cmdState);
}
} else if (sc.ch == '\"') {
QuoteStack.Push(sc.ch, QuoteStyle::String, sc.state);
QuoteStack.Push(sc.ch, QuoteStyle::String, sc.state, cmdState);
if (stylingInside) {
sc.SetState(SCE_SH_STRING | insideCommand);
}
} else if (sc.ch == '`') {
QuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state);
QuoteStack.Push(sc.ch, QuoteStyle::Backtick, sc.state, cmdState);
if (stylingInside) {
sc.SetState(SCE_SH_BACKTICKS | insideCommand);
}
@ -917,7 +947,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
} else {
// HereDoc.Quote always == '\''
sc.SetState(SCE_SH_HERE_Q | insideCommand);
QuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT);
QuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT, cmdState);
}
} else if (HereDoc.DelimiterLength == 0) {
// no delimiter, illegal (but '' and "" are legal)
@ -925,7 +955,7 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
sc.SetState(SCE_SH_DEFAULT | insideCommand);
} else {
sc.SetState(SCE_SH_HERE_Q | insideCommand);
QuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT);
QuoteStack.Start(-1, QuoteStyle::HereDoc, SCE_SH_DEFAULT, cmdState);
}
}
@ -983,13 +1013,13 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
}
} else if (sc.ch == '\"') {
sc.SetState(SCE_SH_STRING | insideCommand);
QuoteStack.Start(sc.ch, QuoteStyle::String, SCE_SH_DEFAULT);
QuoteStack.Start(sc.ch, QuoteStyle::String, SCE_SH_DEFAULT, cmdState);
} else if (sc.ch == '\'') {
QuoteStack.State = SCE_SH_DEFAULT;
sc.SetState(SCE_SH_CHARACTER | insideCommand);
} else if (sc.ch == '`') {
sc.SetState(SCE_SH_BACKTICKS | insideCommand);
QuoteStack.Start(sc.ch, QuoteStyle::Backtick, SCE_SH_DEFAULT);
QuoteStack.Start(sc.ch, QuoteStyle::Backtick, SCE_SH_DEFAULT, cmdState);
} else if (sc.ch == '$') {
QuoteStack.Expand(sc, cmdState, true);
continue;
@ -1002,9 +1032,8 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
} else {
HereDoc.Indent = false;
}
} else if (sc.ch == '-' && // one-char file test operators
setSingleCharOp.Contains(sc.chNext) &&
!setWord.Contains(sc.GetRelative(2)) &&
} else if (sc.ch == '-' && // test operator or short and long option
(IsUpperOrLowerCase(sc.chNext) || sc.chNext == '-') &&
IsASpace(sc.chPrev)) {
sc.SetState(SCE_SH_WORD | insideCommand);
sc.Forward();
@ -1099,26 +1128,28 @@ void SCI_METHOD LexerBash::Lex(Sci_PositionU startPos, Sci_Position length, int
sc.Complete();
}
void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {
void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos_, Sci_Position length, int initStyle, IDocument *pAccess) {
if(!options.fold)
return;
LexAccessor styler(pAccess);
const Sci_PositionU endPos = startPos + length;
const Sci_Position startPos = startPos_;
const Sci_Position endPos = startPos + length;
int visibleChars = 0;
int skipHereCh = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
char chNext = styler[startPos];
int styleNext = MaskCommand(styler.StyleIndexAt(startPos));
int style = MaskCommand(initStyle);
char word[8] = { '\0' }; // we're not interested in long words anyway
unsigned int wordlen = 0;
for (Sci_PositionU i = startPos; i < endPos; i++) {
size_t wordlen = 0;
for (Sci_Position i = startPos; i < endPos; i++) {
const char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
const int style = styleNext;
const int stylePrev = style;
style = styleNext;
styleNext = MaskCommand(styler.StyleIndexAt(i + 1));
const bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
// Comment folding
@ -1153,18 +1184,16 @@ void SCI_METHOD LexerBash::Fold(Sci_PositionU startPos, Sci_Position length, int
}
// Here Document folding
if (style == SCE_SH_HERE_DELIM) {
if (ch == '<' && chNext == '<') {
if (styler.SafeGetCharAt(i + 2) == '<') {
skipHereCh = 1;
} else {
if (skipHereCh == 0) {
if (stylePrev == SCE_SH_HERE_Q) {
levelCurrent--;
} else if (stylePrev != SCE_SH_HERE_DELIM) {
if (ch == '<' && chNext == '<') {
if (styler.SafeGetCharAt(i + 2) != '<') {
levelCurrent++;
} else {
skipHereCh = 0;
}
}
}
} else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) {
} else if (style == SCE_SH_HERE_Q && styleNext == SCE_SH_DEFAULT) {
levelCurrent--;
}
if (atEOL) {

View File

@ -1076,7 +1076,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
assert(!currentText.empty());
std::string currentSuffix = currentText.substr(1);
if (!keywords3.InList(currentSuffix) && !keywords3.InList(currentText)) {
const int subStyleCDKW = classifierDocKeyWords.ValueFor(currentSuffix.c_str());
const int subStyleCDKW = classifierDocKeyWords.ValueFor(currentSuffix);
if (subStyleCDKW >= 0) {
sc.ChangeState(subStyleCDKW | activitySet);
} else {

View File

@ -367,6 +367,7 @@ static void FoldCoffeeScriptDoc(Sci_PositionU startPos, Sci_Position length, int
const Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line
// property fold.coffeescript.comment
// Set to 1 to allow folding of comment blocks in CoffeeScript.
const bool foldComment = styler.GetPropertyInt("fold.coffeescript.comment") != 0;
const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;

View File

@ -64,6 +64,23 @@ bool IsGccExcerpt(const char *s) noexcept {
return true;
}
const std::string_view bashDiagnosticMark = ": line ";
bool IsBashDiagnostic(std::string_view sv) {
const size_t mark = sv.find(bashDiagnosticMark);
if (mark == std::string_view::npos) {
return false;
}
std::string_view rest = sv.substr(mark + bashDiagnosticMark.length());
if (rest.empty() || !Is0To9(rest.front())) {
return false;
}
while (!rest.empty() && Is0To9(rest.front())) {
rest.remove_prefix(1);
}
return !rest.empty() && (rest.front() == ':');
}
int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci_Position &startValue) {
if (lineBuffer[0] == '>') {
// Command or return status
@ -153,6 +170,10 @@ int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci
// Microsoft linker warning:
// {<object> : } (warning|error) LNK9999
return SCE_ERR_MS;
} else if (IsBashDiagnostic(lineBuffer)) {
// Bash diagnostic
// <filename>: line <line>:<message>
return SCE_ERR_BASH;
} else if (IsGccExcerpt(lineBuffer)) {
// GCC code excerpt and pointer to issue
// 73 | GTimeVal last_popdown;

View File

@ -5,12 +5,12 @@
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <cstdarg>
#include <string>
#include <string_view>
@ -42,15 +42,15 @@ namespace {
enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment };
enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc };
inline bool IsAWordChar(const int ch) {
bool IsAWordChar(const int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_');
}
inline bool IsAWordStart(const int ch) {
bool IsAWordStart(const int ch) noexcept {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
inline bool IsOperator(int ch) {
bool IsOperator(int ch) noexcept {
if (IsASCII(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
@ -131,14 +131,14 @@ int PrintScriptingIndicatorOffset(Accessor &styler, Sci_PositionU start, Sci_Pos
return iResult;
}
script_type ScriptOfState(int state) {
script_type ScriptOfState(int state) noexcept {
if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) {
return eScriptPython;
} else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) {
} else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) {
return eScriptVBS;
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
return eScriptJS;
} else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) {
} else if ((state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_COMMENTLINE) || (state == SCE_HPHP_COMPLEX_VARIABLE)) {
return eScriptPHP;
} else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
return eScriptSGML;
@ -149,7 +149,7 @@ script_type ScriptOfState(int state) {
}
}
int statePrintForState(int state, script_mode inScriptType) {
int statePrintForState(int state, script_mode inScriptType) noexcept {
int StateToPrint = state;
if (state >= SCE_HJ_START) {
@ -165,7 +165,7 @@ int statePrintForState(int state, script_mode inScriptType) {
return StateToPrint;
}
int stateForPrintState(int StateToPrint) {
int stateForPrintState(int StateToPrint) noexcept {
int state;
if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) {
@ -185,7 +185,7 @@ constexpr bool IsNumberChar(char ch) noexcept {
return IsADigit(ch) || ch == '.' || ch == '-' || ch == '#';
}
inline bool isStringState(int state) {
bool isStringState(int state) noexcept {
bool bResult;
switch (state) {
@ -216,11 +216,10 @@ inline bool isStringState(int state) {
return bResult;
}
inline bool stateAllowsTermination(int state) {
bool stateAllowsTermination(int state) noexcept {
bool allowTermination = !isStringState(state);
if (allowTermination) {
switch (state) {
case SCE_HB_COMMENTLINE:
case SCE_HPHP_COMMENT:
case SCE_HP_COMMENTLINE:
case SCE_HPA_COMMENTLINE:
@ -230,8 +229,19 @@ inline bool stateAllowsTermination(int state) {
return allowTermination;
}
bool isPreProcessorEndTag(int state, int ch) {
const script_type type = ScriptOfState(state);
if (state == SCE_H_ASP || AnyOf(type, eScriptVBS, eScriptJS, eScriptPython)) {
return ch == '%';
}
if (type == eScriptPHP) {
return ch == '%' || ch == '?';
}
return ch == '?';
}
// not really well done, since it's only comments that should lex the %> and <%
inline bool isCommentASPState(int state) {
bool isCommentASPState(int state) noexcept {
bool bResult;
switch (state) {
@ -434,7 +444,7 @@ bool isWordCdata(Sci_PositionU start, Sci_PositionU end, Accessor &styler) {
}
// Return the first state to reach when entering a scripting language
int StateForScript(script_type scriptLanguage) {
int StateForScript(script_type scriptLanguage) noexcept {
int Result;
switch (scriptLanguage) {
case eScriptVBS:
@ -462,20 +472,20 @@ int StateForScript(script_type scriptLanguage) {
return Result;
}
inline bool issgmlwordchar(int ch) {
bool issgmlwordchar(int ch) noexcept {
return !IsASCII(ch) ||
(isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
}
inline bool IsPhpWordStart(int ch) {
bool IsPhpWordStart(int ch) noexcept {
return (IsASCII(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f);
}
inline bool IsPhpWordChar(int ch) {
bool IsPhpWordChar(int ch) noexcept {
return IsADigit(ch) || IsPhpWordStart(ch);
}
bool InTagState(int state) {
bool InTagState(int state) noexcept {
return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN ||
state == SCE_H_SCRIPT ||
state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN ||
@ -483,16 +493,16 @@ bool InTagState(int state) {
state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING;
}
bool IsCommentState(const int state) {
bool IsCommentState(const int state) noexcept {
return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
}
bool IsScriptCommentState(const int state) {
bool IsScriptCommentState(const int state) noexcept {
return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT ||
state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE;
}
bool isLineEnd(int ch) {
bool isLineEnd(int ch) noexcept {
return ch == '\r' || ch == '\n';
}
@ -546,8 +556,8 @@ class PhpNumberState {
bool exponentChar = false;
public:
inline bool isInvalid() { return invalid; }
inline bool isFinished() { return finished; }
[[nodiscard]] bool isInvalid() const noexcept { return invalid; }
[[nodiscard]] bool isFinished() const noexcept { return finished; }
bool init(int ch, int chPlus1, int chPlus2) {
base = BASE_10;
@ -641,7 +651,7 @@ public:
}
};
bool isPHPStringState(int state) {
bool isPHPStringState(int state) noexcept {
return
(state == SCE_HPHP_HSTRING) ||
(state == SCE_HPHP_SIMPLESTRING) ||
@ -705,8 +715,6 @@ struct OptionsHTML {
bool foldComment = false;
bool foldHeredoc = false;
bool foldXmlAtTagOpen = false;
OptionsHTML() noexcept {
}
};
const char * const htmlWordListDesc[] = {
@ -716,7 +724,7 @@ const char * const htmlWordListDesc[] = {
"Python keywords",
"PHP keywords",
"SGML and DTD keywords",
0,
nullptr,
};
const char * const phpscriptWordListDesc[] = {
@ -726,7 +734,7 @@ const char * const phpscriptWordListDesc[] = {
"", //Unused
"PHP keywords",
"", //Unused
0,
nullptr,
};
struct OptionSetHTML : public OptionSet<OptionsHTML> {
@ -777,7 +785,7 @@ struct OptionSetHTML : public OptionSet<OptionsHTML> {
}
};
LexicalClass lexicalClassesHTML[] = {
const LexicalClass lexicalClassesHTML[] = {
// Lexer HTML SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_:
0, "SCE_H_DEFAULT", "default", "Text",
1, "SCE_H_TAG", "tag", "Tags",
@ -799,7 +807,7 @@ LexicalClass lexicalClassesHTML[] = {
17, "SCE_H_CDATA", "literal", "CDATA",
18, "SCE_H_QUESTION", "preprocessor", "PHP",
19, "SCE_H_VALUE", "literal string", "Unquoted values",
20, "SCE_H_XCCOMMENT", "comment", "JSP Comment <%-- ... --%>",
20, "SCE_H_XCCOMMENT", "comment", "ASP.NET, JSP Comment <%-- ... --%>",
21, "SCE_H_SGML_DEFAULT", "default", "SGML tags <! ... >",
22, "SCE_H_SGML_COMMAND", "preprocessor", "SGML command",
23, "SCE_H_SGML_1ST_PARAM", "preprocessor", "SGML 1st param",
@ -909,7 +917,7 @@ LexicalClass lexicalClassesHTML[] = {
127, "SCE_HPHP_OPERATOR", "server php operator", "PHP operator",
};
LexicalClass lexicalClassesXML[] = {
const LexicalClass lexicalClassesXML[] = {
// Lexer.Secondary XML SCLEX_XML SCE_H_:
0, "SCE_H_DEFAULT", "default", "Default",
1, "SCE_H_TAG", "tag", "Tags",
@ -945,7 +953,7 @@ LexicalClass lexicalClassesXML[] = {
31, "SCE_H_SGML_BLOCK_DEFAULT", "default", "SGML block",
};
const char *tagsThatDoNotFold[] = {
const char * const tagsThatDoNotFold[] = {
"area",
"base",
"basefont",
@ -1037,7 +1045,7 @@ Sci_Position SCI_METHOD LexerHTML::PropertySet(const char *key, const char *val)
}
Sci_Position SCI_METHOD LexerHTML::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
WordList *wordListN = nullptr;
switch (n) {
case 0:
wordListN = &keywords;
@ -1327,7 +1335,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
case SCE_HJ_COMMENTDOC:
//case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide
// the end of script marker from some JS interpreters.
case SCE_HB_COMMENTLINE:
//case SCE_HB_COMMENTLINE:
case SCE_HBA_COMMENTLINE:
case SCE_HJ_DOUBLESTRING:
case SCE_HJ_SINGLESTRING:
@ -1345,8 +1353,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
default :
// check if the closing tag is a script tag
if (const char *tag =
state == SCE_HJ_COMMENTLINE || isXml ? "script" :
state == SCE_H_COMMENT ? "comment" : 0) {
(state == SCE_HJ_COMMENTLINE || state == SCE_HB_COMMENTLINE || isXml) ? "script" :
state == SCE_H_COMMENT ? "comment" : nullptr) {
Sci_Position j = i + 2;
int chr;
do {
@ -1512,7 +1520,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
// fold whole script
if (foldHTMLPreprocessor)
levelCurrent++;
if (chNext2 == '@') {
i += 2; // place as if it was the second next char treated
visibleChars += 2;
@ -1536,9 +1546,6 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
scriptLanguage = aspScript;
}
styler.ColourTo(i, SCE_H_ASP);
// fold whole script
if (foldHTMLPreprocessor)
levelCurrent++;
// should be better
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
@ -1635,7 +1642,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
// handle the end of a pre-processor = Non-HTML
else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
(((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
((chNext == '>') && isPreProcessorEndTag(state, ch))) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
if (state == SCE_H_ASPAT) {
aspScript = segIsScriptingIndicator(styler,

View File

@ -105,11 +105,13 @@ static bool IsSpaceToEOL(Sci_Position startPos, Accessor &styler) {
#define MATLAB_STATE_COMM_DEPTH_MASK (0xFF)
#define MATLAB_STATE_EXPECTING_ARG_BLOCK (1 << MATLAB_STATE_FLAGS_OFFSET)
#define MATLAB_STATE_IN_CLASS_SCOPE (1 <<(MATLAB_STATE_FLAGS_OFFSET+1))
#define MATLAB_STATE_IN_ARGUMENTS_SCOPE (1 <<(MATLAB_STATE_FLAGS_OFFSET+2))
static int ComposeLineState(int commentDepth,
int foldingLevel,
int expectingArgumentsBlock,
int inClassScope) {
int inClassScope,
int inArgumentsScope) {
return ((commentDepth << MATLAB_STATE_COMM_DEPTH_OFFSET)
& MATLAB_STATE_COMM_DEPTH_MASK) |
@ -118,7 +120,9 @@ static int ComposeLineState(int commentDepth,
(expectingArgumentsBlock
& MATLAB_STATE_EXPECTING_ARG_BLOCK) |
(inClassScope
& MATLAB_STATE_IN_CLASS_SCOPE);
& MATLAB_STATE_IN_CLASS_SCOPE) |
(inArgumentsScope
& MATLAB_STATE_IN_ARGUMENTS_SCOPE);
}
static void ColouriseMatlabOctaveDoc(
@ -148,6 +152,8 @@ static void ColouriseMatlabOctaveDoc(
// We've just seen "function" keyword, so now we may expect the "arguments"
// keyword opening the corresponding code block
int expectingArgumentsBlock = 0;
// We saw "arguments" keyword, but not the closing "end"
int inArgumentsScope = 0;
// Current line's folding level
int foldingLevel = 0;
// Current line in in class scope
@ -165,6 +171,7 @@ static void ColouriseMatlabOctaveDoc(
>> MATLAB_STATE_FOLD_LVL_OFFSET;
expectingArgumentsBlock = prevState & MATLAB_STATE_EXPECTING_ARG_BLOCK;
inClassScope = prevState & MATLAB_STATE_IN_CLASS_SCOPE;
inArgumentsScope = prevState & MATLAB_STATE_IN_ARGUMENTS_SCOPE;
}
@ -176,7 +183,7 @@ static void ColouriseMatlabOctaveDoc(
// set the line state to the current commentDepth
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
// reset the column to 0, nonSpace to -1 (not set)
column = 0;
@ -186,18 +193,25 @@ static void ColouriseMatlabOctaveDoc(
funcDeclarationLine = false;
}
// Semicolon ends function declaration
// This condition is for one line functions support
if (sc.chPrev == ';') {
funcDeclarationLine = false;
}
// Only comments allowed between the function declaration and the
// arguments code block
if (expectingArgumentsBlock && !funcDeclarationLine) {
if (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope)) {
if ((sc.state != SCE_MATLAB_KEYWORD) &&
(sc.state != SCE_MATLAB_COMMENT) &&
(sc.state != SCE_MATLAB_DEFAULT)) {
(sc.state != SCE_MATLAB_DEFAULT) &&
!(sc.state == SCE_MATLAB_OPERATOR && sc.chPrev == ';')) {
expectingArgumentsBlock = 0;
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
}
}
// We've just left the class scope
if ((foldingLevel ==0) && inClassScope) {
inClassScope = 0;
@ -235,9 +249,14 @@ static void ColouriseMatlabOctaveDoc(
transpose = false;
if (keywords.InList(s)) {
expectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;
if (strcmp ("end", s) == 0 && allow_end_op) {
sc.ChangeState(SCE_MATLAB_NUMBER);
notKeyword = true;
} else if (strcmp("end", s) == 0 && !allow_end_op) {
inArgumentsScope = 0;
} else if (strcmp("function", s) == 0) {
// Need this flag to handle "arguments" block correctly
funcDeclarationLine = true;
@ -246,17 +265,16 @@ static void ColouriseMatlabOctaveDoc(
// Need this flag to process "events", "methods" and "properties" blocks
inClassScope = MATLAB_STATE_IN_CLASS_SCOPE;
}
expectingArgumentsBlock = funcDeclarationLine ? expectingArgumentsBlock : 0;
} else {
// "arguments" is a keyword here, despite not being in the keywords list
if (expectingArgumentsBlock && (strcmp("arguments", s) == 0)) {
// No need to expect another arguments block
expectingArgumentsBlock = 0;
if (expectingArgumentsBlock && !(funcDeclarationLine || inArgumentsScope) && (strcmp("arguments", s) == 0)) {
// We've entered an "arguments" block
inArgumentsScope = MATLAB_STATE_IN_ARGUMENTS_SCOPE;
} else {
// Found an identifier or a keyword after the function declaration
// No need to wait for the arguments block anymore
expectingArgumentsBlock = funcDeclarationLine ? expectingArgumentsBlock : 0;
expectingArgumentsBlock = (funcDeclarationLine || inArgumentsScope) ? expectingArgumentsBlock : 0;
// "properties", "methods" and "events" are not keywords if they're declared
// inside some function in methods block
// To avoid tracking possible nested functions scopes, lexer considers everything
@ -265,7 +283,7 @@ static void ColouriseMatlabOctaveDoc(
// a separate file, function - only in methods block. However, in case of the invalid
// syntax lexer may erroneously ignore a keyword.
if (!((inClassScope) && (foldingLevel <= 2) && (
strcmp("properties", s) == 0 ||
strcmp("properties", s) == 0 ||
strcmp("methods", s) == 0 ||
strcmp("events", s) == 0 ))) {
sc.ChangeState(SCE_MATLAB_IDENTIFIER);
@ -274,15 +292,15 @@ static void ColouriseMatlabOctaveDoc(
}
}
}
sc.SetState(SCE_MATLAB_DEFAULT);
if (!notKeyword) {
foldingLevel += CheckKeywordFoldPoint(s);
}
}
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
} else if (sc.state == SCE_MATLAB_NUMBER) {
if (!isdigit(sc.ch) && sc.ch != '.'
&& !(sc.ch == 'e' || sc.ch == 'E')
@ -324,7 +342,7 @@ static void ColouriseMatlabOctaveDoc(
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
sc.Forward();
if (commentDepth == 0) {
@ -336,7 +354,7 @@ static void ColouriseMatlabOctaveDoc(
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
sc.Forward();
transpose = false;
@ -360,7 +378,7 @@ static void ColouriseMatlabOctaveDoc(
}
curLine = styler.GetLine(sc.currentPos);
styler.SetLineState(curLine, ComposeLineState(
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope));
commentDepth, foldingLevel, expectingArgumentsBlock, inClassScope, inArgumentsScope));
sc.SetState(SCE_MATLAB_COMMENT);
} else if (sc.ch == '!' && sc.chNext != '=' ) {
if(ismatlab) {

View File

@ -3,6 +3,7 @@
// (c) 2009 Andreas Rumpf
/** @file LexNimrod.cxx
** Lexer for Nimrod.
** This lexer has been superceded by the "nim" lexer in LexNim.cxx.
**/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

View File

@ -139,6 +139,8 @@ static int calculateFoldNsis(Sci_PositionU start, Sci_PositionU end, int foldlev
int newFoldlevel = foldlevel;
bool bIgnoreCase = false;
// property nsis.ignorecase
// Set to 1 to ignore case for NSIS.
if( styler.GetPropertyInt("nsis.ignorecase") == 1 )
bIgnoreCase = true;
@ -177,6 +179,8 @@ static int classifyWordNsis(Sci_PositionU start, Sci_PositionU end, WordList *ke
bIgnoreCase = true;
bool bUserVars = false;
// property nsis.uservars
// Set to 1 to recognise user defined variables in NSIS.
if( styler.GetPropertyInt("nsis.uservars") == 1 )
bUserVars = true;

View File

@ -79,6 +79,8 @@ static void ColourisePSDoc(
StyleContext sc(startPos, length, initStyle, styler);
// property ps.level
// Define level (0..3) of PostScript handled and thus set of keywords. Default is 3.
int pslevel = styler.GetPropertyInt("ps.level", 3);
Sci_Position lineCurrent = styler.GetLine(startPos);
int nestTextCurrent = 0;

View File

@ -55,7 +55,7 @@ struct OptionsRust {
std::string foldExplicitEnd;
bool foldExplicitAnywhere;
bool foldCompact;
int foldAtElseInt;
int foldAtElseInt; // This variable is not used
bool foldAtElse;
OptionsRust() {
fold = false;

View File

@ -286,9 +286,11 @@ struct OptionSetSQL : public OptionSet<OptionsSQL> {
DefineProperty("fold.compact", &OptionsSQL::foldCompact);
DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin,
"Set to 1 to only fold on 'begin' but not other keywords.");
DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier,
"Recognise backtick quoting of identifiers.");
DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
"If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");

View File

@ -2,14 +2,14 @@
/** @file LexVisualProlog.cxx
** Lexer for Visual Prolog.
**/
// Author Thomas Linder Puls, Prolog Development Denter A/S, http://www.visual-prolog.com
// Author Thomas Linder Puls, PDC A/S, http://www.visual-prolog.com
// Based on Lexer for C++, C, Java, and JavaScript.
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// The line state contains:
// In SCE_VISUALPROLOG_STRING_VERBATIM_EOL (i.e. multiline string literal): The closingQuote.
// else (for SCE_VISUALPROLOG_COMMENT_BLOCK): The comment nesting level
// In SCE_VISUALPROLOG_STRING: The closing quote and information about verbatim string.
// and a stack of nesting kinds: comment, embedded (syntax) and (syntax) place holder
#include <stdlib.h>
#include <string.h>
@ -46,6 +46,7 @@
using namespace Scintilla;
using namespace Lexilla;
namespace {
// Options used for LexerVisualProlog
struct OptionsVisualProlog {
bool verbatimStrings;
@ -56,7 +57,7 @@ struct OptionsVisualProlog {
}
};
static const char *const visualPrologWordLists[] = {
static const char* const visualPrologWordLists[] = {
"Major keywords (class, predicates, ...)",
"Minor keywords (if, then, try, ...)",
"Directive keywords without the '#' (include, requires, ...)",
@ -74,6 +75,39 @@ struct OptionSetVisualProlog : public OptionSet<OptionsVisualProlog> {
}
};
LexicalClass lexicalClasses[] = {
SCE_VISUALPROLOG_DEFAULT, "SCE_VISUALPROLOG_DEFAULT", "default", "Default style",
SCE_VISUALPROLOG_KEY_MAJOR, "SCE_VISUALPROLOG_KEY_MAJOR", "keyword major", "Major keyword",
SCE_VISUALPROLOG_KEY_MINOR, "SCE_VISUALPROLOG_KEY_MINOR", "keyword minor", "Minor keyword",
SCE_VISUALPROLOG_KEY_DIRECTIVE, "SCE_VISUALPROLOG_KEY_DIRECTIVE", "keyword preprocessor", "Directove keyword",
SCE_VISUALPROLOG_COMMENT_BLOCK, "SCE_VISUALPROLOG_COMMENT_BLOCK", "comment", "Multiline comment /* */",
SCE_VISUALPROLOG_COMMENT_LINE, "SCE_VISUALPROLOG_COMMENT_LINE", "comment line", "Line comment % ...",
SCE_VISUALPROLOG_COMMENT_KEY, "SCE_VISUALPROLOG_COMMENT_KEY", "comment documentation keyword", "Doc keyword in comment % @short ...",
SCE_VISUALPROLOG_COMMENT_KEY_ERROR, "SCE_VISUALPROLOG_COMMENT_KEY_ERROR", "comment", "A non recognized doc keyword % @qqq ...",
SCE_VISUALPROLOG_IDENTIFIER, "SCE_VISUALPROLOG_IDENTIFIER", "identifier", "Identifier (black)",
SCE_VISUALPROLOG_VARIABLE, "SCE_VISUALPROLOG_VARIABLE", "variable identifier", "Variable (green)",
SCE_VISUALPROLOG_ANONYMOUS, "SCE_VISUALPROLOG_ANONYMOUS", "variable anonymous identifier", "Anonymous Variable _XXX (dimmed green)",
SCE_VISUALPROLOG_NUMBER, "SCE_VISUALPROLOG_NUMBER", "numeric", "Number",
SCE_VISUALPROLOG_OPERATOR, "SCE_VISUALPROLOG_OPERATOR", "operator", "Operator",
SCE_VISUALPROLOG_STRING, "SCE_VISUALPROLOG_STRING", "literal string", "String literal",
SCE_VISUALPROLOG_STRING_QUOTE, "SCE_VISUALPROLOG_STRING_QUOTE", "literal string quote", "Quotes surrounding string literals",
SCE_VISUALPROLOG_STRING_ESCAPE, "SCE_VISUALPROLOG_STRING_ESCAPE", "literal string escapesequence", "Escape sequence in string literal",
SCE_VISUALPROLOG_STRING_ESCAPE_ERROR, "SCE_VISUALPROLOG_STRING_ESCAPE_ERROR", "error literal string escapesequence", "Error in escape sequence in string literal",
SCE_VISUALPROLOG_STRING_EOL, "SCE_VISUALPROLOG_STRING_EOL", "literal string multiline raw escapesequence", "Verbatim/multiline string literal EOL",
SCE_VISUALPROLOG_EMBEDDED, "SCE_VISUALPROLOG_EMBEDDED", "literal string embedded", "Embedded syntax [| ... |]",
SCE_VISUALPROLOG_PLACEHOLDER, "SCE_VISUALPROLOG_PLACEHOLDER", "operator embedded", "Syntax place holder {| ... |}:ident in embedded syntax"
};
LexicalClass getLexicalClass(int style) {
for (auto lc : lexicalClasses) {
if (style == lc.value) {
return lc;
}
}
return {style, "", "unused", ""};
}
class LexerVisualProlog : public DefaultLexer {
WordList majorKeywords;
WordList minorKeywords;
@ -92,57 +126,76 @@ public:
int SCI_METHOD Version() const override {
return lvRelease5;
}
const char * SCI_METHOD PropertyNames() override {
const char* SCI_METHOD PropertyNames() override {
return osVisualProlog.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) override {
int SCI_METHOD PropertyType(const char* name) override {
return osVisualProlog.PropertyType(name);
}
const char * SCI_METHOD DescribeProperty(const char *name) override {
const char* SCI_METHOD DescribeProperty(const char* name) override {
return osVisualProlog.DescribeProperty(name);
}
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
const char * SCI_METHOD PropertyGet(const char *key) override {
return osVisualProlog.PropertyGet(key);
}
const char * SCI_METHOD DescribeWordListSets() override {
Sci_Position SCI_METHOD PropertySet(const char* key, const char* val) override;
const char* SCI_METHOD PropertyGet(const char* key) override {
return osVisualProlog.PropertyGet(key);
}
const char* SCI_METHOD DescribeWordListSets() override {
return osVisualProlog.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;
Sci_Position SCI_METHOD WordListSet(int n, const char* wl) override;
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) override;
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) override;
void * SCI_METHOD PrivateCall(int, void *) override {
void* SCI_METHOD PrivateCall(int, void*) override {
return 0;
}
static ILexer5 *LexerFactoryVisualProlog() {
int SCI_METHOD NamedStyles() override {
int namedStyles = 0;
for (auto lc : lexicalClasses) {
if (namedStyles < lc.value) {
namedStyles = lc.value;
}
}
return namedStyles;
}
const char* SCI_METHOD NameOfStyle(int style) override {
return getLexicalClass(style).name;
}
const char* SCI_METHOD TagsOfStyle(int style) override {
return getLexicalClass(style).tags;
}
const char* SCI_METHOD DescriptionOfStyle(int style) override {
return getLexicalClass(style).description;
}
static ILexer5* LexerFactoryVisualProlog() {
return new LexerVisualProlog();
}
};
Sci_Position SCI_METHOD LexerVisualProlog::PropertySet(const char *key, const char *val) {
Sci_Position SCI_METHOD LexerVisualProlog::PropertySet(const char* key, const char* val) {
if (osVisualProlog.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
Sci_Position SCI_METHOD LexerVisualProlog::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
Sci_Position SCI_METHOD LexerVisualProlog::WordListSet(int n, const char* wl) {
WordList* wordListN = 0;
switch (n) {
case 0:
wordListN = &majorKeywords;
break;
case 1:
wordListN = &minorKeywords;
break;
case 2:
wordListN = &directiveKeywords;
break;
case 3:
wordListN = &docKeywords;
break;
case 0:
wordListN = &majorKeywords;
break;
case 1:
wordListN = &minorKeywords;
break;
case 2:
wordListN = &directiveKeywords;
break;
case 3:
wordListN = &docKeywords;
break;
}
Sci_Position firstModification = -1;
if (wordListN) {
@ -156,78 +209,37 @@ Sci_Position SCI_METHOD LexerVisualProlog::WordListSet(int n, const char *wl) {
return firstModification;
}
static bool isLowerLetter(int ch){
static bool isLowerLetter(int ch) {
return ccLl == CategoriseCharacter(ch);
}
static bool isUpperLetter(int ch){
static bool isUpperLetter(int ch) {
return ccLu == CategoriseCharacter(ch);
}
static bool isAlphaNum(int ch){
static bool isAlphaNum(int ch) {
CharacterCategory cc = CategoriseCharacter(ch);
return (ccLu == cc || ccLl == cc || ccLt == cc || ccLm == cc || ccLo == cc || ccNd == cc || ccNl == cc || ccNo == cc);
}
static bool isStringVerbatimOpenClose(int ch){
static bool isStringVerbatimOpenClose(int ch) {
CharacterCategory cc = CategoriseCharacter(ch);
return (ccPc <= cc && cc <= ccSo);
}
static bool isIdChar(int ch){
static bool isIdChar(int ch) {
return ('_') == ch || isAlphaNum(ch);
}
static bool isOpenStringVerbatim(int next, int &closingQuote){
switch (next) {
case L'<':
closingQuote = L'>';
return true;
case L'>':
closingQuote = L'<';
return true;
case L'(':
closingQuote = L')';
return true;
case L')':
closingQuote = L'(';
return true;
case L'[':
closingQuote = L']';
return true;
case L']':
closingQuote = L'[';
return true;
case L'{':
closingQuote = L'}';
return true;
case L'}':
closingQuote = L'{';
return true;
case L'_':
case L'.':
case L',':
case L';':
return false;
default:
if (isStringVerbatimOpenClose(next)) {
closingQuote = next;
return true;
} else {
return false;
}
}
}
// Look ahead to see which colour "end" should have (takes colour after the following keyword)
static void endLookAhead(char s[], LexAccessor &styler, Sci_Position start) {
static void endLookAhead(char s[], LexAccessor& styler, Sci_Position start) {
char ch = styler.SafeGetCharAt(start, '\n');
while (' ' == ch) {
start++;
ch = styler.SafeGetCharAt(start, '\n');
}
Sci_Position i = 0;
while (i < 100 && isLowerLetter(ch)){
while (i < 100 && isLowerLetter(ch)) {
s[i] = ch;
i++;
ch = styler.SafeGetCharAt(start + i, '\n');
@ -235,196 +247,327 @@ static void endLookAhead(char s[], LexAccessor &styler, Sci_Position start) {
s[i] = '\0';
}
static void forwardEscapeLiteral(StyleContext &sc, int EscapeState) {
sc.Forward();
if (sc.Match('"') || sc.Match('\'') || sc.Match('\\') || sc.Match('n') || sc.Match('l') || sc.Match('r') || sc.Match('t')) {
sc.ChangeState(EscapeState);
} else if (sc.Match('u')) {
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
sc.ChangeState(EscapeState);
}
class lineState {
public:
bool verbatim = false;
int closingQuote = 0;
int kindStack = 0;
bool isOpenStringVerbatim(int next) {
if (next > 0x7FFF) {
return false;
}
switch (next) {
case L'<':
closingQuote = L'>';
return true;
case L'>':
closingQuote = L'<';
return true;
case L'(':
closingQuote = L')';
return true;
case L')':
closingQuote = L'(';
return true;
case L'[':
closingQuote = L']';
return true;
case L']':
closingQuote = L'[';
return true;
case L'{':
closingQuote = L'}';
return true;
case L'}':
closingQuote = L'{';
return true;
case L'_':
case L'.':
case L',':
case L';':
return false;
default:
if (isStringVerbatimOpenClose(next)) {
closingQuote = next;
return true;
} else {
return false;
}
}
}
enum kind {
none = 0,
comment = 1,
embedded = 2,
placeholder = 3
};
void setState(int state) {
verbatim = state >> 31;
closingQuote = state >> 16 & 0x7FFF;
kindStack = state & 0xFFFF;
}
int getState() {
return verbatim << 31 | closingQuote << 16 | (kindStack & 0xFFFF);
}
void enter(kind k) {
kindStack = kindStack << 2 | k;
}
void leave(kind k) {
if (k == currentKind()) {
kindStack = kindStack >> 2;
}
}
kind currentKind() {
return static_cast<kind>(kindStack & 0x3);
}
kind stateKind2(int ks) {
if (0 == ks) {
return none;
} else {
kind k1 = stateKind2(ks >> 2);
kind k2 = static_cast<kind>(ks & 0x3);
if (embedded == k1 && k2 == comment) {
return embedded;
} else {
return k2;
}
}
}
}
kind stateKind() {
return stateKind2(kindStack);
}
};
void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) {
LexAccessor styler(pAccess);
CharacterSet setDoxygen(CharacterSet::setAlpha, "");
CharacterSet setNumber(CharacterSet::setNone, "0123456789abcdefABCDEFxoXO");
CharacterSet setNumber(CharacterSet::setNone, "0123456789abcdefABCDEFxoXO_");
StyleContext sc(startPos, length, initStyle, styler, 0x7f);
int styleBeforeDocKeyword = SCE_VISUALPROLOG_DEFAULT;
Sci_Position currentLine = styler.GetLine(startPos);
int closingQuote = '"';
int nestLevel = 0;
if (currentLine >= 1)
{
nestLevel = styler.GetLineState(currentLine - 1);
closingQuote = nestLevel;
lineState ls;
if (sc.currentLine >= 1) {
ls.setState(styler.GetLineState(sc.currentLine - 1));
}
// Truncate ppDefineHistory before current line
bool newState = false;
for (; sc.More(); sc.Forward()) {
Sci_Position currentLineEntry = sc.currentLine;
if (newState) {
newState = false;
int state;
switch (ls.stateKind()) {
case lineState::comment:
state = SCE_VISUALPROLOG_COMMENT_BLOCK;
break;
case lineState::embedded:
state = SCE_VISUALPROLOG_EMBEDDED;
break;
case lineState::placeholder:
state = SCE_VISUALPROLOG_PLACEHOLDER;
break;
default:
state = SCE_VISUALPROLOG_DEFAULT;
break;
}
sc.SetState(state);
}
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_VISUALPROLOG_OPERATOR:
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
break;
case SCE_VISUALPROLOG_NUMBER:
// We accept almost anything because of hex. and number suffixes
if (!(setNumber.Contains(sc.ch)) || (sc.Match('.') && IsADigit(sc.chNext))) {
case SCE_VISUALPROLOG_OPERATOR:
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
case SCE_VISUALPROLOG_IDENTIFIER:
if (!isIdChar(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (0 == strcmp(s, "end")) {
endLookAhead(s, styler, sc.currentPos);
break;
case SCE_VISUALPROLOG_NUMBER:
// We accept almost anything because of hex, '.' and number suffixes
if (!(setNumber.Contains(sc.ch)) || (sc.Match('.') && IsADigit(sc.chNext))) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
if (majorKeywords.InList(s)) {
sc.ChangeState(SCE_VISUALPROLOG_KEY_MAJOR);
} else if (minorKeywords.InList(s)) {
sc.ChangeState(SCE_VISUALPROLOG_KEY_MINOR);
break;
case SCE_VISUALPROLOG_IDENTIFIER:
if (!isIdChar(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (0 == strcmp(s, "end")) {
endLookAhead(s, styler, sc.currentPos);
}
if (majorKeywords.InList(s)) {
sc.ChangeState(SCE_VISUALPROLOG_KEY_MAJOR);
} else if (minorKeywords.InList(s)) {
sc.ChangeState(SCE_VISUALPROLOG_KEY_MINOR);
}
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
case SCE_VISUALPROLOG_VARIABLE:
case SCE_VISUALPROLOG_ANONYMOUS:
if (!isIdChar(sc.ch)) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
case SCE_VISUALPROLOG_KEY_DIRECTIVE:
if (!isLowerLetter(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (!directiveKeywords.InList(s+1)) {
sc.ChangeState(SCE_VISUALPROLOG_IDENTIFIER);
break;
case SCE_VISUALPROLOG_VARIABLE:
case SCE_VISUALPROLOG_ANONYMOUS:
if (!isIdChar(sc.ch)) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
case SCE_VISUALPROLOG_COMMENT_BLOCK:
if (sc.Match('*', '/')) {
sc.Forward();
nestLevel--;
int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK;
sc.ForwardSetState(nextState);
} else if (sc.Match('/', '*')) {
sc.Forward();
nestLevel++;
} else if (sc.Match('@')) {
styleBeforeDocKeyword = sc.state;
sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
}
break;
case SCE_VISUALPROLOG_COMMENT_LINE:
if (sc.MatchLineEnd()) {
int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK;
sc.SetState(nextState);
} else if (sc.Match('@')) {
styleBeforeDocKeyword = sc.state;
sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
}
break;
case SCE_VISUALPROLOG_COMMENT_KEY_ERROR:
if (!setDoxygen.Contains(sc.ch) || sc.MatchLineEnd()) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (docKeywords.InList(s+1)) {
sc.ChangeState(SCE_VISUALPROLOG_COMMENT_KEY);
break;
case SCE_VISUALPROLOG_KEY_DIRECTIVE:
if (!isLowerLetter(sc.ch)) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (!directiveKeywords.InList(s + 1)) {
sc.ChangeState(SCE_VISUALPROLOG_IDENTIFIER);
}
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
if (SCE_VISUALPROLOG_COMMENT_LINE == styleBeforeDocKeyword && sc.MatchLineEnd()) {
// end line comment
int nextState = (nestLevel == 0) ? SCE_VISUALPROLOG_DEFAULT : SCE_VISUALPROLOG_COMMENT_BLOCK;
break;
case SCE_VISUALPROLOG_COMMENT_LINE:
if (sc.MatchLineEnd()) {
int nextState = (lineState::comment == ls.currentKind()) ? SCE_VISUALPROLOG_COMMENT_BLOCK : SCE_VISUALPROLOG_DEFAULT;
sc.SetState(nextState);
} else {
sc.SetState(styleBeforeDocKeyword);
if (SCE_VISUALPROLOG_COMMENT_BLOCK == styleBeforeDocKeyword && sc.Match('*', '/')) {
// we have consumed the '*' if it comes immediately after the docKeyword
sc.Forward();
sc.Forward();
nestLevel--;
if (0 == nestLevel) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
} else if (sc.Match('@')) {
styleBeforeDocKeyword = SCE_VISUALPROLOG_COMMENT_LINE;
sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
}
break;
case SCE_VISUALPROLOG_COMMENT_BLOCK:
if (sc.Match('*', '/')) {
sc.Forward();
ls.leave(lineState::comment);
newState = true;
} else if (sc.Match('/', '*')) {
sc.Forward();
ls.enter(lineState::comment);
} else if (sc.Match('@')) {
styleBeforeDocKeyword = SCE_VISUALPROLOG_COMMENT_BLOCK;
sc.SetState(SCE_VISUALPROLOG_COMMENT_KEY_ERROR);
}
break;
case SCE_VISUALPROLOG_COMMENT_KEY_ERROR:
if (!setDoxygen.Contains(sc.ch) || sc.MatchLineEnd()) {
char s[1000];
sc.GetCurrent(s, sizeof(s));
if (docKeywords.InList(s + 1)) {
sc.ChangeState(SCE_VISUALPROLOG_COMMENT_KEY);
}
if (SCE_VISUALPROLOG_COMMENT_LINE == styleBeforeDocKeyword && sc.MatchLineEnd()) {
// end line comment
int nextState = (lineState::comment == ls.currentKind()) ? SCE_VISUALPROLOG_COMMENT_BLOCK : SCE_VISUALPROLOG_DEFAULT;
sc.SetState(nextState);
} else {
sc.SetState(styleBeforeDocKeyword);
if (SCE_VISUALPROLOG_COMMENT_BLOCK == styleBeforeDocKeyword && sc.Match('*', '/')) {
// we have consumed the '*' if it comes immediately after the docKeyword
sc.Forward();
ls.leave(lineState::comment);
newState = true;
}
}
}
}
break;
case SCE_VISUALPROLOG_STRING_ESCAPE:
case SCE_VISUALPROLOG_STRING_ESCAPE_ERROR:
// return to SCE_VISUALPROLOG_STRING and treat as such (fall-through)
sc.SetState(SCE_VISUALPROLOG_STRING);
// Falls through.
case SCE_VISUALPROLOG_STRING:
if (sc.MatchLineEnd()) {
sc.SetState(SCE_VISUALPROLOG_STRING_EOL_OPEN);
} else if (sc.Match(closingQuote)) {
sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
} else if (sc.Match('\\')) {
sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);
forwardEscapeLiteral(sc, SCE_VISUALPROLOG_STRING_ESCAPE);
}
break;
case SCE_VISUALPROLOG_STRING_EOL_OPEN:
if (sc.atLineStart) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
case SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL:
case SCE_VISUALPROLOG_STRING_VERBATIM_EOL:
if(sc.state == SCE_VISUALPROLOG_STRING_VERBATIM_EOL && !sc.atLineStart)
break;
// return to SCE_VISUALPROLOG_STRING_VERBATIM and treat as such (fall-through)
sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM);
// Falls through.
case SCE_VISUALPROLOG_STRING_VERBATIM:
if (sc.MatchLineEnd()) {
sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_EOL);
} else if (sc.Match(closingQuote)) {
if (closingQuote == sc.chNext) {
sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL);
sc.Forward();
} else {
sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
case SCE_VISUALPROLOG_STRING_ESCAPE_ERROR:
if (sc.atLineStart) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
break;
}
}
break;
[[fallthrough]];
case SCE_VISUALPROLOG_STRING_ESCAPE:
case SCE_VISUALPROLOG_STRING_QUOTE:
case SCE_VISUALPROLOG_STRING_EOL:
// return to SCE_VISUALPROLOG_STRING and treat as such (fallthrough)
sc.SetState(SCE_VISUALPROLOG_STRING);
[[fallthrough]];
case SCE_VISUALPROLOG_STRING:
if (sc.MatchLineEnd() | sc.atLineEnd) {
if (ls.verbatim) {
sc.SetState(SCE_VISUALPROLOG_STRING_EOL);
} else {
ls.closingQuote = 0;
sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);
}
} else if (sc.Match(ls.closingQuote)) {
if (ls.verbatim && ls.closingQuote == sc.chNext) {
sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE);
sc.Forward();
} else {
ls.closingQuote = 0;
sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);
sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
}
} else if (!ls.verbatim && sc.Match('\\')) {
sc.SetState(SCE_VISUALPROLOG_STRING_ESCAPE_ERROR);
sc.Forward();
if (sc.MatchLineEnd()) {
sc.ForwardSetState(SCE_VISUALPROLOG_DEFAULT);
} else {
if (sc.Match('"') || sc.Match('\'') || sc.Match('\\') || sc.Match('n') || sc.Match('l') || sc.Match('r') || sc.Match('t')) {
sc.ChangeState(SCE_VISUALPROLOG_STRING_ESCAPE);
} else if (sc.Match('u')) {
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
if (IsADigit(sc.chNext, 16)) {
sc.Forward();
sc.ChangeState(SCE_VISUALPROLOG_STRING_ESCAPE);
}
}
}
}
}
}
}
break;
case SCE_VISUALPROLOG_EMBEDDED:
if (sc.Match('|', ']')) {
sc.Forward();
ls.leave(lineState::embedded);
newState = true;
} else if (sc.Match('[', '|')) {
sc.Forward();
ls.enter(lineState::embedded);
} else if (sc.Match('{', '|') && lineState::comment != ls.currentKind()) {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
} else if (sc.Match('/', '*')) {
sc.Forward();
ls.enter(lineState::comment);
} else if (sc.Match('*', '/')) {
sc.Forward();
ls.leave(lineState::comment);
newState = true;
}
break;
case SCE_VISUALPROLOG_PLACEHOLDER:
if (lineState::embedded == ls.currentKind()) {
sc.SetState(SCE_VISUALPROLOG_EMBEDDED);
} else {
sc.SetState(SCE_VISUALPROLOG_DEFAULT);
}
break;
}
if (sc.MatchLineEnd()) {
// Update the line state, so it can be seen by next line
int lineState = 0;
if (SCE_VISUALPROLOG_STRING_VERBATIM_EOL == sc.state) {
lineState = closingQuote;
} else if (SCE_VISUALPROLOG_COMMENT_BLOCK == sc.state) {
lineState = nestLevel;
if (currentLineEntry != sc.currentLine) {
styler.SetLineState(currentLineEntry, ls.getState());
}
if (sc.MatchLineEnd() | sc.atLineEnd) {
if (sc.More()) { // currentLine can be outside the document
styler.SetLineState(sc.currentLine, ls.getState());
}
styler.SetLineState(currentLine, lineState);
currentLine++;
}
// Determine if a new state should be entered.
if (sc.state == SCE_VISUALPROLOG_DEFAULT) {
if (options.verbatimStrings && sc.Match('@') && isOpenStringVerbatim(sc.chNext, closingQuote)) {
sc.SetState(SCE_VISUALPROLOG_STRING_VERBATIM);
if (options.verbatimStrings && sc.Match('@') && ls.isOpenStringVerbatim(sc.chNext)) {
ls.verbatim = true;
sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);
sc.Forward();
} else if (IsADigit(sc.ch) || (sc.Match('.') && IsADigit(sc.chNext))) {
sc.SetState(SCE_VISUALPROLOG_NUMBER);
@ -436,19 +579,40 @@ void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position leng
sc.SetState(SCE_VISUALPROLOG_ANONYMOUS);
} else if (sc.Match('/', '*')) {
sc.SetState(SCE_VISUALPROLOG_COMMENT_BLOCK);
nestLevel = 1;
sc.Forward(); // Eat the * so it isn't used for the end of the comment
ls.enter(lineState::comment);
sc.Forward();
} else if (sc.Match('%')) {
sc.SetState(SCE_VISUALPROLOG_COMMENT_LINE);
} else if (sc.Match('[', '|')) {
sc.SetState(SCE_VISUALPROLOG_EMBEDDED);
ls.enter(lineState::embedded);
sc.Forward();
} else if (sc.Match('{', '|')) {
sc.SetState(SCE_VISUALPROLOG_PLACEHOLDER);
ls.enter(lineState::placeholder);
sc.Forward();
} else if (sc.Match('|', '}')) {
sc.SetState(SCE_VISUALPROLOG_PLACEHOLDER);
sc.Forward();
if (':' == sc.chNext) {
sc.Forward();
for (; isIdChar(sc.chNext); sc.Forward()) {
}
}
ls.leave(lineState::placeholder);
newState = true;
} else if (sc.Match('\'')) {
closingQuote = '\'';
sc.SetState(SCE_VISUALPROLOG_STRING);
ls.verbatim = false;
ls.closingQuote = '\'';
sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);
} else if (sc.Match('"')) {
closingQuote = '"';
sc.SetState(SCE_VISUALPROLOG_STRING);
ls.verbatim = false;
ls.closingQuote = '"';
sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);
} else if (options.backQuotedStrings && sc.Match('`')) {
closingQuote = '`';
sc.SetState(SCE_VISUALPROLOG_STRING);
ls.verbatim = false;
ls.closingQuote = '`';
sc.SetState(SCE_VISUALPROLOG_STRING_QUOTE);
} else if (sc.Match('#')) {
sc.SetState(SCE_VISUALPROLOG_KEY_DIRECTIVE);
} else if (isoperator(static_cast<char>(sc.ch)) || sc.Match('\\') ||
@ -456,7 +620,6 @@ void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position leng
sc.SetState(SCE_VISUALPROLOG_OPERATOR);
}
}
}
sc.Complete();
styler.Flush();
@ -473,7 +636,7 @@ void SCI_METHOD LexerVisualProlog::Lex(Sci_PositionU startPos, Sci_Position leng
#endif
#endif
void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument* pAccess) {
LexAccessor styler(pAccess);
@ -482,7 +645,7 @@ void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position len
Sci_Position currentLine = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (currentLine > 0)
levelCurrent = styler.LevelAt(currentLine-1) >> 16;
levelCurrent = styler.LevelAt(currentLine - 1) >> 16;
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
@ -508,7 +671,7 @@ void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position len
}
if (!IsASpace(ch))
visibleChars++;
if (atEOL || (i == endPos-1)) {
if (atEOL || (i == endPos - 1)) {
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
if (levelUse < levelNext)
@ -519,7 +682,7 @@ void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position len
currentLine++;
levelCurrent = levelNext;
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
styler.SetLevel(currentLine, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
}
@ -527,5 +690,6 @@ void SCI_METHOD LexerVisualProlog::Fold(Sci_PositionU startPos, Sci_Position len
}
}
}
}
LexerModule lmVisualProlog(SCLEX_VISUALPROLOG, LexerVisualProlog::LexerFactoryVisualProlog, "visualprolog", visualPrologWordLists);

View File

@ -251,6 +251,9 @@ void FoldYAMLDoc(Sci_PositionU startPos, Sci_Position length, int /*initStyle -
const Sci_Position maxPos = startPos + length;
const Sci_Position maxLines = styler.GetLine(maxPos - 1); // Requested last line
const Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line
// property fold.comment.yaml
// Set to 1 to allow folding of comment blocks in YAML.
const bool foldComment = styler.GetPropertyInt("fold.comment.yaml") != 0;
// Backtrack to previous non-blank line so we can determine indent level

View File

@ -73,7 +73,7 @@ using CharacterSet = CharacterSetArray<0x80>;
template <typename T, typename... Args>
constexpr bool AnyOf(T t, Args... args) noexcept {
#if defined(__clang__)
static_assert(__is_integral(T));
static_assert(__is_integral(T) || __is_enum(T));
#endif
return ((t == args) || ...);
}

View File

@ -134,7 +134,7 @@ public:
void DefineWordListSets(const char * const wordListDescriptions[]) {
if (wordListDescriptions) {
for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
if (!wordLists.empty())
if (wl > 0)
wordLists += "\n";
wordLists += wordListDescriptions[wl];
}

View File

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

View File

@ -853,7 +853,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.2.5;
CURRENT_PROJECT_VERSION = 5.2.6;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;
@ -880,7 +880,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 5.2.5;
CURRENT_PROJECT_VERSION = 5.2.6;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 4F446KW87E;
DYLIB_COMPATIBILITY_VERSION = 1;

View File

@ -4,8 +4,8 @@
#include <windows.h>
#define VERSION_LEXILLA "5.2.5"
#define VERSION_WORDS 5, 2, 5, 0
#define VERSION_LEXILLA "5.2.6"
#define VERSION_WORDS 5, 2, 6, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_WORDS

View File

@ -39,7 +39,7 @@
{2}# here-doc-delimiter=12, here-doc=13{0}
{12}<<EOF{13}
Here-doc.
EOF{0}
{12}EOF{0}
{2}# other quoted types are mapped to current classes{0}

View File

@ -0,0 +1,7 @@
echo '$'
echo "$"
echo "$"
echo "$"x""
echo x$'\t'y
echo "x$'\t'y"
echo "x\ty"

View File

@ -0,0 +1,8 @@
0 400 0 echo '$'
0 400 0 echo "$"
0 400 0 echo "$"
0 400 0 echo "$"x""
0 400 0 echo x$'\t'y
0 400 0 echo "x$'\t'y"
0 400 0 echo "x\ty"
0 400 0

View File

@ -0,0 +1,7 @@
{4}echo{0} {6}'$'{0}
{4}echo{0} {5}"$"{0}
{4}echo{0} {5}"$"{0}
{4}echo{0} {5}"$"{8}x{5}""{0}
{4}echo{0} {8}x{5}$'\t'{8}y{0}
{4}echo{0} {5}"x$'\t'y"{0}
{4}echo{0} {5}"x\ty"{0}

View File

@ -0,0 +1,7 @@
if [ -n "$eth" -o -n "$wlan" ]; then
fi
test $((1 + 1)) -eq 2 && echo yes
[ $((1 + 1)) -eq 2 ] && echo yes
ls -a --directory

View File

@ -0,0 +1,8 @@
2 400 0 + if [ -n "$eth" -o -n "$wlan" ]; then
0 401 0 | fi
1 400 0
0 400 0 test $((1 + 1)) -eq 2 && echo yes
0 400 0 [ $((1 + 1)) -eq 2 ] && echo yes
1 400 0
0 400 0 ls -a --directory
0 400 0

View File

@ -0,0 +1,7 @@
{4}if{0} {7}[{0} {4}-n{0} {5}"{9}$eth{5}"{0} {4}-o{0} {4}-n{0} {5}"{9}$wlan{5}"{0} {7}];{0} {4}then{0}
{4}fi{0}
{4}test{0} {7}$(({3}1{0} {7}+{0} {3}1{7})){0} {4}-eq{0} {3}2{0} {7}&&{0} {4}echo{0} {8}yes{0}
{7}[{0} {7}$(({3}1{0} {7}+{0} {3}1{7})){0} {4}-eq{0} {3}2{0} {7}]{0} {7}&&{0} {4}echo{0} {8}yes{0}
{8}ls{0} {8}-a{0} {8}--directory{0}

View File

@ -0,0 +1,11 @@
echo $*
echo $@
echo $?
echo $-
echo $$
echo $!
echo $_
echo $%
echo $<
ifeth=$(ls /sys/class/net | grep ^"$intf" | grep "$intf"$)

View File

@ -0,0 +1,12 @@
0 400 0 echo $*
0 400 0 echo $@
0 400 0 echo $?
0 400 0 echo $-
0 400 0 echo $$
0 400 0 echo $!
0 400 0 echo $_
0 400 0 echo $%
0 400 0 echo $<
1 400 0
0 400 0 ifeth=$(ls /sys/class/net | grep ^"$intf" | grep "$intf"$)
0 400 0

View File

@ -0,0 +1,11 @@
{4}echo{0} {9}$*{0}
{4}echo{0} {9}$@{0}
{4}echo{0} {9}$?{0}
{4}echo{0} {9}$-{0}
{4}echo{0} {9}$${0}
{4}echo{0} {9}$!{0}
{4}echo{0} {9}$_{0}
{4}echo{0} ${7}%{0}
{4}echo{0} ${7}<{0}
{8}ifeth{7}=$({8}ls{0} {7}/{8}sys{7}/{8}class{7}/{8}net{0} {7}|{0} {8}grep{0} {7}^{5}"{9}$intf{5}"{0} {7}|{0} {8}grep{0} {5}"{9}$intf{5}"{0}${7}){0}

View File

@ -0,0 +1,11 @@
echo $*
echo $@
echo $?
echo $-
echo $$
echo $!
echo $_
echo $%
echo $<
ifeth=$(ls /sys/class/net | grep ^"$intf" | grep "$intf"$)

View File

@ -0,0 +1,12 @@
0 400 0 echo $*
0 400 0 echo $@
0 400 0 echo $?
0 400 0 echo $-
0 400 0 echo $$
0 400 0 echo $!
0 400 0 echo $_
0 400 0 echo $%
0 400 0 echo $<
1 400 0
0 400 0 ifeth=$(ls /sys/class/net | grep ^"$intf" | grep "$intf"$)
0 400 0

View File

@ -0,0 +1,11 @@
{4}echo{0} {9}$*{0}
{4}echo{0} {9}$@{0}
{4}echo{0} {9}$?{0}
{4}echo{0} {9}$-{0}
{4}echo{0} {9}$${0}
{4}echo{0} {9}$!{0}
{4}echo{0} {9}$_{0}
{4}echo{0} {9}$%{0}
{4}echo{0} {9}$<{0}
{8}ifeth{7}=$({8}ls{0} {7}/{8}sys{7}/{8}class{7}/{8}net{0} {7}|{0} {8}grep{0} {7}^{5}"{9}$intf{5}"{0} {7}|{0} {8}grep{0} {5}"{9}$intf{5}"{0}${7}){0}

View File

@ -40,7 +40,7 @@
$((1+2))
$(pwd)
`pwd`
EOF{0}
{12}EOF{0}
{2}# Quoted delimiter treats here-doc as simple string{0}
{4}cat{0} {12}<<"EOF"{13}
@ -49,12 +49,12 @@ EOF{0}
$((1+2))
$(pwd)
`pwd`
EOF{0}
{12}EOF{0}
{2}# Escaped same as quoted{0}
{4}cat{0} {12}<<\EOF{13}
$scalar
EOF{0}
{12}EOF{0}
{2}# Nesting{0}
{4}echo{0} {5}"$((1 + 2))"{0} {2}#{0}

View File

@ -2,15 +2,15 @@
{2}# so that both the scope of the command and the internal structure are visible.{0}
{2}# Nested command{0}
{71}$({72}ls{64} {71}-{72}la{71}$({72}ls{64} {71}*.{72}c{71})){0}
{71}$({72}ls{64} {72}-la{71}$({72}ls{64} {71}*.{72}c{71})){0}
{2}# Check strings and backticks in command{0}
{4}echo{0} {71}$({70}'ls'{64} {69}"."{64} {75}`ls`{64} {69}$'.'{64} {69}$"."{71}){0}
{8}PROJECT_DIR{7}={71}$({72}rlwrap{64} {72}-S{64} {69}"Enter source path: "{64} {72}-e{64} {70}''{64} {71}-{72}i{64} {72}-o{64} {72}cat{71}){0}
{8}PROJECT_DIR{7}={71}$({72}rlwrap{64} {72}-S{64} {69}"Enter source path: "{64} {72}-e{64} {70}''{64} {72}-i{64} {72}-o{64} {72}cat{71}){0}
{2}# Multiple nesting levels{0}
{71}$({72}ls{64} {71}-{72}la{71}$({72}ls{64} {71}$({72}c{71}){64} {69}$'*.c'{64} {75}` $(${s})`{71})){0}
{71}$({72}ls{64} {72}-la{71}$({72}ls{64} {71}$({72}c{71}){64} {69}$'*.c'{64} {75}` $(${s})`{71})){0}
{2}# Multi-line{0}
{71}$({72}ls{64} {71}|{64}

View File

@ -11,7 +11,7 @@
{5}"x{7}$({8}ls{7}){5}"{0}
{2}# Nested command{0}
{7}$({8}ls{0} {7}-{8}la{7}$({8}ls{0} {7}*.{8}c{7})){0}
{7}$({8}ls{0} {8}-la{7}$({8}ls{0} {7}*.{8}c{7})){0}
{2}# Check strings and backticks in command{0}
{4}echo{0} {7}$({6}'ls'{0} {5}"."{0} {11}`ls`{0} {5}$'.'{0} {5}$"."{7}){0}
@ -38,9 +38,9 @@
{9}$scalar{13}
{10}${var}{13}
{7}$(({3}1{7}+{3}2{7})){13}
{7}$({8}pwd{7}){13}
{7}$({4}pwd{7}){13}
{11}`pwd`{13}
EOF{0}
{12}EOF{0}
{2}# Quoted delimiter treats here-doc as simple string{0}
{4}cat{0} {12}<<"EOF"{13}
@ -49,19 +49,19 @@ EOF{0}
$((1+2))
$(pwd)
`pwd`
EOF{0}
{12}EOF{0}
{2}# Escaped same as quoted{0}
{4}cat{0} {12}<<\EOF{13}
$scalar
EOF{0}
{12}EOF{0}
{2}# Nesting{0}
{4}echo{0} {5}"{7}$(({3}1{0} {7}+{0} {3}2{7})){5}"{0} {2}#{0}
{4}echo{0} {5}"{7}$[{3}1{0} {7}+{0} {3}2{7}]{5}"{0} {2}#{0}
{2}# Multiple nesting levels{0}
{7}$({8}ls{0} {7}-{8}la{7}$({8}ls{0} {7}$({8}c{7}){0} {5}$'*.c'{0} {11}` {7}$({10}${s}{7}){11}`{7})){0}
{7}$({8}ls{0} {8}-la{7}$({8}ls{0} {7}$({8}c{7}){0} {5}$'*.c'{0} {11}` {7}$({10}${s}{7}){11}`{7})){0}
{2}# Multi-line{0}
{7}$({8}ls{0} {7}|{0}

View File

@ -1,7 +1,7 @@
lexer.*.bsh=bash
fold=1
fold.comment=1
keywords.*.bsh=case cat do done echo else esac exit export fi find for if in set then while
keywords.*.bsh=case cat do done echo else esac exit export fi find for if in pwd set then while
# Can use substyles for identifiers and scalars
substyles.bash.8=1
@ -15,6 +15,21 @@ lexer.bash.styling.inside.parameter=0
lexer.bash.styling.inside.heredoc=0
lexer.bash.command.substitution=0
match Issue180.bsh
lexer.bash.styling.inside.string=1
match Issue182.bsh
lexer.bash.styling.inside.string=1
match Issue184.bsh
lexer.bash.styling.inside.string=1
lexer.bash.command.substitution=1
match Issue184Copy.bsh
lexer.bash.styling.inside.string=1
lexer.bash.command.substitution=1
lexer.bash.special.parameter=*@#?-$!%<
match NestedStyledInside.bsh
lexer.bash.styling.inside.string=1
lexer.bash.styling.inside.backticks=1

View File

@ -21,6 +21,9 @@ OUT_FILE=${PROJECT_PATH}/testing.txt
EOF
) > $OUT_FILE
# Issue 188, keyword before redirection operator
pwd>>$OUT_FILE
find "$PROJECT_PATH/src" -maxdepth 1 -type f |\
while read -r f; do
{

View File

@ -21,6 +21,9 @@
0 401 0 | EOF
0 400 0 ) > $OUT_FILE
1 400 0
0 400 0 # Issue 188, keyword before redirection operator
0 400 0 pwd>>$OUT_FILE
1 400 0
0 400 0 find "$PROJECT_PATH/src" -maxdepth 1 -type f |\
2 400 0 + while read -r f; do
2 401 0 + {

View File

@ -16,12 +16,15 @@
{8}OUT_FILE{7}={10}${PROJECT_PATH}{7}/{8}testing.txt{0}
{7}({8}cat{12}<<EOF{13}
{7}({4}cat{12}<<EOF{13}
Last run $(date +'%Y-%m-%d') at $(date +'%H:%M:%S.%2N')
EOF{0}
{12}EOF{0}
{7}){0} {7}>{0} {9}$OUT_FILE{0}
{4}find{0} {5}"$PROJECT_PATH/src"{0} {7}-{8}maxdepth{0} {3}1{0} {7}-{8}type{0} {8}f{0} {7}|\{0}
{2}# Issue 188, keyword before redirection operator{0}
{4}pwd{7}>>{9}$OUT_FILE{0}
{4}find{0} {5}"$PROJECT_PATH/src"{0} {8}-maxdepth{0} {3}1{0} {8}-type{0} {8}f{0} {7}|\{0}
{4}while{0} {8}read{0} {8}-r{0} {8}f{7};{0} {4}do{0}
{7}{{0}
{8}python3{0} {8}-c{0} {5}"print();print('='*50)"{7};\{0}
@ -33,7 +36,7 @@ EOF{0}
{2}# Issue 137, should be shift but here-doc was detected{0}
{4}echo{0} {7}$(({0} {8}x{0} {7}<<{0} {8}END{0} {7})){0}
{8}pwd{0}
{4}pwd{0}
{8}END{0}
{8}INVALID_NUMBER{7}={1}0#0000{0}

View File

@ -95,6 +95,10 @@ GCC Pointer 25
| ^
Bash Diagnostic 26
echoer153.sh: line 22: [: missing `]'
Escape Sequence 23


View File

@ -95,6 +95,10 @@
0 400 0 | ^
0 400 0
0 400 0
0 400 0 Bash Diagnostic 26
0 400 0 echoer153.sh: line 22: [: missing `]'
0 400 0
0 400 0
0 400 0 Escape Sequence 23
0 400 0 
0 400 0

View File

@ -95,6 +95,10 @@ GCC Pointer 25
| ^
{0}
Bash Diagnostic 26
{26}echoer153.sh: line 22: [: missing `]'
{0}
Escape Sequence 23
{23}{0}

View File

@ -1,8 +1,8 @@
lexer.*=hypertext
keywords.*=b body content head height href html img link meta \
name rel script src strong title type width xmlns
keywords.*=b body content head height href html img language link meta \
name rel runat script src strong title type width xmlns
keywords2.*=function var
keywords3.*=sub
keywords3.*=dim sub
keywords5.*=echo __file__ __line__
fold=1
fold.html=1

View File

@ -0,0 +1,24 @@
<%@ register tagprefix="uc1"
tagname="CalendarUserControl"
src="~/CalendarUserControl.ascx" %>
<!DOCTYPE html>
<html>
<%@language=VBScript%>
<%-- comment --%>
<script type="text/vbscript">
'1%>2
'1?>2
'%>
'?>
</script>
<script type="text/vbscript">
dim e="%>"
dim f="?>"
</script>
Start
<%response.write("1")%>
<% 'comment%>
<%dim x="2"'comment%>
<%response.write(x)%>
End
</html>

View File

@ -0,0 +1,25 @@
2 400 0 + <%@ register tagprefix="uc1"
0 401 0 | tagname="CalendarUserControl"
0 401 0 | src="~/CalendarUserControl.ascx" %>
0 400 0 <!DOCTYPE html>
2 400 0 + <html>
0 401 0 | <%@language=VBScript%>
0 401 0 | <%-- comment --%>
2 401 0 + <script type="text/vbscript">
0 402 0 | '1%>2
0 402 0 | '1?>2
0 402 0 | '%>
0 402 0 | '?>
0 402 0 | </script>
2 401 0 + <script type="text/vbscript">
0 402 0 | dim e="%>"
0 402 0 | dim f="?>"
0 402 0 | </script>
0 401 0 | Start
0 401 0 | <%response.write("1")%>
0 401 0 | <% 'comment%>
0 401 0 | <%dim x="2"'comment%>
0 401 0 | <%response.write(x)%>
0 401 0 | End
0 401 0 | </html>
0 400 0

View File

@ -0,0 +1,24 @@
{15}<%@{16} register tagprefix="uc1"
tagname="CalendarUserControl"
src="~/CalendarUserControl.ascx" {15}%>{0}
{21}<!{26}DOCTYPE html{21}>{0}
{1}<html>{0}
{15}<%@{16}language=VBScript{15}%>{0}
{15}<%--{20} comment --{15}%>{0}
{1}<script{8} {3}type{8}={6}"text/vbscript"{1}>{70}
{72}'1%>2{71}
{72}'1?>2{71}
{72}'%>{71}
{72}'?>{71}
{1}</script>{0}
{1}<script{8} {3}type{8}={6}"text/vbscript"{1}>{70}
{74}dim{71} {76}e{71}={75}"%>"{71}
{74}dim{71} {76}f{71}={75}"?>"{71}
{1}</script>{0}
Start
{15}<%{86}response.write{81}({85}"1"{81}){15}%>{0}
{15}<%{81} {82}'comment{15}%>{0}
{15}<%{84}dim{81} {86}x{81}={85}"2"{82}'comment{15}%>{0}
{15}<%{86}response.write{81}({86}x{81}){15}%>{0}
End
{1}</html>{0}

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<%@language=JScript%>
<%-- comment --%>
<script type="text/javascript">
//%>
//?>
</script>
<script type="text/javascript">
e="%>";
f="?>";
</script>
Start
<%Response.Write("1")%>
<%var x=3;//comment%>
<%x=3;//comment ?> %>
<%Response.Write(x)%>
End
</html>

View File

@ -0,0 +1,20 @@
0 400 0 <!DOCTYPE html>
2 400 0 + <html>
0 401 0 | <%@language=JScript%>
0 401 0 | <%-- comment --%>
2 401 0 + <script type="text/javascript">
0 402 0 | //%>
0 402 0 | //?>
0 402 0 | </script>
2 401 0 + <script type="text/javascript">
0 402 0 | e="%>";
0 402 0 | f="?>";
0 402 0 | </script>
0 401 0 | Start
0 401 0 | <%Response.Write("1")%>
0 401 0 | <%var x=3;//comment%>
0 401 0 | <%x=3;//comment ?> %>
0 401 0 | <%Response.Write(x)%>
0 401 0 | End
0 401 0 | </html>
0 400 0

View File

@ -0,0 +1,19 @@
{21}<!{26}DOCTYPE html{21}>{0}
{1}<html>{0}
{15}<%@{16}language=JScript{15}%>{0}
{15}<%--{20} comment --{15}%>{0}
{1}<script{8} {3}type{8}={6}"text/javascript"{1}>{40}
{43}//%>{41}
{43}//?>{41}
{1}</script>{0}
{1}<script{8} {3}type{8}={6}"text/javascript"{1}>{40}
{46}e{50}={48}"%>"{50};{41}
{46}f{50}={48}"?>"{50};{41}
{1}</script>{0}
Start
{15}<%{61}Response.Write{65}({63}"1"{65}){15}%>{0}
{15}<%{62}var{56} {61}x{65}={60}3{65};{58}//comment{15}%>{0}
{15}<%{61}x{65}={60}3{65};{58}//comment ?> {15}%>{0}
{15}<%{61}Response.Write{65}({61}x{65}){15}%>{0}
End
{1}</html>{0}

View File

@ -59,6 +59,15 @@ arguments = 10;
y = x + arguments;
end
% Semicolon is equivalent to a comment
function y = foo(x)
;;;;;;;
arguments
x
end
y = x + 2;
end
% Arguments block is illegal in nested functions,
% but lexer should process it anyway
function y = foo (x)
@ -70,6 +79,7 @@ end
arguments
x (1,2) {mustBeReal(x)}
end
var = 0;
arguments = 5;
y = arguments + x;
end
@ -86,4 +96,42 @@ arguments
x
end
y = x;
end
end
% "arguments" is an argument name too
function r = foo(x, arguments)
arguments
x
arguments
end
r = bar(x, arguments{:});
end
% Multiple arguments blocks
function [a, b] = foo(x, y, varargin)
arguments(Input)
x (1,4) {mustBeReal}
y (1,:) {mustBeInteger} = x(2:end);
end
arguments(Input, Repeating)
varargin
end
arguments(Output)
a (1,1) {mustBeReal}
b (1,1) {mustBeNonNegative}
end
var = 10;
arguments = {"now", "it's", "variable"};
[a, b] = bar(x, y, arguments);
end
% One line function with arguments block.
% This code style is rarely used (if at all), but the
% lexer shouldn't break
function y = foo(x); arguments; x; end; y = bar(x); end

View File

@ -59,6 +59,15 @@
0 401 401 | y = x + arguments;
0 401 400 | end
1 400 400
0 400 400 % Semicolon is equivalent to a comment
2 400 401 + function y = foo(x)
0 401 401 | ;;;;;;;
2 401 402 + arguments
0 402 402 | x
0 402 401 | end
0 401 401 | y = x + 2;
0 401 400 | end
1 400 400
0 400 400 % Arguments block is illegal in nested functions,
0 400 400 % but lexer should process it anyway
2 400 401 + function y = foo (x)
@ -70,6 +79,7 @@
2 402 403 + arguments
0 403 403 | x (1,2) {mustBeReal(x)}
0 403 402 | end
0 402 402 | var = 0;
0 402 402 | arguments = 5;
0 402 402 | y = arguments + x;
0 402 401 | end
@ -86,4 +96,43 @@
0 401 401 | x
0 401 400 | end
0 400 400 y = x;
0 400 3ff end
0 400 3ff end
1 3ff 3ff
0 3ff 3ff % "arguments" is an argument name too
2 3ff 400 + function r = foo(x, arguments)
2 400 401 + arguments
0 401 401 | x
0 401 401 | arguments
0 401 400 | end
0 400 400 r = bar(x, arguments{:});
0 400 3ff end
1 3ff 3ff
0 3ff 3ff % Multiple arguments blocks
2 3ff 400 + function [a, b] = foo(x, y, varargin)
1 400 400
2 400 401 + arguments(Input)
0 401 401 | x (1,4) {mustBeReal}
0 401 401 | y (1,:) {mustBeInteger} = x(2:end);
0 401 400 | end
1 400 400
2 400 401 + arguments(Input, Repeating)
0 401 401 | varargin
0 401 400 | end
1 400 400
2 400 401 + arguments(Output)
0 401 401 | a (1,1) {mustBeReal}
0 401 401 | b (1,1) {mustBeNonNegative}
0 401 400 | end
1 400 400
0 400 400 var = 10;
0 400 400 arguments = {"now", "it's", "variable"};
1 400 400
0 400 400 [a, b] = bar(x, y, arguments);
1 400 400
0 400 3ff end
1 3ff 3ff
0 3ff 3ff % One line function with arguments block.
0 3ff 3ff % This code style is rarely used (if at all), but the
0 3ff 3ff % lexer shouldn't break
0 3ff 3ff function y = foo(x); arguments; x; end; y = bar(x); end
1 3ff 3ff

View File

@ -59,6 +59,15 @@
{7}y{0} {6}={0} {7}x{0} {6}+{0} {7}arguments{6};{0}
{4}end{0}
{1}% Semicolon is equivalent to a comment{0}
{4}function{0} {7}y{0} {6}={0} {7}foo{6}({7}x{6}){0}
{6};;;;;;;{0}
{4}arguments{0}
{7}x{0}
{4}end{0}
{7}y{0} {6}={0} {7}x{0} {6}+{0} {3}2{6};{0}
{4}end{0}
{1}% Arguments block is illegal in nested functions,{0}
{1}% but lexer should process it anyway{0}
{4}function{0} {7}y{0} {6}={0} {7}foo{0} {6}({7}x{6}){0}
@ -70,6 +79,7 @@
{4}arguments{0}
{7}x{0} {6}({3}1{6},{3}2{6}){0} {6}{{7}mustBeReal{6}({7}x{6})}{0}
{4}end{0}
{7}var{0} {6}={0} {3}0{6};{0}
{7}arguments{0} {6}={0} {3}5{6};{0}
{7}y{0} {6}={0} {7}arguments{0} {6}+{0} {7}x{6};{0}
{4}end{0}
@ -86,4 +96,42 @@
{7}x{0}
{4}end{0}
{7}y{0} {6}={0} {7}x{6};{0}
{4}end
{4}end{0}
{1}% "arguments" is an argument name too{0}
{4}function{0} {7}r{0} {6}={0} {7}foo{6}({7}x{6},{0} {7}arguments{6}){0}
{4}arguments{0}
{7}x{0}
{7}arguments{0}
{4}end{0}
{7}r{0} {6}={0} {7}bar{6}({7}x{6},{0} {7}arguments{6}{:});{0}
{4}end{0}
{1}% Multiple arguments blocks{0}
{4}function{0} {6}[{7}a{6},{0} {7}b{6}]{0} {6}={0} {7}foo{6}({7}x{6},{0} {7}y{6},{0} {7}varargin{6}){0}
{4}arguments{6}({7}Input{6}){0}
{7}x{0} {6}({3}1{6},{3}4{6}){0} {6}{{7}mustBeReal{6}}{0}
{7}y{0} {6}({3}1{6},:){0} {6}{{7}mustBeInteger{6}}{0} {6}={0} {7}x{6}({3}2{6}:{3}end{6});{0}
{4}end{0}
{4}arguments{6}({7}Input{6},{0} {7}Repeating{6}){0}
{7}varargin{0}
{4}end{0}
{4}arguments{6}({7}Output{6}){0}
{7}a{0} {6}({3}1{6},{3}1{6}){0} {6}{{7}mustBeReal{6}}{0}
{7}b{0} {6}({3}1{6},{3}1{6}){0} {6}{{7}mustBeNonNegative{6}}{0}
{4}end{0}
{7}var{0} {6}={0} {3}10{6};{0}
{7}arguments{0} {6}={0} {6}{{8}"now"{6},{0} {8}"it's"{6},{0} {8}"variable"{6}};{0}
{6}[{7}a{6},{0} {7}b{6}]{0} {6}={0} {7}bar{6}({7}x{6},{0} {7}y{6},{0} {7}arguments{6});{0}
{4}end{0}
{1}% One line function with arguments block.{0}
{1}% This code style is rarely used (if at all), but the{0}
{1}% lexer shouldn't break{0}
{4}function{0} {7}y{0} {6}={0} {7}foo{6}({7}x{6});{0} {4}arguments{6};{0} {7}x{6};{0} {4}end{6};{0} {7}y{0} {6}={0} {7}bar{6}({7}x{6});{0} {4}end{0}

View File

@ -1,10 +1,13 @@
% SCE_VISUALPROLOG_KEY_MAJOR (1)
% No keywords in ISO/SWI-Prolog
goal
% SCE_VISUALPROLOG_KEY_MINOR (2)
% No minor keywords in ISO/SWI-Prolog
procedure
% SCE_VISUALPROLOG_KEY_DIRECTIVE (3)
% No directives in ISO/SWI-Prolog
#include
% SCE_VISUALPROLOG_COMMENT_BLOCK (4)
@ -27,12 +30,15 @@ singleton -->
}.
% SCE_VISUALPROLOG_COMMENT_LINE (5)
% @detail
% @unknown
% comment line
% SCE_VISUALPROLOG_STRING (16)
% SCE_VISUALPROLOG_STRING_QUOTE (16)
""
% SCE_VISUALPROLOG_STRING (20)
"string"
'string'
% ISO Prolog back-quoted string
`string`
@ -42,16 +48,18 @@ singleton -->
% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)
"\ "
% SCE_VISUALPROLOG_STRING_EOL_OPEN (19)
"open string
% Not implemented for ISO/SWI-Prolog:
% SCE_VISUALPROLOG_STRING_VERBATIM
% SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL
% SCE_VISUALPROLOG_STRING_VERBATIM_EOL
@"verbatim string"
@"""special"" verbatim string"
@"multi-line
@[<div class="test">]
% SCE_VISUALPROLOG_STRING_EOL (22)
@#multi-line
verbatim
string"
string#
% SCE_VISUALPROLOG_EMBEDDED (23)
[| |]
% SCE_VISUALPROLOG_PLACEHOLDER (24)
{| |}:test

View File

@ -1,10 +1,13 @@
0 400 400 % SCE_VISUALPROLOG_KEY_MAJOR (1)
0 400 400 % No keywords in ISO/SWI-Prolog
0 400 400 goal
0 400 400
0 400 400 % SCE_VISUALPROLOG_KEY_MINOR (2)
0 400 400 % No minor keywords in ISO/SWI-Prolog
0 400 400 procedure
0 400 400
0 400 400 % SCE_VISUALPROLOG_KEY_DIRECTIVE (3)
0 400 400 % No directives in ISO/SWI-Prolog
0 400 400 #include
0 400 400
0 400 400 % SCE_VISUALPROLOG_COMMENT_BLOCK (4)
@ -27,12 +30,15 @@
0 401 400 | }.
0 400 400
0 400 400 % SCE_VISUALPROLOG_COMMENT_LINE (5)
0 400 400 % @detail
0 400 400 % @unknown
0 400 400 % comment line
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING (16)
0 400 400 % SCE_VISUALPROLOG_STRING_QUOTE (16)
0 400 400 ""
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING (20)
0 400 400 "string"
0 400 400 'string'
0 400 400
0 400 400 % ISO Prolog back-quoted string
0 400 400 `string`
0 400 400
@ -42,17 +48,19 @@
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)
0 400 400 "\ "
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_EOL_OPEN (19)
0 400 400 "open string
0 400 400
0 400 400 % Not implemented for ISO/SWI-Prolog:
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM_EOL
0 400 400 @"verbatim string"
0 400 400 @"""special"" verbatim string"
0 400 400 @"multi-line
0 400 400 @[<div class="test">]
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_EOL (22)
0 400 400 @#multi-line
0 400 400 verbatim
0 400 400 string"
0 400 400 string#
0 400 400
0 400 400 % SCE_VISUALPROLOG_EMBEDDED (23)
0 400 400 [| |]
0 400 400 % SCE_VISUALPROLOG_PLACEHOLDER (24)
0 400 400 {| |}:test
1 400 400

View File

@ -1,10 +1,13 @@
{5}% SCE_VISUALPROLOG_KEY_MAJOR (1){0}
{5}% No keywords in ISO/SWI-Prolog{0}
{1}goal{0}
{5}% SCE_VISUALPROLOG_KEY_MINOR (2){0}
{5}% No minor keywords in ISO/SWI-Prolog{0}
{2}procedure{0}
{5}% SCE_VISUALPROLOG_KEY_DIRECTIVE (3){0}
{5}% No directives in ISO/SWI-Prolog{0}
{3}#include{0}
{5}% SCE_VISUALPROLOG_COMMENT_BLOCK (4){0}
@ -27,14 +30,17 @@
{12}}.{0}
{5}% SCE_VISUALPROLOG_COMMENT_LINE (5){0}
{5}% {6}@detail{0}
{5}% {7}@unknown{0}
{5}% comment line{0}
{5}% SCE_VISUALPROLOG_STRING_QUOTE (16){0}
{16}""{0}
{5}% SCE_VISUALPROLOG_STRING (20){0}
{16}"{20}string{16}"{0}
{16}'{20}string{16}'{0}
{5}% SCE_VISUALPROLOG_STRING (16){0}
{16}"string"{0}
{16}'string'{0}
{5}% ISO Prolog back-quoted string{0}
{16}`string`{0}
{16}`{20}string{16}`{0}
{5}% SCE_VISUALPROLOG_STRING_ESCAPE (17){0}
{16}"{17}\n{16}"{0}
@ -42,16 +48,18 @@
{5}% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18){0}
{16}"{18}\ {16}"{0}
{5}% SCE_VISUALPROLOG_STRING_EOL_OPEN (19){0}
{16}"open string{19}
{16}"{20}open string{18}
{0}
{5}% Not implemented for ISO/SWI-Prolog:{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM_EOL{0}
{12}@{16}"verbatim string"{0}
{12}@{16}"""special"" verbatim string"{0}
{12}@{16}"multi-line{19}
{0} {8}verbatim{0}
{8}string{16}"{19}
{12}@{16}"{20}verbatim string{16}"{0}
{12}@[<{2}div{0} {1}class{12}={16}"{20}test{16}"{12}>]{0}
{5}% SCE_VISUALPROLOG_STRING_EOL (22){0}
{12}@{8}#multi{12}-{8}line{0}
{8}verbatim{0}
{8}string#{0}
{5}% SCE_VISUALPROLOG_EMBEDDED (23){0}
{23}[| |]{0}
{5}% SCE_VISUALPROLOG_PLACEHOLDER (24){0}
{24}{|{0} {24}|}:test{0}

View File

@ -23,12 +23,16 @@ lambda = {
}.
% SCE_VISUALPROLOG_COMMENT_LINE (5)
% @detail
% @unknown
% comment line
% SCE_VISUALPROLOG_STRING (16)
% SCE_VISUALPROLOG_STRING_QUOTE (16)
""
% SCE_VISUALPROLOG_STRING (20)
"string"
'string'
@"verbatim string"
@[<div class="test">]
% SCE_VISUALPROLOG_STRING_ESCAPE (17)
"\n"
@ -36,17 +40,31 @@ lambda = {
% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)
"\ "
% SCE_VISUALPROLOG_STRING_EOL_OPEN (19)
"open string
% SCE_VISUALPROLOG_STRING_VERBATIM (20)
@"verbatim string"
% SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL (21)
@"""special"" verbatim string"
% SCE_VISUALPROLOG_STRING_VERBATIM_EOL (22)
@"multi-line
% SCE_VISUALPROLOG_STRING_EOL (22)
@#multi-line
verbatim
string"
string#
% SCE_VISUALPROLOG_EMBEDDED (23)
[| |]
% SCE_VISUALPROLOG_PLACEHOLDER (24)
{| |}:test
% line state & nesting
[|
{|
/*
% /*
*/
% */
[|
{|
@!string!
%
/*
*/
|}
|]
|}
|]

View File

@ -23,12 +23,16 @@
0 401 400 | }.
0 400 400
0 400 400 % SCE_VISUALPROLOG_COMMENT_LINE (5)
0 400 400 % @detail
0 400 400 % @unknown
0 400 400 % comment line
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING (16)
0 400 400 % SCE_VISUALPROLOG_STRING_QUOTE (16)
0 400 400 ""
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING (20)
0 400 400 "string"
0 400 400 'string'
0 400 400 @"verbatim string"
0 400 400 @[<div class="test">]
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_ESCAPE (17)
0 400 400 "\n"
@ -36,18 +40,32 @@
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18)
0 400 400 "\ "
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_EOL_OPEN (19)
0 400 400 "open string
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM (20)
0 400 400 @"verbatim string"
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL (21)
0 400 400 @"""special"" verbatim string"
0 400 400
0 400 400 % SCE_VISUALPROLOG_STRING_VERBATIM_EOL (22)
0 400 400 @"multi-line
0 400 400 % SCE_VISUALPROLOG_STRING_EOL (22)
0 400 400 @#multi-line
0 400 400 verbatim
0 400 400 string"
0 400 400 string#
0 400 400
0 400 400 % SCE_VISUALPROLOG_EMBEDDED (23)
0 400 400 [| |]
0 400 400 % SCE_VISUALPROLOG_PLACEHOLDER (24)
0 400 400 {| |}:test
0 400 400 % line state & nesting
0 400 400 [|
0 400 400 {|
0 400 400 /*
0 400 400 % /*
0 400 400 */
0 400 400 % */
0 400 400 [|
0 400 400 {|
0 400 400 @!string!
0 400 400 %
0 400 400 /*
0 400 400 */
0 400 400 |}
0 400 400 |]
0 400 400 |}
0 400 400 |]
1 400 400

View File

@ -23,12 +23,16 @@
{12}}.{0}
{5}% SCE_VISUALPROLOG_COMMENT_LINE (5){0}
{5}% {6}@detail{0}
{5}% {7}@unknown{0}
{5}% comment line{0}
{5}% SCE_VISUALPROLOG_STRING (16){0}
{16}"string"{0}
{16}'string'{0}
{5}% SCE_VISUALPROLOG_STRING_QUOTE (16){0}
{16}""{0}
{5}% SCE_VISUALPROLOG_STRING (20){0}
{16}"{20}string{16}"{0}
{16}'{20}string{16}'{0}
{16}@"{20}verbatim string{16}"{0}
{16}@[{20}<div class="test">{16}]{0}
{5}% SCE_VISUALPROLOG_STRING_ESCAPE (17){0}
{16}"{17}\n{16}"{0}
@ -36,17 +40,31 @@
{5}% SCE_VISUALPROLOG_STRING_ESCAPE_ERROR (18){0}
{16}"{18}\ {16}"{0}
{5}% SCE_VISUALPROLOG_STRING_EOL_OPEN (19){0}
{16}"open string{19}
{16}"{20}open string{18}
{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM (20){0}
{20}@"verbatim string"{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL (21){0}
{20}@"{21}""{20}special{21}""{20} verbatim string"{0}
{5}% SCE_VISUALPROLOG_STRING_VERBATIM_EOL (22){0}
{20}@"multi-line{22}
{5}% SCE_VISUALPROLOG_STRING_EOL (22){0}
{16}@#{20}multi-line{22}
{20} verbatim{22}
{20} string"{0}
{20} string{16}#{0}
{5}% SCE_VISUALPROLOG_EMBEDDED (23){0}
{23}[| |]{0}
{5}% SCE_VISUALPROLOG_PLACEHOLDER (24){0}
{24}{|{0} {24}|}:test{0}
{5}% line state & nesting{0}
{23}[|
{24}{|{0}
{4}/*
% /*
*/
% */{0}
{23}[|
{24}{|{0}
{16}@!{20}string{16}!{0}
{5}%{0}
{4}/*
*/{0}
{24}|}{23}
|]{0}
{24}|}{23}
|]{0}

View File

@ -2,8 +2,8 @@
** Unit Tests for Lexilla internal data structures
**/
#include <cstdlib>
#include <cassert>
#include <cstring>
#include "CharacterSet.h"

View File

@ -3,10 +3,9 @@
**/
#include <cassert>
#include <cstring>
#include <string>
#include <string_view>
#include <iostream>
#include "ILexer.h"
#include "Scintilla.h"
@ -22,15 +21,19 @@ using namespace Lexilla;
// Test LexerSimple.
namespace {
constexpr const char *propertyName = "lexer.tex.comment.process";
constexpr const char *propertyValue = "1";
static void ColouriseDocument(Sci_PositionU, Sci_Position, int, WordList *[], Accessor &) {
void ColouriseDocument(Sci_PositionU, Sci_Position, int, WordList *[], Accessor &) {
// Do no styling
}
LexerModule lmSimpleExample(123456, ColouriseDocument, "simpleexample");
}
TEST_CASE("LexerNoExceptions") {
SECTION("Identifier") {
@ -40,7 +43,7 @@ TEST_CASE("LexerNoExceptions") {
SECTION("Identifier") {
LexerSimple lexSimple(&lmSimpleExample);
REQUIRE(strcmp(lexSimple.GetName(), "simpleexample") == 0);
REQUIRE_THAT(lexSimple.GetName(), Catch::Matchers::Equals("simpleexample"));
}
SECTION("SetAndGet") {
@ -57,7 +60,7 @@ TEST_CASE("LexerNoExceptions") {
REQUIRE(pos2 == -1);
const char *value = lexSimple.PropertyGet(propertyName);
REQUIRE(strcmp(propertyValue, value) == 0);
REQUIRE_THAT(propertyValue, Catch::Matchers::Equals(value));
}
}

View File

@ -0,0 +1,126 @@
/** @file testOptionSet.cxx
** Unit Tests for Lexilla internal data structures
** Tests OptionSet.
**/
#include <string>
#include <string_view>
#include <vector>
#include <map>
#include "Scintilla.h"
#include "OptionSet.h"
#include "catch.hpp"
using namespace Lexilla;
// Test OptionSet.
namespace {
// Simple example options structure with each type: string, bool, int
struct Options {
std::string so;
bool bo = false;
int io = 0;
};
const char *const denseWordLists[] = {
"Keywords 1",
"Keywords 2",
"Keywords 3",
"Keywords 4",
nullptr,
};
const char *const sparseWordLists[] = {
"",
"",
"Keywords 1",
"",
"Keywords 2",
nullptr,
};
}
using Catch::Matchers::Equals;
TEST_CASE("OptionSet") {
OptionSet<Options> os;
Options options;
SECTION("IsEmptyInitially") {
REQUIRE_THAT(os.PropertyNames(), Equals(""));
}
SECTION("MissingOption") {
// Check for not present option
REQUIRE_FALSE(os.PropertyGet("missing"));
REQUIRE(SC_TYPE_BOOLEAN == os.PropertyType("missing"));
REQUIRE_FALSE(os.PropertySet(&options, "missing", "1"));
}
SECTION("Define") {
os.DefineProperty("string.option", &Options::so, "StringOption");
REQUIRE_THAT(os.PropertyGet("string.option"), Equals(""));
REQUIRE(SC_TYPE_STRING == os.PropertyType("string.option"));
REQUIRE_THAT(os.DescribeProperty("string.option"), Equals("StringOption"));
os.DefineProperty("bool.option", &Options::bo, "BoolOption");
REQUIRE_THAT(os.PropertyGet("bool.option"), Equals(""));
REQUIRE(SC_TYPE_BOOLEAN == os.PropertyType("bool.option"));
REQUIRE_THAT(os.DescribeProperty("bool.option"), Equals("BoolOption"));
os.DefineProperty("int.option", &Options::io, "IntOption");
REQUIRE_THAT(os.PropertyGet("int.option"), Equals(""));
REQUIRE(SC_TYPE_INTEGER == os.PropertyType("int.option"));
REQUIRE_THAT(os.DescribeProperty("int.option"), Equals("IntOption"));
// This is really a set and could be reordered but is currently in definition order
REQUIRE_THAT(os.PropertyNames(), Equals("string.option\nbool.option\nint.option"));
}
SECTION("Set") {
os.DefineProperty("string.option", &Options::so, "StringOption");
REQUIRE_THAT(os.PropertyGet("string.option"), Equals(""));
REQUIRE(os.PropertySet(&options, "string.option", "string"));
REQUIRE_THAT(os.PropertyGet("string.option"), Equals("string"));
// Setting to same as before returns false
REQUIRE_FALSE(os.PropertySet(&options, "string.option", "string"));
REQUIRE(os.PropertySet(&options, "string.option", "anotherString"));
REQUIRE_THAT(os.PropertyGet("string.option"), Equals("anotherString"));
os.DefineProperty("bool.option", &Options::so, "BoolOption");
REQUIRE(os.PropertySet(&options, "bool.option", "1"));
REQUIRE_THAT(os.PropertyGet("bool.option"), Equals("1"));
// Setting to same as before returns false
REQUIRE_FALSE(os.PropertySet(&options, "bool.option", "1"));
REQUIRE(os.PropertySet(&options, "bool.option", "0"));
os.DefineProperty("int.option", &Options::so, "IntOption");
REQUIRE(os.PropertySet(&options, "int.option", "2"));
REQUIRE_THAT(os.PropertyGet("int.option"), Equals("2"));
// Setting to same as before returns false
REQUIRE_FALSE(os.PropertySet(&options, "int.option", "2"));
REQUIRE(os.PropertySet(&options, "int.option", "3"));
}
// WordListSets feature is really completely separate from options
SECTION("WordListSets") {
REQUIRE_THAT(os.DescribeWordListSets(), Equals(""));
os.DefineWordListSets(denseWordLists);
REQUIRE_THAT(os.DescribeWordListSets(),
Equals("Keywords 1\nKeywords 2\nKeywords 3\nKeywords 4"));
OptionSet<Options> os2;
REQUIRE_THAT(os2.DescribeWordListSets(), Equals(""));
os2.DefineWordListSets(sparseWordLists);
REQUIRE_THAT(os2.DescribeWordListSets(),
Equals("\n\nKeywords 1\n\nKeywords 2"));
}
}

View File

@ -2,11 +2,8 @@
** Unit Tests for Lexilla internal data structures
**/
#include <cassert>
#include <cstring>
#include <string>
#include <string_view>
#include <iostream>
#include "PropSetSimple.h"
@ -16,22 +13,26 @@ using namespace Lexilla;
// Test PropSetSimple.
namespace {
constexpr const char *propertyName = "lexer.tex.comment.process";
constexpr const char *propertyValue = "1";
}
TEST_CASE("PropSetSimple") {
SECTION("IsEmptyInitially") {
PropSetSimple pss;
const char *value = pss.Get(propertyName);
REQUIRE(strcmp("", value) == 0);
REQUIRE_THAT(value, Catch::Matchers::Equals(""));
}
SECTION("SetAndGet") {
PropSetSimple pss;
pss.Set(propertyName, propertyValue);
const char *value = pss.Get(propertyName);
REQUIRE(strcmp(propertyValue, value) == 0);
REQUIRE_THAT(value, Catch::Matchers::Equals(propertyValue));
}
SECTION("GetInt") {

View File

@ -3,8 +3,6 @@
** Tests WordList, WordClassifier, and SubStyles
**/
#include <string.h>
#include <string>
#include <string_view>
#include <vector>
@ -71,7 +69,7 @@ TEST_CASE("WordList") {
SECTION("WordAt") {
wl.Set("else struct");
REQUIRE(0 == strcmp(wl.WordAt(0), "else"));
REQUIRE_THAT(wl.WordAt(0), Catch::Matchers::Equals("else"));
}
SECTION("InListAbbreviated") {

View File

@ -1 +1 @@
525
526

View File

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

View File

@ -573,7 +573,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.5;
CURRENT_PROJECT_VERSION = 5.3.6;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -636,7 +636,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5.3.5;
CURRENT_PROJECT_VERSION = 5.3.6;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
@ -667,7 +667,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.5;
CURRENT_PROJECT_VERSION = 5.3.6;
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
@ -702,7 +702,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 5.3.5;
CURRENT_PROJECT_VERSION = 5.3.6;
DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";

View File

@ -1,5 +1,6 @@
// File to suppress cppcheck warnings for files that will not be fixed.
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
// Configured for cppcheck 2.11
// Coding style is to use assignments in constructor when there are many
// members to initialize or the initialization is complex or has comments.
@ -13,6 +14,12 @@ useStlAlgorithm
// Written with variable for consistency
knownArgument:scintilla/src/SparseVector.h
// cppcheck 2.11 can't find system headers on Win32.
missingIncludeSystem
// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive
checkLevelNormal:scintilla/src/Editor.cxx
// The cast converts from 'unsigned char ' to 'char' so isn't unused.
// Redundant code: Found unused cast of expression 'leadByte'
constStatement:scintilla/src/Document.cxx
@ -30,31 +37,42 @@ unusedFunction:scintilla/win32/ScintillaDLL.cxx
unusedFunction:scintilla/qt/ScintillaEdit/ScintillaDocument.cpp
// Doesn't understand changing dropWentOutside in Editor
knownConditionTrueFalse:scintilla/qt/ScintillaEditBase/ScintillaQt.cpp
knownConditionTrueFalse:scintilla/win32/ScintillaWin.cxx
// GetData is implementing interface so shouldn't add const
constParameterPointer:scintilla/win32/ScintillaWin.cxx
// Doesn't handle intptr_t (long long) being signed
knownConditionTrueFalse:scintilla/src/Editor.cxx
knownConditionTrueFalse:scintilla/src/EditView.cxx
// cppcheck seems to believe that unique_ptr<T *[]>::get returns void* instead of T**
arithOperationsOnVoidPointer:scintilla/src/PerLine.cxx
arithOperationsOnVoidPointer:scintilla/src/PositionCache.cxx
// Cppcheck wrongly assumes string_view::remove_prefix can not empty the view
knownConditionTrueFalse:scintilla/src/CallTip.cxx
// G_DEFINE_TYPE is too complex to pass to cppcheck
unknownMacro:scintilla/gtk/PlatGTK.cxx
// maskSmooth set depending on preprocessor allowing Wayland definition
badBitmaskCheck:scintilla/gtk/ScintillaGTK.cxx
// Changing events to const pointers changes signature and would require casts when hooking up
constParameterPointer:scintilla/gtk/ScintillaGTK.cxx
constParameterCallback:scintilla/gtk/ScintillaGTK.cxx
// Difficult to test accessibility so don't change
constVariable:scintilla/gtk/ScintillaGTKAccessible.cxx
// Have no way of testing ScintillaEdit so don't fix even simple warnings
cstyleCast:scintilla/qt/ScintillaEdit/ScintillaEdit.cpp
shadowFunction:scintilla/qt/ScintillaEdit/ScintillaEdit.cpp
// cppcheck fails emit from Qt
shadowFunction:scintilla/qt/ScintillaEditBase/ScintillaQt.cpp
shadowFunction:scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp
constParameterPointer:scintilla/gtk/ScintillaGTKAccessible.cxx
constVariableReference:scintilla/gtk/ScintillaGTKAccessible.cxx
constVariablePointer:scintilla/gtk/ScintillaGTKAccessible.cxx
// moc_ files show #error as they are not built with standard context
preprocessorErrorDirective:scintilla/qt/*.cpp
// moc_ files are not understood by cppcheck
noValidConfiguration
// Doesn't understand Qt slots macro
unknownMacro:scintilla/qt/ScintillaEditBase/*.h
// The performance cost of by-value passing is often small and using a reference decreases
// code legibility.

View File

@ -1347,7 +1347,7 @@ struct Sci_TextToFindFull {
Coalescing treats coalescible container actions as transparent so will still only group together insertions that
look like typing or deletions that look like multiple uses of the Backspace or Delete keys.
</p>
<h2 id="ChangeHistory">Change history</h2>
<p>Scintilla can display document changes (modified, saved, ...) in the margin or in the text.</p>
@ -3366,114 +3366,114 @@ struct Sci_TextToFindFull {
<tbody>
<tr>
<td><code>SC_CHARSET_ANSI</code></td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003; (8859-1)</td></tr>
<td>&check;</td>
<td>&check;</td>
<td>&check; (8859-1)</td></tr>
<tr>
<td><code>SC_CHARSET_ARABIC</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_BALTIC</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_CHINESEBIG5</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_DEFAULT</code></td>
<td>&#10003;</td>
<td>&#10003; (8859-1)</td>
<td>&#10003; (8859-1)</td></tr>
<td>&check;</td>
<td>&check; (8859-1)</td>
<td>&check; (8859-1)</td></tr>
<tr>
<td><code>SC_CHARSET_EASTEUROPE</code></td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td></tr>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_GB2312</code></td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td></tr>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_GREEK</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_HANGUL</code></td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td></tr>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_HEBREW</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_JOHAB</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_MAC</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_OEM</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_RUSSIAN</code></td>
<td>&#10003; (cp1251)</td>
<td>&#10003; (koi8-r)</td>
<td>&#10003; (cp1251)</td></tr>
<td>&check; (cp1251)</td>
<td>&check; (koi8-r)</td>
<td>&check; (cp1251)</td></tr>
<tr>
<td><code>SC_CHARSET_SHIFTJIS</code></td>
<td>&#10003;</td>
<td>&#10003;</td>
<td>&#10003;</td></tr>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_SYMBOL</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_THAI</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_TURKISH</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_VIETNAMESE</code></td>
<td>&#10003;</td>
<td>&check;</td>
<td></td>
<td>&#10003;</td></tr>
<td>&check;</td></tr>
<tr>
<td><code>SC_CHARSET_OEM866</code></td>
<td></td>
<td>&#10003; (cp866)</td>
<td>&check; (cp866)</td>
<td></td></tr>
<tr>
<td><code>SC_CHARSET_CYRILLIC</code></td>
<td></td>
<td>&#10003; (cp1251)</td>
<td>&#10003; (cp1251)</td></tr>
<td>&check; (cp1251)</td>
<td>&check; (cp1251)</td></tr>
<tr>
<td><code>SC_CHARSET_8859_15</code></td>
<td></td>
<td>&#10003;</td>
<td>&#10003;</td></tr>
<td>&check;</td>
<td>&check;</td></tr>
</tbody></table>
<p><b id="SCI_STYLESETCASE">SCI_STYLESETCASE(int style, int caseVisible)</b><br />
@ -4882,12 +4882,12 @@ struct Sci_TextToFindFull {
rectangular and multiple selection, with IME interactions such as retrieve-surrounding or reconversion feature.</p>
<table class="standard" summary="IME input method">
<caption>IME input method support (O=present, X=absent)</caption>
<caption>IME input method support</caption>
<thead align="left">
<tr>
<th>IME input method</th>
<th>Windows</th>
<th>Gtk</th>
<th>GTK</th>
<th>Qt</th>
<th>macOS</th>
</tr>
@ -4895,17 +4895,17 @@ struct Sci_TextToFindFull {
<tbody valign="top">
<tr>
<th align="left"><code>SC_IME_WINDOWED</code></th>
<td>O</td>
<td>O</td>
<td>X</td>
<td>X</td>
<td>&check;</td>
<td>&check;</td>
<td> </td>
<td> </td>
</tr>
<tr>
<th align="left"><code>SC_IME_INLINE</code></th>
<td>O</td>
<td>O</td>
<td>O</td>
<td>O</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
</tr>
</tbody>
</table>
@ -4917,7 +4917,7 @@ struct Sci_TextToFindFull {
<tr>
<th>IME interaction</th>
<th>Windows</th>
<th>Gtk</th>
<th>GTK</th>
<th>Qt</th>
<th>macOS</th>
</tr>
@ -4925,24 +4925,24 @@ struct Sci_TextToFindFull {
<tbody valign="top">
<tr>
<th align="left">Retrieve Surrounding</th>
<td>O</td>
<td>O</td>
<td>O</td>
<td>O</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
</tr>
<tr>
<th align="left">Reconversion</th>
<td>O</td>
<td>O</td>
<td>O</td>
<td>O</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
</tr>
<tr>
<th align="left">Delete Surrounding</th>
<td>O</td>
<td>O</td>
<td>X</td>
<td>O</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
<td>&check;</td>
</tr>
</tbody>
</table>
@ -4979,7 +4979,7 @@ struct Sci_TextToFindFull {
</p>
<p>Opaque selection drawing (<a class="seealso" href="#SCI_SETSELECTIONLAYER">SCI_SETSELECTIONLAYER(SC_LAYER_BASE)</a>)
is not supported in bidirectional mode.
Use <code>SC_LAYER_UNDER_TEXT</code> or <code>SC_LAYER_OVER_TEXT</code> instead.
Use <code>SC_LAYER_UNDER_TEXT</code> or <code>SC_LAYER_OVER_TEXT</code> instead.
</p>
</div>
@ -9683,7 +9683,7 @@ for line = lineStart to lineEnd do SCI_ENSUREVISIBLE(line) next
<td align="center">6</td>
<td>There was only a single choice in the list and 'choose single' mode was active as set by
<td>There was only a single choice in the list and 'choose single' mode was active as set by
<code>
<a class="seealso" href="#SCI_AUTOCSETCHOOSESINGLE">SCI_AUTOCSETCHOOSESINGLE</a></code>. ch is 0.</td>

View File

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

View File

@ -581,6 +581,43 @@
</tr>
</table>
<h2>Releases</h2>
<h3>
<a href="https://www.scintilla.org/scintilla536.zip">Release 5.3.6</a>
</h3>
<ul>
<li>
Released 26 July 2023.
</li>
<li>
Redraw calltip after showing as didn't update when size of new text exactly same as
previous.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1486/">Feature #1486</a>.
</li>
<li>
On Win32 fix reverse arrow cursor when scaled.
<a href="https://sourceforge.net/p/scintilla/bugs/2382/">Bug #2382</a>.
</li>
<li>
On Win32 hide cursor when typing if that system preference has been chosen.
<a href="https://sourceforge.net/p/scintilla/bugs/2333/">Bug #2333</a>.
</li>
<li>
On Win32 and Qt, stop aligning IME candidate window to target.
It is now always aligned to start of composition string.
This undoes part of feature #1300.
<a href="https://sourceforge.net/p/scintilla/feature-requests/1488/">Feature #1488</a>,
<a href="https://sourceforge.net/p/scintilla/bugs/2391/">Bug #2391</a>,
<a href="https://sourceforge.net/p/scintilla/feature-requests/1300/">Feature #1300</a>.
</li>
<li>
On Qt, for IMEs, update micro focus when selection changes.
This may move the location of IME popups to align with the caret.
</li>
<li>
On Qt, implement replacement for IMEs which may help with actions like reconversion.
This is similar to delete-surrounding on GTK.
</li>
</ul>
<h3>
<a href="https://www.scintilla.org/scintilla535.zip">Release 5.3.5</a>
</h3>

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

View File

@ -9,7 +9,7 @@
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
<meta name="Description"
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
<meta name="Date.Modified" content="20230531" />
<meta name="Date.Modified" content="20230726" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
.logo {
@ -60,8 +60,8 @@
GTK, and macOS</font>
</td>
<td width="40%" align="right">
<font color="#FFCC99" size="3"> Release version 5.3.5<br />
Site last modified May 31 2023</font>
<font color="#FFCC99" size="3"> Release version 5.3.6<br />
Site last modified July 26 2023</font>
</td>
<td width="20%">
&nbsp;
@ -76,12 +76,11 @@
</tr>
</table>
<ul id="versionlist">
<li>Version 5.3.6 improves cursor behaviour on Win32 and IME support on Win32 and Qt.</li>
<li>Version 5.3.5 improves IME support on Win32 and Qt.</li>
<li>Version 5.3.4 adds multithreaded wrapping.</li>
<li>Version 5.3.3 fixes minor bugs in APIs and platform layers.</li>
<li>Version 5.3.2 adds SCI_REPLACETARGETMINIMAL to modify text without marking unchanged start and end text in change history.</li>
<li>Version 5.3.1 can represent invisible text with a character to simplify editing and provide summarized views.</li>
<li>Version 5.3.0 adds change history.</li>
</ul>
<ul id="menu">
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>

View File

@ -370,7 +370,7 @@ UniquePangoContext SurfaceImpl::MeasuringContext() {
pango_context_set_base_dir(contextMeasure.get(), direction);
pango_cairo_context_set_font_options(contextMeasure.get(), fontOptions);
pango_context_set_language(contextMeasure.get(), language);
return contextMeasure;
}

View File

@ -541,7 +541,7 @@ gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
}
void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) {
ScintillaGTK *sciThis = FromWidget(widget);
const ScintillaGTK *sciThis = FromWidget(widget);
requisition->width = 1;
requisition->height = 1;
GtkRequisition child_requisition;
@ -1168,7 +1168,7 @@ void ScintillaGTK::SetScrollBars() {
// On GTK, unlike other platforms, modifying scrollbars inside some events including
// resizes causes problems. Deferring the modification to a lower priority (125) idle
// event avoids the problems. This code did not always work when the priority was
// higher than GTK's resize (GTK_PRIORITY_RESIZE=110) or redraw
// higher than GTK's resize (GTK_PRIORITY_RESIZE=110) or redraw
// (GDK_PRIORITY_REDRAW=120) idle tasks.
scrollBarIdleID = gdk_threads_add_idle_full(priorityScrollBar,
[](gpointer pSci) -> gboolean {

View File

@ -182,7 +182,7 @@ void ScintillaDocument::insert_string(int position, QByteArray &str) {
}
QByteArray ScintillaDocument::get_char_range(int position, int length) {
Document *doc = static_cast<Document *>(pdoc);
const Document *doc = static_cast<Document *>(pdoc);
if (position < 0 || length <= 0 || position + length > doc->Length())
return QByteArray();

View File

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

View File

@ -542,6 +542,17 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)
sqt->view.imeCaretBlockOverride = false;
preeditPos = -1; // reset not to interrupt Qt::ImCursorRectangle.
const int rpLength = event->replacementLength();
if (rpLength != 0) {
// Qt has called setCommitString().
// Make room for the string to sit in.
const int rpStart = event->replacementStart();
const Scintilla::Position rpBase = sqt->CurrentPosition();
const Scintilla::Position start = sqt->pdoc->GetRelativePositionUTF16(rpBase, rpStart);
const Scintilla::Position end = sqt->pdoc->GetRelativePositionUTF16(start, rpLength);
sqt->pdoc->DeleteChars(start, end - start);
}
if (!event->commitString().isEmpty()) {
const QString &commitStr = event->commitString();
const int commitStrLen = commitStr.length();
@ -600,14 +611,6 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)
#endif
sqt->view.imeCaretBlockOverride = true;
}
// Set Candidate window position again at imeCaret when target input.
const bool targetAny = std::any_of(imeIndicator.begin(), imeIndicator.end(), [](int i) noexcept {
return i == IndicatorTarget;
});
if (targetAny)
preeditPos = sqt->CurrentPosition();
sqt->EnsureCaretVisible();
}
sqt->ShowCaretAtCurrentPosition();
@ -712,6 +715,9 @@ void ScintillaEditBase::notifyParent(NotificationData scn)
break;
case Notification::UpdateUI:
if (FlagSet(scn.updated, Update::Selection)) {
updateMicroFocus();
}
emit updateUi(scn.updated);
break;

View File

@ -12,7 +12,7 @@ TEMPLATE = lib
CONFIG += lib_bundle
CONFIG += c++1z
VERSION = 5.3.5
VERSION = 5.3.6
SOURCES += \
PlatQt.cpp \

View File

@ -170,7 +170,7 @@ class LineVector : public ILineVector {
return static_cast<POS>(pos);
}
// line_from_pos_cast(): return 32-bit or 64-bit value as Sci::Line
// line_from_pos_cast(): return 32-bit or 64-bit value as Sci::Line
// This avoids warnings from Visual C++ Code Analysis and shortens code
static constexpr Sci::Line line_from_pos_cast(POS line) noexcept {
return static_cast<Sci::Line>(line);

View File

@ -209,7 +209,7 @@ void ChangeLog::SetSavePoint() {
}
startRun = endRun;
}
for (Sci::Position positionDeletion = 0; positionDeletion <= length;) {
const EditionSetOwned &editions = deleteEdition.ValueAt(positionDeletion);
if (editions) {

View File

@ -910,7 +910,7 @@ SelectionPosition Editor::MovePositionSoVisible(Sci::Position pos, int moveDir)
}
Point Editor::PointMainCaret() {
return LocationFromPosition(sel.Range(sel.Main()).caret);
return LocationFromPosition(sel.RangeMain().caret);
}
/**
@ -3273,7 +3273,7 @@ void Editor::CursorUpOrDown(int direction, Selection::SelTypes selt) {
if ((selt == Selection::SelTypes::none) && sel.MoveExtends()) {
selt = !sel.IsRectangular() ? Selection::SelTypes::stream : Selection::SelTypes::rectangle;
}
SelectionPosition caretToUse = sel.Range(sel.Main()).caret;
SelectionPosition caretToUse = sel.RangeMain().caret;
if (sel.IsRectangular()) {
if (selt == Selection::SelTypes::none) {
caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start;
@ -3297,7 +3297,7 @@ void Editor::CursorUpOrDown(int direction, Selection::SelTypes selt) {
// Calculate new caret position and call SetSelection(), which will ensure whole lines are selected.
const SelectionPosition posNew = MovePositionSoVisible(
PositionUpOrDown(caretToUse, direction, -1), direction);
SetSelection(posNew, sel.Range(sel.Main()).anchor);
SetSelection(posNew, sel.RangeMain().anchor);
} else {
InvalidateWholeSelection();
if (!additionalSelectionTyping || (sel.IsRectangular())) {

View File

@ -699,7 +699,7 @@ public:
AutoSurface(const Editor *ed) :
surf(ed->CreateMeasurementSurface()) {
}
AutoSurface(SurfaceID sid, Editor *ed, std::optional<Scintilla::Technology> technology = {}) :
AutoSurface(SurfaceID sid, const Editor *ed, std::optional<Scintilla::Technology> technology = {}) :
surf(ed->CreateDrawingSurface(sid, technology)) {
}
// Deleted so AutoSurface objects can not be copied.

View File

@ -540,7 +540,7 @@ bool LineTabstops::AddTabstop(Sci::Line line, int x) {
int LineTabstops::GetNextTabstop(Sci::Line line, int x) const noexcept {
if (line < tabstops.Length()) {
TabstopList *tl = tabstops[line].get();
const TabstopList *tl = tabstops[line].get();
if (tl) {
for (const int i : *tl) {
if (i > x) {

View File

@ -515,6 +515,7 @@ void ScintillaBase::CallTipShow(Point pt, const char *defn) {
CreateCallTipWindow(rc);
ct.wCallTip.SetPositionRelative(rc, &wMain);
ct.wCallTip.Show();
ct.wCallTip.InvalidateAll();
}
void ScintillaBase::CallTipClick() {

View File

@ -598,7 +598,7 @@ class TestSimple(unittest.TestCase):
self.ed.SetSel(3, 3)
# Duplicates the second line containing 'b'
self.ed.LineDuplicate()
# Same as above but end of duplicated line is \r\n
# Same as above but end of duplicated line is \r\n
self.assertEquals(self.ed.Contents(), b"1\nb\r\nb\n2")
def testTransposeLines(self):
@ -2419,7 +2419,7 @@ class TestElements(unittest.TestCase):
self.assertEquals(self.ed.SelectionHidden, True)
self.ed.HideSelection(False) # Restore
self.assertEquals(self.ed.SelectionHidden, False)
class TestIndices(unittest.TestCase):
def setUp(self):
self.xite = Xite.xiteFrame

View File

@ -1 +1 @@
535
536

View File

@ -99,7 +99,7 @@ class HanjaDic {
IHanjaDic *instance = nullptr;
hr = CoCreateInstance(CLSID_HanjaDic, nullptr,
CLSCTX_INPROC_SERVER, IID_IHanjaDic,
(LPVOID *)&instance);
reinterpret_cast<LPVOID *>(&instance));
if (SUCCEEDED(hr) && instance) {
HJinterface.reset(instance);
hr = instance->OpenMainDic();

View File

@ -167,6 +167,9 @@ GetWindowDpiAwarenessContextSig fnGetWindowDpiAwarenessContext = nullptr;
using GetScaleFactorForMonitorSig = HRESULT(WINAPI *)(HMONITOR, DEVICE_SCALE_FACTOR *);
GetScaleFactorForMonitorSig fnGetScaleFactorForMonitor = nullptr;
using GetThreadDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)();
GetThreadDpiAwarenessContextSig fnGetThreadDpiAwarenessContext = nullptr;
using SetThreadDpiAwarenessContextSig = DPI_AWARENESS_CONTEXT(WINAPI *)(DPI_AWARENESS_CONTEXT);
SetThreadDpiAwarenessContextSig fnSetThreadDpiAwarenessContext = nullptr;
@ -175,6 +178,7 @@ void LoadDpiForWindow() noexcept {
fnGetDpiForWindow = DLLFunction<GetDpiForWindowSig>(user32, "GetDpiForWindow");
fnGetSystemMetricsForDpi = DLLFunction<GetSystemMetricsForDpiSig>(user32, "GetSystemMetricsForDpi");
fnAdjustWindowRectExForDpi = DLLFunction<AdjustWindowRectExForDpiSig>(user32, "AdjustWindowRectExForDpi");
fnGetThreadDpiAwarenessContext = DLLFunction<GetThreadDpiAwarenessContextSig>(user32, "GetThreadDpiAwarenessContext");
fnSetThreadDpiAwarenessContext = DLLFunction<SetThreadDpiAwarenessContextSig>(user32, "SetThreadDpiAwarenessContext");
using GetDpiForSystemSig = UINT(WINAPI *)(void);
@ -393,7 +397,7 @@ HMONITOR MonitorFromWindowHandleScaling(HWND hWnd) noexcept {
return monitor;
}
int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept {
float GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept {
if (fnAreDpiAwarenessContextsEqual) {
PLATFORM_ASSERT(fnGetWindowDpiAwarenessContext && fnGetScaleFactorForMonitor);
if (fnAreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, fnGetWindowDpiAwarenessContext(hWnd))) {
@ -401,10 +405,10 @@ int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept {
const HMONITOR hMonitor = MonitorFromWindowHandleScaling(hRootWnd);
DEVICE_SCALE_FACTOR deviceScaleFactor;
if (S_OK == fnGetScaleFactorForMonitor(hMonitor, &deviceScaleFactor))
return (static_cast<int>(deviceScaleFactor) + 99) / 100; // increase to first integral multiple of 1
return deviceScaleFactor / 100.f;
}
}
return 1;
return 1.f;
}
std::shared_ptr<Font> Font::Allocate(const FontParameters &fp) {
@ -2778,56 +2782,102 @@ void Window::InvalidateRectangle(PRectangle rc) {
::InvalidateRect(HwndFromWindowID(wid), &rcw, FALSE);
}
namespace {
void FlipBitmap(HBITMAP bitmap, int width, int height) noexcept {
HDC hdc = ::CreateCompatibleDC({});
if (hdc) {
HBITMAP prevBmp = SelectBitmap(hdc, bitmap);
::StretchBlt(hdc, width - 1, 0, -width, height, hdc, 0, 0, width, height, SRCCOPY);
SelectBitmap(hdc, prevBmp);
::DeleteDC(hdc);
}
}
}
HCURSOR LoadReverseArrowCursor(UINT dpi) noexcept {
HCURSOR reverseArrowCursor {};
bool created = false;
HCURSOR cursor = ::LoadCursor({}, IDC_ARROW);
if (dpi != uSystemDPI) {
const int width = SystemMetricsForDpi(SM_CXCURSOR, dpi);
const int height = SystemMetricsForDpi(SM_CYCURSOR, dpi);
HCURSOR copy = static_cast<HCURSOR>(::CopyImage(cursor, IMAGE_CURSOR, width, height, LR_COPYFROMRESOURCE | LR_COPYRETURNORG));
if (copy) {
created = copy != cursor;
cursor = copy;
class CursorHelper {
public:
ICONINFO info{};
BITMAP bmp{};
bool HasBitmap() const noexcept {
return bmp.bmWidth > 0;
}
}
ICONINFO info;
if (::GetIconInfo(cursor, &info)) {
BITMAP bmp {};
if (::GetObject(info.hbmMask, sizeof(bmp), &bmp)) {
FlipBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight);
CursorHelper(const HCURSOR cursor) noexcept {
Init(cursor);
}
~CursorHelper() {
CleanUp();
}
CursorHelper &operator=(const HCURSOR cursor) noexcept {
CleanUp();
Init(cursor);
return *this;
}
bool MatchesSize(const int width, const int height) noexcept {
return bmp.bmWidth == width && bmp.bmHeight == height;
}
HCURSOR CreateFlippedCursor() noexcept {
if (info.hbmMask)
FlipBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight);
if (info.hbmColor)
FlipBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight);
info.xHotspot = bmp.bmWidth - 1 - info.xHotspot;
reverseArrowCursor = ::CreateIconIndirect(&info);
return ::CreateIconIndirect(&info);
}
::DeleteObject(info.hbmMask);
if (info.hbmColor)
::DeleteObject(info.hbmColor);
private:
void Init(const HCURSOR &cursor) noexcept {
if (::GetIconInfo(cursor, &info)) {
::GetObject(info.hbmMask, sizeof(bmp), &bmp);
PLATFORM_ASSERT(HasBitmap());
}
}
void CleanUp() noexcept {
if (info.hbmMask)
::DeleteObject(info.hbmMask);
if (info.hbmColor)
::DeleteObject(info.hbmColor);
info = {};
bmp = {};
}
static void FlipBitmap(const HBITMAP bitmap, const int width, const int height) noexcept {
HDC hdc = ::CreateCompatibleDC({});
if (hdc) {
HBITMAP prevBmp = SelectBitmap(hdc, bitmap);
::StretchBlt(hdc, width - 1, 0, -width, height, hdc, 0, 0, width, height, SRCCOPY);
SelectBitmap(hdc, prevBmp);
::DeleteDC(hdc);
}
}
};
HCURSOR reverseArrowCursor {};
const int width = SystemMetricsForDpi(SM_CXCURSOR, dpi);
const int height = SystemMetricsForDpi(SM_CYCURSOR, dpi);
DPI_AWARENESS_CONTEXT oldContext = nullptr;
if (fnAreDpiAwarenessContextsEqual && fnAreDpiAwarenessContextsEqual(fnGetThreadDpiAwarenessContext(), DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) {
oldContext = fnSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
PLATFORM_ASSERT(oldContext != nullptr);
}
if (created) {
::DestroyCursor(cursor);
const HCURSOR cursor = static_cast<HCURSOR>(::LoadImage({}, IDC_ARROW, IMAGE_CURSOR, width, height, LR_SHARED));
if (cursor) {
CursorHelper cursorHelper(cursor);
if (cursorHelper.HasBitmap() && !cursorHelper.MatchesSize(width, height)) {
const HCURSOR copy = static_cast<HCURSOR>(::CopyImage(cursor, IMAGE_CURSOR, width, height, LR_COPYFROMRESOURCE | LR_COPYRETURNORG));
if (copy) {
cursorHelper = copy;
::DestroyCursor(copy);
}
}
if (cursorHelper.HasBitmap()) {
reverseArrowCursor = cursorHelper.CreateFlippedCursor();
}
}
if (oldContext) {
fnSetThreadDpiAwarenessContext(oldContext);
}
return reverseArrowCursor;
}

View File

@ -46,7 +46,7 @@ void SetWindowPointer(HWND hWnd, void *ptr) noexcept;
HMONITOR MonitorFromWindowHandleScaling(HWND hWnd) noexcept;
UINT DpiForWindow(WindowID wid) noexcept;
int GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept;
float GetDeviceScaleFactorWhenGdiScalingActive(HWND hWnd) noexcept;
int SystemMetricsForDpi(int nIndex, UINT dpi) noexcept;

View File

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

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