mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-04-08 17:15:37 +02:00
Update to scintilla 5.5.3 & Lexilla 5.4.1
Release 5.5.3 (https://www.scintilla.org/scintilla553.zip) Released 19 October 2024. On Win32 change direction of horizontal mouse wheel and touchpad scrolling to match other applications. Bug #2449. Release 5.4.1 (https://www.scintilla.org/lexilla541.zip) Released 19 October 2024. Lexer added for Dart "dart". Pull request #265, Pull request #275. Lexer added for troff / nroff "troff". Pull request #264. Lexer added for Zig "zig". Pull request #267. C++: Fix crash for empty documentation comment keyword where '<' occurs at line end. F#: Include EOLs in the style range of SCE_FSHARP_COMMENTLINE. Stabilizes EOL detection when folding line comment groups. Issue #276. F#: Fix per-line folding in F# documents. Issue #277. HTML: Improve SGML/DTD lexing. Don't terminate SGML when > inside quoted string. Lex both [ and ] as SCE_H_SGML_DEFAULT. Nested sections handled instead of switching to SCE_H_SGML_ERROR. Issue #272. JavaScript: New SCE_HJ_TEMPLATELITERAL and SCE_HJA_TEMPLATELITERAL styles for template literals when lexer is hypertext, or xml. Issue #280. PHP: Fix failure to recognize PHP start "<?php' at end of document. Caused by not capping retrieval range at document end causing no text to be retrieved. Issue #269. Smalltalk: Fix scaled decimal numbers without decimal separator. Pull request #274. Fix #15228, fix #15368, fix #15650, close #15717
This commit is contained in:
parent
ba8cd8c46f
commit
213e9135ba
Binary file not shown.
Binary file not shown.
5
lexilla/.gitattributes
vendored
5
lexilla/.gitattributes
vendored
@ -35,6 +35,7 @@
|
||||
**.cob text
|
||||
**.cmake text
|
||||
**.d text
|
||||
**.dart text
|
||||
**.diff text
|
||||
**.erl text
|
||||
**.f text
|
||||
@ -55,8 +56,10 @@
|
||||
**.ps1 text
|
||||
**.r text
|
||||
**.rb text
|
||||
**.roff text
|
||||
**.rs text
|
||||
**.sql text
|
||||
**.st text
|
||||
**.tcl text
|
||||
**.toml text
|
||||
**.tsql text
|
||||
@ -67,7 +70,9 @@
|
||||
**.vh text
|
||||
**.vhd text
|
||||
**.x12 text
|
||||
**.xml text
|
||||
**.yaml text
|
||||
**.zig text
|
||||
**.md text
|
||||
**.txt text
|
||||
**.pch text
|
||||
|
@ -1,6 +1,12 @@
|
||||
// File to suppress cppcheck warnings for files that will not be fixed.
|
||||
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
|
||||
// Configured for cppcheck 2.12
|
||||
// Configured for cppcheck 2.15
|
||||
|
||||
// Just a report of how many checkers are run
|
||||
checkersReport
|
||||
|
||||
// This just warns that cppcheck isn't exhaustive and it still appears in exhaustive mode
|
||||
normalCheckLevelMaxBranches
|
||||
|
||||
// Coding style is to use assignments in constructor when there are many
|
||||
// members to initialize or the initialization is complex or has comments.
|
||||
@ -28,9 +34,6 @@ missingIncludeSystem
|
||||
danglingTemporaryLifetime:lexilla/access/LexillaAccess.cxx
|
||||
returnDanglingLifetime:lexilla/access/LexillaAccess.cxx
|
||||
|
||||
// cppcheck seems to believe that unique_ptr<char *[]>::get returns void* instead of char**
|
||||
arithOperationsOnVoidPointer:lexilla/lexlib/WordList.cxx
|
||||
|
||||
// cppcheck 2.11 limits checking of complex functions unless --check-level=exhaustive but that
|
||||
// only finds one false issue in LexRuby
|
||||
checkLevelNormal:lexilla/lexers/LexBash.cxx
|
||||
@ -73,6 +76,7 @@ variableScope:lexilla/lexers/LexCSS.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexDataflex.cxx
|
||||
constParameterReference:lexilla/lexers/LexDataflex.cxx
|
||||
variableScope:lexilla/lexers/LexDataflex.cxx
|
||||
constParameterReference:lexilla/lexers/LexDart.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexECL.cxx
|
||||
variableScope:lexilla/lexers/LexECL.cxx
|
||||
constParameter:lexilla/lexers/LexEDIFACT.cxx
|
||||
@ -156,6 +160,7 @@ constVariableReference:lexilla/lexers/LexTCL.cxx
|
||||
invalidscanf:lexilla/lexers/LexTCMD.cxx
|
||||
constParameterReference:lexilla/lexers/LexTeX.cxx
|
||||
variableScope:lexilla/lexers/LexTeX.cxx
|
||||
constVariableReference:lexilla/lexers/LexTroff.cxx
|
||||
knownConditionTrueFalse:lexilla/lexers/LexVB.cxx
|
||||
constParameterReference:lexilla/lexers/LexVerilog.cxx
|
||||
variableScope:lexilla/lexers/LexVerilog.cxx
|
||||
|
@ -9,7 +9,7 @@
|
||||
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
|
||||
<meta name="Description"
|
||||
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
|
||||
<meta name="Date.Modified" content="20240821" />
|
||||
<meta name="Date.Modified" content="20241019" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
.logo {
|
||||
@ -61,8 +61,8 @@
|
||||
<font color="#FFCC99" size="4"> A library of language lexers for use with Scintilla</font>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<font color="#FFCC99" size="3">Release version 5.4.0<br />
|
||||
Site last modified August 21 2024</font>
|
||||
<font color="#FFCC99" size="3">Release version 5.4.1<br />
|
||||
Site last modified October 19 2024</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -77,11 +77,11 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.4.1 adds Dart, troff, and Zig lexers. Improves C++, F#, HTML, and Smalltalk.</li>
|
||||
<li>Version 5.4.0 adds a TOML lexer.</li>
|
||||
<li>Version 5.3.3 improves HTML, JavaScript, Lua, PHP, and XML.</li>
|
||||
<li>Version 5.3.2 improves COBOL, HTML, Lua, Ruby, and Rust.</li>
|
||||
<li>Version 5.3.1 improves Assembler, Bash, Batch, JavaScript, Python, and Ruby.</li>
|
||||
<li>Version 5.3.0 improves Bash, HTML, and Lua.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
@ -26,9 +26,9 @@
|
||||
<table bgcolor="#CCCCCC" width="100%" cellspacing="0" cellpadding="8" border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<font size="4"> <a href="https://www.scintilla.org/lexilla540.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/lexilla541.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/lexilla540.tgz">
|
||||
<a href="https://www.scintilla.org/lexilla541.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.4.0
|
||||
Release 5.4.1
|
||||
</h3>
|
||||
<h4>
|
||||
Source Code
|
||||
@ -50,8 +50,8 @@
|
||||
The source code package contains all of the source code for Lexilla but no binary
|
||||
executable code and is available in
|
||||
<ul>
|
||||
<li><a href="https://www.scintilla.org/lexilla540.zip">zip format</a> (1.3M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla540.tgz">tgz format</a> (0.9M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla541.zip">zip format</a> (1.3M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/lexilla541.tgz">tgz format</a> (1.0M) commonly used on Linux and compatible operating systems</li>
|
||||
</ul>
|
||||
Instructions for building on both Windows and Linux are included in the readme file.
|
||||
<h4>
|
||||
|
@ -585,9 +585,65 @@
|
||||
<td>Tsuyoshi Miyake</td>
|
||||
<td>Martin Schäfer</td>
|
||||
<td>RainRat</td>
|
||||
</tr><tr>
|
||||
<td>Henrik S. Johansen</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Releases</h2>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla541.zip">Release 5.4.1</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 19 October 2024.
|
||||
</li>
|
||||
<li>
|
||||
Lexer added for Dart "dart".
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/265">Pull request #265</a>,
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/275">Pull request #275</a>.
|
||||
</li>
|
||||
<li>
|
||||
Lexer added for troff / nroff "troff".
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/264">Pull request #264</a>.
|
||||
</li>
|
||||
<li>
|
||||
Lexer added for Zig "zig".
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/267">Pull request #267</a>.
|
||||
</li>
|
||||
<li>
|
||||
C++: Fix crash for empty documentation comment keyword where '<' occurs at line end.
|
||||
</li>
|
||||
<li>
|
||||
F#: Include EOLs in the style range of SCE_FSHARP_COMMENTLINE.
|
||||
Stabilizes EOL detection when folding line comment groups.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/276">Issue #276</a>.
|
||||
</li>
|
||||
<li>
|
||||
F#: Fix per-line folding in F# documents.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/277">Issue #277</a>.
|
||||
</li>
|
||||
<li>
|
||||
HTML: Improve SGML/DTD lexing.
|
||||
Don't terminate SGML when > inside quoted string.
|
||||
Lex both [ and ] as SCE_H_SGML_DEFAULT.
|
||||
Nested sections handled instead of switching to SCE_H_SGML_ERROR.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/272">Issue #272</a>.
|
||||
</li>
|
||||
<li>
|
||||
JavaScript: New SCE_HJ_TEMPLATELITERAL and SCE_HJA_TEMPLATELITERAL
|
||||
styles for template literals when lexer is hypertext, or xml.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/280">Issue #280</a>.
|
||||
</li>
|
||||
<li>
|
||||
PHP: Fix failure to recognize PHP start "<?php' at end of document.
|
||||
Caused by not capping retrieval range at document end causing no text to be retrieved.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/issues/269">Issue #269</a>.
|
||||
</li>
|
||||
<li>
|
||||
Smalltalk: Fix scaled decimal numbers without decimal separator.
|
||||
<a href="https://github.com/ScintillaOrg/lexilla/pull/274">Pull request #274</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/lexilla540.zip">Release 5.4.0</a>
|
||||
</h3>
|
||||
|
@ -27,6 +27,7 @@ style.simple.1=fore:#FF0000
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "ILexer.h"
|
||||
|
@ -145,6 +145,9 @@ val SCLEX_JULIA=133
|
||||
val SCLEX_ASCIIDOC=134
|
||||
val SCLEX_GDSCRIPT=135
|
||||
val SCLEX_TOML=136
|
||||
val SCLEX_TROFF=137
|
||||
val SCLEX_DART=138
|
||||
val SCLEX_ZIG=139
|
||||
|
||||
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
|
||||
# value assigned in sequence from SCLEX_AUTOMATIC+1.
|
||||
@ -313,6 +316,7 @@ val SCE_HJ_SINGLESTRING=49
|
||||
val SCE_HJ_SYMBOLS=50
|
||||
val SCE_HJ_STRINGEOL=51
|
||||
val SCE_HJ_REGEX=52
|
||||
val SCE_HJ_TEMPLATELITERAL=53
|
||||
# ASP Javascript
|
||||
val SCE_HJA_START=55
|
||||
val SCE_HJA_DEFAULT=56
|
||||
@ -327,6 +331,7 @@ val SCE_HJA_SINGLESTRING=64
|
||||
val SCE_HJA_SYMBOLS=65
|
||||
val SCE_HJA_STRINGEOL=66
|
||||
val SCE_HJA_REGEX=67
|
||||
val SCE_HJA_TEMPLATELITERAL=68
|
||||
# Embedded VBScript
|
||||
val SCE_HB_START=70
|
||||
val SCE_HB_DEFAULT=71
|
||||
@ -2328,3 +2333,81 @@ val SCE_TOML_TRIPLE_STRING_SQ=11
|
||||
val SCE_TOML_TRIPLE_STRING_DQ=12
|
||||
val SCE_TOML_ESCAPECHAR=13
|
||||
val SCE_TOML_DATETIME=14
|
||||
# Lexical states for SCLEX_TROFF
|
||||
lex troff=SCLEX_TROFF SCE_TROFF_
|
||||
val SCE_TROFF_DEFAULT=0
|
||||
val SCE_TROFF_REQUEST=1
|
||||
val SCE_TROFF_COMMAND=2
|
||||
val SCE_TROFF_NUMBER=3
|
||||
val SCE_TROFF_OPERATOR=4
|
||||
val SCE_TROFF_STRING=5
|
||||
val SCE_TROFF_COMMENT=6
|
||||
val SCE_TROFF_IGNORE=7
|
||||
val SCE_TROFF_ESCAPE_STRING=8
|
||||
val SCE_TROFF_ESCAPE_MACRO=9
|
||||
val SCE_TROFF_ESCAPE_FONT=10
|
||||
val SCE_TROFF_ESCAPE_NUMBER=11
|
||||
val SCE_TROFF_ESCAPE_COLOUR=12
|
||||
val SCE_TROFF_ESCAPE_GLYPH=13
|
||||
val SCE_TROFF_ESCAPE_ENV=14
|
||||
val SCE_TROFF_ESCAPE_SUPPRESSION=15
|
||||
val SCE_TROFF_ESCAPE_SIZE=16
|
||||
val SCE_TROFF_ESCAPE_TRANSPARENT=17
|
||||
val SCE_TROFF_ESCAPE_ISVALID=18
|
||||
val SCE_TROFF_ESCAPE_DRAW=19
|
||||
val SCE_TROFF_ESCAPE_MOVE=20
|
||||
val SCE_TROFF_ESCAPE_HEIGHT=21
|
||||
val SCE_TROFF_ESCAPE_OVERSTRIKE=22
|
||||
val SCE_TROFF_ESCAPE_SLANT=23
|
||||
val SCE_TROFF_ESCAPE_WIDTH=24
|
||||
val SCE_TROFF_ESCAPE_VSPACING=25
|
||||
val SCE_TROFF_ESCAPE_DEVICE=26
|
||||
val SCE_TROFF_ESCAPE_NOMOVE=27
|
||||
# Lexical states for SCLEX_DART
|
||||
lex Dart=SCLEX_DART SCE_DART_
|
||||
val SCE_DART_DEFAULT=0
|
||||
val SCE_DART_COMMENTLINE=1
|
||||
val SCE_DART_COMMENTLINEDOC=2
|
||||
val SCE_DART_COMMENTBLOCK=3
|
||||
val SCE_DART_COMMENTBLOCKDOC=4
|
||||
val SCE_DART_STRING_SQ=5
|
||||
val SCE_DART_STRING_DQ=6
|
||||
val SCE_DART_TRIPLE_STRING_SQ=7
|
||||
val SCE_DART_TRIPLE_STRING_DQ=8
|
||||
val SCE_DART_RAWSTRING_SQ=9
|
||||
val SCE_DART_RAWSTRING_DQ=10
|
||||
val SCE_DART_TRIPLE_RAWSTRING_SQ=11
|
||||
val SCE_DART_TRIPLE_RAWSTRING_DQ=12
|
||||
val SCE_DART_ESCAPECHAR=13
|
||||
val SCE_DART_IDENTIFIER=14
|
||||
val SCE_DART_IDENTIFIER_STRING=15
|
||||
val SCE_DART_OPERATOR=16
|
||||
val SCE_DART_OPERATOR_STRING=17
|
||||
val SCE_DART_SYMBOL_IDENTIFIER=18
|
||||
val SCE_DART_SYMBOL_OPERATOR=19
|
||||
val SCE_DART_NUMBER=20
|
||||
val SCE_DART_KEY=21
|
||||
val SCE_DART_METADATA=22
|
||||
val SCE_DART_KW_PRIMARY=23
|
||||
val SCE_DART_KW_SECONDARY=24
|
||||
val SCE_DART_KW_TERTIARY=25
|
||||
val SCE_DART_KW_TYPE=26
|
||||
# Lexical states for SCLEX_ZIG
|
||||
lex Zig=SCLEX_ZIG SCE_ZIG_
|
||||
val SCE_ZIG_DEFAULT=0
|
||||
val SCE_ZIG_COMMENTLINE=1
|
||||
val SCE_ZIG_COMMENTLINEDOC=2
|
||||
val SCE_ZIG_COMMENTLINETOP=3
|
||||
val SCE_ZIG_NUMBER=4
|
||||
val SCE_ZIG_OPERATOR=5
|
||||
val SCE_ZIG_CHARACTER=6
|
||||
val SCE_ZIG_STRING=7
|
||||
val SCE_ZIG_MULTISTRING=8
|
||||
val SCE_ZIG_ESCAPECHAR=9
|
||||
val SCE_ZIG_IDENTIFIER=10
|
||||
val SCE_ZIG_FUNCTION=11
|
||||
val SCE_ZIG_BUILTIN_FUNCTION=12
|
||||
val SCE_ZIG_KW_PRIMARY=13
|
||||
val SCE_ZIG_KW_SECONDARY=14
|
||||
val SCE_ZIG_KW_TERTIARY=15
|
||||
val SCE_ZIG_KW_TYPE=16
|
||||
|
@ -149,6 +149,9 @@
|
||||
#define SCLEX_ASCIIDOC 134
|
||||
#define SCLEX_GDSCRIPT 135
|
||||
#define SCLEX_TOML 136
|
||||
#define SCLEX_TROFF 137
|
||||
#define SCLEX_DART 138
|
||||
#define SCLEX_ZIG 139
|
||||
#define SCLEX_SEARCHRESULT 150
|
||||
#define SCLEX_OBJC 151
|
||||
#define SCLEX_USER 152
|
||||
@ -292,6 +295,7 @@
|
||||
#define SCE_HJ_SYMBOLS 50
|
||||
#define SCE_HJ_STRINGEOL 51
|
||||
#define SCE_HJ_REGEX 52
|
||||
#define SCE_HJ_TEMPLATELITERAL 53
|
||||
#define SCE_HJA_START 55
|
||||
#define SCE_HJA_DEFAULT 56
|
||||
#define SCE_HJA_COMMENT 57
|
||||
@ -305,6 +309,7 @@
|
||||
#define SCE_HJA_SYMBOLS 65
|
||||
#define SCE_HJA_STRINGEOL 66
|
||||
#define SCE_HJA_REGEX 67
|
||||
#define SCE_HJA_TEMPLATELITERAL 68
|
||||
#define SCE_HB_START 70
|
||||
#define SCE_HB_DEFAULT 71
|
||||
#define SCE_HB_COMMENTLINE 72
|
||||
@ -2077,6 +2082,78 @@
|
||||
#define SCE_TOML_TRIPLE_STRING_DQ 12
|
||||
#define SCE_TOML_ESCAPECHAR 13
|
||||
#define SCE_TOML_DATETIME 14
|
||||
#define SCE_TROFF_DEFAULT 0
|
||||
#define SCE_TROFF_REQUEST 1
|
||||
#define SCE_TROFF_COMMAND 2
|
||||
#define SCE_TROFF_NUMBER 3
|
||||
#define SCE_TROFF_OPERATOR 4
|
||||
#define SCE_TROFF_STRING 5
|
||||
#define SCE_TROFF_COMMENT 6
|
||||
#define SCE_TROFF_IGNORE 7
|
||||
#define SCE_TROFF_ESCAPE_STRING 8
|
||||
#define SCE_TROFF_ESCAPE_MACRO 9
|
||||
#define SCE_TROFF_ESCAPE_FONT 10
|
||||
#define SCE_TROFF_ESCAPE_NUMBER 11
|
||||
#define SCE_TROFF_ESCAPE_COLOUR 12
|
||||
#define SCE_TROFF_ESCAPE_GLYPH 13
|
||||
#define SCE_TROFF_ESCAPE_ENV 14
|
||||
#define SCE_TROFF_ESCAPE_SUPPRESSION 15
|
||||
#define SCE_TROFF_ESCAPE_SIZE 16
|
||||
#define SCE_TROFF_ESCAPE_TRANSPARENT 17
|
||||
#define SCE_TROFF_ESCAPE_ISVALID 18
|
||||
#define SCE_TROFF_ESCAPE_DRAW 19
|
||||
#define SCE_TROFF_ESCAPE_MOVE 20
|
||||
#define SCE_TROFF_ESCAPE_HEIGHT 21
|
||||
#define SCE_TROFF_ESCAPE_OVERSTRIKE 22
|
||||
#define SCE_TROFF_ESCAPE_SLANT 23
|
||||
#define SCE_TROFF_ESCAPE_WIDTH 24
|
||||
#define SCE_TROFF_ESCAPE_VSPACING 25
|
||||
#define SCE_TROFF_ESCAPE_DEVICE 26
|
||||
#define SCE_TROFF_ESCAPE_NOMOVE 27
|
||||
#define SCE_DART_DEFAULT 0
|
||||
#define SCE_DART_COMMENTLINE 1
|
||||
#define SCE_DART_COMMENTLINEDOC 2
|
||||
#define SCE_DART_COMMENTBLOCK 3
|
||||
#define SCE_DART_COMMENTBLOCKDOC 4
|
||||
#define SCE_DART_STRING_SQ 5
|
||||
#define SCE_DART_STRING_DQ 6
|
||||
#define SCE_DART_TRIPLE_STRING_SQ 7
|
||||
#define SCE_DART_TRIPLE_STRING_DQ 8
|
||||
#define SCE_DART_RAWSTRING_SQ 9
|
||||
#define SCE_DART_RAWSTRING_DQ 10
|
||||
#define SCE_DART_TRIPLE_RAWSTRING_SQ 11
|
||||
#define SCE_DART_TRIPLE_RAWSTRING_DQ 12
|
||||
#define SCE_DART_ESCAPECHAR 13
|
||||
#define SCE_DART_IDENTIFIER 14
|
||||
#define SCE_DART_IDENTIFIER_STRING 15
|
||||
#define SCE_DART_OPERATOR 16
|
||||
#define SCE_DART_OPERATOR_STRING 17
|
||||
#define SCE_DART_SYMBOL_IDENTIFIER 18
|
||||
#define SCE_DART_SYMBOL_OPERATOR 19
|
||||
#define SCE_DART_NUMBER 20
|
||||
#define SCE_DART_KEY 21
|
||||
#define SCE_DART_METADATA 22
|
||||
#define SCE_DART_KW_PRIMARY 23
|
||||
#define SCE_DART_KW_SECONDARY 24
|
||||
#define SCE_DART_KW_TERTIARY 25
|
||||
#define SCE_DART_KW_TYPE 26
|
||||
#define SCE_ZIG_DEFAULT 0
|
||||
#define SCE_ZIG_COMMENTLINE 1
|
||||
#define SCE_ZIG_COMMENTLINEDOC 2
|
||||
#define SCE_ZIG_COMMENTLINETOP 3
|
||||
#define SCE_ZIG_NUMBER 4
|
||||
#define SCE_ZIG_OPERATOR 5
|
||||
#define SCE_ZIG_CHARACTER 6
|
||||
#define SCE_ZIG_STRING 7
|
||||
#define SCE_ZIG_MULTISTRING 8
|
||||
#define SCE_ZIG_ESCAPECHAR 9
|
||||
#define SCE_ZIG_IDENTIFIER 10
|
||||
#define SCE_ZIG_FUNCTION 11
|
||||
#define SCE_ZIG_BUILTIN_FUNCTION 12
|
||||
#define SCE_ZIG_KW_PRIMARY 13
|
||||
#define SCE_ZIG_KW_SECONDARY 14
|
||||
#define SCE_ZIG_KW_TERTIARY 15
|
||||
#define SCE_ZIG_KW_TYPE 16
|
||||
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
|
||||
|
||||
|
||||
|
@ -1073,7 +1073,7 @@ void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int i
|
||||
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
|
||||
sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
|
||||
}
|
||||
} else if ((sc.ch == '<' && sc.chNext != '/')
|
||||
} else if ((sc.ch == '<' && !(IsASpace(sc.chNext) || sc.chNext == '/'))
|
||||
|| (sc.ch == '/' && sc.chPrev == '<')) { // XML comment style
|
||||
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
|
||||
sc.ForwardSetState(SCE_C_COMMENTDOCKEYWORD | activitySet);
|
||||
|
702
lexilla/lexers/LexDart.cxx
Normal file
702
lexilla/lexers/LexDart.cxx
Normal file
@ -0,0 +1,702 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexDart.cxx
|
||||
** Lexer for Dart.
|
||||
**/
|
||||
// Based on Zufu Liu's Notepad4 Dart lexer
|
||||
// Modified for Scintilla by Jiri Techet, 2024
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
using namespace Lexilla;
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
constexpr bool IsEOLChar(int ch) noexcept {
|
||||
return ch == '\r' || ch == '\n';
|
||||
}
|
||||
|
||||
constexpr bool IsAGraphic(int ch) noexcept {
|
||||
// excludes C0 control characters and whitespace
|
||||
return ch > 32 && ch < 127;
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierChar(int ch) noexcept {
|
||||
return IsAlphaNumeric(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierStart(int ch) noexcept {
|
||||
return IsUpperOrLowerCase(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {
|
||||
return ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))
|
||||
|| (ch == '.' && chNext != '.');
|
||||
}
|
||||
|
||||
constexpr bool IsNumberStart(int ch, int chNext) noexcept {
|
||||
return IsADigit(ch) || (ch == '.' && IsADigit(chNext));
|
||||
}
|
||||
|
||||
constexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {
|
||||
return IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);
|
||||
}
|
||||
|
||||
struct EscapeSequence {
|
||||
int outerState = SCE_DART_DEFAULT;
|
||||
int digitsLeft = 0;
|
||||
bool brace = false;
|
||||
|
||||
// highlight any character as escape sequence.
|
||||
bool resetEscapeState(int state, int chNext) noexcept {
|
||||
if (IsEOLChar(chNext)) {
|
||||
return false;
|
||||
}
|
||||
outerState = state;
|
||||
brace = false;
|
||||
digitsLeft = (chNext == 'x')? 3 : ((chNext == 'u') ? 5 : 1);
|
||||
return true;
|
||||
}
|
||||
bool atEscapeEnd(int ch) noexcept {
|
||||
--digitsLeft;
|
||||
return digitsLeft <= 0 || !IsAHeXDigit(ch);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool IsDartIdentifierStart(int ch) noexcept {
|
||||
return IsIdentifierStart(ch) || ch == '$';
|
||||
}
|
||||
|
||||
constexpr bool IsDartIdentifierChar(int ch) noexcept {
|
||||
return IsIdentifierChar(ch) || ch == '$';
|
||||
}
|
||||
|
||||
constexpr bool IsDefinableOperator(int ch) noexcept {
|
||||
// https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/symbol.dart
|
||||
return AnyOf(ch, '+', '-', '*', '/', '%', '~', '&', '|',
|
||||
'^', '<', '>', '=', '[', ']');
|
||||
}
|
||||
|
||||
constexpr bool IsSpaceEquiv(int state) noexcept {
|
||||
return state == SCE_DART_DEFAULT ||
|
||||
state == SCE_DART_COMMENTLINE ||
|
||||
state == SCE_DART_COMMENTLINEDOC ||
|
||||
state == SCE_DART_COMMENTBLOCK ||
|
||||
state == SCE_DART_COMMENTBLOCKDOC;
|
||||
}
|
||||
|
||||
constexpr bool IsTripleString(int state) noexcept {
|
||||
return state == SCE_DART_TRIPLE_STRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_STRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr bool IsDoubleQuoted(int state) noexcept {
|
||||
return state == SCE_DART_STRING_DQ ||
|
||||
state == SCE_DART_RAWSTRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_STRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr bool IsRaw(int state) noexcept {
|
||||
return state == SCE_DART_RAWSTRING_SQ ||
|
||||
state == SCE_DART_RAWSTRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr int GetStringQuote(int state) noexcept {
|
||||
return IsDoubleQuoted(state) ? '\"' : '\'';
|
||||
}
|
||||
|
||||
enum {
|
||||
DartLineStateMaskLineComment = 1, // line comment
|
||||
DartLineStateMaskImport = (1 << 1), // import
|
||||
DartLineStateMaskInterpolation = (1 << 2), // string interpolation
|
||||
};
|
||||
|
||||
// string interpolating state
|
||||
struct InterpolatingState {
|
||||
int state;
|
||||
int braceCount;
|
||||
};
|
||||
|
||||
struct FoldLineState {
|
||||
int lineComment;
|
||||
int packageImport;
|
||||
constexpr explicit FoldLineState(int lineState) noexcept:
|
||||
lineComment(lineState & DartLineStateMaskLineComment),
|
||||
packageImport((lineState >> 1) & 1) {
|
||||
}
|
||||
};
|
||||
|
||||
// Options used for LexerDart
|
||||
struct OptionsDart {
|
||||
bool fold = false;
|
||||
};
|
||||
|
||||
const char * const dartWordListDesc[] = {
|
||||
"Primary keywords",
|
||||
"Secondary keywords",
|
||||
"Tertiary keywords",
|
||||
"Global type definitions",
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetDart : public OptionSet<OptionsDart> {
|
||||
OptionSetDart() {
|
||||
DefineProperty("fold", &OptionsDart::fold);
|
||||
|
||||
DefineWordListSets(dartWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer DART SCLEX_DART SCE_DART_:
|
||||
0, "SCE_DART_DEFAULT", "default", "White space",
|
||||
1, "SCE_DART_COMMENTLINE", "comment line", "Comment: //",
|
||||
2, "SCE_DART_COMMENTLINEDOC", "comment line documentation", "Comment: ///",
|
||||
3, "SCE_DART_COMMENTBLOCK", "comment", "Comment: /* */",
|
||||
4, "SCE_DART_COMMENTBLOCKDOC", "comment documentation", "Comment: /** */",
|
||||
5, "SCE_DART_STRING_SQ", "literal string", "Single quoted string",
|
||||
6, "SCE_DART_STRING_DQ", "literal string", "Double quoted string",
|
||||
7, "SCE_DART_TRIPLE_STRING_SQ", "literal string multiline", "Single quoted multiline string",
|
||||
8, "SCE_DART_TRIPLE_STRING_DQ", "literal string multiline", "Double quoted multiline string",
|
||||
9, "SCE_DART_RAWSTRING_SQ", "literal string raw", "Single quoted raw string",
|
||||
10, "SCE_DART_RAWSTRING_DQ", "literal string raw", "Double quoted raw string",
|
||||
11, "SCE_DART_TRIPLE_RAWSTRING_SQ", "literal string multiline raw", "Single quoted multiline raw string",
|
||||
12, "SCE_DART_TRIPLE_RAWSTRING_DQ", "literal string multiline raw", "Double quoted multiline raw string",
|
||||
13, "SCE_DART_ESCAPECHAR", "literal string escapesequence", "Escape sequence",
|
||||
14, "SCE_DART_IDENTIFIER", "identifier", "Identifier",
|
||||
15, "SCE_DART_IDENTIFIER_STRING", "identifier interpolated", "Identifier following $ inside strings",
|
||||
16, "SCE_DART_OPERATOR", "operator", "Operator",
|
||||
17, "SCE_DART_OPERATOR_STRING", "operator interpolated", "Braces following $ inside string",
|
||||
18, "SCE_DART_SYMBOL_IDENTIFIER", "identifier symbol", "Symbol name introduced by #",
|
||||
19, "SCE_DART_SYMBOL_OPERATOR", "operator symbol", "Operator introduced by #",
|
||||
20, "SCE_DART_NUMBER", "literal numeric", "Number",
|
||||
21, "SCE_DART_KEY", "key", "Keys preceding ':' and named parameters",
|
||||
22, "SCE_DART_METADATA", "preprocessor", "Metadata introduced by @",
|
||||
23, "SCE_DART_KW_PRIMARY", "keyword", "Primary keywords",
|
||||
24, "SCE_DART_KW_SECONDARY", "identifier", "Secondary keywords",
|
||||
25, "SCE_DART_KW_TERTIARY", "identifier", "Tertiary keywords",
|
||||
26, "SCE_DART_KW_TYPE", "identifier", "Global types",
|
||||
};
|
||||
|
||||
class LexerDart : public DefaultLexer {
|
||||
WordList keywordsPrimary;
|
||||
WordList keywordsSecondary;
|
||||
WordList keywordsTertiary;
|
||||
WordList keywordsTypes;
|
||||
OptionsDart options;
|
||||
OptionSetDart osDart;
|
||||
public:
|
||||
LexerDart(const char *languageName_, int language_) :
|
||||
DefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {
|
||||
}
|
||||
// Deleted so LexerDart objects can not be copied.
|
||||
LexerDart(const LexerDart &) = delete;
|
||||
LexerDart(LexerDart &&) = delete;
|
||||
void operator=(const LexerDart &) = delete;
|
||||
void operator=(LexerDart &&) = delete;
|
||||
~LexerDart() override = default;
|
||||
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvRelease5;
|
||||
}
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osDart.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osDart.PropertyType(name);
|
||||
}
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osDart.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osDart.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osDart.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);
|
||||
Sci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);
|
||||
|
||||
static ILexer5 *LexerFactoryDart() {
|
||||
return new LexerDart("dart", SCLEX_DART);
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerDart::PropertySet(const char *key, const char *val) {
|
||||
if (osDart.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerDart::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywordsPrimary;
|
||||
break;
|
||||
case 1:
|
||||
wordListN = &keywordsSecondary;
|
||||
break;
|
||||
case 2:
|
||||
wordListN = &keywordsTertiary;
|
||||
break;
|
||||
case 3:
|
||||
wordListN = &keywordsTypes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN && wordListN->Set(wl, false)) {
|
||||
firstModification = 0;
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerDart::BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle) {
|
||||
const Sci_Position currentLine = styler.GetLine(startPos);
|
||||
if (currentLine != 0) {
|
||||
Sci_Position line = currentLine - 1;
|
||||
int lineState = styler.GetLineState(line);
|
||||
while ((lineState & stateMask) != 0 && line != 0) {
|
||||
--line;
|
||||
lineState = styler.GetLineState(line);
|
||||
}
|
||||
if ((lineState & stateMask) == 0) {
|
||||
++line;
|
||||
}
|
||||
if (line != currentLine) {
|
||||
const Sci_PositionU endPos = startPos + lengthDoc;
|
||||
startPos = (line == 0) ? 0 : styler.LineStart(line);
|
||||
lengthDoc = endPos - startPos;
|
||||
initStyle = (startPos == 0) ? 0 : styler.StyleAt(startPos - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sci_PositionU LexerDart::LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite) {
|
||||
do {
|
||||
--startPos;
|
||||
const unsigned style = styler.StyleAt(startPos);
|
||||
if (!IsSpaceEquiv(style)) {
|
||||
stylePrevNonWhite = style;
|
||||
chPrevNonWhite = static_cast<unsigned char>(styler[startPos]);
|
||||
break;
|
||||
}
|
||||
} while (startPos != 0);
|
||||
return startPos;
|
||||
}
|
||||
|
||||
void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
int lineStateLineType = 0;
|
||||
int commentLevel = 0; // nested block comment level
|
||||
|
||||
std::vector<InterpolatingState> interpolatingStack;
|
||||
|
||||
int visibleChars = 0;
|
||||
int chBefore = 0;
|
||||
int chPrevNonWhite = 0;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
if (startPos != 0) {
|
||||
// backtrack to the line where interpolation starts
|
||||
BacktrackToStart(styler, DartLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, lengthDoc, initStyle, styler);
|
||||
if (sc.currentLine > 0) {
|
||||
const int lineState = styler.GetLineState(sc.currentLine - 1);
|
||||
commentLevel = lineState >> 4;
|
||||
}
|
||||
if (startPos == 0) {
|
||||
if (sc.Match('#', '!')) {
|
||||
// Shell Shebang at beginning of file
|
||||
sc.SetState(SCE_DART_COMMENTLINE);
|
||||
sc.Forward();
|
||||
lineStateLineType = DartLineStateMaskLineComment;
|
||||
}
|
||||
} else if (IsSpaceEquiv(initStyle)) {
|
||||
LookbackNonWhite(styler, startPos, chPrevNonWhite, initStyle);
|
||||
chBefore = chPrevNonWhite;
|
||||
}
|
||||
|
||||
while (sc.More()) {
|
||||
switch (sc.state) {
|
||||
case SCE_DART_OPERATOR:
|
||||
case SCE_DART_OPERATOR_STRING:
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
break;
|
||||
|
||||
case SCE_DART_NUMBER:
|
||||
if (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_IDENTIFIER:
|
||||
case SCE_DART_IDENTIFIER_STRING:
|
||||
case SCE_DART_METADATA:
|
||||
case SCE_DART_SYMBOL_IDENTIFIER:
|
||||
if (!IsDartIdentifierChar(sc.ch) || (sc.ch == '$' && sc.state == SCE_DART_IDENTIFIER_STRING)) {
|
||||
if (sc.state == SCE_DART_METADATA || sc.state == SCE_DART_SYMBOL_IDENTIFIER) {
|
||||
if (sc.ch == '.') {
|
||||
const int state = sc.state;
|
||||
sc.SetState(SCE_DART_OPERATOR);
|
||||
sc.ForwardSetState(state);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
char s[64];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
const int state = sc.state;
|
||||
if (state == SCE_DART_IDENTIFIER_STRING) {
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
} else if (keywordsPrimary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_PRIMARY);
|
||||
if (strcmp(s, "import") == 0 || strcmp(s, "part") == 0) {
|
||||
if (visibleChars == sc.LengthCurrent()) {
|
||||
lineStateLineType = DartLineStateMaskImport;
|
||||
}
|
||||
}
|
||||
} else if (keywordsSecondary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_SECONDARY);
|
||||
} else if (keywordsTertiary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_TERTIARY);
|
||||
} else if (keywordsTypes.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_TYPE);
|
||||
} else if (state == SCE_DART_IDENTIFIER && sc.ch == ':') {
|
||||
if (chBefore == ',' || chBefore == '{' || chBefore == '(') {
|
||||
sc.ChangeState(SCE_DART_KEY); // map key or named parameter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_SYMBOL_OPERATOR:
|
||||
if (!IsDefinableOperator(sc.ch)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_COMMENTLINE:
|
||||
case SCE_DART_COMMENTLINEDOC:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_COMMENTBLOCK:
|
||||
case SCE_DART_COMMENTBLOCKDOC:
|
||||
if (sc.Match('*', '/')) {
|
||||
sc.Forward();
|
||||
--commentLevel;
|
||||
if (commentLevel == 0) {
|
||||
sc.ForwardSetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
} else if (sc.Match('/', '*')) {
|
||||
sc.Forward();
|
||||
++commentLevel;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_STRING_SQ:
|
||||
case SCE_DART_STRING_DQ:
|
||||
case SCE_DART_TRIPLE_STRING_SQ:
|
||||
case SCE_DART_TRIPLE_STRING_DQ:
|
||||
case SCE_DART_RAWSTRING_SQ:
|
||||
case SCE_DART_RAWSTRING_DQ:
|
||||
case SCE_DART_TRIPLE_RAWSTRING_SQ:
|
||||
case SCE_DART_TRIPLE_RAWSTRING_DQ:
|
||||
if (sc.atLineStart && !IsTripleString(sc.state)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
} else if (sc.ch == '\\' && !IsRaw(sc.state)) {
|
||||
if (escSeq.resetEscapeState(sc.state, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_ESCAPECHAR);
|
||||
sc.Forward();
|
||||
if (sc.Match('u', '{')) {
|
||||
escSeq.brace = true;
|
||||
escSeq.digitsLeft = 7; // Unicode code point
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
} else if (sc.ch == '$' && !IsRaw(sc.state)) {
|
||||
escSeq.outerState = sc.state;
|
||||
sc.SetState(SCE_DART_OPERATOR_STRING);
|
||||
sc.Forward();
|
||||
if (sc.ch == '{') {
|
||||
interpolatingStack.push_back({escSeq.outerState, 1});
|
||||
} else if (sc.ch != '$' && IsDartIdentifierStart(sc.ch)) {
|
||||
sc.SetState(SCE_DART_IDENTIFIER_STRING);
|
||||
} else { // error
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
}
|
||||
} else if (sc.ch == GetStringQuote(sc.state) &&
|
||||
(!IsTripleString(sc.state) || (sc.Match(IsDoubleQuoted(sc.state) ? R"(""")" : R"(''')")))) {
|
||||
if (IsTripleString(sc.state)) {
|
||||
sc.Forward(2);
|
||||
}
|
||||
sc.Forward();
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
if (escSeq.brace && sc.ch == '}') {
|
||||
sc.Forward();
|
||||
}
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc.state == SCE_DART_DEFAULT) {
|
||||
if (sc.ch == '/' && (sc.chNext == '/' || sc.chNext == '*')) {
|
||||
const int chNext = sc.chNext;
|
||||
sc.SetState((chNext == '/') ? SCE_DART_COMMENTLINE : SCE_DART_COMMENTBLOCK);
|
||||
sc.Forward(2);
|
||||
if (sc.ch == chNext && sc.chNext != chNext) {
|
||||
if (sc.state == SCE_DART_COMMENTLINE) {
|
||||
sc.ChangeState(SCE_DART_COMMENTLINEDOC);
|
||||
} else {
|
||||
sc.ChangeState(SCE_DART_COMMENTBLOCKDOC);
|
||||
}
|
||||
}
|
||||
if (chNext == '/') {
|
||||
if (visibleChars == 0) {
|
||||
lineStateLineType = DartLineStateMaskLineComment;
|
||||
}
|
||||
} else {
|
||||
commentLevel = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sc.ch == 'r' && (sc.chNext == '\'' || sc.chNext == '"')) {
|
||||
sc.SetState((sc.chNext == '\'') ? SCE_DART_RAWSTRING_SQ : SCE_DART_RAWSTRING_DQ);
|
||||
sc.Forward(2);
|
||||
if (sc.chPrev == '\'' && sc.Match('\'', '\'')) {
|
||||
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_SQ);
|
||||
sc.Forward(2);
|
||||
} else if (sc.chPrev == '"' && sc.Match('"', '"')) {
|
||||
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_DQ);
|
||||
sc.Forward(2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sc.ch == '"') {
|
||||
if (sc.Match(R"(""")")) {
|
||||
sc.SetState(SCE_DART_TRIPLE_STRING_DQ);
|
||||
sc.Forward(2);
|
||||
} else {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_STRING_DQ);
|
||||
}
|
||||
} else if (sc.ch == '\'') {
|
||||
if (sc.Match(R"(''')")) {
|
||||
sc.SetState(SCE_DART_TRIPLE_STRING_SQ);
|
||||
sc.Forward(2);
|
||||
} else {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_STRING_SQ);
|
||||
}
|
||||
} else if (IsNumberStart(sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_NUMBER);
|
||||
} else if ((sc.ch == '@' || sc.ch == '#') && IsDartIdentifierStart(sc.chNext)) {
|
||||
sc.SetState((sc.ch == '@') ? SCE_DART_METADATA : SCE_DART_SYMBOL_IDENTIFIER);
|
||||
} else if (IsDartIdentifierStart(sc.ch)) {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_IDENTIFIER);
|
||||
} else if (sc.ch == '#' && IsDefinableOperator(sc.chNext)) {
|
||||
sc.SetState(SCE_DART_SYMBOL_OPERATOR);
|
||||
} else if (IsAGraphic(sc.ch)) {
|
||||
sc.SetState(SCE_DART_OPERATOR);
|
||||
if (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {
|
||||
InterpolatingState ¤t = interpolatingStack.back();
|
||||
if (sc.ch == '{') {
|
||||
current.braceCount += 1;
|
||||
} else {
|
||||
current.braceCount -= 1;
|
||||
if (current.braceCount == 0) {
|
||||
sc.ChangeState(SCE_DART_OPERATOR_STRING);
|
||||
sc.ForwardSetState(current.state);
|
||||
interpolatingStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isspacechar(sc.ch)) {
|
||||
visibleChars++;
|
||||
if (!IsSpaceEquiv(sc.state)) {
|
||||
chPrevNonWhite = sc.ch;
|
||||
}
|
||||
}
|
||||
if (sc.atLineEnd) {
|
||||
int lineState = (commentLevel << 4) | lineStateLineType;
|
||||
if (!interpolatingStack.empty()) {
|
||||
lineState |= DartLineStateMaskInterpolation;
|
||||
}
|
||||
styler.SetLineState(sc.currentLine, lineState);
|
||||
lineStateLineType = 0;
|
||||
visibleChars = 0;
|
||||
}
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
const Sci_PositionU endPos = startPos + lengthDoc;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
startPos = styler.LineStart(lineCurrent);
|
||||
initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;
|
||||
if (initStyle != SCE_DART_COMMENTBLOCKDOC && initStyle != SCE_DART_COMMENTBLOCK &&
|
||||
initStyle != SCE_DART_TRIPLE_RAWSTRING_SQ && initStyle != SCE_DART_TRIPLE_RAWSTRING_DQ &&
|
||||
initStyle != SCE_DART_TRIPLE_STRING_SQ && initStyle != SCE_DART_TRIPLE_STRING_DQ)
|
||||
break;
|
||||
}
|
||||
FoldLineState foldPrev(0);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0) {
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
foldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));
|
||||
}
|
||||
|
||||
int levelNext = levelCurrent;
|
||||
FoldLineState foldCurrent(styler.GetLineState(lineCurrent));
|
||||
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleIndexAt(startPos);
|
||||
int style = initStyle;
|
||||
|
||||
while (startPos < endPos) {
|
||||
const char ch = chNext;
|
||||
const int stylePrev = style;
|
||||
style = styleNext;
|
||||
chNext = styler[++startPos];
|
||||
styleNext = styler.StyleIndexAt(startPos);
|
||||
|
||||
switch (style) {
|
||||
case SCE_DART_COMMENTBLOCKDOC:
|
||||
case SCE_DART_COMMENTBLOCK: {
|
||||
const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0);
|
||||
if (level != 0) {
|
||||
levelNext += level;
|
||||
startPos++;
|
||||
chNext = styler[startPos];
|
||||
styleNext = styler.StyleIndexAt(startPos);
|
||||
}
|
||||
} break;
|
||||
|
||||
case SCE_DART_TRIPLE_RAWSTRING_SQ:
|
||||
case SCE_DART_TRIPLE_RAWSTRING_DQ:
|
||||
case SCE_DART_TRIPLE_STRING_SQ:
|
||||
case SCE_DART_TRIPLE_STRING_DQ:
|
||||
if (style != stylePrev && !AnyOf(stylePrev, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
|
||||
levelNext++;
|
||||
}
|
||||
if (style != styleNext && !AnyOf(styleNext, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
|
||||
levelNext--;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_OPERATOR:
|
||||
case SCE_DART_OPERATOR_STRING:
|
||||
if (ch == '{' || ch == '[' || ch == '(') {
|
||||
levelNext++;
|
||||
} else if (ch == '}' || ch == ']' || ch == ')') {
|
||||
levelNext--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (startPos == lineStartNext) {
|
||||
const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));
|
||||
levelNext = std::max(levelNext, SC_FOLDLEVELBASE);
|
||||
if (foldCurrent.lineComment) {
|
||||
levelNext += foldNext.lineComment - foldPrev.lineComment;
|
||||
} else if (foldCurrent.packageImport) {
|
||||
levelNext += foldNext.packageImport - foldPrev.packageImport;
|
||||
}
|
||||
|
||||
const int levelUse = levelCurrent;
|
||||
int lev = levelUse | (levelNext << 16);
|
||||
if (levelUse < levelNext) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
|
||||
lineCurrent++;
|
||||
lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
levelCurrent = levelNext;
|
||||
foldPrev = foldCurrent;
|
||||
foldCurrent = foldNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace end
|
||||
|
||||
extern const LexerModule lmDart(SCLEX_DART, LexerDart::LexerFactoryDart, "dart", dartWordListDesc);
|
@ -3,7 +3,7 @@
|
||||
* Lexer for F# 5.0
|
||||
* Copyright (c) 2021 Robert Di Pardo <dipardo.r@gmail.com>
|
||||
* Parts of LexerFSharp::Lex were adapted from LexCaml.cxx by Robert Roessler ("RR").
|
||||
* Parts of LexerFSharp::Fold were adapted from LexCPP.cxx by Neil Hodgson and Udo Lechner.
|
||||
* Parts of LexerFSharp::Fold were adapted from LexBash.cxx by Neil Hodgson and Kein-Hong Man.
|
||||
* The License.txt file describes the conditions under which this software may be distributed.
|
||||
*/
|
||||
// clang-format off
|
||||
@ -442,9 +442,13 @@ void SCI_METHOD LexerFSharp::Lex(Sci_PositionU start, Sci_Position length, int i
|
||||
break;
|
||||
case SCE_FSHARP_LINENUM:
|
||||
case SCE_FSHARP_PREPROCESSOR:
|
||||
case SCE_FSHARP_COMMENTLINE:
|
||||
if (sc.MatchLineEnd()) {
|
||||
state = SCE_FSHARP_DEFAULT;
|
||||
}
|
||||
break;
|
||||
case SCE_FSHARP_COMMENTLINE:
|
||||
if (sc.atLineStart) {
|
||||
state = SCE_FSHARP_DEFAULT;
|
||||
advance = false;
|
||||
}
|
||||
break;
|
||||
@ -647,27 +651,26 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
|
||||
}
|
||||
|
||||
LexAccessor styler(pAccess);
|
||||
const Sci_Position startPos = static_cast<Sci_Position>(start);
|
||||
Sci_Position startPos = static_cast<Sci_Position>(start);
|
||||
const Sci_PositionU endPos = start + length;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
if (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
startPos = styler.LineStart(lineCurrent);
|
||||
initStyle = (startPos > 0) ? styler.StyleAt(startPos - 1) : SCE_FSHARP_DEFAULT;
|
||||
}
|
||||
Sci_Position lineNext = lineCurrent + 1;
|
||||
Sci_Position lineStartNext = styler.LineStart(lineNext);
|
||||
int style = initStyle;
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
char chNext = styler[startPos];
|
||||
int levelNext;
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
int levelCurrent = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int levelNext = levelCurrent;
|
||||
int visibleChars = 0;
|
||||
|
||||
if (lineCurrent > 0) {
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 0x10;
|
||||
}
|
||||
|
||||
levelNext = levelCurrent;
|
||||
|
||||
for (Sci_PositionU i = start; i < endPos; i++) {
|
||||
for (Sci_PositionU i = static_cast<Sci_PositionU>(startPos); i < endPos; i++) {
|
||||
const Sci_Position currentPos = static_cast<Sci_Position>(i);
|
||||
const bool atEOL = (currentPos == (lineStartNext - 1) || styler.SafeGetCharAt(currentPos) == '\r');
|
||||
const bool atEOL = (currentPos == (lineStartNext - 1));
|
||||
const bool atLineOrDocEnd = (atEOL || (i == (endPos - 1)));
|
||||
const int stylePrev = style;
|
||||
const char ch = chNext;
|
||||
@ -708,10 +711,6 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
|
||||
FoldLexicalGroup(styler, levelNext, lineCurrent, "open ", SCE_FSHARP_KEYWORD);
|
||||
}
|
||||
|
||||
if (!IsASpace(ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
|
||||
if (atLineOrDocEnd) {
|
||||
int levelUse = levelCurrent;
|
||||
int lev = levelUse | levelNext << 16;
|
||||
@ -719,7 +718,7 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
|
||||
if (visibleChars == 0 && options.foldCompact) {
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
}
|
||||
if (levelUse < levelNext) {
|
||||
if ((levelUse < levelNext) && (visibleChars > 0)) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
@ -731,12 +730,14 @@ void SCI_METHOD LexerFSharp::Fold(Sci_PositionU start, Sci_Position length, int
|
||||
lineNext = lineCurrent + 1;
|
||||
lineStartNext = styler.LineStart(lineNext);
|
||||
levelCurrent = levelNext;
|
||||
}
|
||||
|
||||
if (atEOL && (currentPos == (styler.Length() - 1))) {
|
||||
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
|
||||
}
|
||||
if (!IsASpace(ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
}
|
||||
const int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(lineCurrent, levelCurrent | flagsNext);
|
||||
}
|
||||
|
||||
bool LineContains(LexAccessor &styler, const char *word, const Sci_Position start, const int chAttr) {
|
||||
|
@ -91,7 +91,7 @@ bool Contains(const std::string &s, std::string_view search) noexcept {
|
||||
return s.find(search) != std::string::npos;
|
||||
}
|
||||
|
||||
script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) {
|
||||
script_type segIsScriptingIndicator(const Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) {
|
||||
const std::string s = styler.GetRangeLowered(start, end+1);
|
||||
if (Contains(s, "vbs"))
|
||||
return eScriptVBS;
|
||||
@ -103,13 +103,12 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
|
||||
return eScriptJS;
|
||||
if (Contains(s, "php"))
|
||||
return eScriptPHP;
|
||||
if (Contains(s, "xml")) {
|
||||
const size_t xml = s.find("xml");
|
||||
if (xml != std::string::npos) {
|
||||
for (size_t t = 0; t < xml; t++) {
|
||||
if (!IsASpace(s[t])) {
|
||||
return prevValue;
|
||||
}
|
||||
|
||||
const size_t xml = s.find("xml");
|
||||
if (xml != std::string::npos) {
|
||||
for (size_t t = 0; t < xml; t++) {
|
||||
if (!IsASpace(s[t])) {
|
||||
return prevValue;
|
||||
}
|
||||
}
|
||||
return eScriptXML;
|
||||
@ -118,13 +117,8 @@ script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_P
|
||||
return prevValue;
|
||||
}
|
||||
|
||||
int PrintScriptingIndicatorOffset(Accessor &styler, Sci_PositionU start, Sci_PositionU end) {
|
||||
int iResult = 0;
|
||||
const std::string s = styler.GetRangeLowered(start, end+1);
|
||||
if (0 == strncmp(s.c_str(), "php", 3)) {
|
||||
iResult = 3;
|
||||
}
|
||||
return iResult;
|
||||
constexpr bool IsPHPScriptState(int state) noexcept {
|
||||
return (state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_OPERATOR) || (state == SCE_HPHP_COMPLEX_VARIABLE);
|
||||
}
|
||||
|
||||
script_type ScriptOfState(int state) noexcept {
|
||||
@ -132,9 +126,9 @@ script_type ScriptOfState(int state) noexcept {
|
||||
return eScriptPython;
|
||||
} else if ((state >= SCE_HB_START && state <= SCE_HB_STRINGEOL) || (state == SCE_H_ASPAT || state == SCE_H_XCCOMMENT)) {
|
||||
return eScriptVBS;
|
||||
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) {
|
||||
} else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_TEMPLATELITERAL)) {
|
||||
return eScriptJS;
|
||||
} else if ((state >= SCE_HPHP_DEFAULT && state <= SCE_HPHP_COMMENTLINE) || (state == SCE_HPHP_COMPLEX_VARIABLE)) {
|
||||
} else if (IsPHPScriptState(state)) {
|
||||
return eScriptPHP;
|
||||
} else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) {
|
||||
return eScriptSGML;
|
||||
@ -168,7 +162,7 @@ constexpr int stateForPrintState(int StateToPrint) noexcept {
|
||||
state = StateToPrint - SCE_HA_PYTHON;
|
||||
} else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) {
|
||||
state = StateToPrint - SCE_HA_VBS;
|
||||
} else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) {
|
||||
} else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_TEMPLATELITERAL)) {
|
||||
state = StateToPrint - SCE_HA_JS;
|
||||
}
|
||||
|
||||
@ -185,8 +179,12 @@ constexpr bool isStringState(int state) noexcept {
|
||||
switch (state) {
|
||||
case SCE_HJ_DOUBLESTRING:
|
||||
case SCE_HJ_SINGLESTRING:
|
||||
case SCE_HJ_REGEX:
|
||||
case SCE_HJ_TEMPLATELITERAL:
|
||||
case SCE_HJA_DOUBLESTRING:
|
||||
case SCE_HJA_SINGLESTRING:
|
||||
case SCE_HJA_REGEX:
|
||||
case SCE_HJA_TEMPLATELITERAL:
|
||||
case SCE_HB_STRING:
|
||||
case SCE_HBA_STRING:
|
||||
case SCE_HP_STRING:
|
||||
@ -454,12 +452,12 @@ void classifyWordHTPHP(Sci_PositionU start, Sci_PositionU end, const WordList &k
|
||||
styler.ColourTo(end, chAttr);
|
||||
}
|
||||
|
||||
bool isWordHSGML(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, Accessor &styler) {
|
||||
bool isWordHSGML(Sci_PositionU start, Sci_PositionU end, const WordList &keywords, const Accessor &styler) {
|
||||
const std::string s = styler.GetRange(start, end + 1);
|
||||
return keywords.InList(s);
|
||||
}
|
||||
|
||||
bool isWordCdata(Sci_PositionU start, Sci_PositionU end, Accessor &styler) {
|
||||
bool isWordCdata(Sci_PositionU start, Sci_PositionU end, const Accessor &styler) {
|
||||
const std::string s = styler.GetRange(start, end + 1);
|
||||
return s == "[CDATA[";
|
||||
}
|
||||
@ -492,9 +490,13 @@ constexpr int StateForScript(script_type scriptLanguage) noexcept {
|
||||
return Result;
|
||||
}
|
||||
|
||||
constexpr int defaultStateForSGML(script_type scriptLanguage) noexcept {
|
||||
return (scriptLanguage == eScriptSGMLblock)? SCE_H_SGML_BLOCK_DEFAULT : SCE_H_SGML_DEFAULT;
|
||||
}
|
||||
|
||||
constexpr bool issgmlwordchar(int ch) noexcept {
|
||||
return !IsASCII(ch) ||
|
||||
(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
|
||||
(IsAlphaNumeric(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
|
||||
}
|
||||
|
||||
constexpr bool IsPhpWordStart(int ch) noexcept {
|
||||
@ -512,15 +514,6 @@ constexpr bool InTagState(int state) noexcept {
|
||||
SCE_H_DOUBLESTRING, SCE_H_SINGLESTRING);
|
||||
}
|
||||
|
||||
constexpr bool IsCommentState(const int state) noexcept {
|
||||
return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT;
|
||||
}
|
||||
|
||||
constexpr bool IsScriptCommentState(const int state) noexcept {
|
||||
return AnyOf(state, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJA_COMMENT,
|
||||
SCE_HJA_COMMENTLINE, SCE_HB_COMMENTLINE, SCE_HBA_COMMENTLINE);
|
||||
}
|
||||
|
||||
constexpr bool isLineEnd(int ch) noexcept {
|
||||
return ch == '\r' || ch == '\n';
|
||||
}
|
||||
@ -681,22 +674,31 @@ enum class AllowPHP : int {
|
||||
Question, // <?
|
||||
};
|
||||
|
||||
constexpr bool IsPHPEntryState(int state) noexcept {
|
||||
return !(isPHPStringState(state) || IsScriptCommentState(state) || AnyOf(state, SCE_H_ASPAT, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE));
|
||||
}
|
||||
enum class InstructionTag {
|
||||
None,
|
||||
XML,
|
||||
Open,// <? ?> short open tag
|
||||
Echo,// <?= ?> short echo tag
|
||||
PHP, // <?php ?> standard tag
|
||||
};
|
||||
|
||||
bool IsPHPStart(AllowPHP allowPHP, Accessor &styler, Sci_PositionU start) {
|
||||
if (allowPHP == AllowPHP::None) {
|
||||
return false;
|
||||
}
|
||||
if (allowPHP == AllowPHP::PHP) {
|
||||
InstructionTag segIsScriptInstruction(AllowPHP allowPHP, int state, const Accessor &styler, Sci_PositionU start, bool isXml) {
|
||||
constexpr std::string_view phpTag = "php";
|
||||
constexpr std::string_view xmlTag = "xml";
|
||||
const std::string tag = styler.GetRangeLowered(start, start + phpTag.length());
|
||||
if (allowPHP != AllowPHP::None) {
|
||||
// Require <?php or <?=
|
||||
constexpr std::string_view phpTag = "<?php";
|
||||
constexpr std::string_view echoTag = "<?=";
|
||||
const std::string tag = styler.GetRangeLowered(start, start + phpTag.length());
|
||||
return (tag == phpTag) || (tag.substr(0, echoTag.length()) == echoTag);
|
||||
if (tag == phpTag) {
|
||||
return InstructionTag::PHP;
|
||||
}
|
||||
if (!tag.empty() && (tag.front() == '=')) {
|
||||
return InstructionTag::Echo;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
if (isXml || tag == xmlTag) {
|
||||
return AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)? InstructionTag::XML : InstructionTag::None;
|
||||
}
|
||||
return (allowPHP == AllowPHP::Question) ? InstructionTag::Open : InstructionTag::None;
|
||||
}
|
||||
|
||||
Sci_Position FindPhpStringDelimiter(std::string &phpStringDelimiter, Sci_Position i, const Sci_Position lengthDoc, Accessor &styler, bool &isSimpleString) {
|
||||
@ -902,7 +904,7 @@ const LexicalClass lexicalClassesHTML[] = {
|
||||
50, "SCE_HJ_SYMBOLS", "client javascript operator", "JS Symbols",
|
||||
51, "SCE_HJ_STRINGEOL", "client javascript error literal string", "JavaScript EOL",
|
||||
52, "SCE_HJ_REGEX", "client javascript literal regex", "JavaScript RegEx",
|
||||
53, "", "unused", "",
|
||||
53, "SCE_HJ_TEMPLATELITERAL", "client javascript literal template", "JS Template Literal",
|
||||
54, "", "unused", "",
|
||||
55, "SCE_HJA_START", "server javascript default", "JS Start - allows eol filled background to not start on same line as SCRIPT tag",
|
||||
56, "SCE_HJA_DEFAULT", "server javascript default", "JS Default",
|
||||
@ -917,7 +919,7 @@ const LexicalClass lexicalClassesHTML[] = {
|
||||
65, "SCE_HJA_SYMBOLS", "server javascript operator", "JS Symbols",
|
||||
66, "SCE_HJA_STRINGEOL", "server javascript error literal string", "JavaScript EOL",
|
||||
67, "SCE_HJA_REGEX", "server javascript literal regex", "JavaScript RegEx",
|
||||
68, "", "unused", "",
|
||||
68, "SCE_HJA_TEMPLATELITERAL", "server javascript literal template", "JS Template Literal",
|
||||
69, "", "unused", "",
|
||||
70, "SCE_HB_START", "client basic default", "Start",
|
||||
71, "SCE_HB_DEFAULT", "client basic default", "Default",
|
||||
@ -1205,7 +1207,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
length += startPos - backLineStart;
|
||||
startPos = backLineStart;
|
||||
}
|
||||
state = SCE_H_DEFAULT;
|
||||
state = (startPos > 0) ? styler.StyleIndexAt(startPos - 1) : SCE_H_DEFAULT;
|
||||
}
|
||||
// String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState
|
||||
if (isPHPStringState(state)) {
|
||||
@ -1250,6 +1252,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
script_type clientScript = static_cast<script_type>((lineState >> 8) & 0x0F); // 4 bits of script name
|
||||
int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state
|
||||
bool isLanguageType = (lineState >> 20) & 1; // type or language attribute for script tag
|
||||
int sgmlBlockLevel = (lineState >> 21);
|
||||
|
||||
script_type scriptLanguage = ScriptOfState(state);
|
||||
// If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment
|
||||
@ -1335,7 +1338,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
case eScriptPHP:
|
||||
//not currently supported case eScriptVBS:
|
||||
|
||||
if (!AnyOf(state, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE, SCE_HJ_REGEX, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJ_COMMENTDOC) &&
|
||||
if (!AnyOf(state, SCE_HPHP_COMMENT, SCE_HPHP_COMMENTLINE, SCE_HJ_COMMENT, SCE_HJ_COMMENTLINE, SCE_HJ_COMMENTDOC) &&
|
||||
!isStringState(state)) {
|
||||
//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
|
||||
//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
|
||||
@ -1410,7 +1413,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
((aspScript & 0x0F) << 4) |
|
||||
((clientScript & 0x0F) << 8) |
|
||||
((beforePreProc & 0xFF) << 12) |
|
||||
((isLanguageType ? 1 : 0) << 20));
|
||||
((isLanguageType ? 1 : 0) << 20) |
|
||||
(sgmlBlockLevel << 21));
|
||||
lineCurrent++;
|
||||
lineStartVisibleChars = 0;
|
||||
}
|
||||
@ -1455,6 +1459,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
case SCE_HJ_DOUBLESTRING:
|
||||
case SCE_HJ_SINGLESTRING:
|
||||
case SCE_HJ_REGEX:
|
||||
case SCE_HJ_TEMPLATELITERAL:
|
||||
case SCE_HB_STRING:
|
||||
case SCE_HBA_STRING:
|
||||
case SCE_HP_STRING:
|
||||
@ -1496,31 +1501,35 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
|
||||
/////////////////////////////////////
|
||||
// handle the start of PHP pre-processor = Non-HTML
|
||||
else if ((ch == '<') && (chNext == '?') && IsPHPEntryState(state) && IsPHPStart(allowPHP, styler, i)) {
|
||||
beforeLanguage = scriptLanguage;
|
||||
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP);
|
||||
if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue;
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
beforePreProc = state;
|
||||
i++;
|
||||
visibleChars++;
|
||||
i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6);
|
||||
if (scriptLanguage == eScriptXML)
|
||||
styler.ColourTo(i, SCE_H_XMLSTART);
|
||||
else
|
||||
styler.ColourTo(i, SCE_H_QUESTION);
|
||||
state = StateForScript(scriptLanguage);
|
||||
if (inScriptType == eNonHtmlScript)
|
||||
inScriptType = eNonHtmlScriptPreProc;
|
||||
else
|
||||
inScriptType = eNonHtmlPreProc;
|
||||
// Fold whole script, but not if the XML first tag (all XML-like tags in this case)
|
||||
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
|
||||
levelCurrent++;
|
||||
else if ((ch == '<') && (chNext == '?') && !IsPHPScriptState(state)) {
|
||||
const InstructionTag tag = segIsScriptInstruction(allowPHP, state, styler, i + 2, isXml);
|
||||
if (tag != InstructionTag::None) {
|
||||
beforeLanguage = scriptLanguage;
|
||||
scriptLanguage = (tag == InstructionTag::XML) ? eScriptXML : eScriptPHP;
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
beforePreProc = state;
|
||||
i++;
|
||||
visibleChars++;
|
||||
if (tag >= InstructionTag::Echo) {
|
||||
i += (tag == InstructionTag::Echo) ? 1 : 3;
|
||||
}
|
||||
if (scriptLanguage == eScriptXML)
|
||||
styler.ColourTo(i, SCE_H_XMLSTART);
|
||||
else
|
||||
styler.ColourTo(i, SCE_H_QUESTION);
|
||||
state = StateForScript(scriptLanguage);
|
||||
if (inScriptType == eNonHtmlScript)
|
||||
inScriptType = eNonHtmlScriptPreProc;
|
||||
else
|
||||
inScriptType = eNonHtmlPreProc;
|
||||
// Fold whole script, but not if the XML first tag (all XML-like tags in this case)
|
||||
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
|
||||
levelCurrent++;
|
||||
}
|
||||
// should be better
|
||||
ch = SafeGetUnsignedCharAt(styler, i);
|
||||
continue;
|
||||
}
|
||||
// should be better
|
||||
ch = SafeGetUnsignedCharAt(styler, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// handle the start Mako template Python code
|
||||
@ -1662,16 +1671,13 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
|
||||
/////////////////////////////////////
|
||||
// handle the start of SGML language (DTD)
|
||||
else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) &&
|
||||
else if (AnyOf(scriptLanguage, eScriptNone, eScriptXML, eScriptSGMLblock) &&
|
||||
(chPrev == '<') &&
|
||||
(ch == '!') &&
|
||||
(StateToPrint != SCE_H_CDATA) &&
|
||||
(!isStringState(StateToPrint)) &&
|
||||
(!IsCommentState(StateToPrint)) &&
|
||||
(!IsScriptCommentState(StateToPrint))) {
|
||||
AnyOf(state, SCE_H_DEFAULT, SCE_H_SGML_BLOCK_DEFAULT)) {
|
||||
beforePreProc = state;
|
||||
styler.ColourTo(i - 2, StateToPrint);
|
||||
if ((chNext == '-') && (chNext2 == '-')) {
|
||||
if ((state != SCE_H_SGML_BLOCK_DEFAULT) && (chNext == '-') && (chNext2 == '-')) {
|
||||
state = SCE_H_COMMENT; // wait for a pending command
|
||||
styler.ColourTo(i + 2, SCE_H_COMMENT);
|
||||
i += 2; // follow styling after the --
|
||||
@ -1687,12 +1693,18 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
ch = '-';
|
||||
}
|
||||
}
|
||||
} else if (isWordCdata(i + 1, i + 7, styler)) {
|
||||
} else if ((state != SCE_H_SGML_BLOCK_DEFAULT) && isWordCdata(i + 1, i + 7, styler)) {
|
||||
state = SCE_H_CDATA;
|
||||
} else {
|
||||
styler.ColourTo(i, SCE_H_SGML_DEFAULT); // <! is default
|
||||
beforeLanguage = scriptLanguage;
|
||||
scriptLanguage = eScriptSGML;
|
||||
state = SCE_H_SGML_COMMAND; // wait for a pending command
|
||||
if ((chNext == '-') && (chNext2 == '-')) {
|
||||
i += 2;
|
||||
state = SCE_H_SGML_COMMENT;
|
||||
} else {
|
||||
state = (chNext == '[') ? SCE_H_SGML_DEFAULT : SCE_H_SGML_COMMAND; // wait for a pending command
|
||||
}
|
||||
}
|
||||
// fold whole tag (-- when closing the tag)
|
||||
if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)
|
||||
@ -1763,7 +1775,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
|
||||
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
|
||||
((chNext == '>') && isPreProcessorEndTag(state, ch))) ||
|
||||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
|
||||
((scriptLanguage == eScriptSGML) && (ch == '>') && !AnyOf(state, SCE_H_SGML_COMMENT, SCE_H_SGML_DOUBLESTRING, SCE_H_SGML_SIMPLESTRING))) {
|
||||
if (state == SCE_H_ASPAT) {
|
||||
aspScript = segIsScriptingIndicator(styler,
|
||||
styler.GetStartSegment(), i - 1, aspScript);
|
||||
@ -1851,41 +1863,36 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
styler.ColourTo(i - 2, StateToPrint);
|
||||
}
|
||||
state = SCE_H_SGML_COMMENT;
|
||||
} else if (IsUpperOrLowerCase(ch) && (chPrev == '%')) {
|
||||
styler.ColourTo(i - 2, StateToPrint);
|
||||
} else if (ch == '%' && IsUpperOrLowerCase(chNext)) {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_H_SGML_ENTITY;
|
||||
} else if (ch == '#') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_H_SGML_SPECIAL;
|
||||
} else if (ch == '[') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
|
||||
++sgmlBlockLevel;
|
||||
scriptLanguage = eScriptSGMLblock;
|
||||
state = SCE_H_SGML_BLOCK_DEFAULT;
|
||||
} else if (ch == ']') {
|
||||
if (scriptLanguage == eScriptSGMLblock) {
|
||||
styler.ColourTo(i, StateToPrint);
|
||||
if (sgmlBlockLevel > 0) {
|
||||
--sgmlBlockLevel;
|
||||
if (sgmlBlockLevel == 0) {
|
||||
beforePreProc = SCE_H_DEFAULT;
|
||||
}
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
|
||||
scriptLanguage = eScriptSGML;
|
||||
} else {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
styler.ColourTo(i, SCE_H_SGML_ERROR);
|
||||
}
|
||||
state = SCE_H_SGML_DEFAULT;
|
||||
} else if (scriptLanguage == eScriptSGMLblock) {
|
||||
if ((ch == '!') && (chPrev == '<')) {
|
||||
styler.ColourTo(i - 2, StateToPrint);
|
||||
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
|
||||
state = SCE_H_SGML_COMMAND;
|
||||
} else if (ch == '>') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
styler.ColourTo(i, SCE_H_SGML_DEFAULT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_H_SGML_COMMAND:
|
||||
if ((ch == '-') && (chPrev == '-')) {
|
||||
styler.ColourTo(i - 2, StateToPrint);
|
||||
state = SCE_H_SGML_COMMENT;
|
||||
} else if (!issgmlwordchar(ch)) {
|
||||
if (!issgmlwordchar(ch)) {
|
||||
if (isWordHSGML(styler.GetStartSegment(), i - 1, keywordsSGML, styler)) {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_H_SGML_1ST_PARAM;
|
||||
@ -1897,18 +1904,10 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
case SCE_H_SGML_1ST_PARAM:
|
||||
// wait for the beginning of the word
|
||||
if ((ch == '-') && (chPrev == '-')) {
|
||||
if (scriptLanguage == eScriptSGMLblock) {
|
||||
styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT);
|
||||
} else {
|
||||
styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
|
||||
}
|
||||
styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT);
|
||||
state = SCE_H_SGML_1ST_PARAM_COMMENT;
|
||||
} else if (issgmlwordchar(ch)) {
|
||||
if (scriptLanguage == eScriptSGMLblock) {
|
||||
styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT);
|
||||
} else {
|
||||
styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
|
||||
}
|
||||
styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT);
|
||||
// find the length of the word
|
||||
Sci_Position size = 1;
|
||||
while (setHTMLWord.Contains(SafeGetUnsignedCharAt(styler, i + size)))
|
||||
@ -1917,11 +1916,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
i += size - 1;
|
||||
visibleChars += size - 1;
|
||||
ch = SafeGetUnsignedCharAt(styler, i);
|
||||
if (scriptLanguage == eScriptSGMLblock) {
|
||||
state = SCE_H_SGML_BLOCK_DEFAULT;
|
||||
} else {
|
||||
state = SCE_H_SGML_DEFAULT;
|
||||
}
|
||||
state = SCE_H_SGML_DEFAULT;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -1985,12 +1980,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
break;
|
||||
case SCE_H_SGML_ENTITY:
|
||||
if (ch == ';') {
|
||||
styler.ColourTo(i, StateToPrint);
|
||||
state = SCE_H_SGML_DEFAULT;
|
||||
} else if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.') {
|
||||
styler.ColourTo(i, SCE_H_SGML_ERROR);
|
||||
state = SCE_H_SGML_DEFAULT;
|
||||
if (!(IsAlphaNumeric(ch)) && ch != '-' && ch != '.' && ch != '_') {
|
||||
styler.ColourTo(i, ((ch == ';') ? StateToPrint : SCE_H_SGML_ERROR));
|
||||
state = defaultStateForSGML(scriptLanguage);
|
||||
}
|
||||
break;
|
||||
case SCE_H_ENTITY:
|
||||
@ -2203,14 +2195,11 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
state = SCE_HJ_WORD;
|
||||
} else if (ch == '/' && chNext == '*') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
i++;
|
||||
if (chNext2 == '*')
|
||||
state = SCE_HJ_COMMENTDOC;
|
||||
else
|
||||
state = SCE_HJ_COMMENT;
|
||||
if (chNext2 == '/') {
|
||||
// Eat the * so it isn't used for the end of the comment
|
||||
i++;
|
||||
}
|
||||
} else if (ch == '/' && chNext == '/') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_HJ_COMMENTLINE;
|
||||
@ -2223,6 +2212,9 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
} else if (ch == '\'') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_HJ_SINGLESTRING;
|
||||
} else if (ch == '`') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_HJ_TEMPLATELITERAL;
|
||||
} else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') &&
|
||||
styler.SafeGetCharAt(i + 3) == '-') {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
@ -2249,6 +2241,7 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
//styler.ColourTo(i - 1, eHTJSKeyword);
|
||||
state = SCE_HJ_DEFAULT;
|
||||
if (ch == '/' && chNext == '*') {
|
||||
i++;
|
||||
if (chNext2 == '*')
|
||||
state = SCE_HJ_COMMENTDOC;
|
||||
else
|
||||
@ -2259,6 +2252,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
state = SCE_HJ_DOUBLESTRING;
|
||||
} else if (ch == '\'') {
|
||||
state = SCE_HJ_SINGLESTRING;
|
||||
} else if (ch == '`') {
|
||||
state = SCE_HJ_TEMPLATELITERAL;
|
||||
} else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
state = SCE_HJ_COMMENTLINE;
|
||||
@ -2314,6 +2309,16 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCE_HJ_TEMPLATELITERAL:
|
||||
if (ch == '\\') {
|
||||
if (chNext == '$' || chNext == '`' || chNext == '\\') {
|
||||
i++;
|
||||
}
|
||||
} else if (ch == '`') {
|
||||
styler.ColourTo(i, statePrintForState(SCE_HJ_TEMPLATELITERAL, inScriptType));
|
||||
state = SCE_HJ_DEFAULT;
|
||||
}
|
||||
break;
|
||||
case SCE_HJ_STRINGEOL:
|
||||
if (!isLineEnd(ch)) {
|
||||
styler.ColourTo(i - 1, StateToPrint);
|
||||
@ -2711,7 +2716,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
}
|
||||
} else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded
|
||||
if (ch == '/' && chNext == '*') {
|
||||
if (styler.SafeGetCharAt(i + 2) == '*')
|
||||
i++;
|
||||
if (styler.SafeGetCharAt(i + 1) == '*')
|
||||
state = SCE_HJ_COMMENTDOC;
|
||||
else
|
||||
state = SCE_HJ_COMMENT;
|
||||
@ -2721,6 +2727,8 @@ void SCI_METHOD LexerHTML::Lex(Sci_PositionU startPos, Sci_Position length, int
|
||||
state = SCE_HJ_DOUBLESTRING;
|
||||
} else if ((ch == '\'') && (nonEmptySegment)) {
|
||||
state = SCE_HJ_SINGLESTRING;
|
||||
} else if ((ch == '`') && (nonEmptySegment)) {
|
||||
state = SCE_HJ_TEMPLATELITERAL;
|
||||
} else if (IsAWordStart(ch)) {
|
||||
state = SCE_HJ_WORD;
|
||||
} else if (IsOperator(ch)) {
|
||||
|
@ -191,10 +191,13 @@ static void handleNumeric(StyleContext& sc)
|
||||
}
|
||||
else
|
||||
radix = 10;
|
||||
if (sc.chNext != '.' || !isDigitOfRadix(sc.GetRelative(2), radix))
|
||||
return;
|
||||
sc.Forward();
|
||||
skipInt(sc, radix);
|
||||
if (sc.chNext == '.') {
|
||||
if (!isDigitOfRadix(sc.GetRelative(2), radix))
|
||||
return;
|
||||
sc.Forward();
|
||||
skipInt(sc, radix);
|
||||
}
|
||||
|
||||
if (sc.chNext == 's') {
|
||||
// ScaledDecimal
|
||||
sc.Forward();
|
||||
|
909
lexilla/lexers/LexTroff.cxx
Normal file
909
lexilla/lexers/LexTroff.cxx
Normal file
@ -0,0 +1,909 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexTroff.cxx
|
||||
** Lexer for the Troff typesetting language.
|
||||
** This should work for Groff, Heirloom Troff and Neatroff and consequently
|
||||
** for man pages.
|
||||
**
|
||||
** There are a number of restrictions:
|
||||
** Escapes are not interpreted everywhere e.g. as part of command names.
|
||||
** For the same reasons, changing control characters via `.cc` or `.c2` will
|
||||
** not affect lexing - subsequent requests will not be styled correctly.
|
||||
** Luckily this feature is rarely used.
|
||||
** Line feeds cannot be escaped everywhere - this would require a state machine
|
||||
** for all parsing.
|
||||
** However, the C lexer has the same restriction.
|
||||
** It is impossible to predict which macro argument is a numeric expression or where
|
||||
** the number is actually treated as text.
|
||||
** Also, escapes with levels of indirection (eg. `\\$1`) cannot currently
|
||||
** be highlighted, as it is impossible to predict the context in which an
|
||||
** expansion will be used.
|
||||
** Indirect blocks (.ami, .ami1, .dei and .dei1) cannot be folded.
|
||||
** No effort is done to highlight any of the preprocessors (tbl, pic, grap...).
|
||||
**/
|
||||
// Copyright 2022-2024 by Robin Haberkorn <robin.haberkorn@googlemail.com>
|
||||
// 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 <string>
|
||||
#include <string_view>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
|
||||
using namespace Lexilla;
|
||||
|
||||
// Can be used as the line state to detect continuations
|
||||
// across calls to ColouriseTroffDoc().
|
||||
enum TroffState {
|
||||
DEFAULT = 0,
|
||||
// REQUEST/COMMAND on a line means that it is a command line with continuation.
|
||||
REQUEST,
|
||||
COMMAND,
|
||||
// Flow control request with continuation
|
||||
FLOW_CONTROL,
|
||||
// Inside "ignore input" block (usually .ig)
|
||||
IGNORE
|
||||
};
|
||||
|
||||
static Sci_PositionU TroffEscapeBracketSize(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler);
|
||||
static Sci_PositionU TroffEscapeQuoteSize(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler);
|
||||
|
||||
static Sci_PositionU ColouriseTroffEscape(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler, WordList *keywordlists[],
|
||||
TroffState state);
|
||||
static void ColouriseTroffLine(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler, WordList *keywordlists[],
|
||||
TroffState state);
|
||||
|
||||
// For all escapes that take a one character (\*x), two character (\*(xy) or
|
||||
// arbitrary number of characters (\*[...]).
|
||||
static Sci_PositionU TroffEscapeBracketSize(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler) {
|
||||
if (startLine > endPos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (styler[startLine] == '(') {
|
||||
// two character name
|
||||
return std::min((Sci_PositionU)3, endPos-startLine+1);
|
||||
}
|
||||
|
||||
if (styler[startLine] != '[') {
|
||||
// one character name
|
||||
return 1;
|
||||
}
|
||||
// name with arbitrary size between [...]
|
||||
|
||||
Sci_PositionU i = startLine+1;
|
||||
|
||||
while (i <= endPos) {
|
||||
if (styler[i] == ']') {
|
||||
return i-startLine+1;
|
||||
}
|
||||
|
||||
if (styler[i] != '\\') {
|
||||
// not an escape
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++i > endPos) {
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: Other escapes are not interpreted within \x[...].
|
||||
switch (styler[i]) {
|
||||
case '*': // string register
|
||||
case '$': // macro argument
|
||||
case 'V': // environment variable
|
||||
case 'n': // numeric register
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
break;
|
||||
case 'A': // Is there a string with this name?
|
||||
case 'B': // Is there a register with this name?
|
||||
case 'R': // register increase
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
break;
|
||||
default:
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
}
|
||||
}
|
||||
|
||||
return endPos-startLine+1;
|
||||
}
|
||||
|
||||
// For all escapes that take an argument in quotes, as in \v'...'.
|
||||
// Actually, this works with any character as a delimiter.
|
||||
static Sci_PositionU TroffEscapeQuoteSize(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler) {
|
||||
if (startLine > endPos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char delim = styler[startLine];
|
||||
|
||||
Sci_PositionU i = startLine+1;
|
||||
|
||||
while (i <= endPos) {
|
||||
if (styler[i] == delim) {
|
||||
return i-startLine+1;
|
||||
}
|
||||
|
||||
if (styler[i] != '\\') {
|
||||
// not an escape
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++i > endPos) {
|
||||
break;
|
||||
}
|
||||
|
||||
// NOTE: Other escapes are not interpreted within \x'...'.
|
||||
switch (styler[i]) {
|
||||
case '*': // string register
|
||||
case '$': // macro argument
|
||||
case 'V': // environment variable
|
||||
case 'n': // numeric register
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
break;
|
||||
case 'A': // Is there a string with this name?
|
||||
case 'B': // Is there a register with this name?
|
||||
case 'R': // register increase
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
break;
|
||||
default:
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
}
|
||||
}
|
||||
|
||||
return endPos-startLine+1;
|
||||
}
|
||||
|
||||
static Sci_PositionU ColouriseTroffEscape(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler, WordList *keywordlists[],
|
||||
TroffState state) {
|
||||
Sci_PositionU i = startLine;
|
||||
|
||||
Sci_Position curLine = styler.GetLine(startLine);
|
||||
|
||||
if (styler[i] != '\\') {
|
||||
// not an escape - still consume one character
|
||||
return 1;
|
||||
}
|
||||
styler.ColourTo(i-1, SCE_TROFF_DEFAULT);
|
||||
i++;
|
||||
if (i > endPos) {
|
||||
return i-startLine;
|
||||
}
|
||||
|
||||
switch (styler[i]) {
|
||||
case '"':
|
||||
// ordinary end of line comment
|
||||
styler.ColourTo(endPos, SCE_TROFF_COMMENT);
|
||||
return endPos-startLine+1;
|
||||
|
||||
case '#':
|
||||
// \# comments will also "swallow" the EOL characters similar to
|
||||
// an escape at the end of line.
|
||||
// They are usually used only to comment entire lines, but we support
|
||||
// them after command lines anyway.
|
||||
styler.ColourTo(endPos, SCE_TROFF_COMMENT);
|
||||
// Next line will be a continuation
|
||||
styler.SetLineState(curLine, state);
|
||||
return endPos-startLine+1;
|
||||
|
||||
case '*':
|
||||
// String register
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_STRING);
|
||||
break;
|
||||
case '$':
|
||||
// Macro parameter
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_MACRO);
|
||||
break;
|
||||
case 'V':
|
||||
// Environment variable
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_ENV);
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
// Font change
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_FONT);
|
||||
break;
|
||||
case 'n':
|
||||
// Number register
|
||||
i += 1;
|
||||
if (styler[i] == '+' || styler[i] == '-') {
|
||||
i += 1;
|
||||
}
|
||||
if (i > endPos) {
|
||||
break;
|
||||
}
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);
|
||||
break;
|
||||
case 'g':
|
||||
case 'k':
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);
|
||||
break;
|
||||
case 'R':
|
||||
// Number register increase
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_NUMBER);
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
// Colour change
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_COLOUR);
|
||||
break;
|
||||
case 'O':
|
||||
// Nested suppressions
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_SUPPRESSION);
|
||||
break;
|
||||
case 's':
|
||||
// Type size
|
||||
// This is special in supporting both a +/- prefix directly
|
||||
// after \s and both the [...] and '...' syntax.
|
||||
i += 1;
|
||||
if (i > endPos) {
|
||||
break;
|
||||
}
|
||||
if (styler[i] == '+' || styler[i] == '-') {
|
||||
i += 1;
|
||||
}
|
||||
if (styler[i] == '\'') {
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
} else if (styler[i] == '(') {
|
||||
// You can place a +/- even after the opening brace as in \s(+12.
|
||||
// Otherwise this could be handled by TroffEscapeBracketSize().
|
||||
i += 1;
|
||||
if (i > endPos) {
|
||||
break;
|
||||
}
|
||||
if (styler[i] == '+' || styler[i] == '-') {
|
||||
i += 1;
|
||||
}
|
||||
i += std::min((Sci_PositionU)2, endPos-i);
|
||||
} else {
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
}
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_SIZE);
|
||||
break;
|
||||
case '{':
|
||||
// Opening code block
|
||||
i += 1;
|
||||
styler.ColourTo(i-1, SCE_TROFF_OPERATOR);
|
||||
// Groff actually supports commands immediately
|
||||
// following the opening brace as in `\{.tm`.
|
||||
// That's only why \{\ will actually treat the next line
|
||||
// as an ordinary command again.
|
||||
ColouriseTroffLine(i, endPos, styler, keywordlists, state);
|
||||
return endPos-startLine+1;
|
||||
case '}':
|
||||
// Closing code block
|
||||
// This exists only for the rare case of closing a
|
||||
// block in the middle of a line.
|
||||
i += 1;
|
||||
styler.ColourTo(i-1, SCE_TROFF_OPERATOR);
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
// Escape newline
|
||||
styler.ColourTo(endPos, SCE_TROFF_ESCAPE_GLYPH);
|
||||
i += 1;
|
||||
// Next line will be a continuation
|
||||
styler.SetLineState(curLine, state);
|
||||
break;
|
||||
case '!':
|
||||
// transparent line
|
||||
styler.ColourTo(endPos, SCE_TROFF_ESCAPE_TRANSPARENT);
|
||||
return endPos-startLine+1;
|
||||
case '?':
|
||||
// Transparent embed until \?
|
||||
i++;
|
||||
while (i <= endPos) {
|
||||
if (styler.Match(i, "\\?")) {
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_TRANSPARENT);
|
||||
break;
|
||||
case 'b':
|
||||
// pile of chars
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);
|
||||
break;
|
||||
case 'A':
|
||||
case 'B':
|
||||
// Valid identifier or register?
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_ISVALID);
|
||||
break;
|
||||
case 'C':
|
||||
case 'N':
|
||||
// additional glyphs
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);
|
||||
break;
|
||||
case 'D':
|
||||
case 'l':
|
||||
case 'L':
|
||||
// drawing commands
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_DRAW);
|
||||
break;
|
||||
case 'h':
|
||||
case 'v':
|
||||
// horizontal/vertical movement
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_MOVE);
|
||||
break;
|
||||
case 'H':
|
||||
// font height
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_HEIGHT);
|
||||
break;
|
||||
case 'o':
|
||||
// overstrike
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_OVERSTRIKE);
|
||||
break;
|
||||
case 'S':
|
||||
// slant
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_SLANT);
|
||||
break;
|
||||
case 'w':
|
||||
// width of string
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_WIDTH);
|
||||
break;
|
||||
case 'x':
|
||||
// increase vertical spacing
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_VSPACING);
|
||||
break;
|
||||
case 'X':
|
||||
// device control commands
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_DEVICE);
|
||||
break;
|
||||
case 'Y':
|
||||
// device control commands
|
||||
i += 1;
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_DEVICE);
|
||||
break;
|
||||
case 'Z':
|
||||
// format string without moving
|
||||
i += 1;
|
||||
i += TroffEscapeQuoteSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_NOMOVE);
|
||||
break;
|
||||
case 'z':
|
||||
// Zero-width format
|
||||
i += std::min((Sci_PositionU)2, endPos-i);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_NOMOVE);
|
||||
break;
|
||||
default:
|
||||
i += TroffEscapeBracketSize(i, endPos, styler);
|
||||
styler.ColourTo(i-1, SCE_TROFF_ESCAPE_GLYPH);
|
||||
}
|
||||
|
||||
return i-startLine;
|
||||
}
|
||||
|
||||
static Sci_PositionU ColouriseTroffNumber(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler) {
|
||||
Sci_PositionU i = startLine;
|
||||
|
||||
if (!isdigit(styler[i])) {
|
||||
// not a digit
|
||||
return 0;
|
||||
}
|
||||
|
||||
styler.ColourTo(i-1, SCE_TROFF_DEFAULT);
|
||||
|
||||
i++;
|
||||
while (i <= endPos && isdigit(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
if (i > endPos) {
|
||||
goto done;
|
||||
}
|
||||
if (styler[i] == '.') {
|
||||
i++;
|
||||
while (i <= endPos && isdigit(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
if (i > endPos) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// Unit is part of number
|
||||
if (strchr("ciPpmMnuvsf", styler[i])) {
|
||||
i++;
|
||||
}
|
||||
|
||||
done:
|
||||
styler.ColourTo(i-1, SCE_TROFF_NUMBER);
|
||||
return i-startLine;
|
||||
}
|
||||
|
||||
static void ColouriseTroffLine(Sci_PositionU startLine, Sci_PositionU endPos,
|
||||
Accessor &styler, WordList *keywordlists[],
|
||||
TroffState state) {
|
||||
WordList &requests = *keywordlists[0];
|
||||
WordList &flowControlCond = *keywordlists[1];
|
||||
WordList &flowControlNocond = *keywordlists[2];
|
||||
WordList &ignoreBlocks = *keywordlists[3];
|
||||
Sci_PositionU i = startLine;
|
||||
|
||||
if (startLine > endPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sci_Position curLine = styler.GetLine(startLine);
|
||||
// If the line state was not DEFAULT (i.e. the line had a continuation)
|
||||
// and the corresponding escape is erased, we must make sure that
|
||||
// the line state becomes DEFAULT again.
|
||||
styler.SetLineState(curLine, TroffState::DEFAULT);
|
||||
|
||||
if (state == TroffState::IGNORE) {
|
||||
// Inside "ignore input" blocks
|
||||
if (styler[i] == '.') {
|
||||
i++;
|
||||
// Groff does not appear to allow spaces after the dot on
|
||||
// lines ending ignore blocks.
|
||||
#if 0
|
||||
while (i <= endPos && isspacechar(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
|
||||
Sci_PositionU startCommand = i;
|
||||
while (i <= endPos && !isspacechar(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Check whether this is the end of the block by backtracking.
|
||||
// The alternative would be to maintain a per-lexer data structure
|
||||
// of ignore blocks along with their "end-mac" parameters.
|
||||
if (i > startCommand) {
|
||||
std::string endmac = styler.GetRange(startCommand, i);
|
||||
if (endmac == ".") {
|
||||
endmac.clear();
|
||||
}
|
||||
// We styled right up to the "end-mac" argument or EOL.
|
||||
Sci_PositionU startEndmac = startLine;
|
||||
int style;
|
||||
while ((style = styler.BufferStyleAt(startEndmac-1)) != SCE_TROFF_REQUEST &&
|
||||
style != SCE_TROFF_COMMAND) {
|
||||
startEndmac--;
|
||||
}
|
||||
Sci_PositionU endEndmac = startEndmac;
|
||||
while (!isspacechar(styler.SafeGetCharAt(endEndmac))) {
|
||||
endEndmac++;
|
||||
}
|
||||
|
||||
std::string buf = endEndmac > startEndmac ?
|
||||
styler.GetRange(startEndmac, endEndmac) : "";
|
||||
if (buf == endmac) {
|
||||
// Found the end of the ignore block.
|
||||
// This line can be an ordinary request or macro,
|
||||
// so we completely restyle it.
|
||||
state = TroffState::DEFAULT;
|
||||
ColouriseTroffLine(startLine, endPos, styler, keywordlists, state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
styler.ColourTo(endPos, SCE_TROFF_IGNORE);
|
||||
styler.SetLineState(curLine, TroffState::IGNORE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == TroffState::FLOW_CONTROL) {
|
||||
// Allow leading spaces only in continuations of flow control requests.
|
||||
while (i <= endPos && isspacechar(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: The control characters can theoretically be changed via `.cc` and `.c2`.
|
||||
// This is seldom done and in principle it makes Roff unparseable since there is
|
||||
// no way to determine whether one of those commands has been executed without
|
||||
// executing the entire code which may run forever (halting problem).
|
||||
// So not supporting alternate control characters is simply a necessary restriction of this lexer.
|
||||
if ((state == TroffState::DEFAULT || state == TroffState::FLOW_CONTROL) &&
|
||||
(styler[i] == '.' || styler[i] == '\'')) {
|
||||
// Control line
|
||||
// TODO: It may make sense to highlight the non-breaking control character (') in
|
||||
// a separate style.
|
||||
i++;
|
||||
|
||||
while (i <= endPos && isspacechar(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
Sci_PositionU startCommand = i;
|
||||
while (i <= endPos && !isspacechar(styler[i])) {
|
||||
i++;
|
||||
// FIXME: Highlight escapes in this position?
|
||||
}
|
||||
|
||||
if (startCommand == i) {
|
||||
// lone dot without anything following
|
||||
styler.ColourTo(endPos, SCE_TROFF_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string buf = styler.GetRange(startCommand, i);
|
||||
|
||||
if (buf == "\\\"") {
|
||||
// Handling .\" separately makes sure that the entire line including
|
||||
// the leading dot is highlighted as a comment
|
||||
styler.ColourTo(endPos, SCE_TROFF_COMMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf == "\\}") {
|
||||
// Handling .\} separately makes sure it is styled like
|
||||
// the opening \{ braces.
|
||||
styler.ColourTo(endPos, SCE_TROFF_OPERATOR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore blocks
|
||||
if (ignoreBlocks.InList(buf)) {
|
||||
// It's important to style right up to the optional end-mac argument,
|
||||
// since we use the SCE_TROFF_REQUEST/COMMAND style to check for block ends (see above).
|
||||
while (i <= endPos && isspacechar(styler[i]) &&
|
||||
styler[i] != '\n' && styler[i] != '\r') {
|
||||
i++;
|
||||
}
|
||||
styler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);
|
||||
styler.ColourTo(endPos, SCE_TROFF_DEFAULT);
|
||||
// Next line will be an ignore block
|
||||
styler.SetLineState(curLine, TroffState::IGNORE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Flow control without conditionals
|
||||
if (flowControlNocond.InList(buf)) {
|
||||
styler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);
|
||||
|
||||
state = TroffState::FLOW_CONTROL;
|
||||
styler.ColourTo(i-1, SCE_TROFF_DEFAULT);
|
||||
ColouriseTroffLine(i, endPos, styler, keywordlists, state);
|
||||
return;
|
||||
}
|
||||
|
||||
// It is tempting to treat flow control requests like ordinary requests,
|
||||
// but you cannot really predict the beginning of the next command.
|
||||
// Eg. .if 'FOO'.tm' .tm BAR
|
||||
// We therefore have to parse at least the apostrophe expressions
|
||||
// and keep track of escapes.
|
||||
if (flowControlCond.InList(buf)) {
|
||||
styler.ColourTo(i-1, requests.InList(buf) ? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);
|
||||
|
||||
while (i <= endPos && isspacechar(styler[i])) {
|
||||
i++;
|
||||
}
|
||||
if (i > endPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (styler[i] == '!') {
|
||||
i++;
|
||||
styler.ColourTo(i-1, SCE_TROFF_OPERATOR);
|
||||
}
|
||||
if (i > endPos) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (styler[i] == '\'') {
|
||||
// string comparison: 's1's2'
|
||||
// FIXME: Should be highlighted?
|
||||
// However, none of the conditionals are currently highlighted.
|
||||
i++;
|
||||
while (i <= endPos && styler[i] != '\'') {
|
||||
i += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);
|
||||
}
|
||||
if (i > endPos) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
while (i <= endPos && styler[i] != '\'') {
|
||||
i += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);
|
||||
}
|
||||
if (i > endPos) {
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
// Everything else - including numeric expressions -
|
||||
// can contain spaces only in escapes and inside balanced round braces.
|
||||
int braceLevel = 0;
|
||||
while (i <= endPos && (braceLevel > 0 || !isspacechar(styler[i]))) {
|
||||
Sci_PositionU numLen;
|
||||
|
||||
switch (styler[i]) {
|
||||
case '(':
|
||||
braceLevel++;
|
||||
i++;
|
||||
break;
|
||||
case ')':
|
||||
braceLevel--;
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
numLen = ColouriseTroffNumber(i, endPos, styler);
|
||||
i += numLen;
|
||||
if (numLen > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
i += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state = TroffState::FLOW_CONTROL;
|
||||
styler.ColourTo(i-1, SCE_TROFF_DEFAULT);
|
||||
ColouriseTroffLine(i, endPos, styler, keywordlists, state);
|
||||
return;
|
||||
}
|
||||
|
||||
// remaining non-flow-control requests and commands
|
||||
state = requests.InList(buf) ? TroffState::REQUEST : TroffState::COMMAND;
|
||||
styler.ColourTo(i-1, state == TroffState::REQUEST
|
||||
? SCE_TROFF_REQUEST : SCE_TROFF_COMMAND);
|
||||
}
|
||||
|
||||
// Text line, request/command parameters including continuations
|
||||
while (i <= endPos) {
|
||||
if (state == TroffState::COMMAND && styler[i] == '"') {
|
||||
// Macro or misc command line arguments - assume that double-quoted strings
|
||||
// actually denote arguments.
|
||||
// FIXME: Allow escape linebreaks on the end of strings?
|
||||
// This would require another TroffState.
|
||||
styler.ColourTo(i-1, SCE_TROFF_DEFAULT);
|
||||
|
||||
i++;
|
||||
while (i <= endPos && styler[i] != '"') {
|
||||
styler.ColourTo(i-1, SCE_TROFF_STRING);
|
||||
i += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);
|
||||
}
|
||||
if (styler[i] == '"') {
|
||||
i++;
|
||||
}
|
||||
styler.ColourTo(i-1, SCE_TROFF_STRING);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (state == TroffState::COMMAND || state == TroffState::REQUEST) {
|
||||
// Numbers are supposed to be highlighted on every command line.
|
||||
// FIXME: Not all requests actually treat numbers specially.
|
||||
// Theoretically, we have to parse on a per-request basis.
|
||||
Sci_PositionU numLen;
|
||||
numLen = ColouriseTroffNumber(i, endPos, styler);
|
||||
i += numLen;
|
||||
if (numLen > 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i += ColouriseTroffEscape(i, endPos, styler, keywordlists, state);
|
||||
}
|
||||
|
||||
styler.ColourTo(endPos, SCE_TROFF_DEFAULT);
|
||||
}
|
||||
|
||||
static void ColouriseTroffDoc(Sci_PositionU startPos, Sci_Position length, int,
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
styler.StartAt(startPos);
|
||||
Sci_PositionU startLine = startPos;
|
||||
Sci_Position curLine = styler.GetLine(startLine);
|
||||
|
||||
styler.StartSegment(startLine);
|
||||
|
||||
// NOTE: startPos will always be at the beginning of a line
|
||||
for (Sci_PositionU i = startPos; i < startPos + length; i++) {
|
||||
// NOTE: The CR in CRLF counts into the current line.
|
||||
bool atEOL = (styler[i] == '\r' && styler.SafeGetCharAt(i+1) != '\n') || styler[i] == '\n';
|
||||
|
||||
if (atEOL || i == startPos + length - 1) {
|
||||
// If the previous line had a continuation, the current line
|
||||
// is parsed like an argument to the command that had that continuation.
|
||||
TroffState state = curLine > 0 ? (TroffState)styler.GetLineState(curLine-1)
|
||||
: TroffState::DEFAULT;
|
||||
|
||||
// End of line (or of line buffer) met, colourise it
|
||||
ColouriseTroffLine(startLine, i, styler, keywordlists, state);
|
||||
startLine = i + 1;
|
||||
curLine++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FoldTroffDoc(Sci_PositionU startPos, Sci_Position length, int,
|
||||
WordList *keywordlists[], Accessor &styler) {
|
||||
WordList &endmacBlocks = *keywordlists[4];
|
||||
|
||||
Sci_PositionU endPos = startPos + length;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
|
||||
int levelCurrent = levelPrev;
|
||||
char chNext = styler[startPos];
|
||||
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
||||
int styleNext = styler.StyleAt(startPos);
|
||||
std::string requestName;
|
||||
|
||||
for (Sci_PositionU i = startPos; i < endPos; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
int style = styleNext;
|
||||
styleNext = styler.StyleAt(i + 1);
|
||||
bool atEOL = (ch == '\r' && chNext != '\n') || ch == '\n';
|
||||
|
||||
if (style == SCE_TROFF_OPERATOR && ch == '\\') {
|
||||
if (chNext == '{') {
|
||||
levelCurrent++;
|
||||
} else if (chNext == '}') {
|
||||
levelCurrent--;
|
||||
}
|
||||
} else if (style != SCE_TROFF_IGNORE && styleNext == SCE_TROFF_IGNORE) {
|
||||
// Beginning of ignore block
|
||||
levelCurrent++;
|
||||
} else if (style == SCE_TROFF_IGNORE && styleNext != SCE_TROFF_IGNORE) {
|
||||
// End of ignore block
|
||||
// The end-mac line will not be folded, which is probably okay
|
||||
// since it could start the next ignore block or could be any command that is
|
||||
// executed.
|
||||
// This is not handled by the endmac block handling below
|
||||
// since the `.ig` syntax is different.
|
||||
// FIXME: Fold at least `..` lines.
|
||||
levelCurrent--;
|
||||
} else if ((style == SCE_TROFF_REQUEST || style == SCE_TROFF_COMMAND) &&
|
||||
!isspacechar(ch)) {
|
||||
requestName.push_back(ch);
|
||||
}
|
||||
|
||||
if (!atEOL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int lev = levelPrev;
|
||||
|
||||
if (requestName.length() > 1) {
|
||||
if (endmacBlocks.InList(requestName.substr(1))) {
|
||||
// beginning of block
|
||||
levelCurrent++;
|
||||
} else {
|
||||
// potential end of block
|
||||
// This parsing could be avoided if we kept a list
|
||||
// line numbers and end-mac strings.
|
||||
// The parsing here could also be simplified if
|
||||
// we highlighted the end-mac strings in ColouriseTroffLine().
|
||||
std::string endmac = requestName.substr(1);
|
||||
if (endmac == ".") {
|
||||
endmac.clear();
|
||||
}
|
||||
|
||||
// find start of block
|
||||
Sci_Position startLine = lineCurrent;
|
||||
while (startLine > 0 && styler.LevelAt(startLine-1) >= levelCurrent) {
|
||||
startLine--;
|
||||
}
|
||||
if (startLine) {
|
||||
Sci_Position startEndmac = styler.LineStart(startLine);
|
||||
int reqStyle;
|
||||
// skip the request/command name
|
||||
while ((reqStyle = styler.StyleAt(startEndmac)) == SCE_TROFF_REQUEST ||
|
||||
reqStyle == SCE_TROFF_COMMAND) {
|
||||
startEndmac++;
|
||||
}
|
||||
while (isspacechar(styler.SafeGetCharAt(startEndmac))) {
|
||||
startEndmac++;
|
||||
}
|
||||
// skip the macro name
|
||||
while (!isspacechar(styler.SafeGetCharAt(startEndmac))) {
|
||||
startEndmac++;
|
||||
}
|
||||
while (isspacechar(styler.SafeGetCharAt(startEndmac)) &&
|
||||
styler[startEndmac] != '\n' && styler[startEndmac] != '\r') {
|
||||
startEndmac++;
|
||||
}
|
||||
Sci_Position endEndmac = startEndmac;
|
||||
while (!isspacechar(styler.SafeGetCharAt(endEndmac))) {
|
||||
endEndmac++;
|
||||
}
|
||||
std::string buf = endEndmac > startEndmac ?
|
||||
styler.GetRange(startEndmac, endEndmac) : "";
|
||||
if (buf == endmac) {
|
||||
// FIXME: Better fold the previous line unless it is `..`.
|
||||
levelCurrent--;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (foldCompact && requestName == ".") {
|
||||
// lone dot ona line has no effect
|
||||
lev |= SC_FOLDLEVELWHITEFLAG;
|
||||
}
|
||||
if (levelCurrent > levelPrev) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
if (lev != styler.LevelAt(lineCurrent)) {
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
}
|
||||
lineCurrent++;
|
||||
levelPrev = levelCurrent;
|
||||
requestName.clear();
|
||||
}
|
||||
|
||||
// Fill in the real level of the next line, keeping the current flags as they will be filled in later
|
||||
int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
|
||||
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
|
||||
}
|
||||
|
||||
static const char * const troffWordLists[] = {
|
||||
"Predefined requests",
|
||||
"Flow control requests/commands with conditionals",
|
||||
"Flow control requests/commands without conditionals",
|
||||
"Requests and commands, initiating ignore blocks",
|
||||
"Requests and commands with end-macros",
|
||||
NULL,
|
||||
};
|
||||
|
||||
extern const LexerModule lmTroff(SCLEX_TROFF, ColouriseTroffDoc, "troff", FoldTroffDoc, troffWordLists);
|
@ -363,6 +363,9 @@ void LexerVB::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, ID
|
||||
}
|
||||
|
||||
void LexerVB::Fold(Sci_PositionU startPos, Sci_Position length, int, IDocument *pAccess) {
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
const Sci_Position endPos = startPos + length;
|
||||
|
||||
|
465
lexilla/lexers/LexZig.cxx
Normal file
465
lexilla/lexers/LexZig.cxx
Normal file
@ -0,0 +1,465 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexZig.cxx
|
||||
** Lexer for Zig language.
|
||||
**/
|
||||
// Based on Zufu Liu's Notepad4 Zig lexer
|
||||
// Modified for Scintilla by Jiri Techet, 2024
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
using namespace Lexilla;
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
constexpr bool IsAGraphic(int ch) noexcept {
|
||||
// excludes C0 control characters and whitespace
|
||||
return ch > 32 && ch < 127;
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierStart(int ch) noexcept {
|
||||
return IsUpperOrLowerCase(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierStartEx(int ch) noexcept {
|
||||
return IsIdentifierStart(ch) || ch >= 0x80;
|
||||
}
|
||||
|
||||
constexpr bool IsNumberStart(int ch, int chNext) noexcept {
|
||||
return IsADigit(ch) || (ch == '.' && IsADigit(chNext));
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierChar(int ch) noexcept {
|
||||
return IsAlphaNumeric(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {
|
||||
return ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))
|
||||
|| (ch == '.' && chNext != '.');
|
||||
}
|
||||
|
||||
constexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {
|
||||
return IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierCharEx(int ch) noexcept {
|
||||
return IsIdentifierChar(ch) || ch >= 0x80;
|
||||
}
|
||||
|
||||
// https://ziglang.org/documentation/master/#Escape-Sequences
|
||||
struct EscapeSequence {
|
||||
int outerState = SCE_ZIG_DEFAULT;
|
||||
int digitsLeft = 0;
|
||||
bool brace = false;
|
||||
|
||||
// highlight any character as escape sequence.
|
||||
void resetEscapeState(int state, int chNext) noexcept {
|
||||
outerState = state;
|
||||
digitsLeft = 1;
|
||||
brace = false;
|
||||
if (chNext == 'x') {
|
||||
digitsLeft = 3;
|
||||
} else if (chNext == 'u') {
|
||||
digitsLeft = 5;
|
||||
}
|
||||
}
|
||||
void resetEscapeState(int state) noexcept {
|
||||
outerState = state;
|
||||
digitsLeft = 1;
|
||||
brace = false;
|
||||
}
|
||||
bool atEscapeEnd(int ch) noexcept {
|
||||
--digitsLeft;
|
||||
return digitsLeft <= 0 || !IsAHeXDigit(ch);
|
||||
}
|
||||
};
|
||||
|
||||
enum {
|
||||
ZigLineStateMaskLineComment = 1, // line comment
|
||||
ZigLineStateMaskMultilineString = 1 << 1, // multiline string
|
||||
};
|
||||
|
||||
struct FoldLineState {
|
||||
int lineComment;
|
||||
int multilineString;
|
||||
constexpr explicit FoldLineState(int lineState) noexcept:
|
||||
lineComment(lineState & ZigLineStateMaskLineComment),
|
||||
multilineString((lineState >> 1) & 1) {
|
||||
}
|
||||
};
|
||||
|
||||
enum class KeywordType {
|
||||
None = SCE_ZIG_DEFAULT,
|
||||
Function = SCE_ZIG_FUNCTION,
|
||||
};
|
||||
|
||||
enum {
|
||||
KeywordIndex_Primary = 0,
|
||||
KeywordIndex_Secondary = 1,
|
||||
KeywordIndex_Tertiary = 2,
|
||||
KeywordIndex_Type = 3,
|
||||
};
|
||||
|
||||
// Options used for LexerZig
|
||||
struct OptionsZig {
|
||||
bool fold = false;
|
||||
};
|
||||
|
||||
const char *const zigWordListDesc[] = {
|
||||
"Primary keywords",
|
||||
"Secondary keywords",
|
||||
"Tertiary keywords",
|
||||
"Global type definitions",
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetZig : public OptionSet<OptionsZig> {
|
||||
OptionSetZig() {
|
||||
DefineProperty("fold", &OptionsZig::fold);
|
||||
|
||||
DefineWordListSets(zigWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer ZIG SCLEX_ZIG SCE_ZIG_:
|
||||
0, "SCE_ZIG_DEFAULT", "default", "White space",
|
||||
1, "SCE_ZIG_COMMENTLINE", "comment line", "Comment: //",
|
||||
2, "SCE_ZIG_COMMENTLINEDOC", "comment line documentation", "Comment: ///",
|
||||
3, "SCE_ZIG_COMMENTLINETOP", "comment line documentation", "Comment: //!",
|
||||
4, "SCE_ZIG_NUMBER", "literal numeric", "Number",
|
||||
5, "SCE_ZIG_OPERATOR", "operator", "Operator",
|
||||
6, "SCE_ZIG_CHARACTER", "literal string character", "Single quoted string",
|
||||
7, "SCE_ZIG_STRING", "literal string", "Double quoted string",
|
||||
8, "SCE_ZIG_MULTISTRING", "literal string multiline", "Multiline string introduced by two backslashes",
|
||||
9, "SCE_ZIG_ESCAPECHAR", "literal string escapesequence", "Escape sequence",
|
||||
10, "SCE_ZIG_IDENTIFIER", "identifier", "Identifier",
|
||||
11, "SCE_ZIG_FUNCTION", "identifier", "Function definition",
|
||||
12, "SCE_ZIG_BUILTIN_FUNCTION", "identifier", "Builtin function",
|
||||
13, "SCE_ZIG_KW_PRIMARY", "keyword", "Primary keywords",
|
||||
14, "SCE_ZIG_KW_SECONDARY", "identifier", "Secondary keywords",
|
||||
15, "SCE_ZIG_KW_TERTIARY", "identifier", "Tertiary keywords",
|
||||
16, "SCE_ZIG_KW_TYPE", "identifier", "Global types",
|
||||
};
|
||||
|
||||
class LexerZig : public DefaultLexer {
|
||||
WordList keywordsPrimary;
|
||||
WordList keywordsSecondary;
|
||||
WordList keywordsTertiary;
|
||||
WordList keywordsTypes;
|
||||
OptionsZig options;
|
||||
OptionSetZig osZig;
|
||||
public:
|
||||
LexerZig(const char *languageName_, int language_) :
|
||||
DefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {
|
||||
}
|
||||
// Deleted so LexerZig objects can not be copied.
|
||||
LexerZig(const LexerZig &) = delete;
|
||||
LexerZig(LexerZig &&) = delete;
|
||||
void operator=(const LexerZig &) = delete;
|
||||
void operator=(LexerZig &&) = delete;
|
||||
~LexerZig() override = default;
|
||||
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvRelease5;
|
||||
}
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osZig.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osZig.PropertyType(name);
|
||||
}
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osZig.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osZig.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osZig.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);
|
||||
Sci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);
|
||||
|
||||
static ILexer5 *LexerFactoryZig() {
|
||||
return new LexerZig("zig", SCLEX_ZIG);
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerZig::PropertySet(const char *key, const char *val) {
|
||||
if (osZig.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerZig::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywordsPrimary;
|
||||
break;
|
||||
case 1:
|
||||
wordListN = &keywordsSecondary;
|
||||
break;
|
||||
case 2:
|
||||
wordListN = &keywordsTertiary;
|
||||
break;
|
||||
case 3:
|
||||
wordListN = &keywordsTypes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN && wordListN->Set(wl, false)) {
|
||||
firstModification = 0;
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerZig::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
KeywordType kwType = KeywordType::None;
|
||||
int visibleChars = 0;
|
||||
int lineState = 0;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
StyleContext sc(startPos, lengthDoc, initStyle, styler);
|
||||
|
||||
while (sc.More()) {
|
||||
switch (sc.state) {
|
||||
case SCE_ZIG_OPERATOR:
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
break;
|
||||
|
||||
case SCE_ZIG_NUMBER:
|
||||
if (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_IDENTIFIER:
|
||||
case SCE_ZIG_BUILTIN_FUNCTION:
|
||||
if (!IsIdentifierCharEx(sc.ch)) {
|
||||
if (sc.state == SCE_ZIG_IDENTIFIER) {
|
||||
char s[64];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
if (kwType != KeywordType::None) {
|
||||
sc.ChangeState(static_cast<int>(kwType));
|
||||
} else if (keywordsPrimary.InList(s)) {
|
||||
sc.ChangeState(SCE_ZIG_KW_PRIMARY);
|
||||
kwType = KeywordType::None;
|
||||
if (strcmp(s, "fn") == 0) {
|
||||
kwType = KeywordType::Function;
|
||||
}
|
||||
} else if (keywordsSecondary.InList(s)) {
|
||||
sc.ChangeState(SCE_ZIG_KW_SECONDARY);
|
||||
} else if (keywordsTertiary.InList(s)) {
|
||||
sc.ChangeState(SCE_ZIG_KW_TERTIARY);
|
||||
} else if (keywordsTypes.InList(s)) {
|
||||
sc.ChangeState(SCE_ZIG_KW_TYPE);
|
||||
}
|
||||
}
|
||||
if (sc.state != SCE_ZIG_KW_PRIMARY) {
|
||||
kwType = KeywordType::None;
|
||||
}
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_CHARACTER:
|
||||
case SCE_ZIG_STRING:
|
||||
case SCE_ZIG_MULTISTRING:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
} else if (sc.ch == '\\' && sc.state != SCE_ZIG_MULTISTRING) {
|
||||
escSeq.resetEscapeState(sc.state, sc.chNext);
|
||||
sc.SetState(SCE_ZIG_ESCAPECHAR);
|
||||
sc.Forward();
|
||||
if (sc.Match('u', '{')) {
|
||||
escSeq.brace = true;
|
||||
escSeq.digitsLeft = 9;
|
||||
sc.Forward();
|
||||
}
|
||||
} else if ((sc.ch == '\'' && sc.state == SCE_ZIG_CHARACTER) || (sc.ch == '\"' && sc.state == SCE_ZIG_STRING)) {
|
||||
sc.ForwardSetState(SCE_ZIG_DEFAULT);
|
||||
} else if (sc.state != SCE_ZIG_CHARACTER) {
|
||||
if (sc.ch == '{' || sc.ch == '}') {
|
||||
if (sc.ch == sc.chNext) {
|
||||
escSeq.resetEscapeState(sc.state);
|
||||
sc.SetState(SCE_ZIG_ESCAPECHAR);
|
||||
sc.Forward();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
if (escSeq.brace && sc.ch == '}') {
|
||||
sc.Forward();
|
||||
}
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_ZIG_COMMENTLINE:
|
||||
case SCE_ZIG_COMMENTLINEDOC:
|
||||
case SCE_ZIG_COMMENTLINETOP:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_ZIG_DEFAULT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc.state == SCE_ZIG_DEFAULT) {
|
||||
if (sc.Match('/', '/')) {
|
||||
if (visibleChars == 0) {
|
||||
lineState = ZigLineStateMaskLineComment;
|
||||
}
|
||||
sc.SetState(SCE_ZIG_COMMENTLINE);
|
||||
sc.Forward(2);
|
||||
if (sc.ch == '!') {
|
||||
sc.ChangeState(SCE_ZIG_COMMENTLINETOP);
|
||||
} else if (sc.ch == '/' && sc.chNext != '/') {
|
||||
sc.ChangeState(SCE_ZIG_COMMENTLINEDOC);
|
||||
}
|
||||
} else if (sc.Match('\\', '\\')) {
|
||||
lineState = ZigLineStateMaskMultilineString;
|
||||
sc.SetState(SCE_ZIG_MULTISTRING);
|
||||
} else if (sc.ch == '\"') {
|
||||
sc.SetState(SCE_ZIG_STRING);
|
||||
} else if (sc.ch == '\'') {
|
||||
sc.SetState(SCE_ZIG_CHARACTER);
|
||||
} else if (IsNumberStart(sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_ZIG_NUMBER);
|
||||
} else if ((sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) || IsIdentifierStartEx(sc.ch)) {
|
||||
sc.SetState((sc.ch == '@') ? SCE_ZIG_BUILTIN_FUNCTION : SCE_ZIG_IDENTIFIER);
|
||||
} else if (IsAGraphic(sc.ch)) {
|
||||
sc.SetState(SCE_ZIG_OPERATOR);
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleChars == 0 && !isspacechar(sc.ch)) {
|
||||
visibleChars++;
|
||||
}
|
||||
if (sc.atLineEnd) {
|
||||
styler.SetLineState(sc.currentLine, lineState);
|
||||
lineState = 0;
|
||||
kwType = KeywordType::None;
|
||||
visibleChars = 0;
|
||||
}
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void LexerZig::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
const Sci_PositionU endPos = startPos + lengthDoc;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
startPos = styler.LineStart(lineCurrent);
|
||||
initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;
|
||||
if (!AnyOf(initStyle, SCE_ZIG_MULTISTRING,
|
||||
SCE_ZIG_COMMENTLINE, SCE_ZIG_COMMENTLINEDOC, SCE_ZIG_COMMENTLINETOP)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
FoldLineState foldPrev(0);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0) {
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
foldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));
|
||||
}
|
||||
|
||||
int levelNext = levelCurrent;
|
||||
FoldLineState foldCurrent(styler.GetLineState(lineCurrent));
|
||||
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
|
||||
while (startPos < endPos) {
|
||||
initStyle = styler.StyleIndexAt(startPos);
|
||||
|
||||
if (initStyle == SCE_ZIG_OPERATOR) {
|
||||
const char ch = styler[startPos];
|
||||
if (ch == '{' || ch == '[' || ch == '(') {
|
||||
levelNext++;
|
||||
} else if (ch == '}' || ch == ']' || ch == ')') {
|
||||
levelNext--;
|
||||
}
|
||||
}
|
||||
|
||||
++startPos;
|
||||
if (startPos == lineStartNext) {
|
||||
const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));
|
||||
levelNext = std::max(levelNext, SC_FOLDLEVELBASE);
|
||||
if (foldCurrent.lineComment) {
|
||||
levelNext += foldNext.lineComment - foldPrev.lineComment;
|
||||
} else if (foldCurrent.multilineString) {
|
||||
levelNext += foldNext.multilineString - foldPrev.multilineString;
|
||||
}
|
||||
|
||||
const int levelUse = levelCurrent;
|
||||
int lev = levelUse | (levelNext << 16);
|
||||
if (levelUse < levelNext) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
|
||||
lineCurrent++;
|
||||
lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
levelCurrent = levelNext;
|
||||
foldPrev = foldCurrent;
|
||||
foldCurrent = foldNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace end
|
||||
|
||||
extern const LexerModule lmZig(SCLEX_ZIG, LexerZig::LexerFactoryZig, "zig", zigWordListDesc);
|
@ -29,10 +29,12 @@ bool LexAccessor::MatchIgnoreCase(Sci_Position pos, const char *s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) {
|
||||
void LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const {
|
||||
assert(s);
|
||||
assert(startPos_ <= endPos_ && len != 0);
|
||||
memset(s, '\0', len);
|
||||
endPos_ = std::min(endPos_, startPos_ + len - 1);
|
||||
endPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));
|
||||
len = endPos_ - startPos_;
|
||||
if (startPos_ >= static_cast<Sci_PositionU>(startPos) && endPos_ <= static_cast<Sci_PositionU>(endPos)) {
|
||||
const char * const p = buf + (startPos_ - startPos);
|
||||
@ -40,10 +42,9 @@ void LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char
|
||||
} else {
|
||||
pAccess->GetCharRange(s, startPos_, len);
|
||||
}
|
||||
s[len] = '\0';
|
||||
}
|
||||
|
||||
void LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) {
|
||||
void LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const {
|
||||
assert(s);
|
||||
GetRange(startPos_, endPos_, s, len);
|
||||
while (*s) {
|
||||
@ -54,16 +55,18 @@ void LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_
|
||||
}
|
||||
}
|
||||
|
||||
std::string LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) {
|
||||
std::string LexAccessor::GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) const {
|
||||
assert(startPos_ < endPos_);
|
||||
endPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));
|
||||
const Sci_PositionU len = endPos_ - startPos_;
|
||||
std::string s(len, '\0');
|
||||
GetRange(startPos_, endPos_, s.data(), len + 1);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) {
|
||||
std::string LexAccessor::GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) const {
|
||||
assert(startPos_ < endPos_);
|
||||
endPos_ = std::min(endPos_, static_cast<Sci_PositionU>(lenDoc));
|
||||
const Sci_PositionU len = endPos_ - startPos_;
|
||||
std::string s(len, '\0');
|
||||
GetRangeLowered(startPos_, endPos_, s.data(), len + 1);
|
||||
|
@ -116,11 +116,11 @@ public:
|
||||
bool MatchIgnoreCase(Sci_Position pos, const char *s);
|
||||
|
||||
// Get first len - 1 characters in range [startPos_, endPos_).
|
||||
void GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len);
|
||||
void GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len);
|
||||
void GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const;
|
||||
void GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_, char *s, Sci_PositionU len) const;
|
||||
// Get all characters in range [startPos_, endPos_).
|
||||
std::string GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_);
|
||||
std::string GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_);
|
||||
std::string GetRange(Sci_PositionU startPos_, Sci_PositionU endPos_) const;
|
||||
std::string GetRangeLowered(Sci_PositionU startPos_, Sci_PositionU endPos_) const;
|
||||
|
||||
char StyleAt(Sci_Position position) const {
|
||||
return pAccess->StyleAt(position);
|
||||
|
@ -84,15 +84,15 @@ bool StyleContext::MatchIgnoreCase2(const char *s) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void StyleContext::GetCurrent(char *s, Sci_PositionU len) {
|
||||
void StyleContext::GetCurrent(char *s, Sci_PositionU len) const {
|
||||
styler.GetRange(styler.GetStartSegment(), currentPos, s, len);
|
||||
}
|
||||
|
||||
void StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) {
|
||||
void StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) const {
|
||||
styler.GetRangeLowered(styler.GetStartSegment(), currentPos, s, len);
|
||||
}
|
||||
|
||||
void StyleContext::GetCurrentString(std::string &string, Transform transform) {
|
||||
void StyleContext::GetCurrentString(std::string &string, Transform transform) const {
|
||||
const Sci_PositionU startPos = styler.GetStartSegment();
|
||||
const Sci_PositionU len = currentPos - styler.GetStartSegment();
|
||||
string.resize(len);
|
||||
|
@ -184,10 +184,10 @@ public:
|
||||
// Non-inline
|
||||
bool MatchIgnoreCase(const char *s);
|
||||
bool MatchIgnoreCase2(const char *s);
|
||||
void GetCurrent(char *s, Sci_PositionU len);
|
||||
void GetCurrentLowered(char *s, Sci_PositionU len);
|
||||
void GetCurrent(char *s, Sci_PositionU len) const;
|
||||
void GetCurrentLowered(char *s, Sci_PositionU len) const;
|
||||
enum class Transform { none, lower };
|
||||
void GetCurrentString(std::string &string, Transform transform);
|
||||
void GetCurrentString(std::string &string, Transform transform) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ extern const LexerModule lmCPPNoCase;
|
||||
extern const LexerModule lmCsound;
|
||||
extern const LexerModule lmCss;
|
||||
extern const LexerModule lmD;
|
||||
extern const LexerModule lmDart;
|
||||
extern const LexerModule lmDataflex;
|
||||
extern const LexerModule lmDiff;
|
||||
extern const LexerModule lmDMAP;
|
||||
@ -152,6 +153,7 @@ extern const LexerModule lmTCMD;
|
||||
extern const LexerModule lmTEHex;
|
||||
extern const LexerModule lmTeX;
|
||||
extern const LexerModule lmTOML;
|
||||
extern const LexerModule lmTroff;
|
||||
extern const LexerModule lmTxt2tags;
|
||||
extern const LexerModule lmVB;
|
||||
extern const LexerModule lmVBScript;
|
||||
@ -161,6 +163,7 @@ extern const LexerModule lmVisualProlog;
|
||||
extern const LexerModule lmX12;
|
||||
extern const LexerModule lmXML;
|
||||
extern const LexerModule lmYAML;
|
||||
extern const LexerModule lmZig;
|
||||
|
||||
//--Autogenerated -- end of automatically generated section
|
||||
extern const LexerModule lmObjC;
|
||||
@ -211,6 +214,7 @@ void AddEachLexer() {
|
||||
&lmCsound,
|
||||
&lmCss,
|
||||
&lmD,
|
||||
&lmDart,
|
||||
&lmDataflex,
|
||||
&lmDiff,
|
||||
&lmDMAP,
|
||||
@ -304,6 +308,7 @@ void AddEachLexer() {
|
||||
&lmTEHex,
|
||||
&lmTeX,
|
||||
&lmTOML,
|
||||
&lmTroff,
|
||||
&lmTxt2tags,
|
||||
&lmVB,
|
||||
&lmVBScript,
|
||||
@ -313,6 +318,7 @@ void AddEachLexer() {
|
||||
&lmX12,
|
||||
&lmXML,
|
||||
&lmYAML,
|
||||
&lmZig,
|
||||
|
||||
//--Autogenerated -- end of automatically generated section
|
||||
&lmObjC,
|
||||
|
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.4.0</string>
|
||||
<string>5.4.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
@ -157,6 +157,9 @@
|
||||
70BF497C8D265026B77C97DA /* LexJulia.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 315E4E969868C52C125686B2 /* LexJulia.cxx */; };
|
||||
B32D4A2A9CEC222A5140E99F /* LexFSharp.cxx in Sources */ = {isa = PBXBuildFile; fileRef = F8E54626B22BD9493090F40B /* LexFSharp.cxx */; };
|
||||
3D044C4CA34C6FD7E58E0091 /* LexTOML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */; };
|
||||
14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */ = {isa = PBXBuildFile; fileRef = D2EF4913B8F91656C787F584 /* LexTroff.cxx */; };
|
||||
0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 1F274010A7943C43BA265511 /* LexDart.cxx */; };
|
||||
CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 71684CF6BCC80369BCE2F893 /* LexZig.cxx */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -312,6 +315,9 @@
|
||||
A383409E9A994F461550FEC1 /* LexGDScript.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexGDScript.cxx; path = ../../lexers/LexGDScript.cxx; sourceTree = SOURCE_ROOT; };
|
||||
F8E54626B22BD9493090F40B /* LexFSharp.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexFSharp.cxx; path = ../../lexers/LexFSharp.cxx; sourceTree = SOURCE_ROOT; };
|
||||
42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTOML.cxx; path = ../../lexers/LexTOML.cxx; sourceTree = SOURCE_ROOT; };
|
||||
D2EF4913B8F91656C787F584 /* LexTroff.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTroff.cxx; path = ../../lexers/LexTroff.cxx; sourceTree = SOURCE_ROOT; };
|
||||
1F274010A7943C43BA265511 /* LexDart.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexDart.cxx; path = ../../lexers/LexDart.cxx; sourceTree = SOURCE_ROOT; };
|
||||
71684CF6BCC80369BCE2F893 /* LexZig.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexZig.cxx; path = ../../lexers/LexZig.cxx; sourceTree = SOURCE_ROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -385,6 +391,7 @@
|
||||
28BA731524E34D9500272C2D /* LexCsound.cxx */,
|
||||
28BA732924E34D9600272C2D /* LexCSS.cxx */,
|
||||
28BA72E024E34D9200272C2D /* LexD.cxx */,
|
||||
1F274010A7943C43BA265511 /* LexDart.cxx */,
|
||||
28BA732C24E34D9600272C2D /* LexDataflex.cxx */,
|
||||
28BA72DD24E34D9200272C2D /* LexDiff.cxx */,
|
||||
28BA732024E34D9600272C2D /* LexDMAP.cxx */,
|
||||
@ -468,6 +475,7 @@
|
||||
28BA730324E34D9400272C2D /* LexTCMD.cxx */,
|
||||
28BA730824E34D9400272C2D /* LexTeX.cxx */,
|
||||
42BC44CCB57D4E78DEE6E358 /* LexTOML.cxx */,
|
||||
D2EF4913B8F91656C787F584 /* LexTroff.cxx */,
|
||||
28BA730F24E34D9500272C2D /* LexTxt2tags.cxx */,
|
||||
28BA731F24E34D9600272C2D /* LexVB.cxx */,
|
||||
28BA731A24E34D9500272C2D /* LexVerilog.cxx */,
|
||||
@ -475,6 +483,7 @@
|
||||
28BA731E24E34D9500272C2D /* LexVisualProlog.cxx */,
|
||||
28BA730A24E34D9400272C2D /* LexX12.cxx */,
|
||||
28BA72E724E34D9200272C2D /* LexYAML.cxx */,
|
||||
71684CF6BCC80369BCE2F893 /* LexZig.cxx */,
|
||||
);
|
||||
name = Lexers;
|
||||
sourceTree = "<group>";
|
||||
@ -733,6 +742,9 @@
|
||||
510D44AFB91EE873E86ABDD4 /* LexAsciidoc.cxx in Sources */,
|
||||
00D544CC992062D2E3CD4BF6 /* LexGDScript.cxx in Sources */,
|
||||
3D044C4CA34C6FD7E58E0091 /* LexTOML.cxx in Sources */,
|
||||
14314DCD945FDA90481F0A0D /* LexTroff.cxx in Sources */,
|
||||
0DFB4F5F94B018794ADB389D /* LexDart.cxx in Sources */,
|
||||
CEC8496B8D9712E6EEDBC301 /* LexZig.cxx in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -796,7 +808,6 @@
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
"OTHER_LDFLAGS[arch=*]" = "-Wl,-ld_classic";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
@ -852,7 +863,6 @@
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
"OTHER_LDFLAGS[arch=*]" = "-Wl,-ld_classic";
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
@ -862,7 +872,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.4.0;
|
||||
CURRENT_PROJECT_VERSION = 5.4.1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
@ -890,7 +900,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 5.4.0;
|
||||
CURRENT_PROJECT_VERSION = 5.4.1;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_TEAM = 4F446KW87E;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VERSION_LEXILLA "5.4.0"
|
||||
#define VERSION_WORDS 5, 4, 0, 0
|
||||
#define VERSION_LEXILLA "5.4.1"
|
||||
#define VERSION_WORDS 5, 4, 1, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_WORDS
|
||||
|
@ -461,6 +461,20 @@ $(DIR_O)/LexD.o: \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexDart.o: \
|
||||
../lexers/LexDart.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexDataflex.o: \
|
||||
../lexers/LexDataflex.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
@ -1504,6 +1518,18 @@ $(DIR_O)/LexTOML.o: \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexTroff.o: \
|
||||
../lexers/LexTroff.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexTxt2tags.o: \
|
||||
../lexers/LexTxt2tags.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
@ -1592,3 +1618,17 @@ $(DIR_O)/LexYAML.o: \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexZig.o: \
|
||||
../lexers/LexZig.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
|
@ -113,6 +113,7 @@ LEX_OBJS=\
|
||||
$(DIR_O)\LexCsound.obj \
|
||||
$(DIR_O)\LexCSS.obj \
|
||||
$(DIR_O)\LexD.obj \
|
||||
$(DIR_O)\LexDart.obj \
|
||||
$(DIR_O)\LexDataflex.obj \
|
||||
$(DIR_O)\LexDiff.obj \
|
||||
$(DIR_O)\LexDMAP.obj \
|
||||
@ -196,6 +197,7 @@ LEX_OBJS=\
|
||||
$(DIR_O)\LexTCMD.obj \
|
||||
$(DIR_O)\LexTeX.obj \
|
||||
$(DIR_O)\LexTOML.obj \
|
||||
$(DIR_O)\LexTroff.obj \
|
||||
$(DIR_O)\LexTxt2tags.obj \
|
||||
$(DIR_O)\LexVB.obj \
|
||||
$(DIR_O)\LexVerilog.obj \
|
||||
@ -203,6 +205,7 @@ LEX_OBJS=\
|
||||
$(DIR_O)\LexVisualProlog.obj \
|
||||
$(DIR_O)\LexX12.obj \
|
||||
$(DIR_O)\LexYAML.obj \
|
||||
$(DIR_O)\LexZig.obj \
|
||||
$(DIR_O)\LexObjC.obj \
|
||||
$(DIR_O)\LexSearchResult.obj \
|
||||
$(DIR_O)\LexUser.obj
|
||||
|
@ -461,6 +461,20 @@ $(DIR_O)/LexD.obj: \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexDart.obj: \
|
||||
../lexers/LexDart.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
$(DIR_O)/LexDataflex.obj: \
|
||||
../lexers/LexDataflex.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
@ -1504,6 +1518,18 @@ $(DIR_O)/LexTOML.obj: \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexTroff.obj: \
|
||||
../lexers/LexTroff.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexTxt2tags.obj: \
|
||||
../lexers/LexTxt2tags.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
@ -1592,3 +1618,17 @@ $(DIR_O)/LexYAML.obj: \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h
|
||||
$(DIR_O)/LexZig.obj: \
|
||||
../lexers/LexZig.cxx \
|
||||
../../scintilla/include/ILexer.h \
|
||||
../../scintilla/include/Sci_Position.h \
|
||||
../../scintilla/include/Scintilla.h \
|
||||
../include/SciLexer.h \
|
||||
../lexlib/WordList.h \
|
||||
../lexlib/LexAccessor.h \
|
||||
../lexlib/Accessor.h \
|
||||
../lexlib/StyleContext.h \
|
||||
../lexlib/CharacterSet.h \
|
||||
../lexlib/LexerModule.h \
|
||||
../lexlib/OptionSet.h \
|
||||
../lexlib/DefaultLexer.h
|
||||
|
@ -897,17 +897,22 @@ bool TestFile(const std::filesystem::path &path, const PropertyMap &propertyMap)
|
||||
const std::optional<int> perLineDisable = propertyMap.GetPropertyValue("testlexers.per.line.disable");
|
||||
const bool disablePerLineTests = perLineDisable.value_or(false);
|
||||
|
||||
plex->Release();
|
||||
|
||||
// Test line by line lexing/folding
|
||||
if (success && !disablePerLineTests) {
|
||||
doc.Set(text);
|
||||
StyleLineByLine(doc, plex);
|
||||
const auto [styledTextNewPerLine, foldedTextNewPerLine] = MarkedAndFoldedDocument(pdoc);
|
||||
TestDocument docPerLine;
|
||||
docPerLine.Set(text);
|
||||
Scintilla::ILexer5 *plexPerLine = Lexilla::MakeLexer(*language);
|
||||
if (!SetProperties(plexPerLine, *language, propertyMap, path)) {
|
||||
return false;
|
||||
}
|
||||
StyleLineByLine(docPerLine, plexPerLine);
|
||||
const auto [styledTextNewPerLine, foldedTextNewPerLine] = MarkedAndFoldedDocument(&docPerLine);
|
||||
success = success && CheckSame(styledText, styledTextNewPerLine, "per-line styles", suffixStyled, path);
|
||||
success = success && CheckSame(foldedText, foldedTextNewPerLine, "per-line folds", suffixFolded, path);
|
||||
}
|
||||
|
||||
plex->Release();
|
||||
|
||||
if (success) {
|
||||
Scintilla::ILexer5 *plexCRLF = Lexilla::MakeLexer(*language);
|
||||
SetProperties(plexCRLF, *language, propertyMap, path.filename().string());
|
||||
|
@ -24,6 +24,8 @@ b
|
||||
/** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:
|
||||
@wrong LexCPP.cxx
|
||||
<wrong>filename</wrong>
|
||||
Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed
|
||||
<
|
||||
**/
|
||||
|
||||
#define M\
|
||||
|
@ -24,6 +24,8 @@
|
||||
2 400 401 + /** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:
|
||||
0 401 401 | @wrong LexCPP.cxx
|
||||
0 401 401 | <wrong>filename</wrong>
|
||||
0 401 401 | Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed
|
||||
0 401 401 | <
|
||||
0 401 400 | **/
|
||||
1 400 400
|
||||
0 400 400 #define M\
|
||||
|
@ -24,6 +24,8 @@
|
||||
{3}/** Unknown doc keywords so in SCE_C_COMMENTDOCKEYWORDERROR:
|
||||
{18}@wrong{3} LexCPP.cxx
|
||||
<{18}wrong{3}>filename</{18}wrong{3}>
|
||||
Next line should not start a keyword but before 5.4.1 did and caused bad styling or a crash depending on range lexed
|
||||
<
|
||||
**/{0}
|
||||
|
||||
{9}#define M\
|
||||
|
334
lexilla/test/examples/dart/AllStyles.dart
Normal file
334
lexilla/test/examples/dart/AllStyles.dart
Normal file
@ -0,0 +1,334 @@
|
||||
// coding:utf-8
|
||||
|
||||
void main() {
|
||||
print('Hello, World!');
|
||||
}
|
||||
|
||||
var name = 'Voyager I';
|
||||
var url = 'url'
|
||||
var year = 1977;
|
||||
var antennaDiameter = 3.7;
|
||||
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
|
||||
var image = {
|
||||
'tags': ['saturn'],
|
||||
url: '//path/to/saturn.jpg'
|
||||
};
|
||||
|
||||
|
||||
if (year >= 2001) {
|
||||
print('21st century');
|
||||
} else if (year >= 1901) {
|
||||
print('20th century');
|
||||
}
|
||||
|
||||
for (final object in flybyObjects) {
|
||||
print(object);
|
||||
}
|
||||
|
||||
for (int month = 1; month <= 12; month++) {
|
||||
print(month);
|
||||
}
|
||||
|
||||
while (year < 2016) {
|
||||
year += 1;
|
||||
}
|
||||
|
||||
flybyObjects.where((name) => name.contains('turn')).forEach(print);
|
||||
|
||||
// This is a normal, one-line comment.
|
||||
|
||||
/// This is a documentation comment, used to document libraries,
|
||||
/// classes, and their members. Tools like IDEs and dartdoc treat
|
||||
/// doc comments specially.
|
||||
|
||||
/* Comments like these are also supported. */
|
||||
|
||||
/** Comment
|
||||
block doc */
|
||||
|
||||
// Importing core libraries
|
||||
import 'dart:math';
|
||||
|
||||
// Importing libraries from external packages
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// Importing files
|
||||
import 'path/to/my_other_file.dart';
|
||||
|
||||
class Spacecraft {
|
||||
String name;
|
||||
DateTime? launchDate;
|
||||
|
||||
// Read-only non-final property
|
||||
int? get launchYear => launchDate?.year;
|
||||
|
||||
// Constructor, with syntactic sugar for assignment to members.
|
||||
Spacecraft(this.name, this.launchDate) {
|
||||
// Initialization code goes here.
|
||||
}
|
||||
|
||||
// Named constructor that forwards to the default one.
|
||||
Spacecraft.unlaunched(String name) : this(name, null);
|
||||
|
||||
// Method.
|
||||
void describe() {
|
||||
print('Spacecraft: $name');
|
||||
// Type promotion doesn't work on getters.
|
||||
var launchDate = this.launchDate;
|
||||
if (launchDate != null) {
|
||||
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
|
||||
print('Launched: $launchYear ($years years ago)');
|
||||
} else {
|
||||
print('Unlaunched');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
|
||||
voyager.describe();
|
||||
|
||||
var voyager3 = Spacecraft.unlaunched('Voyager III');
|
||||
voyager3.describe();
|
||||
|
||||
enum PlanetType { terrestrial, gas, ice }
|
||||
|
||||
/// Enum that enumerates the different planets in our solar system
|
||||
/// and some of their properties.
|
||||
enum Planet {
|
||||
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
|
||||
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
|
||||
// ···
|
||||
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
|
||||
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);
|
||||
|
||||
/// A constant generating constructor
|
||||
const Planet(
|
||||
{required this.planetType, required this.moons, required this.hasRings});
|
||||
|
||||
/// All instance variables are final
|
||||
final PlanetType planetType;
|
||||
final int moons;
|
||||
final bool hasRings;
|
||||
|
||||
/// Enhanced enums support getters and other methods
|
||||
bool get isGiant =>
|
||||
planetType == PlanetType.gas || planetType == PlanetType.ice;
|
||||
}
|
||||
|
||||
final yourPlanet = Planet.earth;
|
||||
|
||||
if (!yourPlanet.isGiant) {
|
||||
print('Your planet is not a "giant planet".');
|
||||
}
|
||||
|
||||
mixin Piloted {
|
||||
int astronauts = 1;
|
||||
|
||||
void describeCrew() {
|
||||
print('Number of astronauts: $astronauts');
|
||||
}
|
||||
}
|
||||
|
||||
const oneSecond = Duration(seconds: 1);
|
||||
// ···
|
||||
Future<void> printWithDelay(String message) async {
|
||||
await Future.delayed(oneSecond);
|
||||
print(message);
|
||||
}
|
||||
|
||||
|
||||
Future<void> printWithDelay(String message) {
|
||||
return Future.delayed(oneSecond).then((_) {
|
||||
print(message);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> createDescriptions(Iterable<String> objects) async {
|
||||
for (final object in objects) {
|
||||
try {
|
||||
var file = File('$object.txt');
|
||||
if (await file.exists()) {
|
||||
var modified = await file.lastModified();
|
||||
print(
|
||||
'File for $object already exists. It was modified on $modified.');
|
||||
continue;
|
||||
}
|
||||
await file.create();
|
||||
await file.writeAsString('Start describing $object in this file.');
|
||||
} on IOException catch (e) {
|
||||
print('Cannot create description for $object: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
|
||||
for (final object in objects) {
|
||||
await Future.delayed(oneSecond);
|
||||
yield '${craft.name} flies by $object';
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> describeFlybyObjects(List<String> flybyObjects) async {
|
||||
try {
|
||||
for (final object in flybyObjects) {
|
||||
var description = await File('$object.txt').readAsString();
|
||||
print(description);
|
||||
}
|
||||
} on IOException catch (e) {
|
||||
print('Could not describe object: $e');
|
||||
} finally {
|
||||
flybyObjects.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class Television {
|
||||
/// Use [turnOn] to turn the power on instead.
|
||||
@Deprecated('Use turnOn instead')
|
||||
void activate() {
|
||||
turnOn();
|
||||
}
|
||||
|
||||
/// Turns the TV's power on.
|
||||
void turnOn() {...}
|
||||
// ···
|
||||
}
|
||||
|
||||
String? name // Nullable type. Can be `null` or string.
|
||||
|
||||
String name // Non-nullable type. Cannot be `null` but can be string.
|
||||
|
||||
|
||||
/// A domesticated South American camelid (Lama glama).
|
||||
///
|
||||
/// Andean cultures have used llamas as meat and pack
|
||||
/// animals since pre-Hispanic times.
|
||||
///
|
||||
/// Just like any other animal, llamas need to eat,
|
||||
/// so don't forget to [feed] them some [Food].
|
||||
class Llama {
|
||||
String? name;
|
||||
|
||||
/** Feeds your llama [food].
|
||||
/
|
||||
/ The typical llama eats one bale of hay per week. **/
|
||||
void feed(Food food) {
|
||||
// ...
|
||||
}
|
||||
|
||||
/// Exercises your llama with an [activity] for
|
||||
/// [timeLimit] minutes.
|
||||
void exercise(Activity activity, int timeLimit) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
import 'package:lib1/lib1.dart';
|
||||
import 'package:lib2/lib2.dart' as lib2;
|
||||
// Import only foo.
|
||||
import 'package:lib1/lib1.dart' show foo;
|
||||
// Import all names EXCEPT foo.
|
||||
import 'package:lib2/lib2.dart' hide foo;
|
||||
|
||||
print(#mysymbol);
|
||||
Symbol symbol = #myMethod;
|
||||
Symbol symbol2 = #<;
|
||||
Symbol symbol2 = #void;
|
||||
|
||||
var x = 1;
|
||||
var hex = 0xDEADBEEF;
|
||||
var y = 1.1;
|
||||
var exponents = 1.42e5;
|
||||
|
||||
var s1 = 'Single quotes work well for string literals.';
|
||||
var s2 = "Double quotes work just as well.";
|
||||
var s3 = 'It\'s easy to escape the string delimiter.';
|
||||
var s4 = "It's even easier to use the other delimiter.";
|
||||
|
||||
var s = 'string interpolation';
|
||||
|
||||
assert('Dart has $s, which is very handy.' ==
|
||||
'Dart has string interpolation, '
|
||||
'which is very handy.');
|
||||
assert('That deserves all caps. '
|
||||
'${s.toUpperCase()} is very handy!' ==
|
||||
'That deserves all caps. '
|
||||
'STRING INTERPOLATION is very handy!');
|
||||
|
||||
var s1 = 'String '
|
||||
'concatenation'
|
||||
" works even over line breaks.";
|
||||
assert(s1 ==
|
||||
'String concatenation works even over '
|
||||
'line breaks.');
|
||||
|
||||
var s2 = 'The + operator ' + 'works, as well.';
|
||||
assert(s2 == 'The + operator works, as well.');
|
||||
|
||||
var s1 = '''
|
||||
You can create
|
||||
multi-line strings like this one.
|
||||
''';
|
||||
|
||||
var s2 = """This is also a
|
||||
multi-line string.""";
|
||||
|
||||
var s = r'In a raw string, not even \n gets special treatment.';
|
||||
var 2 = r"In a raw string, not even \n gets special treatment.";
|
||||
|
||||
var s1 = r'''
|
||||
You can create
|
||||
multi-line strings like this one.
|
||||
''';
|
||||
|
||||
var s2 = r"""This is also a
|
||||
multi-line string.""";
|
||||
|
||||
var record = ('first', a: 2, b: true, 'last');
|
||||
|
||||
var record = ('first', a: 2, b: true, 'last');
|
||||
|
||||
print(record.$1); // Prints 'first'
|
||||
print(record.a); // Prints 2
|
||||
print(record.b); // Prints true
|
||||
print(record.$2); // Prints 'last'
|
||||
|
||||
({String name, int age}) userInfo(Map<String, dynamic> json)
|
||||
// ···
|
||||
// Destructures using a record pattern with named fields:
|
||||
final (:name, :age) = userInfo(json);
|
||||
|
||||
var list = [1, 2, 3];
|
||||
var list = [
|
||||
'Car',
|
||||
'Boat',
|
||||
'Plane',
|
||||
];
|
||||
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
|
||||
|
||||
var nobleGases = {
|
||||
2: 'helium',
|
||||
10: 'neon',
|
||||
18: 'argon',
|
||||
};
|
||||
|
||||
var s = """This is also a
|
||||
${foo(
|
||||
"$bar"
|
||||
)}
|
||||
multi-line string.""";
|
||||
|
||||
var s1 = """multi
|
||||
line
|
||||
\n
|
||||
strings
|
||||
""";
|
||||
|
||||
var s2 = """multi-line
|
||||
$x
|
||||
strings
|
||||
""";
|
||||
|
||||
var s3 = """multi-line
|
||||
${x}
|
||||
strings
|
||||
""";
|
335
lexilla/test/examples/dart/AllStyles.dart.folded
Normal file
335
lexilla/test/examples/dart/AllStyles.dart.folded
Normal file
@ -0,0 +1,335 @@
|
||||
0 400 400 // coding:utf-8
|
||||
0 400 400
|
||||
2 400 401 + void main() {
|
||||
0 401 401 | print('Hello, World!');
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 var name = 'Voyager I';
|
||||
0 400 400 var url = 'url'
|
||||
0 400 400 var year = 1977;
|
||||
0 400 400 var antennaDiameter = 3.7;
|
||||
0 400 400 var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
|
||||
2 400 401 + var image = {
|
||||
0 401 401 | 'tags': ['saturn'],
|
||||
0 401 401 | url: '//path/to/saturn.jpg'
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
0 400 400
|
||||
2 400 401 + if (year >= 2001) {
|
||||
0 401 401 | print('21st century');
|
||||
0 401 401 | } else if (year >= 1901) {
|
||||
0 401 401 | print('20th century');
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + for (final object in flybyObjects) {
|
||||
0 401 401 | print(object);
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + for (int month = 1; month <= 12; month++) {
|
||||
0 401 401 | print(month);
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + while (year < 2016) {
|
||||
0 401 401 | year += 1;
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 flybyObjects.where((name) => name.contains('turn')).forEach(print);
|
||||
0 400 400
|
||||
0 400 400 // This is a normal, one-line comment.
|
||||
0 400 400
|
||||
2 400 401 + /// This is a documentation comment, used to document libraries,
|
||||
0 401 401 | /// classes, and their members. Tools like IDEs and dartdoc treat
|
||||
0 401 400 | /// doc comments specially.
|
||||
0 400 400
|
||||
0 400 400 /* Comments like these are also supported. */
|
||||
0 400 400
|
||||
2 400 401 + /** Comment
|
||||
0 401 400 | block doc */
|
||||
0 400 400
|
||||
0 400 400 // Importing core libraries
|
||||
0 400 400 import 'dart:math';
|
||||
0 400 400
|
||||
0 400 400 // Importing libraries from external packages
|
||||
0 400 400 import 'package:test/test.dart';
|
||||
0 400 400
|
||||
0 400 400 // Importing files
|
||||
0 400 400 import 'path/to/my_other_file.dart';
|
||||
0 400 400
|
||||
2 400 401 + class Spacecraft {
|
||||
0 401 401 | String name;
|
||||
0 401 401 | DateTime? launchDate;
|
||||
0 401 401 |
|
||||
0 401 401 | // Read-only non-final property
|
||||
0 401 401 | int? get launchYear => launchDate?.year;
|
||||
0 401 401 |
|
||||
0 401 401 | // Constructor, with syntactic sugar for assignment to members.
|
||||
2 401 402 + Spacecraft(this.name, this.launchDate) {
|
||||
0 402 402 | // Initialization code goes here.
|
||||
0 402 401 | }
|
||||
0 401 401 |
|
||||
0 401 401 | // Named constructor that forwards to the default one.
|
||||
0 401 401 | Spacecraft.unlaunched(String name) : this(name, null);
|
||||
0 401 401 |
|
||||
0 401 401 | // Method.
|
||||
2 401 402 + void describe() {
|
||||
0 402 402 | print('Spacecraft: $name');
|
||||
0 402 402 | // Type promotion doesn't work on getters.
|
||||
0 402 402 | var launchDate = this.launchDate;
|
||||
2 402 403 + if (launchDate != null) {
|
||||
0 403 403 | int years = DateTime.now().difference(launchDate).inDays ~/ 365;
|
||||
0 403 403 | print('Launched: $launchYear ($years years ago)');
|
||||
0 403 403 | } else {
|
||||
0 403 403 | print('Unlaunched');
|
||||
0 403 402 | }
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
|
||||
0 400 400 voyager.describe();
|
||||
0 400 400
|
||||
0 400 400 var voyager3 = Spacecraft.unlaunched('Voyager III');
|
||||
0 400 400 voyager3.describe();
|
||||
0 400 400
|
||||
0 400 400 enum PlanetType { terrestrial, gas, ice }
|
||||
0 400 400
|
||||
2 400 401 + /// Enum that enumerates the different planets in our solar system
|
||||
0 401 400 | /// and some of their properties.
|
||||
2 400 401 + enum Planet {
|
||||
0 401 401 | mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
|
||||
0 401 401 | venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
|
||||
0 401 401 | // ···
|
||||
0 401 401 | uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
|
||||
0 401 401 | neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);
|
||||
0 401 401 |
|
||||
0 401 401 | /// A constant generating constructor
|
||||
2 401 402 + const Planet(
|
||||
0 402 401 | {required this.planetType, required this.moons, required this.hasRings});
|
||||
0 401 401 |
|
||||
0 401 401 | /// All instance variables are final
|
||||
0 401 401 | final PlanetType planetType;
|
||||
0 401 401 | final int moons;
|
||||
0 401 401 | final bool hasRings;
|
||||
0 401 401 |
|
||||
0 401 401 | /// Enhanced enums support getters and other methods
|
||||
0 401 401 | bool get isGiant =>
|
||||
0 401 401 | planetType == PlanetType.gas || planetType == PlanetType.ice;
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 final yourPlanet = Planet.earth;
|
||||
0 400 400
|
||||
2 400 401 + if (!yourPlanet.isGiant) {
|
||||
0 401 401 | print('Your planet is not a "giant planet".');
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + mixin Piloted {
|
||||
0 401 401 | int astronauts = 1;
|
||||
0 401 401 |
|
||||
2 401 402 + void describeCrew() {
|
||||
0 402 402 | print('Number of astronauts: $astronauts');
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 const oneSecond = Duration(seconds: 1);
|
||||
0 400 400 // ···
|
||||
2 400 401 + Future<void> printWithDelay(String message) async {
|
||||
0 401 401 | await Future.delayed(oneSecond);
|
||||
0 401 401 | print(message);
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400
|
||||
2 400 401 + Future<void> printWithDelay(String message) {
|
||||
2 401 403 + return Future.delayed(oneSecond).then((_) {
|
||||
0 403 403 | print(message);
|
||||
0 403 401 | });
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + Future<void> createDescriptions(Iterable<String> objects) async {
|
||||
2 401 402 + for (final object in objects) {
|
||||
2 402 403 + try {
|
||||
0 403 403 | var file = File('$object.txt');
|
||||
2 403 404 + if (await file.exists()) {
|
||||
0 404 404 | var modified = await file.lastModified();
|
||||
2 404 405 + print(
|
||||
0 405 404 | 'File for $object already exists. It was modified on $modified.');
|
||||
0 404 404 | continue;
|
||||
0 404 403 | }
|
||||
0 403 403 | await file.create();
|
||||
0 403 403 | await file.writeAsString('Start describing $object in this file.');
|
||||
0 403 403 | } on IOException catch (e) {
|
||||
0 403 403 | print('Cannot create description for $object: $e');
|
||||
0 403 402 | }
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
|
||||
2 401 402 + for (final object in objects) {
|
||||
0 402 402 | await Future.delayed(oneSecond);
|
||||
0 402 402 | yield '${craft.name} flies by $object';
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + Future<void> describeFlybyObjects(List<String> flybyObjects) async {
|
||||
2 401 402 + try {
|
||||
2 402 403 + for (final object in flybyObjects) {
|
||||
0 403 403 | var description = await File('$object.txt').readAsString();
|
||||
0 403 403 | print(description);
|
||||
0 403 402 | }
|
||||
0 402 402 | } on IOException catch (e) {
|
||||
0 402 402 | print('Could not describe object: $e');
|
||||
0 402 402 | } finally {
|
||||
0 402 402 | flybyObjects.clear();
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + class Television {
|
||||
0 401 401 | /// Use [turnOn] to turn the power on instead.
|
||||
0 401 401 | @Deprecated('Use turnOn instead')
|
||||
2 401 402 + void activate() {
|
||||
0 402 402 | turnOn();
|
||||
0 402 401 | }
|
||||
0 401 401 |
|
||||
0 401 401 | /// Turns the TV's power on.
|
||||
0 401 401 | void turnOn() {...}
|
||||
0 401 401 | // ···
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 String? name // Nullable type. Can be `null` or string.
|
||||
0 400 400
|
||||
0 400 400 String name // Non-nullable type. Cannot be `null` but can be string.
|
||||
0 400 400
|
||||
0 400 400
|
||||
2 400 401 + /// A domesticated South American camelid (Lama glama).
|
||||
0 401 401 | ///
|
||||
0 401 401 | /// Andean cultures have used llamas as meat and pack
|
||||
0 401 401 | /// animals since pre-Hispanic times.
|
||||
0 401 401 | ///
|
||||
0 401 401 | /// Just like any other animal, llamas need to eat,
|
||||
0 401 400 | /// so don't forget to [feed] them some [Food].
|
||||
2 400 401 + class Llama {
|
||||
0 401 401 | String? name;
|
||||
0 401 401 |
|
||||
2 401 402 + /** Feeds your llama [food].
|
||||
0 402 402 | /
|
||||
0 402 401 | / The typical llama eats one bale of hay per week. **/
|
||||
2 401 402 + void feed(Food food) {
|
||||
0 402 402 | // ...
|
||||
0 402 401 | }
|
||||
0 401 401 |
|
||||
2 401 402 + /// Exercises your llama with an [activity] for
|
||||
0 402 401 | /// [timeLimit] minutes.
|
||||
2 401 402 + void exercise(Activity activity, int timeLimit) {
|
||||
0 402 402 | // ...
|
||||
0 402 401 | }
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + import 'package:lib1/lib1.dart';
|
||||
0 401 400 | import 'package:lib2/lib2.dart' as lib2;
|
||||
0 400 400 // Import only foo.
|
||||
0 400 400 import 'package:lib1/lib1.dart' show foo;
|
||||
0 400 400 // Import all names EXCEPT foo.
|
||||
0 400 400 import 'package:lib2/lib2.dart' hide foo;
|
||||
0 400 400
|
||||
0 400 400 print(#mysymbol);
|
||||
0 400 400 Symbol symbol = #myMethod;
|
||||
0 400 400 Symbol symbol2 = #<;
|
||||
0 400 400 Symbol symbol2 = #void;
|
||||
0 400 400
|
||||
0 400 400 var x = 1;
|
||||
0 400 400 var hex = 0xDEADBEEF;
|
||||
0 400 400 var y = 1.1;
|
||||
0 400 400 var exponents = 1.42e5;
|
||||
0 400 400
|
||||
0 400 400 var s1 = 'Single quotes work well for string literals.';
|
||||
0 400 400 var s2 = "Double quotes work just as well.";
|
||||
0 400 400 var s3 = 'It\'s easy to escape the string delimiter.';
|
||||
0 400 400 var s4 = "It's even easier to use the other delimiter.";
|
||||
0 400 400
|
||||
0 400 400 var s = 'string interpolation';
|
||||
0 400 400
|
||||
2 400 401 + assert('Dart has $s, which is very handy.' ==
|
||||
0 401 401 | 'Dart has string interpolation, '
|
||||
0 401 400 | 'which is very handy.');
|
||||
2 400 401 + assert('That deserves all caps. '
|
||||
0 401 401 | '${s.toUpperCase()} is very handy!' ==
|
||||
0 401 401 | 'That deserves all caps. '
|
||||
0 401 400 | 'STRING INTERPOLATION is very handy!');
|
||||
0 400 400
|
||||
0 400 400 var s1 = 'String '
|
||||
0 400 400 'concatenation'
|
||||
0 400 400 " works even over line breaks.";
|
||||
2 400 401 + assert(s1 ==
|
||||
0 401 401 | 'String concatenation works even over '
|
||||
0 401 400 | 'line breaks.');
|
||||
0 400 400
|
||||
0 400 400 var s2 = 'The + operator ' + 'works, as well.';
|
||||
0 400 400 assert(s2 == 'The + operator works, as well.');
|
||||
0 400 400
|
||||
2 400 401 + var s1 = '''
|
||||
0 401 401 | You can create
|
||||
0 401 401 | multi-line strings like this one.
|
||||
0 401 400 | ''';
|
||||
0 400 400
|
||||
2 400 401 + var s2 = """This is also a
|
||||
0 401 400 | multi-line string.""";
|
||||
0 400 400
|
||||
0 400 400 var s = r'In a raw string, not even \n gets special treatment.';
|
||||
0 400 400 var 2 = r"In a raw string, not even \n gets special treatment.";
|
||||
0 400 400
|
||||
2 400 401 + var s1 = r'''
|
||||
0 401 401 | You can create
|
||||
0 401 401 | multi-line strings like this one.
|
||||
0 401 400 | ''';
|
||||
0 400 400
|
||||
2 400 401 + var s2 = r"""This is also a
|
||||
0 401 400 | multi-line string.""";
|
||||
0 400 400
|
||||
0 400 400 var record = ('first', a: 2, b: true, 'last');
|
||||
0 400 400
|
||||
0 400 400 var record = ('first', a: 2, b: true, 'last');
|
||||
0 400 400
|
||||
0 400 400 print(record.$1); // Prints 'first'
|
||||
0 400 400 print(record.a); // Prints 2
|
||||
0 400 400 print(record.b); // Prints true
|
||||
0 400 400 print(record.$2); // Prints 'last'
|
||||
0 400 400
|
||||
0 400 400 ({String name, int age}) userInfo(Map<String, dynamic> json)
|
||||
2 400 401 + // ···
|
||||
0 401 400 | // Destructures using a record pattern with named fields:
|
||||
0 400 400 final (:name, :age) = userInfo(json);
|
||||
0 400 400
|
||||
0 400 400 var list = [1, 2, 3];
|
||||
2 400 401 + var list = [
|
||||
0 401 401 | 'Car',
|
||||
0 401 401 | 'Boat',
|
||||
0 401 401 | 'Plane',
|
||||
0 401 400 | ];
|
||||
0 400 400 var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
|
||||
0 400 400
|
||||
2 400 401 + var nobleGases = {
|
||||
0 401 401 | 2: 'helium',
|
||||
0 401 401 | 10: 'neon',
|
||||
0 401 401 | 18: 'argon',
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
2 400 401 + var s = """This is also a
|
||||
2 401 403 + ${foo(
|
||||
0 403 403 | "$bar"
|
||||
0 403 401 | )}
|
||||
0 401 400 | multi-line string.""";
|
||||
0 400 400
|
||||
2 400 401 + var s1 = """multi
|
||||
0 401 401 | line
|
||||
0 401 401 | \n
|
||||
0 401 401 | strings
|
||||
0 401 400 | """;
|
||||
0 400 400
|
||||
2 400 401 + var s2 = """multi-line
|
||||
0 401 401 | $x
|
||||
0 401 401 | strings
|
||||
0 401 400 | """;
|
||||
0 400 400
|
||||
2 400 401 + var s3 = """multi-line
|
||||
0 401 401 | ${x}
|
||||
0 401 401 | strings
|
||||
0 401 400 | """;
|
||||
0 400 0
|
334
lexilla/test/examples/dart/AllStyles.dart.styled
Normal file
334
lexilla/test/examples/dart/AllStyles.dart.styled
Normal file
@ -0,0 +1,334 @@
|
||||
{1}// coding:utf-8
|
||||
{0}
|
||||
{24}void{0} {14}main{16}(){0} {16}{{0}
|
||||
{14}print{16}({5}'Hello, World!'{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}var{0} {14}name{0} {16}={0} {5}'Voyager I'{16};{0}
|
||||
{23}var{0} {14}url{0} {16}={0} {5}'url'{0}
|
||||
{23}var{0} {14}year{0} {16}={0} {20}1977{16};{0}
|
||||
{23}var{0} {14}antennaDiameter{0} {16}={0} {20}3.7{16};{0}
|
||||
{23}var{0} {14}flybyObjects{0} {16}={0} {16}[{5}'Jupiter'{16},{0} {5}'Saturn'{16},{0} {5}'Uranus'{16},{0} {5}'Neptune'{16}];{0}
|
||||
{23}var{0} {14}image{0} {16}={0} {16}{{0}
|
||||
{5}'tags'{16}:{0} {16}[{5}'saturn'{16}],{0}
|
||||
{21}url{16}:{0} {5}'//path/to/saturn.jpg'{0}
|
||||
{16}};{0}
|
||||
|
||||
|
||||
{23}if{0} {16}({14}year{0} {16}>={0} {20}2001{16}){0} {16}{{0}
|
||||
{14}print{16}({5}'21st century'{16});{0}
|
||||
{16}}{0} {23}else{0} {23}if{0} {16}({14}year{0} {16}>={0} {20}1901{16}){0} {16}{{0}
|
||||
{14}print{16}({5}'20th century'{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}flybyObjects{16}){0} {16}{{0}
|
||||
{14}print{16}({14}object{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}for{0} {16}({24}int{0} {14}month{0} {16}={0} {20}1{16};{0} {14}month{0} {16}<={0} {20}12{16};{0} {14}month{16}++){0} {16}{{0}
|
||||
{14}print{16}({14}month{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}while{0} {16}({14}year{0} {16}<{0} {20}2016{16}){0} {16}{{0}
|
||||
{14}year{0} {16}+={0} {20}1{16};{0}
|
||||
{16}}{0}
|
||||
|
||||
{14}flybyObjects{16}.{14}where{16}(({14}name{16}){0} {16}=>{0} {14}name{16}.{14}contains{16}({5}'turn'{16})).{14}forEach{16}({14}print{16});{0}
|
||||
|
||||
{1}// This is a normal, one-line comment.
|
||||
{0}
|
||||
{2}/// This is a documentation comment, used to document libraries,
|
||||
/// classes, and their members. Tools like IDEs and dartdoc treat
|
||||
/// doc comments specially.
|
||||
{0}
|
||||
{3}/* Comments like these are also supported. */{0}
|
||||
|
||||
{4}/** Comment
|
||||
block doc */{0}
|
||||
|
||||
{1}// Importing core libraries
|
||||
{23}import{0} {5}'dart:math'{16};{0}
|
||||
|
||||
{1}// Importing libraries from external packages
|
||||
{23}import{0} {5}'package:test/test.dart'{16};{0}
|
||||
|
||||
{1}// Importing files
|
||||
{23}import{0} {5}'path/to/my_other_file.dart'{16};{0}
|
||||
|
||||
{23}class{0} {26}Spacecraft{0} {16}{{0}
|
||||
{25}String{0} {14}name{16};{0}
|
||||
{25}DateTime{16}?{0} {14}launchDate{16};{0}
|
||||
|
||||
{1}// Read-only non-final property
|
||||
{0} {24}int{16}?{0} {23}get{0} {14}launchYear{0} {16}=>{0} {14}launchDate{16}?.{14}year{16};{0}
|
||||
|
||||
{1}// Constructor, with syntactic sugar for assignment to members.
|
||||
{0} {26}Spacecraft{16}({23}this{16}.{14}name{16},{0} {23}this{16}.{14}launchDate{16}){0} {16}{{0}
|
||||
{1}// Initialization code goes here.
|
||||
{0} {16}}{0}
|
||||
|
||||
{1}// Named constructor that forwards to the default one.
|
||||
{0} {26}Spacecraft{16}.{14}unlaunched{16}({25}String{0} {14}name{16}){0} {16}:{0} {23}this{16}({14}name{16},{0} {23}null{16});{0}
|
||||
|
||||
{1}// Method.
|
||||
{0} {24}void{0} {14}describe{16}(){0} {16}{{0}
|
||||
{14}print{16}({5}'Spacecraft: {17}${15}name{5}'{16});{0}
|
||||
{1}// Type promotion doesn't work on getters.
|
||||
{0} {23}var{0} {14}launchDate{0} {16}={0} {23}this{16}.{14}launchDate{16};{0}
|
||||
{23}if{0} {16}({14}launchDate{0} {16}!={0} {23}null{16}){0} {16}{{0}
|
||||
{24}int{0} {14}years{0} {16}={0} {25}DateTime{16}.{14}now{16}().{14}difference{16}({14}launchDate{16}).{14}inDays{0} {16}~/{0} {20}365{16};{0}
|
||||
{14}print{16}({5}'Launched: {17}${15}launchYear{5} ({17}${15}years{5} years ago)'{16});{0}
|
||||
{16}}{0} {23}else{0} {16}{{0}
|
||||
{14}print{16}({5}'Unlaunched'{16});{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}var{0} {14}voyager{0} {16}={0} {26}Spacecraft{16}({5}'Voyager I'{16},{0} {25}DateTime{16}({20}1977{16},{0} {20}9{16},{0} {20}5{16}));{0}
|
||||
{14}voyager{16}.{14}describe{16}();{0}
|
||||
|
||||
{23}var{0} {14}voyager3{0} {16}={0} {26}Spacecraft{16}.{14}unlaunched{16}({5}'Voyager III'{16});{0}
|
||||
{14}voyager3{16}.{14}describe{16}();{0}
|
||||
|
||||
{23}enum{0} {14}PlanetType{0} {16}{{0} {14}terrestrial{16},{0} {14}gas{16},{0} {14}ice{0} {16}}{0}
|
||||
|
||||
{2}/// Enum that enumerates the different planets in our solar system
|
||||
/// and some of their properties.
|
||||
{23}enum{0} {14}Planet{0} {16}{{0}
|
||||
{14}mercury{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}terrestrial{16},{0} {21}moons{16}:{0} {20}0{16},{0} {21}hasRings{16}:{0} {23}false{16}),{0}
|
||||
{14}venus{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}terrestrial{16},{0} {21}moons{16}:{0} {20}0{16},{0} {21}hasRings{16}:{0} {23}false{16}),{0}
|
||||
{1}// ···
|
||||
{0} {14}uranus{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}ice{16},{0} {21}moons{16}:{0} {20}27{16},{0} {21}hasRings{16}:{0} {23}true{16}),{0}
|
||||
{14}neptune{16}({21}planetType{16}:{0} {14}PlanetType{16}.{14}ice{16},{0} {21}moons{16}:{0} {20}14{16},{0} {21}hasRings{16}:{0} {23}true{16});{0}
|
||||
|
||||
{2}/// A constant generating constructor
|
||||
{0} {23}const{0} {14}Planet{16}({0}
|
||||
{16}{{23}required{0} {23}this{16}.{14}planetType{16},{0} {23}required{0} {23}this{16}.{14}moons{16},{0} {23}required{0} {23}this{16}.{14}hasRings{16}});{0}
|
||||
|
||||
{2}/// All instance variables are final
|
||||
{0} {23}final{0} {14}PlanetType{0} {14}planetType{16};{0}
|
||||
{23}final{0} {24}int{0} {14}moons{16};{0}
|
||||
{23}final{0} {24}bool{0} {14}hasRings{16};{0}
|
||||
|
||||
{2}/// Enhanced enums support getters and other methods
|
||||
{0} {24}bool{0} {23}get{0} {14}isGiant{0} {16}=>{0}
|
||||
{14}planetType{0} {16}=={0} {14}PlanetType{16}.{14}gas{0} {16}||{0} {14}planetType{0} {16}=={0} {14}PlanetType{16}.{14}ice{16};{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}final{0} {14}yourPlanet{0} {16}={0} {14}Planet{16}.{14}earth{16};{0}
|
||||
|
||||
{23}if{0} {16}(!{14}yourPlanet{16}.{14}isGiant{16}){0} {16}{{0}
|
||||
{14}print{16}({5}'Your planet is not a "giant planet".'{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}mixin{0} {14}Piloted{0} {16}{{0}
|
||||
{24}int{0} {14}astronauts{0} {16}={0} {20}1{16};{0}
|
||||
|
||||
{24}void{0} {14}describeCrew{16}(){0} {16}{{0}
|
||||
{14}print{16}({5}'Number of astronauts: {17}${15}astronauts{5}'{16});{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}const{0} {14}oneSecond{0} {16}={0} {25}Duration{16}({21}seconds{16}:{0} {20}1{16});{0}
|
||||
{1}// ···
|
||||
{25}Future{16}<{24}void{16}>{0} {14}printWithDelay{16}({25}String{0} {14}message{16}){0} {23}async{0} {16}{{0}
|
||||
{23}await{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16});{0}
|
||||
{14}print{16}({14}message{16});{0}
|
||||
{16}}{0}
|
||||
|
||||
|
||||
{25}Future{16}<{24}void{16}>{0} {14}printWithDelay{16}({25}String{0} {14}message{16}){0} {16}{{0}
|
||||
{23}return{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16}).{14}then{16}(({14}_{16}){0} {16}{{0}
|
||||
{14}print{16}({14}message{16});{0}
|
||||
{16}});{0}
|
||||
{16}}{0}
|
||||
|
||||
{25}Future{16}<{24}void{16}>{0} {14}createDescriptions{16}({25}Iterable{16}<{25}String{16}>{0} {14}objects{16}){0} {23}async{0} {16}{{0}
|
||||
{23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}objects{16}){0} {16}{{0}
|
||||
{23}try{0} {16}{{0}
|
||||
{23}var{0} {14}file{0} {16}={0} {25}File{16}({5}'{17}${15}object{5}.txt'{16});{0}
|
||||
{23}if{0} {16}({23}await{0} {14}file{16}.{14}exists{16}()){0} {16}{{0}
|
||||
{23}var{0} {14}modified{0} {16}={0} {23}await{0} {14}file{16}.{14}lastModified{16}();{0}
|
||||
{14}print{16}({0}
|
||||
{5}'File for {17}${15}object{5} already exists. It was modified on {17}${15}modified{5}.'{16});{0}
|
||||
{23}continue{16};{0}
|
||||
{16}}{0}
|
||||
{23}await{0} {14}file{16}.{14}create{16}();{0}
|
||||
{23}await{0} {14}file{16}.{14}writeAsString{16}({5}'Start describing {17}${15}object{5} in this file.'{16});{0}
|
||||
{16}}{0} {23}on{0} {25}IOException{0} {23}catch{0} {16}({14}e{16}){0} {16}{{0}
|
||||
{14}print{16}({5}'Cannot create description for {17}${15}object{5}: {17}${15}e{5}'{16});{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{25}Stream{16}<{25}String{16}>{0} {14}report{16}({26}Spacecraft{0} {14}craft{16},{0} {25}Iterable{16}<{25}String{16}>{0} {14}objects{16}){0} {23}async{16}*{0} {16}{{0}
|
||||
{23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}objects{16}){0} {16}{{0}
|
||||
{23}await{0} {25}Future{16}.{14}delayed{16}({14}oneSecond{16});{0}
|
||||
{23}yield{0} {5}'{17}${{14}craft{16}.{14}name{17}}{5} flies by {17}${15}object{5}'{16};{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{25}Future{16}<{24}void{16}>{0} {14}describeFlybyObjects{16}({25}List{16}<{25}String{16}>{0} {14}flybyObjects{16}){0} {23}async{0} {16}{{0}
|
||||
{23}try{0} {16}{{0}
|
||||
{23}for{0} {16}({23}final{0} {14}object{0} {23}in{0} {14}flybyObjects{16}){0} {16}{{0}
|
||||
{23}var{0} {14}description{0} {16}={0} {23}await{0} {25}File{16}({5}'{17}${15}object{5}.txt'{16}).{14}readAsString{16}();{0}
|
||||
{14}print{16}({14}description{16});{0}
|
||||
{16}}{0}
|
||||
{16}}{0} {23}on{0} {25}IOException{0} {23}catch{0} {16}({14}e{16}){0} {16}{{0}
|
||||
{14}print{16}({5}'Could not describe object: {17}${15}e{5}'{16});{0}
|
||||
{16}}{0} {23}finally{0} {16}{{0}
|
||||
{14}flybyObjects{16}.{14}clear{16}();{0}
|
||||
{16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}class{0} {14}Television{0} {16}{{0}
|
||||
{2}/// Use [turnOn] to turn the power on instead.
|
||||
{0} {22}@Deprecated{16}({5}'Use turnOn instead'{16}){0}
|
||||
{24}void{0} {14}activate{16}(){0} {16}{{0}
|
||||
{14}turnOn{16}();{0}
|
||||
{16}}{0}
|
||||
|
||||
{2}/// Turns the TV's power on.
|
||||
{0} {24}void{0} {14}turnOn{16}(){0} {16}{...}{0}
|
||||
{1}// ···
|
||||
{16}}{0}
|
||||
|
||||
{25}String{16}?{0} {14}name{0} {1}// Nullable type. Can be `null` or string.
|
||||
{0}
|
||||
{25}String{0} {14}name{0} {1}// Non-nullable type. Cannot be `null` but can be string.
|
||||
{0}
|
||||
|
||||
{2}/// A domesticated South American camelid (Lama glama).
|
||||
///
|
||||
/// Andean cultures have used llamas as meat and pack
|
||||
/// animals since pre-Hispanic times.
|
||||
///
|
||||
/// Just like any other animal, llamas need to eat,
|
||||
/// so don't forget to [feed] them some [Food].
|
||||
{23}class{0} {14}Llama{0} {16}{{0}
|
||||
{25}String{16}?{0} {14}name{16};{0}
|
||||
|
||||
{4}/** Feeds your llama [food].
|
||||
/
|
||||
/ The typical llama eats one bale of hay per week. **/{0}
|
||||
{24}void{0} {14}feed{16}({14}Food{0} {14}food{16}){0} {16}{{0}
|
||||
{1}// ...
|
||||
{0} {16}}{0}
|
||||
|
||||
{2}/// Exercises your llama with an [activity] for
|
||||
{0} {2}/// [timeLimit] minutes.
|
||||
{0} {24}void{0} {14}exercise{16}({14}Activity{0} {14}activity{16},{0} {24}int{0} {14}timeLimit{16}){0} {16}{{0}
|
||||
{1}// ...
|
||||
{0} {16}}{0}
|
||||
{16}}{0}
|
||||
|
||||
{23}import{0} {5}'package:lib1/lib1.dart'{16};{0}
|
||||
{23}import{0} {5}'package:lib2/lib2.dart'{0} {23}as{0} {14}lib2{16};{0}
|
||||
{1}// Import only foo.
|
||||
{23}import{0} {5}'package:lib1/lib1.dart'{0} {23}show{0} {14}foo{16};{0}
|
||||
{1}// Import all names EXCEPT foo.
|
||||
{23}import{0} {5}'package:lib2/lib2.dart'{0} {23}hide{0} {14}foo{16};{0}
|
||||
|
||||
{14}print{16}({18}#mysymbol{16});{0}
|
||||
{25}Symbol{0} {14}symbol{0} {16}={0} {18}#myMethod{16};{0}
|
||||
{25}Symbol{0} {14}symbol2{0} {16}={0} {19}#<{16};{0}
|
||||
{25}Symbol{0} {14}symbol2{0} {16}={0} {18}#void{16};{0}
|
||||
|
||||
{23}var{0} {14}x{0} {16}={0} {20}1{16};{0}
|
||||
{23}var{0} {14}hex{0} {16}={0} {20}0xDEADBEEF{16};{0}
|
||||
{23}var{0} {14}y{0} {16}={0} {20}1.1{16};{0}
|
||||
{23}var{0} {14}exponents{0} {16}={0} {20}1.42e5{16};{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {5}'Single quotes work well for string literals.'{16};{0}
|
||||
{23}var{0} {14}s2{0} {16}={0} {6}"Double quotes work just as well."{16};{0}
|
||||
{23}var{0} {14}s3{0} {16}={0} {5}'It{13}\'{5}s easy to escape the string delimiter.'{16};{0}
|
||||
{23}var{0} {14}s4{0} {16}={0} {6}"It's even easier to use the other delimiter."{16};{0}
|
||||
|
||||
{23}var{0} {14}s{0} {16}={0} {5}'string interpolation'{16};{0}
|
||||
|
||||
{23}assert{16}({5}'Dart has {17}${15}s{5}, which is very handy.'{0} {16}=={0}
|
||||
{5}'Dart has string interpolation, '{0}
|
||||
{5}'which is very handy.'{16});{0}
|
||||
{23}assert{16}({5}'That deserves all caps. '{0}
|
||||
{5}'{17}${{14}s{16}.{14}toUpperCase{16}(){17}}{5} is very handy!'{0} {16}=={0}
|
||||
{5}'That deserves all caps. '{0}
|
||||
{5}'STRING INTERPOLATION is very handy!'{16});{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {5}'String '{0}
|
||||
{5}'concatenation'{0}
|
||||
{6}" works even over line breaks."{16};{0}
|
||||
{23}assert{16}({14}s1{0} {16}=={0}
|
||||
{5}'String concatenation works even over '{0}
|
||||
{5}'line breaks.'{16});{0}
|
||||
|
||||
{23}var{0} {14}s2{0} {16}={0} {5}'The + operator '{0} {16}+{0} {5}'works, as well.'{16};{0}
|
||||
{23}assert{16}({14}s2{0} {16}=={0} {5}'The + operator works, as well.'{16});{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {7}'''
|
||||
You can create
|
||||
multi-line strings like this one.
|
||||
'''{16};{0}
|
||||
|
||||
{23}var{0} {14}s2{0} {16}={0} {8}"""This is also a
|
||||
multi-line string."""{16};{0}
|
||||
|
||||
{23}var{0} {14}s{0} {16}={0} {9}r'In a raw string, not even \n gets special treatment.'{16};{0}
|
||||
{23}var{0} {20}2{0} {16}={0} {10}r"In a raw string, not even \n gets special treatment."{16};{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {11}r'''
|
||||
You can create
|
||||
multi-line strings like this one.
|
||||
'''{16};{0}
|
||||
|
||||
{23}var{0} {14}s2{0} {16}={0} {12}r"""This is also a
|
||||
multi-line string."""{16};{0}
|
||||
|
||||
{23}var{0} {14}record{0} {16}={0} {16}({5}'first'{16},{0} {21}a{16}:{0} {20}2{16},{0} {21}b{16}:{0} {23}true{16},{0} {5}'last'{16});{0}
|
||||
|
||||
{23}var{0} {14}record{0} {16}={0} {16}({5}'first'{16},{0} {21}a{16}:{0} {20}2{16},{0} {21}b{16}:{0} {23}true{16},{0} {5}'last'{16});{0}
|
||||
|
||||
{14}print{16}({14}record{16}.{14}$1{16});{0} {1}// Prints 'first'
|
||||
{14}print{16}({14}record{16}.{14}a{16});{0} {1}// Prints 2
|
||||
{14}print{16}({14}record{16}.{14}b{16});{0} {1}// Prints true
|
||||
{14}print{16}({14}record{16}.{14}$2{16});{0} {1}// Prints 'last'
|
||||
{0}
|
||||
{16}({{25}String{0} {14}name{16},{0} {24}int{0} {14}age{16}}){0} {14}userInfo{16}({25}Map{16}<{25}String{16},{0} {24}dynamic{16}>{0} {14}json{16}){0}
|
||||
{1}// ···
|
||||
// Destructures using a record pattern with named fields:
|
||||
{23}final{0} {16}(:{14}name{16},{0} {16}:{14}age{16}){0} {16}={0} {14}userInfo{16}({14}json{16});{0}
|
||||
|
||||
{23}var{0} {14}list{0} {16}={0} {16}[{20}1{16},{0} {20}2{16},{0} {20}3{16}];{0}
|
||||
{23}var{0} {14}list{0} {16}={0} {16}[{0}
|
||||
{5}'Car'{16},{0}
|
||||
{5}'Boat'{16},{0}
|
||||
{5}'Plane'{16},{0}
|
||||
{16}];{0}
|
||||
{23}var{0} {14}halogens{0} {16}={0} {16}{{5}'fluorine'{16},{0} {5}'chlorine'{16},{0} {5}'bromine'{16},{0} {5}'iodine'{16},{0} {5}'astatine'{16}};{0}
|
||||
|
||||
{23}var{0} {14}nobleGases{0} {16}={0} {16}{{0}
|
||||
{20}2{16}:{0} {5}'helium'{16},{0}
|
||||
{20}10{16}:{0} {5}'neon'{16},{0}
|
||||
{20}18{16}:{0} {5}'argon'{16},{0}
|
||||
{16}};{0}
|
||||
|
||||
{23}var{0} {14}s{0} {16}={0} {8}"""This is also a
|
||||
{17}${{14}foo{16}({0}
|
||||
{6}"{17}${15}bar{6}"{0}
|
||||
{16}){17}}{8}
|
||||
multi-line string."""{16};{0}
|
||||
|
||||
{23}var{0} {14}s1{0} {16}={0} {8}"""multi
|
||||
line
|
||||
{13}\n{8}
|
||||
strings
|
||||
"""{16};{0}
|
||||
|
||||
{23}var{0} {14}s2{0} {16}={0} {8}"""multi-line
|
||||
{17}${15}x{8}
|
||||
strings
|
||||
"""{16};{0}
|
||||
|
||||
{23}var{0} {14}s3{0} {16}={0} {8}"""multi-line
|
||||
{17}${{14}x{17}}{8}
|
||||
strings
|
||||
"""{16};{0}
|
20
lexilla/test/examples/dart/SciTE.properties
Normal file
20
lexilla/test/examples/dart/SciTE.properties
Normal file
@ -0,0 +1,20 @@
|
||||
lexer.*.dart=dart
|
||||
fold=1
|
||||
keywords.*.dart=abstract as assert async await base break case catch class const \
|
||||
continue covariant default deferred do else enum export extends extension external \
|
||||
factory false final finally for get hide if implements import in interface is late \
|
||||
library mixin native new null of on operator part required rethrow return sealed \
|
||||
set show static super switch sync this throw true try type typedef var when while \
|
||||
with yield
|
||||
keywords2.*.dart=Function Never bool double dynamic int num void
|
||||
keywords3.*.dart=fBigInt Comparable Comparator Completer DateTime Deprecated \
|
||||
Directory DoubleLinkedQueue Duration Enum Error Exception Expando File FileLock \
|
||||
FileMode FileStat FileSystemEntity FileSystemEvent Future FutureOr HashMap HashSet \
|
||||
IOException Invocation Iterable IterableBase IterableMixin Iterator LinkedHashMap \
|
||||
LinkedHashSet LinkedList LinkedListEntry List ListBase ListMixin ListQueue Map \
|
||||
MapBase MapEntry MapMixin MapView Match Null OSError Object Pattern Platform \
|
||||
Point Process Queue Random RawSocket RawSocketEvent Record Rectangle RegExp \
|
||||
RegExpMatch RuneIterator Runes ServerSocket Set SetBase SetMixin Sink Socket \
|
||||
SocketException SplayTreeMap SplayTreeSet StackTrace Stopwatch Stream String \
|
||||
StringBuffer StringSink Symbol SystemHash Timer Type Uri UriData WeakReference
|
||||
keywords4.*.dart=Spacecraft
|
@ -49,4 +49,4 @@
|
||||
0 400 400 printfn $"""%.2f {x}"""
|
||||
0 400 400 printfn $@"""%.2f {x}"""
|
||||
0 400 400 printfn @$"""%.2f {x}"""
|
||||
1 400 400
|
||||
0 400 0
|
@ -2,43 +2,43 @@
|
||||
|
||||
{1}let{0} {6}x{0} {12}={0} {3}List{0}.{2}fold{0} {12}(*){0} {13}24.5{0} {12}[{0} {13}1.{12};{0} {13}2.{12};{0} {13}3.{0} {12}]{0}
|
||||
|
||||
{9}// expect "147.00"{0}
|
||||
{9}// expect "147.00"
|
||||
{2}printfn{0} {15}"Speed: {19}%.2f{15} m/s"{0} {6}x{0}
|
||||
{2}printfn{0} {15}$"Speed: {19}%.2f{15}{x} m/s"{0}
|
||||
{2}printfn{0} {15}$"Speed: {x{19}:f2{15}} m/s"{0}
|
||||
{2}printfn{0} {16}$@"Speed: {19}%.2f{16}{x} m/s"{0}
|
||||
{2}printfn{0} {16}@$"Speed: {x{19}:f2{16}} m/s"{0}
|
||||
|
||||
{9}// expect " 147%"{0}
|
||||
{9}// expect " 147%"
|
||||
{2}printfn{0} {15}"""{19}%%{15} increase:{19}% .0F%%{15} over last year"""{0} {6}x{0}
|
||||
{2}printfn{0} {15}$"""{19}%%{15} increase:{19}% .0F{15}{x}{19}%%{15} over last year"""{0}
|
||||
{2}printfn{0} {15}$"""{19}%%{15} increase:{x / 100.{19},5:P0{15}} over last year"""{0}
|
||||
{2}printfn{0} {16}$@"""{19}%%{16} increase:{19}% .0F{16}{x}{19}%%{16} over last year"""{0}
|
||||
{2}printfn{0} {16}@$"""{19}%%{16} increase:{x / 100.{19},5:P0{16}} over last year"""{0}
|
||||
|
||||
{9}// expect "1.5E+002"{0}
|
||||
{9}// NB: units should look like text even without a space{0}
|
||||
{9}// expect "1.5E+002"
|
||||
// NB: units should look like text even without a space
|
||||
{2}printfn{0} {16}@"Time: {19}%-0.1E{16}secs"{0} {6}x{0}
|
||||
{2}printfn{0} {15}$"Time: {19}%-0.1E{15}{x}secs"{0}
|
||||
{2}printfn{0} {15}$"Time: {x{19}:E1{15}}secs"{0}
|
||||
{2}printfn{0} {16}$@"Time: {19}%-0.1E{16}{x}secs"{0}
|
||||
{2}printfn{0} {16}@$"Time: {x{19}:E1{16}}secs"{0}
|
||||
|
||||
{9}// expect "\" +147\""{0}
|
||||
{9}// expect "\" +147\""
|
||||
{2}printfn{0} {16}@"""Temp: {19}%+12.3g{16} K"""{0} {6}x{0}
|
||||
{2}printfn{0} {15}$"""{'"'}Temp: {19}%+12.3g{15}{x} K{'"'}"""{0}
|
||||
{2}printfn{0} {15}$"""{'"'}Temp: {'+'{19},9{15}}{x{19}:g3{15}} K{'"'}"""{0}
|
||||
{2}printfn{0} {16}$@"""Temp: {19}%+12.3g{16}{x} K"""{0}
|
||||
{2}printfn{0} {16}@$"""Temp: {'+'{19},9{16}}{x{19}:g3{16}} K"""{0}
|
||||
|
||||
{9}// Since F# 6.0{0}
|
||||
{9}// Since F# 6.0
|
||||
{2}printfn{0} {16}@"{19}%B{16}"{0} {13}0b1_000_000{0}
|
||||
{2}printfn{0} {15}"{19}%B{15}"{0} {15}"\x40"B{0}.{12}[{13}0{12}]{0}
|
||||
{2}printfn{0} {15}$"""{19}%B{15}{'\064'B}"""{0}
|
||||
{2}printfn{0} {16}$@"""{19}%B{16}{0b1_000_000}"""{0}
|
||||
{2}printfn{0} {16}@$"""{19}%B{16}{'\064'B}"""{0}
|
||||
|
||||
{9}// These don't work{0}
|
||||
{9}// These don't work
|
||||
{2}printfn{0} {7}``%.2f``{0} {6}x{0}
|
||||
{2}printfn{0} {15}$"%.2f"{0} {6}x{0}
|
||||
{2}printfn{0} {16}$@"%.2f"{0} {6}x{0}
|
||||
|
@ -12,4 +12,4 @@
|
||||
0 401 400 | open FSharp.Reflection
|
||||
1 400 400
|
||||
0 400 400 () |> ignore
|
||||
1 400 400
|
||||
0 400 0
|
@ -1,8 +1,8 @@
|
||||
{9}// not folded{0}
|
||||
|
||||
{9}// first line in comment fold{0}
|
||||
{9}// second . . .{0}
|
||||
{9}// third . . .{0}
|
||||
{9}// not folded
|
||||
{0}
|
||||
{9}// first line in comment fold
|
||||
// second . . .
|
||||
// third . . .
|
||||
{1}namespace{0} {6}Issue56{0}
|
||||
|
||||
{1}open{0} {3}System{0}
|
||||
|
@ -44,4 +44,4 @@
|
||||
0 401 400 | *)
|
||||
2 400 401 + // Prints:
|
||||
0 401 400 | // "not an evaluated expression"
|
||||
1 400 400
|
||||
0 400 0
|
@ -13,16 +13,16 @@
|
||||
*)
|
||||
*)
|
||||
*){0}
|
||||
{9}// declare a namespace{0}
|
||||
{9}// for the module{0}
|
||||
{9}// declare a namespace
|
||||
// for the module
|
||||
{1}namespace{0} {6}Issue93{0}
|
||||
|
||||
{1}module{0} {6}NestedComments{0} {12}={0}
|
||||
{1}open{0} {3}FSharp{0}.{6}Quotations{0}
|
||||
{1}open{0} {3}FSharp{0}.{6}Quotations{0}.{6}Patterns{0}
|
||||
{9}// print the arguments{0}
|
||||
{9}// of an evaluated expression{0}
|
||||
{8}(* Example:
|
||||
{9}// print the arguments
|
||||
{0} {9}// of an evaluated expression
|
||||
{0} {8}(* Example:
|
||||
(*
|
||||
printArgs <@ 1 + 2 @> ;;
|
||||
// 1
|
||||
@ -42,5 +42,5 @@
|
||||
printArgs constExpr ;;
|
||||
*)
|
||||
*){0}
|
||||
{9}// Prints:{0}
|
||||
{9}// "not an evaluated expression"{0}
|
||||
{9}// Prints:
|
||||
{0} {9}// "not an evaluated expression"
|
||||
|
@ -83,4 +83,4 @@
|
||||
0 400 400 let b = +0b0111_111UL-0x100UL
|
||||
0 400 400 let c = -01.0F + +001.f
|
||||
0 400 400 let d = -0x100UL - +0b0111_111UL
|
||||
1 400 400
|
||||
0 400 0
|
@ -4,8 +4,8 @@
|
||||
{1}let{0} {6}hexA{0} {12}={0} {13}+0xA1B2C3D4{0}
|
||||
{1}let{0} {6}hexB{0} {12}={0} {13}-0xCC100000{0}
|
||||
|
||||
{9}// regression checks{0}
|
||||
{1}let{0} {6}hexC{0} {12}={0} {13}0xCC100000{0}
|
||||
{9}// regression checks
|
||||
{0} {1}let{0} {6}hexC{0} {12}={0} {13}0xCC100000{0}
|
||||
{1}let{0} {6}binA{0} {12}={0} {13}+0b0000_1010{0}
|
||||
{1}let{0} {6}binB{0} {12}={0} {13}-0b1010_0000{0}
|
||||
{1}let{0} {6}binC{0} {12}={0} {13}0b1010_0000{0}
|
||||
@ -22,8 +22,8 @@
|
||||
{1}let{0} {6}f128b{0} {12}={0} {13}-0.001m{0}
|
||||
{1}let{0} {6}f128c{0} {12}={0} {13}0.001m{0}
|
||||
|
||||
{9}// invalid literals{0}
|
||||
{1}let{0} {6}hexD{0} {12}={0} {13}0xa0bcde0{0}o
|
||||
{9}// invalid literals
|
||||
{0} {1}let{0} {6}hexD{0} {12}={0} {13}0xa0bcde0{0}o
|
||||
{1}let{0} {6}hexE{0} {12}={0} {13}+0xa0bcd0{0}o
|
||||
{1}let{0} {6}hexF{0} {12}={0} {13}-0xa0bcd0{0}o
|
||||
{1}let{0} {6}binD{0} {12}={0} {13}0b1010_1110{0}x{6}f000{0}
|
||||
@ -40,8 +40,8 @@
|
||||
{1}let{0} {6}octI{0} {12}={0} {13}0o3330{0}b
|
||||
|
||||
{1}module{0} {6}Issue111{0} {12}={0}
|
||||
{9}// invalid literals{0}
|
||||
{1}let{0} {6}a{0} {12}={0} {13}0000_123{0}a{6}bc{0}
|
||||
{9}// invalid literals
|
||||
{0} {1}let{0} {6}a{0} {12}={0} {13}0000_123{0}a{6}bc{0}
|
||||
{1}let{0} {6}b{0} {12}={0} {13}+000_123{0}a{6}bc{0}
|
||||
{1}let{0} {6}c{0} {12}={0} {13}-0001_23{0}a{6}bc{0}
|
||||
{1}let{0} {6}d{0} {12}={0} {13}00123_000{0}b
|
||||
@ -64,8 +64,8 @@
|
||||
{1}let{0} {6}f128b{0} {12}={0} {13}+01.0M{0}
|
||||
{1}let{0} {6}f128c{0} {12}={0} {13}-01.00000M{0}
|
||||
|
||||
{9}// regression checks{0}
|
||||
{1}let{0} {6}i32{0} {12}={0} {13}-0001l{0}
|
||||
{9}// regression checks
|
||||
{0} {1}let{0} {6}i32{0} {12}={0} {13}-0001l{0}
|
||||
{1}let{0} {6}u32{0} {12}={0} {13}+001ul{0}
|
||||
{1}let{0} {6}i128{0} {12}={0} {13}9999999999999999999999999999I{0}
|
||||
{1}let{0} {6}f32g{0} {12}={0} {13}001.f{0}
|
||||
@ -78,8 +78,8 @@
|
||||
{1}let{0} {6}f128e{0} {12}={0} {13}+01.0m{0}
|
||||
{1}let{0} {6}f128f{0} {12}={0} {13}-01.00000m{0}
|
||||
|
||||
{9}// arithmetic expressions{0}
|
||||
{1}let{0} {6}a{0} {12}={0} {13}-001.f{12}+{13}01.0F{0}
|
||||
{9}// arithmetic expressions
|
||||
{0} {1}let{0} {6}a{0} {12}={0} {13}-001.f{12}+{13}01.0F{0}
|
||||
{1}let{0} {6}b{0} {12}={0} {13}+0b0111_111UL{12}-{13}0x100UL{0}
|
||||
{1}let{0} {6}c{0} {12}={0} {13}-01.0F{0} {12}+{0} {13}+001.f{0}
|
||||
{1}let{0} {6}d{0} {12}={0} {13}-0x100UL{0} {12}-{0} {13}+0b0111_111UL{0}
|
||||
|
@ -40,3 +40,4 @@ uint uint8 uint16 uint32 uint64 unit void voidptr voption
|
||||
|
||||
fold.fsharp.preprocessor=1
|
||||
fold.comment=1
|
||||
|
||||
|
@ -51,4 +51,4 @@
|
||||
0 400 400 unescapeWinPath "\\\"Program Files (x86)\\Windows NT\\Accessories\\\""
|
||||
0 400 400 |> System.IO.Directory.GetFiles
|
||||
0 400 400 |> printfn "%A"
|
||||
1 400 400
|
||||
0 400 0
|
@ -1,6 +1,6 @@
|
||||
{9}// x.fs{0}
|
||||
{9}// Sample source file to test F# syntax highlighting{0}
|
||||
|
||||
{9}// x.fs
|
||||
// Sample source file to test F# syntax highlighting
|
||||
{0}
|
||||
{18}[<AutoOpen>]{0}
|
||||
{1}module{0} {6}Example{0}
|
||||
|
||||
@ -12,10 +12,10 @@
|
||||
{10}#endif{0}
|
||||
|
||||
{11}# 14 @"See: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/strings#remarks"{0}
|
||||
{9}// verbatim string{0}
|
||||
{9}// verbatim string
|
||||
{1}let{0} {6}xmlFragment1{0} {12}={0} {16}@"<book href=""https://www.worldcat.org/title/paradise-lost/oclc/1083714070"" title=""Paradise Lost"">"{0}
|
||||
|
||||
{9}// triple-quoted string{0}
|
||||
{9}// triple-quoted string
|
||||
{1}let{0} {6}xmlFragment2{0} {12}={0} {15}"""<book href="https://www.worldcat.org/title/paradise-lost/oclc/1083714070" title="Paradise Lost">"""{0}
|
||||
|
||||
{8}(* you need .NET 5.0 to compile this:
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
{1}let{0} {7}``a byte literal``{0} {12}={0} {14}'\209'B{0}
|
||||
|
||||
{9}// quoted expression{0}
|
||||
{9}// quoted expression
|
||||
{1}let{0} {6}expr{0} {12}={0}
|
||||
{17}<@@
|
||||
let foo () = "bar"
|
||||
@ -44,7 +44,7 @@
|
||||
{12}|{0} {3}None{0} {12}->{0} {2}sprintf{0} {15}"{19}%A{15}"{0} {15}"Have a byte string!"B{0}
|
||||
{12}|>{0} {2}printfn{0} {15}"{19}%s{15}"{0}
|
||||
|
||||
{9}// GitHub Issue #38{0}
|
||||
{9}// GitHub Issue #38
|
||||
{1}let{0} {6}unescapeWinPath{0} {12}({6}path{12}:{0} {3}string{12}){0} {12}={0}
|
||||
{6}path{0}.{6}Replace{12}({15}"\\\\"{12},{0} {15}"\\"{12}){0}.{6}Replace{12}({15}"\""{12},{0} {15}""{12}){0}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{21}<!{26}DOCTYPE html{21}>{0}
|
||||
{21}<!{22}DOCTYPE{21} {23}html{21}>{0}
|
||||
{1}<html>{0}
|
||||
{1}<script>{40}
|
||||
{41} {47}var{41} {46}example{41} {50}={41} {48}"<!-- -->"{50};{41} {43}// closing "-->" is string{41}
|
||||
|
@ -6,7 +6,7 @@
|
||||
{18}?>{0}
|
||||
|
||||
{9}<!-- Short echo tag: enabled -->{0}
|
||||
{18}<?{127}={118} {120}'echo'{118} {18}?>{0}
|
||||
{18}<?={118} {120}'echo'{118} {18}?>{0}
|
||||
|
||||
{9}<!-- Short tag: disabled -->{0}
|
||||
{2}<?
|
||||
|
8
lexilla/test/examples/hypertext/Issue272SGML.xml
Normal file
8
lexilla/test/examples/hypertext/Issue272SGML.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE root [
|
||||
<!ELEMENT root (p)>
|
||||
<!ELEMENT p (#PCDATA)>
|
||||
<!-- Example 1 from XML spec 1.0 Appendix D -->
|
||||
<!ENTITY example "<p>An ampersand (&#38;) may be escaped
|
||||
numerically (&#38;#38) or with a general entity (&amp;).</p>" >
|
||||
]>
|
||||
<root>&example;</root>
|
9
lexilla/test/examples/hypertext/Issue272SGML.xml.folded
Normal file
9
lexilla/test/examples/hypertext/Issue272SGML.xml.folded
Normal file
@ -0,0 +1,9 @@
|
||||
2 400 0 + <!DOCTYPE root [
|
||||
0 401 0 | <!ELEMENT root (p)>
|
||||
0 401 0 | <!ELEMENT p (#PCDATA)>
|
||||
0 401 0 | <!-- Example 1 from XML spec 1.0 Appendix D -->
|
||||
2 401 0 + <!ENTITY example "<p>An ampersand (&#38;) may be escaped
|
||||
0 402 0 | numerically (&#38;#38) or with a general entity (&amp;).</p>" >
|
||||
0 401 0 | ]>
|
||||
0 400 0 <root>&example;</root>
|
||||
0 400 0
|
8
lexilla/test/examples/hypertext/Issue272SGML.xml.styled
Normal file
8
lexilla/test/examples/hypertext/Issue272SGML.xml.styled
Normal file
@ -0,0 +1,8 @@
|
||||
{21}<!{22}DOCTYPE{21} {23}root{21} [{31}
|
||||
{21}<!{22}ELEMENT{21} {23}root{21} (p)>{31}
|
||||
{21}<!{22}ELEMENT{21} {23}p{21} ({27}#PCDATA{21})>{31}
|
||||
{21}<!{29}-- Example 1 from XML spec 1.0 Appendix D --{21}>{31}
|
||||
{21}<!{22}ENTITY{21} {23}example{21} {24}"<p>An ampersand (&#38;) may be escaped
|
||||
numerically (&#38;#38) or with a general entity (&amp;).</p>"{21} >{31}
|
||||
{21}]>{0}
|
||||
{2}<root>{10}&example;{2}</root>{0}
|
17
lexilla/test/examples/hypertext/Issue273JavaScript.html
Normal file
17
lexilla/test/examples/hypertext/Issue273JavaScript.html
Normal file
@ -0,0 +1,17 @@
|
||||
<script>
|
||||
var pi/*/=3.1415/*/=3.14;
|
||||
/*
|
||||
<?xml>
|
||||
<!doctype>
|
||||
*/
|
||||
/**
|
||||
<?xml>
|
||||
<!doctype>
|
||||
*/
|
||||
var template = `
|
||||
<?xml encoding='${encoding}'>
|
||||
<!doctype>
|
||||
`;
|
||||
/<?xml>/.test('<?xml>');
|
||||
/<!doctype>/.test("<!doctype>");
|
||||
</script>
|
@ -0,0 +1,18 @@
|
||||
2 400 0 + <script>
|
||||
0 401 0 | var pi/*/=3.1415/*/=3.14;
|
||||
0 401 0 | /*
|
||||
0 401 0 | <?xml>
|
||||
0 401 0 | <!doctype>
|
||||
0 401 0 | */
|
||||
0 401 0 | /**
|
||||
0 401 0 | <?xml>
|
||||
0 401 0 | <!doctype>
|
||||
0 401 0 | */
|
||||
0 401 0 | var template = `
|
||||
0 401 0 | <?xml encoding='${encoding}'>
|
||||
0 401 0 | <!doctype>
|
||||
0 401 0 | `;
|
||||
0 401 0 | /<?xml>/.test('<?xml>');
|
||||
0 401 0 | /<!doctype>/.test("<!doctype>");
|
||||
0 401 0 | </script>
|
||||
0 400 0
|
@ -0,0 +1,17 @@
|
||||
{1}<script>{40}
|
||||
{47}var{41} {46}pi{42}/*/=3.1415/*/{50}={45}3.14{50};{41}
|
||||
{42}/*
|
||||
<?xml>
|
||||
<!doctype>
|
||||
*/{41}
|
||||
{44}/**
|
||||
<?xml>
|
||||
<!doctype>
|
||||
*/{41}
|
||||
{47}var{41} {46}template{41} {50}={41} {53}`
|
||||
<?xml encoding='${encoding}'>
|
||||
<!doctype>
|
||||
`{50};{41}
|
||||
{52}/<?xml>/{50}.{46}test{50}({49}'<?xml>'{50});{41}
|
||||
{52}/<!doctype>/{50}.{46}test{50}({48}"<!doctype>"{50});{41}
|
||||
{1}</script>{0}
|
@ -11,7 +11,7 @@ keywords4.*=import pass
|
||||
# PHP
|
||||
keywords5.*=echo __file__ __line__
|
||||
# SGML
|
||||
keywords6.*=ELEMENT
|
||||
keywords6.*=DOCTYPE ELEMENT ENTITY NOTATION
|
||||
|
||||
# Tag
|
||||
substyles.hypertext.1=1
|
||||
@ -40,6 +40,9 @@ fold.html=1
|
||||
fold.html.preprocessor=1
|
||||
fold.hypertext.comment=1
|
||||
|
||||
match Issue273JavaScript.html
|
||||
fold.hypertext.comment=0
|
||||
|
||||
match mako.html
|
||||
lexer.html.mako=1
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{15}<%@{16} register tagprefix="uc1"
|
||||
tagname="CalendarUserControl"
|
||||
src="~/CalendarUserControl.ascx" {15}%>{0}
|
||||
{21}<!{26}DOCTYPE html{21}>{0}
|
||||
{21}<!{22}DOCTYPE{21} {23}html{21}>{0}
|
||||
{1}<html>{0}
|
||||
{15}<%@{16}language=VBScript{15}%>{0}
|
||||
{15}<%--{20} comment --{15}%>{0}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{21}<!{26}DOCTYPE html{21}>{0}
|
||||
{21}<!{22}DOCTYPE{21} {23}html{21}>{0}
|
||||
{1}<html>{0}
|
||||
{15}<%@{16}language=JScript{15}%>{0}
|
||||
{15}<%--{20} comment --{15}%>{0}
|
||||
|
@ -6,11 +6,11 @@
|
||||
{124}/* ?> */{118}
|
||||
{18}?>{0}
|
||||
{1}<strong>{0}for{1}</strong><b>{0}if{1}</b>{0}
|
||||
{18}<?{127}={118} {120}'short echo tag'{118} {18}?>{0}
|
||||
{18}<?={118} {120}'short echo tag'{118} {18}?>{0}
|
||||
{18}<?{118} {121}echo{118} {120}'short tag'{118} {18}?>{0}
|
||||
{1}<script>{40}
|
||||
{41} {46}alert{50}({48}"{18}<?php{118} {121}echo{118} {119}"PHP"{118} {127}.{118} {120}' Code'{127};{118} {18}?>{48}"{50});{41}
|
||||
{46}alert{50}({49}'{18}<?{127}={118} {120}'PHP'{118} {127}.{118} {119}"Code"{127};{118} {18}?>{49}'{50});{41}
|
||||
{46}alert{50}({49}'{18}<?={118} {120}'PHP'{118} {127}.{118} {119}"Code"{127};{118} {18}?>{49}'{50});{41}
|
||||
{47}var{41} {46}xml{41} {50}={41}
|
||||
{49}'<?xml version="1.0" encoding="iso-8859-1"?><SO_GL>'{41} {50}+{41}
|
||||
{49}'<GLOBAL_LIST mode="complete"><NAME>SO_SINGLE_MULTIPLE_COMMAND_BUILDER</NAME>'{41} {50}+{41}
|
||||
|
@ -2,3 +2,4 @@ lexer.*.jl=julia
|
||||
keywords.*.jl=const end for function in where
|
||||
keywords2.*.jl=Int Number
|
||||
keywords3.*.jl=true
|
||||
testlexers.per.line.disable=1
|
||||
|
52
lexilla/test/examples/smalltalk/ClassificationTable.st
Normal file
52
lexilla/test/examples/smalltalk/ClassificationTable.st
Normal file
@ -0,0 +1,52 @@
|
||||
" File contains examples of all SCE_ST_* lexical states 0-16 "
|
||||
" Smalltalk code from the lexer that generates the character classification table."
|
||||
| lexTable classificationBlock charClasses |
|
||||
charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
|
||||
lexTable := ByteArray new: 128.
|
||||
classificationBlock := [ :charClass :chars |
|
||||
| flag |
|
||||
flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
|
||||
chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
|
||||
|
||||
classificationBlock
|
||||
value: #DecDigit value: '0123456789';
|
||||
value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
value: #Special value: '()[]{};.^:';
|
||||
value: #BinSel value: '~@%&*-+=|\/,<>?!';
|
||||
value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
|
||||
|
||||
((String new: 500) streamContents: [ :stream |
|
||||
stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
|
||||
lexTable keysAndValuesDo: [ :index :value |
|
||||
((index - 1) rem: 16) == 0 ifTrue: [
|
||||
stream crLf; tab]
|
||||
ifFalse: [
|
||||
stream space].
|
||||
stream print: value.
|
||||
index ~= 256 ifTrue: [
|
||||
stream nextPut: $,]].
|
||||
stream crLf; nextPutAll: '};'; crLf.
|
||||
|
||||
charClasses keysAndValuesDo: [ :index :name |
|
||||
stream
|
||||
crLf;
|
||||
nextPutAll: (
|
||||
('static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
|
||||
expandMacrosWith: name with: (1 bitShift: (index - 1)))
|
||||
]]) edit
|
||||
|
||||
" Some more syntax examples:
|
||||
^ is return (SCE_ST_RETURN)
|
||||
true or false is bool (SCE_ST_BOOL)
|
||||
self (SCE_ST_SELF)
|
||||
super (SCE_ST_SUPER)
|
||||
nil (SCE_ST_NIL)
|
||||
"
|
||||
foo
|
||||
^ Array with: 1 with: 2 with: false with: self with: super with: nil.
|
||||
|
||||
" Issue 274: A decimal separator is not required for scaled decimal numbers"
|
||||
32.0s2
|
||||
4.0e3
|
||||
32s2
|
||||
4e3
|
@ -0,0 +1,53 @@
|
||||
0 400 0 " File contains examples of all SCE_ST_* lexical states 0-16 "
|
||||
0 400 0 " Smalltalk code from the lexer that generates the character classification table."
|
||||
0 400 0 | lexTable classificationBlock charClasses |
|
||||
0 400 0 charClasses := #(#DecDigit #Letter #Special #Upper #BinSel).
|
||||
0 400 0 lexTable := ByteArray new: 128.
|
||||
0 400 0 classificationBlock := [ :charClass :chars |
|
||||
0 400 0 | flag |
|
||||
0 400 0 flag := 1 bitShift: (charClasses indexOf: charClass) - 1.
|
||||
0 400 0 chars do: [ :char | lexTable at: char codePoint + 1 put: ((lexTable at: char codePoint + 1) bitOr: flag)]].
|
||||
0 400 0
|
||||
0 400 0 classificationBlock
|
||||
0 400 0 value: #DecDigit value: '0123456789';
|
||||
0 400 0 value: #Letter value: '_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
0 400 0 value: #Special value: '()[]{};.^:';
|
||||
0 400 0 value: #BinSel value: '~@%&*-+=|\/,<>?!';
|
||||
0 400 0 value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
|
||||
0 400 0
|
||||
0 400 0 ((String new: 500) streamContents: [ :stream |
|
||||
0 400 0 stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
|
||||
0 400 0 lexTable keysAndValuesDo: [ :index :value |
|
||||
0 400 0 ((index - 1) rem: 16) == 0 ifTrue: [
|
||||
0 400 0 stream crLf; tab]
|
||||
0 400 0 ifFalse: [
|
||||
0 400 0 stream space].
|
||||
0 400 0 stream print: value.
|
||||
0 400 0 index ~= 256 ifTrue: [
|
||||
0 400 0 stream nextPut: $,]].
|
||||
0 400 0 stream crLf; nextPutAll: '};'; crLf.
|
||||
0 400 0
|
||||
0 400 0 charClasses keysAndValuesDo: [ :index :name |
|
||||
0 400 0 stream
|
||||
0 400 0 crLf;
|
||||
0 400 0 nextPutAll: (
|
||||
0 400 0 ('static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}')
|
||||
0 400 0 expandMacrosWith: name with: (1 bitShift: (index - 1)))
|
||||
0 400 0 ]]) edit
|
||||
0 400 0
|
||||
0 400 0 " Some more syntax examples:
|
||||
0 400 0 ^ is return (SCE_ST_RETURN)
|
||||
0 400 0 true or false is bool (SCE_ST_BOOL)
|
||||
0 400 0 self (SCE_ST_SELF)
|
||||
0 400 0 super (SCE_ST_SUPER)
|
||||
0 400 0 nil (SCE_ST_NIL)
|
||||
0 400 0 "
|
||||
0 400 0 foo
|
||||
0 400 0 ^ Array with: 1 with: 2 with: false with: self with: super with: nil.
|
||||
0 400 0
|
||||
0 400 0 " Issue 274: A decimal separator is not required for scaled decimal numbers"
|
||||
0 400 0 32.0s2
|
||||
0 400 0 4.0e3
|
||||
0 400 0 32s2
|
||||
0 400 0 4e3
|
||||
0 400 0
|
@ -0,0 +1,52 @@
|
||||
{3}" File contains examples of all SCE_ST_* lexical states 0-16 "{0}
|
||||
{3}" Smalltalk code from the lexer that generates the character classification table."{0}
|
||||
{5}|{0} lexTable classificationBlock charClasses {5}|{0}
|
||||
charClasses {14}:={0} {12}#({4}#DecDigit{0} {4}#Letter{0} {4}#Special{0} {4}#Upper{0} {4}#BinSel{12}).{0}
|
||||
lexTable {14}:={0} {10}ByteArray{0} {13}new:{0} {2}128{12}.{0}
|
||||
classificationBlock {14}:={0} {12}[{0} {12}:{0}charClass {12}:{0}chars {5}|{0}
|
||||
{5}|{0} flag {5}|{0}
|
||||
flag {14}:={0} {2}1{0} {13}bitShift:{0} {12}({0}charClasses {13}indexOf:{0} charClass{12}){0} {5}-{0} {2}1{12}.{0}
|
||||
chars {13}do:{0} {12}[{0} {12}:{0}char {5}|{0} lexTable {13}at:{0} char codePoint {5}+{0} {2}1{0} {13}put:{0} {12}(({0}lexTable {13}at:{0} char codePoint {5}+{0} {2}1{12}){0} {13}bitOr:{0} flag{12})]].{0}
|
||||
|
||||
classificationBlock
|
||||
{13}value:{0} {4}#DecDigit{0} {13}value:{0} {1}'0123456789'{12};{0}
|
||||
{13}value:{0} {4}#Letter{0} {13}value:{0} {1}'_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'{12};{0}
|
||||
{13}value:{0} {4}#Special{0} {13}value:{0} {1}'()[]{};.^:'{12};{0}
|
||||
{13}value:{0} {4}#BinSel{0} {13}value:{0} {1}'~@%&*-+=|\/,<>?!'{12};{0}
|
||||
{13}value:{0} {4}#Upper{0} {13}value:{0} {1}'ABCDEFGHIJKLMNOPQRSTUVWXYZ'{12}.{0}
|
||||
|
||||
{12}(({10}String{0} {13}new:{0} {2}500{12}){0} {13}streamContents:{0} {12}[{0} {12}:{0}stream {5}|{0}
|
||||
stream crLf{12};{0} {13}nextPutAll:{0} {1}'static int ClassificationTable[256] = {'{12}.{0}
|
||||
lexTable {13}keysAndValuesDo:{0} {12}[{0} {12}:{0}index {12}:{0}value {5}|{0}
|
||||
{12}(({0}index {5}-{0} {2}1{12}){0} {13}rem:{0} {2}16{12}){0} {5}=={0} {2}0{0} {16}ifTrue:{0} {12}[{0}
|
||||
stream crLf{12};{0} tab{12}]{0}
|
||||
{16}ifFalse:{0} {12}[{0}
|
||||
stream space{12}].{0}
|
||||
stream {13}print:{0} value{12}.{0}
|
||||
index {5}~={0} {2}256{0} {16}ifTrue:{0} {12}[{0}
|
||||
stream {13}nextPut:{0} {15}$,{12}]].{0}
|
||||
stream crLf{12};{0} {13}nextPutAll:{0} {1}'};'{12};{0} crLf{12}.{0}
|
||||
|
||||
charClasses {13}keysAndValuesDo:{0} {12}[{0} {12}:{0}index {12}:{0}name {5}|{0}
|
||||
stream
|
||||
crLf{12};{0}
|
||||
{13}nextPutAll:{0} {12}({0}
|
||||
{12}({1}'static inline bool is<1s>(unsigned char ch) {return (ch %< 0x80) && ((ClassificationTable[ch] & <2p>) != 0);}'{12}){0}
|
||||
{13}expandMacrosWith:{0} name {13}with:{0} {12}({2}1{0} {13}bitShift:{0} {12}({0}index {5}-{0} {2}1{12}))){0}
|
||||
{12}]]){0} edit
|
||||
|
||||
{3}" Some more syntax examples:
|
||||
^ is return (SCE_ST_RETURN)
|
||||
true or false is bool (SCE_ST_BOOL)
|
||||
self (SCE_ST_SELF)
|
||||
super (SCE_ST_SUPER)
|
||||
nil (SCE_ST_NIL)
|
||||
"{0}
|
||||
foo
|
||||
{11}^{0} {10}Array{0} {13}with:{0} {2}1{0} {13}with:{0} {2}2{0} {13}with:{0} {6}false{0} {13}with:{0} {7}self{0} {13}with:{0} {8}super{0} {13}with:{0} {9}nil{12}.{0}
|
||||
|
||||
{3}" Issue 274: A decimal separator is not required for scaled decimal numbers"{0}
|
||||
{2}32.0s2{0}
|
||||
{2}4.0e3{0}
|
||||
{2}32s2{0}
|
||||
{2}4e3{0}
|
2
lexilla/test/examples/smalltalk/SciTE.properties
Normal file
2
lexilla/test/examples/smalltalk/SciTE.properties
Normal file
@ -0,0 +1,2 @@
|
||||
lexer.*.st=smalltalk
|
||||
keywords.*.st=ifTrue: ifFalse: whileTrue: whileFalse: ifNil: ifNotNil: whileTrue whileFalse repeat isNil notNil
|
@ -1,3 +1,4 @@
|
||||
# coding:utf-8
|
||||
# This is a full-line comment
|
||||
key = "value" # This is a comment at the end of a line
|
||||
another = "# This is not a comment"
|
||||
|
@ -1,4 +1,5 @@
|
||||
0 400 0 # This is a full-line comment
|
||||
2 400 0 + # coding:utf-8
|
||||
0 401 0 | # This is a full-line comment
|
||||
0 400 0 key = "value" # This is a comment at the end of a line
|
||||
0 400 0 another = "# This is not a comment"
|
||||
0 400 0
|
||||
|
@ -1,4 +1,5 @@
|
||||
{1}# This is a full-line comment
|
||||
{1}# coding:utf-8
|
||||
# This is a full-line comment
|
||||
{6}key{0} {8}={0} {10}"value"{0} {1}# This is a comment at the end of a line
|
||||
{6}another{0} {8}={0} {10}"# This is not a comment"{0}
|
||||
|
||||
|
52
lexilla/test/examples/troff/AllStyles.roff
Normal file
52
lexilla/test/examples/troff/AllStyles.roff
Normal file
@ -0,0 +1,52 @@
|
||||
.tm Hello world "FOO"
|
||||
.if 'foo'b a r' .if 23 .FOO 2332 "hell\fBo\fP" \
|
||||
foo "Hello world"
|
||||
.if (1 + 1) .nop
|
||||
.if 1 \
|
||||
.tm Bar
|
||||
.if 23+1 \
|
||||
.tm Bar
|
||||
.if 1 \{\
|
||||
. tm TEST
|
||||
. tm FOO
|
||||
.\}
|
||||
.
|
||||
.\" Hello world
|
||||
.if 0 \{\
|
||||
. tm Bar
|
||||
. tm sffsdf\}
|
||||
\# Hello world
|
||||
.tm End
|
||||
.ig ig
|
||||
This is \fBignored\fP.
|
||||
|
||||
This line as well.
|
||||
.ig
|
||||
.tm Hello world
|
||||
..
|
||||
.
|
||||
.de Macro END
|
||||
. FOO
|
||||
.END
|
||||
\*[FOO*\[hello]fdsf]sdfsdf
|
||||
.END
|
||||
\$1 \" will never be met in the wild...
|
||||
\f[BI]Hello world\fP
|
||||
\na-\n(ab-\n[ab]-
|
||||
\m[green]green text\m[]
|
||||
\(lqquoted text\(rq
|
||||
$PATH=\V[PATH]
|
||||
\O0test
|
||||
\s0small\s+1larger\s+[100]very large\s-'100'smaller
|
||||
\!transparent \fBline\fP
|
||||
transparent\?embed\?
|
||||
\A'id'
|
||||
\D'c 10' \l'10c' \L'10c'
|
||||
\h'12c' \v'4'
|
||||
\H@23@
|
||||
\o#abc#
|
||||
\S'45'
|
||||
\w'width of'
|
||||
\x'1'
|
||||
\X'device control' \Y[foo]
|
||||
\Z"No move" \zN
|
53
lexilla/test/examples/troff/AllStyles.roff.folded
Normal file
53
lexilla/test/examples/troff/AllStyles.roff.folded
Normal file
@ -0,0 +1,53 @@
|
||||
0 400 0 .tm Hello world "FOO"
|
||||
0 400 0 .if 'foo'b a r' .if 23 .FOO 2332 "hell\fBo\fP" \
|
||||
0 400 0 foo "Hello world"
|
||||
0 400 0 .if (1 + 1) .nop
|
||||
0 400 0 .if 1 \
|
||||
0 400 0 .tm Bar
|
||||
0 400 0 .if 23+1 \
|
||||
0 400 0 .tm Bar
|
||||
2 400 0 + .if 1 \{\
|
||||
0 401 0 | . tm TEST
|
||||
0 401 0 | . tm FOO
|
||||
0 401 0 | .\}
|
||||
1 400 0 .
|
||||
0 400 0 .\" Hello world
|
||||
2 400 0 + .if 0 \{\
|
||||
0 401 0 | . tm Bar
|
||||
0 401 0 | . tm sffsdf\}
|
||||
0 400 0 \# Hello world
|
||||
0 400 0 .tm End
|
||||
2 400 0 + .ig ig
|
||||
0 401 0 | This is \fBignored\fP.
|
||||
0 401 0 |
|
||||
0 401 0 | This line as well.
|
||||
2 400 0 + .ig
|
||||
0 401 0 | .tm Hello world
|
||||
0 400 0 ..
|
||||
1 400 0 .
|
||||
2 400 0 + .de Macro END
|
||||
0 401 0 | . FOO
|
||||
0 401 0 | .END
|
||||
0 400 0 \*[FOO*\[hello]fdsf]sdfsdf
|
||||
0 400 0 .END
|
||||
0 400 0 \$1 \" will never be met in the wild...
|
||||
0 400 0 \f[BI]Hello world\fP
|
||||
0 400 0 \na-\n(ab-\n[ab]-
|
||||
0 400 0 \m[green]green text\m[]
|
||||
0 400 0 \(lqquoted text\(rq
|
||||
0 400 0 $PATH=\V[PATH]
|
||||
0 400 0 \O0test
|
||||
0 400 0 \s0small\s+1larger\s+[100]very large\s-'100'smaller
|
||||
0 400 0 \!transparent \fBline\fP
|
||||
0 400 0 transparent\?embed\?
|
||||
0 400 0 \A'id'
|
||||
0 400 0 \D'c 10' \l'10c' \L'10c'
|
||||
0 400 0 \h'12c' \v'4'
|
||||
0 400 0 \H@23@
|
||||
0 400 0 \o#abc#
|
||||
0 400 0 \S'45'
|
||||
0 400 0 \w'width of'
|
||||
0 400 0 \x'1'
|
||||
0 400 0 \X'device control' \Y[foo]
|
||||
0 400 0 \Z"No move" \zN
|
||||
0 400 0
|
52
lexilla/test/examples/troff/AllStyles.roff.styled
Normal file
52
lexilla/test/examples/troff/AllStyles.roff.styled
Normal file
@ -0,0 +1,52 @@
|
||||
{1}.tm{0} Hello world "FOO"
|
||||
{1}.if{0} 'foo'b a r'{1} .if{0} {3}23{2} .FOO{0} {3}2332{0} {5}"hell{10}\fB{5}o{10}\fP{5}"{0} {13}\
|
||||
{0} foo {5}"Hello world"{0}
|
||||
{1}.if{0} ({3}1{0} + {3}1{0}){1} .nop
|
||||
.if{0} {3}1{0} {13}\
|
||||
{1} .tm{0} Bar
|
||||
{1}.if{0} {3}23{0}+{3}1{0} {13}\
|
||||
{1} .tm{0} Bar
|
||||
{1}.if{0} {3}1{0} {4}\{{13}\
|
||||
{1}. tm{0} TEST
|
||||
{1}. tm{0} FOO
|
||||
{4}.\}
|
||||
{1}.
|
||||
{6}.\" Hello world
|
||||
{1}.if{0} {3}0{0} {4}\{{13}\
|
||||
{1}. tm{0} Bar
|
||||
{1}. tm{0} sffsdf{4}\}{0}
|
||||
{6}\# Hello world
|
||||
{1}.tm{0} End
|
||||
{1}.ig {0}ig
|
||||
{7}This is \fBignored\fP.
|
||||
|
||||
This line as well.
|
||||
{1}.ig{0}
|
||||
{7}.tm Hello world
|
||||
{1}..{0}
|
||||
{1}.
|
||||
.de{0} Macro END
|
||||
{2}. FOO{0}
|
||||
{2}.END{0}
|
||||
{8}\*[FOO*\[hello]fdsf]{0}sdfsdf
|
||||
{2}.END{0}
|
||||
{9}\$1{0} {6}\" will never be met in the wild...
|
||||
{10}\f[BI]{0}Hello world{10}\fP{0}
|
||||
{11}\na{0}-{11}\n(ab{0}-{11}\n[ab]{0}-
|
||||
{12}\m[green]{0}green text{12}\m[]{0}
|
||||
{13}\(lq{0}quoted text{13}\(rq{0}
|
||||
$PATH={14}\V[PATH]{0}
|
||||
{15}\O0{0}test
|
||||
{16}\s0{0}small{16}\s+1{0}larger{16}\s+[100]{0}very large{16}\s-'100'{0}smaller
|
||||
{17}\!transparent \fBline\fP
|
||||
{0}transparent{17}\?embed\?{0}
|
||||
{18}\A'id'{0}
|
||||
{19}\D'c 10'{0} {19}\l'10c'{0} {19}\L'10c'{0}
|
||||
{20}\h'12c'{0} {20}\v'4'{0}
|
||||
{21}\H@23@{0}
|
||||
{22}\o#abc#{0}
|
||||
{23}\S'45'{0}
|
||||
{24}\w'width of'{0}
|
||||
{25}\x'1'{0}
|
||||
{26}\X'device control'{0} {26}\Y[foo]{0}
|
||||
{27}\Z"No move"{0} {27}\zN{0}
|
35
lexilla/test/examples/troff/SciTE.properties
Normal file
35
lexilla/test/examples/troff/SciTE.properties
Normal file
@ -0,0 +1,35 @@
|
||||
lexer.*.roff=troff
|
||||
|
||||
# Predefined requests
|
||||
keywords.*.roff= \
|
||||
ab ad af aln als am am1 ami ami1 as as1 asciify \
|
||||
backtrace bd blm box boxa bp br brp break \
|
||||
c2 cc ce cf cflags ch char chop class close color composite continue cp cs cu \
|
||||
da de de1 defcolor dei dei1 device devicem di do ds ds1 dt \
|
||||
ec ecr ecs el em eo ev evc ex \
|
||||
fam fc fchar fcolor fi fl fp fschar fspecial ft ftr fzoom \
|
||||
gcolor \
|
||||
hc hcode hla hlm hpf hpfa hpfcode hw hy hym hys \
|
||||
ie if ig . in it itc \
|
||||
kern \
|
||||
lc length linetabs linetabs lf lg ll lsm ls lt \
|
||||
mc mk mso \
|
||||
na ne nf nh nm nn nop nr nroff ns nx \
|
||||
open opena os output \
|
||||
pc pev pi pl pm pn pnr po ps psbb pso ptr pvs pvs \
|
||||
rchar rd return rfschar rj rm rn rnn rr rs rt \
|
||||
schar shc shift sizes so sp special spreadwarn ss sty substring sv sy \
|
||||
ta tc ti tkf tl tm tm1 tmc tr trf trin trnt troff \
|
||||
uf ul unformat \
|
||||
vpt vs \
|
||||
warn warnscale wh while write writec writem
|
||||
# Flow control requests/commands with conditionals
|
||||
keywords2.*.roff=if ie while
|
||||
# Flow control requests/commands without conditionals
|
||||
keywords3.*.roff=el nop
|
||||
# Requests and commands, initiating ignore blocks
|
||||
keywords4.*.roff=ig
|
||||
# Requests and commands with end-macros
|
||||
keywords5.*.roff=am am1 de de1
|
||||
|
||||
fold=1
|
277
lexilla/test/examples/zig/AllStyles.zig
Normal file
277
lexilla/test/examples/zig/AllStyles.zig
Normal file
@ -0,0 +1,277 @@
|
||||
// coding:utf-8
|
||||
|
||||
/// A structure for storing a timestamp, with nanosecond precision (this is a
|
||||
/// multiline doc comment).
|
||||
const Timestamp = struct {
|
||||
/// The number of seconds since the epoch (this is also a doc comment).
|
||||
seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
|
||||
/// The number of nanoseconds past the second (doc comment again).
|
||||
nanos: u32,
|
||||
|
||||
/// Returns a `Timestamp` struct representing the Unix epoch; that is, the
|
||||
/// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
|
||||
pub fn unixEpoch() Timestamp {
|
||||
return Timestamp{
|
||||
.seconds = 0,
|
||||
.nanos = 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//! This module provides functions for retrieving the current date and
|
||||
//! time with varying degrees of precision and accuracy. It does not
|
||||
//! depend on libc, but will use functions from it if available.
|
||||
|
||||
const S = struct {
|
||||
//! Top level comments are allowed inside a container other than a module,
|
||||
//! but it is not very useful. Currently, when producing the package
|
||||
//! documentation, these comments are ignored.
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Hello, {s}!\n", .{"world"});
|
||||
}
|
||||
|
||||
|
||||
// Top-level declarations are order-independent:
|
||||
const print = std.debug.print;
|
||||
const std = @import("std");
|
||||
const os = std.os;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
pub fn main() void {
|
||||
// integers
|
||||
const one_plus_one: i32 = 1 + 1;
|
||||
print("1 + 1 = {}\n", .{one_plus_one});
|
||||
|
||||
// floats
|
||||
const seven_div_three: f32 = 7.0 / 3.0;
|
||||
print("7.0 / 3.0 = {}\n", .{seven_div_three});
|
||||
|
||||
// boolean
|
||||
print("{}\n{}\n{}\n", .{
|
||||
true and false,
|
||||
true or false,
|
||||
!true,
|
||||
});
|
||||
|
||||
// optional
|
||||
var optional_value: ?[]const u8 = null;
|
||||
assert(optional_value == null);
|
||||
|
||||
print("\noptional 1\ntype: {}\nvalue: {?s}\n", .{
|
||||
@TypeOf(optional_value), optional_value,
|
||||
});
|
||||
|
||||
optional_value = "hi";
|
||||
assert(optional_value != null);
|
||||
|
||||
print("\noptional 2\ntype: {}\nvalue: {?s}\n", .{
|
||||
@TypeOf(optional_value), optional_value,
|
||||
});
|
||||
|
||||
// error union
|
||||
var number_or_error: anyerror!i32 = error.ArgNotFound;
|
||||
|
||||
print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{
|
||||
@TypeOf(number_or_error),
|
||||
number_or_error,
|
||||
});
|
||||
|
||||
number_or_error = 1234;
|
||||
|
||||
print("\nerror union 2\ntype: {}\nvalue: {!}\n", .{
|
||||
@TypeOf(number_or_error), number_or_error,
|
||||
});
|
||||
}
|
||||
|
||||
const print = @import("std").debug.print;
|
||||
const mem = @import("std").mem; // will be used to compare bytes
|
||||
|
||||
pub fn main() void {
|
||||
const bytes = "hello\u{12345678}";
|
||||
print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u8
|
||||
print("{d}\n", .{bytes.len}); // 5
|
||||
print("{c}\n", .{bytes[1]}); // 'e'
|
||||
print("{d}\n", .{bytes[5]}); // 0
|
||||
print("{}\n", .{'e' == '\x65'}); // true
|
||||
print("{d}\n", .{'\u{1f4a9}'}); // 128169
|
||||
print("{d}\n", .{'💯'}); // 128175
|
||||
print("{u}\n", .{'⚡'});
|
||||
print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true
|
||||
print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true
|
||||
const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.
|
||||
print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...
|
||||
print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters
|
||||
}
|
||||
|
||||
const hello_world_in_c =
|
||||
\\#include <stdio.h>
|
||||
\\
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ printf("hello world\n");
|
||||
\\ return 0;
|
||||
\\}
|
||||
;
|
||||
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
threadlocal var x: i32 = 1234;
|
||||
|
||||
test "thread local storage" {
|
||||
const thread1 = try std.Thread.spawn(.{}, testTls, .{});
|
||||
const thread2 = try std.Thread.spawn(.{}, testTls, .{});
|
||||
testTls();
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
|
||||
fn testTls() void {
|
||||
assert(x == 1234);
|
||||
x += 1;
|
||||
assert(x == 1235);
|
||||
}
|
||||
|
||||
const decimal_int = 98222;
|
||||
const hex_int = 0xff;
|
||||
const another_hex_int = 0xFF;
|
||||
const octal_int = 0o755;
|
||||
const binary_int = 0b11110000;
|
||||
|
||||
// underscores may be placed between two digits as a visual separator
|
||||
const one_billion = 1_000_000_000;
|
||||
const binary_mask = 0b1_1111_1111;
|
||||
const permissions = 0o7_5_5;
|
||||
const big_address = 0xFF80_0000_0000_0000;
|
||||
|
||||
|
||||
const floating_point = 123.0E+77;
|
||||
const another_float = 123.0;
|
||||
const yet_another = 123.0e+77;
|
||||
|
||||
const hex_floating_point = 0x103.70p-5;
|
||||
const another_hex_float = 0x103.70;
|
||||
const yet_another_hex_float = 0x103.70P-5;
|
||||
|
||||
// underscores may be placed between two digits as a visual separator
|
||||
const lightspeed = 299_792_458.000_000;
|
||||
const nanosecond = 0.000_000_001;
|
||||
const more_hex = 0x1234_5678.9ABC_CDEFp-10;
|
||||
|
||||
const Vec3 = struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
|
||||
pub fn init(x: f32, y: f32, z: f32) Vec3 {
|
||||
return Vec3{
|
||||
.x = x,
|
||||
.y = y,
|
||||
.z = z,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn dot(self: Vec3, other: Vec3) f32 {
|
||||
return self.x * other.x + self.y * other.y + self.z * other.z;
|
||||
}
|
||||
};
|
||||
|
||||
fn LinkedList(comptime T: type) type {
|
||||
return struct {
|
||||
pub const Node = struct {
|
||||
prev: ?*Node,
|
||||
next: ?*Node,
|
||||
data: T,
|
||||
};
|
||||
|
||||
first: ?*Node,
|
||||
last: ?*Node,
|
||||
len: usize,
|
||||
};
|
||||
}
|
||||
|
||||
const Point = struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
};
|
||||
|
||||
// Maybe we want to pass it to OpenGL so we want to be particular about
|
||||
// how the bytes are arranged.
|
||||
const Point2 = packed struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
};
|
||||
|
||||
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
const Color = enum {
|
||||
auto,
|
||||
off,
|
||||
on,
|
||||
};
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const expect = std.testing.expect;
|
||||
|
||||
test "switch simple" {
|
||||
const a: u64 = 10;
|
||||
const zz: u64 = 103;
|
||||
|
||||
// All branches of a switch expression must be able to be coerced to a
|
||||
// common type.
|
||||
//
|
||||
// Branches cannot fallthrough. If fallthrough behavior is desired, combine
|
||||
// the cases and use an if.
|
||||
const b = switch (a) {
|
||||
// Multiple cases can be combined via a ','
|
||||
1, 2, 3 => 0,
|
||||
|
||||
// Ranges can be specified using the ... syntax. These are inclusive
|
||||
// of both ends.
|
||||
5...100 => 1,
|
||||
|
||||
// Branches can be arbitrarily complex.
|
||||
101 => blk: {
|
||||
const c: u64 = 5;
|
||||
break :blk c * 2 + 1;
|
||||
},
|
||||
|
||||
// Switching on arbitrary expressions is allowed as long as the
|
||||
// expression is known at compile-time.
|
||||
zz => zz,
|
||||
blk: {
|
||||
const d: u32 = 5;
|
||||
const e: u32 = 100;
|
||||
break :blk d + e;
|
||||
} => 107,
|
||||
|
||||
// The else branch catches everything not already captured.
|
||||
// Else branches are mandatory unless the entire range of values
|
||||
// is handled.
|
||||
else => 9,
|
||||
};
|
||||
|
||||
try expect(b == 1);
|
||||
}
|
||||
|
||||
fn charToDigit(c: u8) u8 {
|
||||
return switch (c) {
|
||||
'0'...'9' => c - '0',
|
||||
'A'...'Z' => c - 'A' + 10,
|
||||
'a'...'z' => c - 'a' + 10,
|
||||
else => maxInt(u8),
|
||||
};
|
||||
}
|
||||
|
||||
const optional_value: ?i32 = null;
|
||||
|
||||
//! This module provides functions for retrieving the current date and
|
||||
//! time with varying degrees of precision and accuracy. It does not
|
||||
//! depend on libc, but will use functions from it if available.
|
278
lexilla/test/examples/zig/AllStyles.zig.folded
Normal file
278
lexilla/test/examples/zig/AllStyles.zig.folded
Normal file
@ -0,0 +1,278 @@
|
||||
0 400 400 // coding:utf-8
|
||||
0 400 400
|
||||
2 400 401 + /// A structure for storing a timestamp, with nanosecond precision (this is a
|
||||
0 401 400 | /// multiline doc comment).
|
||||
2 400 401 + const Timestamp = struct {
|
||||
0 401 401 | /// The number of seconds since the epoch (this is also a doc comment).
|
||||
0 401 401 | seconds: i64, // signed so we can represent pre-1970 (not a doc comment)
|
||||
0 401 401 | /// The number of nanoseconds past the second (doc comment again).
|
||||
0 401 401 | nanos: u32,
|
||||
0 401 401 |
|
||||
2 401 402 + /// Returns a `Timestamp` struct representing the Unix epoch; that is, the
|
||||
0 402 401 | /// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
|
||||
2 401 402 + pub fn unixEpoch() Timestamp {
|
||||
2 402 403 + return Timestamp{
|
||||
0 403 403 | .seconds = 0,
|
||||
0 403 403 | .nanos = 0,
|
||||
0 403 402 | };
|
||||
0 402 401 | }
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
2 400 401 + //! This module provides functions for retrieving the current date and
|
||||
0 401 401 | //! time with varying degrees of precision and accuracy. It does not
|
||||
0 401 400 | //! depend on libc, but will use functions from it if available.
|
||||
0 400 400
|
||||
2 400 401 + const S = struct {
|
||||
2 401 402 + //! Top level comments are allowed inside a container other than a module,
|
||||
0 402 402 | //! but it is not very useful. Currently, when producing the package
|
||||
0 402 401 | //! documentation, these comments are ignored.
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
0 400 400 const std = @import("std");
|
||||
0 400 400
|
||||
2 400 401 + pub fn main() !void {
|
||||
0 401 401 | const stdout = std.io.getStdOut().writer();
|
||||
0 401 401 | try stdout.print("Hello, {s}!\n", .{"world"});
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400
|
||||
0 400 400 // Top-level declarations are order-independent:
|
||||
0 400 400 const print = std.debug.print;
|
||||
0 400 400 const std = @import("std");
|
||||
0 400 400 const os = std.os;
|
||||
0 400 400 const assert = std.debug.assert;
|
||||
0 400 400
|
||||
2 400 401 + pub fn main() void {
|
||||
0 401 401 | // integers
|
||||
0 401 401 | const one_plus_one: i32 = 1 + 1;
|
||||
0 401 401 | print("1 + 1 = {}\n", .{one_plus_one});
|
||||
0 401 401 |
|
||||
0 401 401 | // floats
|
||||
0 401 401 | const seven_div_three: f32 = 7.0 / 3.0;
|
||||
0 401 401 | print("7.0 / 3.0 = {}\n", .{seven_div_three});
|
||||
0 401 401 |
|
||||
0 401 401 | // boolean
|
||||
2 401 403 + print("{}\n{}\n{}\n", .{
|
||||
0 403 403 | true and false,
|
||||
0 403 403 | true or false,
|
||||
0 403 403 | !true,
|
||||
0 403 401 | });
|
||||
0 401 401 |
|
||||
0 401 401 | // optional
|
||||
0 401 401 | var optional_value: ?[]const u8 = null;
|
||||
0 401 401 | assert(optional_value == null);
|
||||
0 401 401 |
|
||||
2 401 403 + print("\noptional 1\ntype: {}\nvalue: {?s}\n", .{
|
||||
0 403 403 | @TypeOf(optional_value), optional_value,
|
||||
0 403 401 | });
|
||||
0 401 401 |
|
||||
0 401 401 | optional_value = "hi";
|
||||
0 401 401 | assert(optional_value != null);
|
||||
0 401 401 |
|
||||
2 401 403 + print("\noptional 2\ntype: {}\nvalue: {?s}\n", .{
|
||||
0 403 403 | @TypeOf(optional_value), optional_value,
|
||||
0 403 401 | });
|
||||
0 401 401 |
|
||||
0 401 401 | // error union
|
||||
0 401 401 | var number_or_error: anyerror!i32 = error.ArgNotFound;
|
||||
0 401 401 |
|
||||
2 401 403 + print("\nerror union 1\ntype: {}\nvalue: {!}\n", .{
|
||||
0 403 403 | @TypeOf(number_or_error),
|
||||
0 403 403 | number_or_error,
|
||||
0 403 401 | });
|
||||
0 401 401 |
|
||||
0 401 401 | number_or_error = 1234;
|
||||
0 401 401 |
|
||||
2 401 403 + print("\nerror union 2\ntype: {}\nvalue: {!}\n", .{
|
||||
0 403 403 | @TypeOf(number_or_error), number_or_error,
|
||||
0 403 401 | });
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 const print = @import("std").debug.print;
|
||||
0 400 400 const mem = @import("std").mem; // will be used to compare bytes
|
||||
0 400 400
|
||||
2 400 401 + pub fn main() void {
|
||||
0 401 401 | const bytes = "hello\u{12345678}";
|
||||
0 401 401 | print("{}\n", .{@TypeOf(bytes)}); // *const [5:0]u8
|
||||
0 401 401 | print("{d}\n", .{bytes.len}); // 5
|
||||
0 401 401 | print("{c}\n", .{bytes[1]}); // 'e'
|
||||
0 401 401 | print("{d}\n", .{bytes[5]}); // 0
|
||||
0 401 401 | print("{}\n", .{'e' == '\x65'}); // true
|
||||
0 401 401 | print("{d}\n", .{'\u{1f4a9}'}); // 128169
|
||||
0 401 401 | print("{d}\n", .{'💯'}); // 128175
|
||||
0 401 401 | print("{u}\n", .{'⚡'});
|
||||
0 401 401 | print("{}\n", .{mem.eql(u8, "hello", "h\x65llo")}); // true
|
||||
0 401 401 | print("{}\n", .{mem.eql(u8, "💯", "\xf0\x9f\x92\xaf")}); // also true
|
||||
0 401 401 | const invalid_utf8 = "\xff\xfe"; // non-UTF-8 strings are possible with \xNN notation.
|
||||
0 401 401 | print("0x{x}\n", .{invalid_utf8[1]}); // indexing them returns individual bytes...
|
||||
0 401 401 | print("0x{x}\n", .{"💯"[1]}); // ...as does indexing part-way through non-ASCII characters
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 const hello_world_in_c =
|
||||
2 400 401 + \\#include <stdio.h>
|
||||
0 401 401 | \\
|
||||
0 401 401 | \\int main(int argc, char **argv) {
|
||||
0 401 401 | \\ printf("hello world\n");
|
||||
0 401 401 | \\ return 0;
|
||||
0 401 400 | \\}
|
||||
0 400 400 ;
|
||||
0 400 400
|
||||
0 400 400 const std = @import("std");
|
||||
0 400 400 const assert = std.debug.assert;
|
||||
0 400 400
|
||||
0 400 400 threadlocal var x: i32 = 1234;
|
||||
0 400 400
|
||||
2 400 401 + test "thread local storage" {
|
||||
0 401 401 | const thread1 = try std.Thread.spawn(.{}, testTls, .{});
|
||||
0 401 401 | const thread2 = try std.Thread.spawn(.{}, testTls, .{});
|
||||
0 401 401 | testTls();
|
||||
0 401 401 | thread1.join();
|
||||
0 401 401 | thread2.join();
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + fn testTls() void {
|
||||
0 401 401 | assert(x == 1234);
|
||||
0 401 401 | x += 1;
|
||||
0 401 401 | assert(x == 1235);
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 const decimal_int = 98222;
|
||||
0 400 400 const hex_int = 0xff;
|
||||
0 400 400 const another_hex_int = 0xFF;
|
||||
0 400 400 const octal_int = 0o755;
|
||||
0 400 400 const binary_int = 0b11110000;
|
||||
0 400 400
|
||||
0 400 400 // underscores may be placed between two digits as a visual separator
|
||||
0 400 400 const one_billion = 1_000_000_000;
|
||||
0 400 400 const binary_mask = 0b1_1111_1111;
|
||||
0 400 400 const permissions = 0o7_5_5;
|
||||
0 400 400 const big_address = 0xFF80_0000_0000_0000;
|
||||
0 400 400
|
||||
0 400 400
|
||||
0 400 400 const floating_point = 123.0E+77;
|
||||
0 400 400 const another_float = 123.0;
|
||||
0 400 400 const yet_another = 123.0e+77;
|
||||
0 400 400
|
||||
0 400 400 const hex_floating_point = 0x103.70p-5;
|
||||
0 400 400 const another_hex_float = 0x103.70;
|
||||
0 400 400 const yet_another_hex_float = 0x103.70P-5;
|
||||
0 400 400
|
||||
0 400 400 // underscores may be placed between two digits as a visual separator
|
||||
0 400 400 const lightspeed = 299_792_458.000_000;
|
||||
0 400 400 const nanosecond = 0.000_000_001;
|
||||
0 400 400 const more_hex = 0x1234_5678.9ABC_CDEFp-10;
|
||||
0 400 400
|
||||
2 400 401 + const Vec3 = struct {
|
||||
0 401 401 | x: f32,
|
||||
0 401 401 | y: f32,
|
||||
0 401 401 | z: f32,
|
||||
0 401 401 |
|
||||
2 401 402 + pub fn init(x: f32, y: f32, z: f32) Vec3 {
|
||||
2 402 403 + return Vec3{
|
||||
0 403 403 | .x = x,
|
||||
0 403 403 | .y = y,
|
||||
0 403 403 | .z = z,
|
||||
0 403 402 | };
|
||||
0 402 401 | }
|
||||
0 401 401 |
|
||||
2 401 402 + pub fn dot(self: Vec3, other: Vec3) f32 {
|
||||
0 402 402 | return self.x * other.x + self.y * other.y + self.z * other.z;
|
||||
0 402 401 | }
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
2 400 401 + fn LinkedList(comptime T: type) type {
|
||||
2 401 402 + return struct {
|
||||
2 402 403 + pub const Node = struct {
|
||||
0 403 403 | prev: ?*Node,
|
||||
0 403 403 | next: ?*Node,
|
||||
0 403 403 | data: T,
|
||||
0 403 402 | };
|
||||
0 402 402 |
|
||||
0 402 402 | first: ?*Node,
|
||||
0 402 402 | last: ?*Node,
|
||||
0 402 402 | len: usize,
|
||||
0 402 401 | };
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + const Point = struct {
|
||||
0 401 401 | x: f32,
|
||||
0 401 401 | y: f32,
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
2 400 401 + // Maybe we want to pass it to OpenGL so we want to be particular about
|
||||
0 401 400 | // how the bytes are arranged.
|
||||
2 400 401 + const Point2 = packed struct {
|
||||
0 401 401 | x: f32,
|
||||
0 401 401 | y: f32,
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
0 400 400
|
||||
0 400 400 const std = @import("std");
|
||||
0 400 400 const expect = std.testing.expect;
|
||||
0 400 400
|
||||
2 400 401 + const Color = enum {
|
||||
0 401 401 | auto,
|
||||
0 401 401 | off,
|
||||
0 401 401 | on,
|
||||
0 401 400 | };
|
||||
0 400 400
|
||||
0 400 400 const std = @import("std");
|
||||
0 400 400 const builtin = @import("builtin");
|
||||
0 400 400 const expect = std.testing.expect;
|
||||
0 400 400
|
||||
2 400 401 + test "switch simple" {
|
||||
0 401 401 | const a: u64 = 10;
|
||||
0 401 401 | const zz: u64 = 103;
|
||||
0 401 401 |
|
||||
2 401 402 + // All branches of a switch expression must be able to be coerced to a
|
||||
0 402 402 | // common type.
|
||||
0 402 402 | //
|
||||
0 402 402 | // Branches cannot fallthrough. If fallthrough behavior is desired, combine
|
||||
0 402 401 | // the cases and use an if.
|
||||
2 401 402 + const b = switch (a) {
|
||||
0 402 402 | // Multiple cases can be combined via a ','
|
||||
0 402 402 | 1, 2, 3 => 0,
|
||||
0 402 402 |
|
||||
2 402 403 + // Ranges can be specified using the ... syntax. These are inclusive
|
||||
0 403 402 | // of both ends.
|
||||
0 402 402 | 5...100 => 1,
|
||||
0 402 402 |
|
||||
0 402 402 | // Branches can be arbitrarily complex.
|
||||
2 402 403 + 101 => blk: {
|
||||
0 403 403 | const c: u64 = 5;
|
||||
0 403 403 | break :blk c * 2 + 1;
|
||||
0 403 402 | },
|
||||
0 402 402 |
|
||||
2 402 403 + // Switching on arbitrary expressions is allowed as long as the
|
||||
0 403 402 | // expression is known at compile-time.
|
||||
0 402 402 | zz => zz,
|
||||
2 402 403 + blk: {
|
||||
0 403 403 | const d: u32 = 5;
|
||||
0 403 403 | const e: u32 = 100;
|
||||
0 403 403 | break :blk d + e;
|
||||
0 403 402 | } => 107,
|
||||
0 402 402 |
|
||||
2 402 403 + // The else branch catches everything not already captured.
|
||||
0 403 403 | // Else branches are mandatory unless the entire range of values
|
||||
0 403 402 | // is handled.
|
||||
0 402 402 | else => 9,
|
||||
0 402 401 | };
|
||||
0 401 401 |
|
||||
0 401 401 | try expect(b == 1);
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
2 400 401 + fn charToDigit(c: u8) u8 {
|
||||
2 401 402 + return switch (c) {
|
||||
0 402 402 | '0'...'9' => c - '0',
|
||||
0 402 402 | 'A'...'Z' => c - 'A' + 10,
|
||||
0 402 402 | 'a'...'z' => c - 'a' + 10,
|
||||
0 402 402 | else => maxInt(u8),
|
||||
0 402 401 | };
|
||||
0 401 400 | }
|
||||
0 400 400
|
||||
0 400 400 const optional_value: ?i32 = null;
|
||||
0 400 400
|
||||
2 400 401 + //! This module provides functions for retrieving the current date and
|
||||
0 401 401 | //! time with varying degrees of precision and accuracy. It does not
|
||||
0 401 400 | //! depend on libc, but will use functions from it if available.
|
||||
0 400 0
|
277
lexilla/test/examples/zig/AllStyles.zig.styled
Normal file
277
lexilla/test/examples/zig/AllStyles.zig.styled
Normal file
@ -0,0 +1,277 @@
|
||||
{1}// coding:utf-8
|
||||
{0}
|
||||
{2}/// A structure for storing a timestamp, with nanosecond precision (this is a
|
||||
/// multiline doc comment).
|
||||
{13}const{0} {15}Timestamp{0} {5}={0} {13}struct{0} {5}{{0}
|
||||
{2}/// The number of seconds since the epoch (this is also a doc comment).
|
||||
{0} {10}seconds{5}:{0} {14}i64{5},{0} {1}// signed so we can represent pre-1970 (not a doc comment)
|
||||
{0} {2}/// The number of nanoseconds past the second (doc comment again).
|
||||
{0} {10}nanos{5}:{0} {14}u32{5},{0}
|
||||
|
||||
{2}/// Returns a `Timestamp` struct representing the Unix epoch; that is, the
|
||||
{0} {2}/// moment of 1970 Jan 1 00:00:00 UTC (this is a doc comment too).
|
||||
{0} {13}pub{0} {13}fn{0} {11}unixEpoch{5}(){0} {15}Timestamp{0} {5}{{0}
|
||||
{13}return{0} {15}Timestamp{5}{{0}
|
||||
{5}.{10}seconds{0} {5}={0} {4}0{5},{0}
|
||||
{5}.{10}nanos{0} {5}={0} {4}0{5},{0}
|
||||
{5}};{0}
|
||||
{5}}{0}
|
||||
{5}};{0}
|
||||
|
||||
{3}//! This module provides functions for retrieving the current date and
|
||||
//! time with varying degrees of precision and accuracy. It does not
|
||||
//! depend on libc, but will use functions from it if available.
|
||||
{0}
|
||||
{13}const{0} {10}S{0} {5}={0} {13}struct{0} {5}{{0}
|
||||
{3}//! Top level comments are allowed inside a container other than a module,
|
||||
{0} {3}//! but it is not very useful. Currently, when producing the package
|
||||
{0} {3}//! documentation, these comments are ignored.
|
||||
{5}};{0}
|
||||
|
||||
{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}"std"{5});{0}
|
||||
|
||||
{13}pub{0} {13}fn{0} {11}main{5}(){0} {5}!{14}void{0} {5}{{0}
|
||||
{13}const{0} {10}stdout{0} {5}={0} {10}std{5}.{10}io{5}.{10}getStdOut{5}().{10}writer{5}();{0}
|
||||
{13}try{0} {10}stdout{5}.{10}print{5}({7}"Hello, {s}!{9}\n{7}"{5},{0} {5}.{{7}"world"{5}});{0}
|
||||
{5}}{0}
|
||||
|
||||
|
||||
{1}// Top-level declarations are order-independent:
|
||||
{13}const{0} {10}print{0} {5}={0} {10}std{5}.{10}debug{5}.{10}print{5};{0}
|
||||
{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}"std"{5});{0}
|
||||
{13}const{0} {10}os{0} {5}={0} {10}std{5}.{10}os{5};{0}
|
||||
{13}const{0} {13}assert{0} {5}={0} {10}std{5}.{10}debug{5}.{13}assert{5};{0}
|
||||
|
||||
{13}pub{0} {13}fn{0} {11}main{5}(){0} {14}void{0} {5}{{0}
|
||||
{1}// integers
|
||||
{0} {13}const{0} {10}one_plus_one{5}:{0} {14}i32{0} {5}={0} {4}1{0} {5}+{0} {4}1{5};{0}
|
||||
{10}print{5}({7}"1 + 1 = {}{9}\n{7}"{5},{0} {5}.{{10}one_plus_one{5}});{0}
|
||||
|
||||
{1}// floats
|
||||
{0} {13}const{0} {10}seven_div_three{5}:{0} {14}f32{0} {5}={0} {4}7.0{0} {5}/{0} {4}3.0{5};{0}
|
||||
{10}print{5}({7}"7.0 / 3.0 = {}{9}\n{7}"{5},{0} {5}.{{10}seven_div_three{5}});{0}
|
||||
|
||||
{1}// boolean
|
||||
{0} {10}print{5}({7}"{}{9}\n{7}{}{9}\n{7}{}{9}\n{7}"{5},{0} {5}.{{0}
|
||||
{13}true{0} {13}and{0} {13}false{5},{0}
|
||||
{13}true{0} {13}or{0} {13}false{5},{0}
|
||||
{5}!{13}true{5},{0}
|
||||
{5}});{0}
|
||||
|
||||
{1}// optional
|
||||
{0} {13}var{0} {10}optional_value{5}:{0} {5}?[]{13}const{0} {14}u8{0} {5}={0} {13}null{5};{0}
|
||||
{13}assert{5}({10}optional_value{0} {5}=={0} {13}null{5});{0}
|
||||
|
||||
{10}print{5}({7}"{9}\n{7}optional 1{9}\n{7}type: {}{9}\n{7}value: {?s}{9}\n{7}"{5},{0} {5}.{{0}
|
||||
{12}@TypeOf{5}({10}optional_value{5}),{0} {10}optional_value{5},{0}
|
||||
{5}});{0}
|
||||
|
||||
{10}optional_value{0} {5}={0} {7}"hi"{5};{0}
|
||||
{13}assert{5}({10}optional_value{0} {5}!={0} {13}null{5});{0}
|
||||
|
||||
{10}print{5}({7}"{9}\n{7}optional 2{9}\n{7}type: {}{9}\n{7}value: {?s}{9}\n{7}"{5},{0} {5}.{{0}
|
||||
{12}@TypeOf{5}({10}optional_value{5}),{0} {10}optional_value{5},{0}
|
||||
{5}});{0}
|
||||
|
||||
{1}// error union
|
||||
{0} {13}var{0} {10}number_or_error{5}:{0} {14}anyerror{5}!{14}i32{0} {5}={0} {13}error{5}.{10}ArgNotFound{5};{0}
|
||||
|
||||
{10}print{5}({7}"{9}\n{7}error union 1{9}\n{7}type: {}{9}\n{7}value: {!}{9}\n{7}"{5},{0} {5}.{{0}
|
||||
{12}@TypeOf{5}({10}number_or_error{5}),{0}
|
||||
{10}number_or_error{5},{0}
|
||||
{5}});{0}
|
||||
|
||||
{10}number_or_error{0} {5}={0} {4}1234{5};{0}
|
||||
|
||||
{10}print{5}({7}"{9}\n{7}error union 2{9}\n{7}type: {}{9}\n{7}value: {!}{9}\n{7}"{5},{0} {5}.{{0}
|
||||
{12}@TypeOf{5}({10}number_or_error{5}),{0} {10}number_or_error{5},{0}
|
||||
{5}});{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}const{0} {10}print{0} {5}={0} {12}@import{5}({7}"std"{5}).{10}debug{5}.{10}print{5};{0}
|
||||
{13}const{0} {10}mem{0} {5}={0} {12}@import{5}({7}"std"{5}).{10}mem{5};{0} {1}// will be used to compare bytes
|
||||
{0}
|
||||
{13}pub{0} {13}fn{0} {11}main{5}(){0} {14}void{0} {5}{{0}
|
||||
{13}const{0} {10}bytes{0} {5}={0} {7}"hello{9}\u{12345678}{7}"{5};{0}
|
||||
{10}print{5}({7}"{}{9}\n{7}"{5},{0} {5}.{{12}@TypeOf{5}({10}bytes{5})});{0} {1}// *const [5:0]u8
|
||||
{0} {10}print{5}({7}"{d}{9}\n{7}"{5},{0} {5}.{{10}bytes{5}.{10}len{5}});{0} {1}// 5
|
||||
{0} {10}print{5}({7}"{c}{9}\n{7}"{5},{0} {5}.{{10}bytes{5}[{4}1{5}]});{0} {1}// 'e'
|
||||
{0} {10}print{5}({7}"{d}{9}\n{7}"{5},{0} {5}.{{10}bytes{5}[{4}5{5}]});{0} {1}// 0
|
||||
{0} {10}print{5}({7}"{}{9}\n{7}"{5},{0} {5}.{{6}'e'{0} {5}=={0} {6}'{9}\x65{6}'{5}});{0} {1}// true
|
||||
{0} {10}print{5}({7}"{d}{9}\n{7}"{5},{0} {5}.{{6}'{9}\u{1f4a9}{6}'{5}});{0} {1}// 128169
|
||||
{0} {10}print{5}({7}"{d}{9}\n{7}"{5},{0} {5}.{{6}'💯'{5}});{0} {1}// 128175
|
||||
{0} {10}print{5}({7}"{u}{9}\n{7}"{5},{0} {5}.{{6}'⚡'{5}});{0}
|
||||
{10}print{5}({7}"{}{9}\n{7}"{5},{0} {5}.{{10}mem{5}.{10}eql{5}({14}u8{5},{0} {7}"hello"{5},{0} {7}"h{9}\x65{7}llo"{5})});{0} {1}// true
|
||||
{0} {10}print{5}({7}"{}{9}\n{7}"{5},{0} {5}.{{10}mem{5}.{10}eql{5}({14}u8{5},{0} {7}"💯"{5},{0} {7}"{9}\xf0\x9f\x92\xaf{7}"{5})});{0} {1}// also true
|
||||
{0} {13}const{0} {10}invalid_utf8{0} {5}={0} {7}"{9}\xff\xfe{7}"{5};{0} {1}// non-UTF-8 strings are possible with \xNN notation.
|
||||
{0} {10}print{5}({7}"0x{x}{9}\n{7}"{5},{0} {5}.{{10}invalid_utf8{5}[{4}1{5}]});{0} {1}// indexing them returns individual bytes...
|
||||
{0} {10}print{5}({7}"0x{x}{9}\n{7}"{5},{0} {5}.{{7}"💯"{5}[{4}1{5}]});{0} {1}// ...as does indexing part-way through non-ASCII characters
|
||||
{5}}{0}
|
||||
|
||||
{13}const{0} {10}hello_world_in_c{0} {5}={0}
|
||||
{8}\\#include <stdio.h>
|
||||
{0} {8}\\
|
||||
{0} {8}\\int main(int argc, char **argv) {
|
||||
{0} {8}\\ printf("hello world\n");
|
||||
{0} {8}\\ return 0;
|
||||
{0} {8}\\}
|
||||
{5};{0}
|
||||
|
||||
{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}"std"{5});{0}
|
||||
{13}const{0} {13}assert{0} {5}={0} {10}std{5}.{10}debug{5}.{13}assert{5};{0}
|
||||
|
||||
{13}threadlocal{0} {13}var{0} {10}x{5}:{0} {14}i32{0} {5}={0} {4}1234{5};{0}
|
||||
|
||||
{13}test{0} {7}"thread local storage"{0} {5}{{0}
|
||||
{13}const{0} {10}thread1{0} {5}={0} {13}try{0} {10}std{5}.{10}Thread{5}.{10}spawn{5}(.{},{0} {10}testTls{5},{0} {5}.{});{0}
|
||||
{13}const{0} {10}thread2{0} {5}={0} {13}try{0} {10}std{5}.{10}Thread{5}.{10}spawn{5}(.{},{0} {10}testTls{5},{0} {5}.{});{0}
|
||||
{10}testTls{5}();{0}
|
||||
{10}thread1{5}.{10}join{5}();{0}
|
||||
{10}thread2{5}.{10}join{5}();{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}fn{0} {11}testTls{5}(){0} {14}void{0} {5}{{0}
|
||||
{13}assert{5}({10}x{0} {5}=={0} {4}1234{5});{0}
|
||||
{10}x{0} {5}+={0} {4}1{5};{0}
|
||||
{13}assert{5}({10}x{0} {5}=={0} {4}1235{5});{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}const{0} {10}decimal_int{0} {5}={0} {4}98222{5};{0}
|
||||
{13}const{0} {10}hex_int{0} {5}={0} {4}0xff{5};{0}
|
||||
{13}const{0} {10}another_hex_int{0} {5}={0} {4}0xFF{5};{0}
|
||||
{13}const{0} {10}octal_int{0} {5}={0} {4}0o755{5};{0}
|
||||
{13}const{0} {10}binary_int{0} {5}={0} {4}0b11110000{5};{0}
|
||||
|
||||
{1}// underscores may be placed between two digits as a visual separator
|
||||
{13}const{0} {10}one_billion{0} {5}={0} {4}1_000_000_000{5};{0}
|
||||
{13}const{0} {10}binary_mask{0} {5}={0} {4}0b1_1111_1111{5};{0}
|
||||
{13}const{0} {10}permissions{0} {5}={0} {4}0o7_5_5{5};{0}
|
||||
{13}const{0} {10}big_address{0} {5}={0} {4}0xFF80_0000_0000_0000{5};{0}
|
||||
|
||||
|
||||
{13}const{0} {10}floating_point{0} {5}={0} {4}123.0E+77{5};{0}
|
||||
{13}const{0} {10}another_float{0} {5}={0} {4}123.0{5};{0}
|
||||
{13}const{0} {10}yet_another{0} {5}={0} {4}123.0e+77{5};{0}
|
||||
|
||||
{13}const{0} {10}hex_floating_point{0} {5}={0} {4}0x103.70p{5}-{4}5{5};{0}
|
||||
{13}const{0} {10}another_hex_float{0} {5}={0} {4}0x103.70{5};{0}
|
||||
{13}const{0} {10}yet_another_hex_float{0} {5}={0} {4}0x103.70P{5}-{4}5{5};{0}
|
||||
|
||||
{1}// underscores may be placed between two digits as a visual separator
|
||||
{13}const{0} {10}lightspeed{0} {5}={0} {4}299_792_458.000_000{5};{0}
|
||||
{13}const{0} {10}nanosecond{0} {5}={0} {4}0.000_000_001{5};{0}
|
||||
{13}const{0} {10}more_hex{0} {5}={0} {4}0x1234_5678.9ABC_CDEFp{5}-{4}10{5};{0}
|
||||
|
||||
{13}const{0} {16}Vec3{0} {5}={0} {13}struct{0} {5}{{0}
|
||||
{10}x{5}:{0} {14}f32{5},{0}
|
||||
{10}y{5}:{0} {14}f32{5},{0}
|
||||
{10}z{5}:{0} {14}f32{5},{0}
|
||||
|
||||
{13}pub{0} {13}fn{0} {11}init{5}({10}x{5}:{0} {14}f32{5},{0} {10}y{5}:{0} {14}f32{5},{0} {10}z{5}:{0} {14}f32{5}){0} {16}Vec3{0} {5}{{0}
|
||||
{13}return{0} {16}Vec3{5}{{0}
|
||||
{5}.{10}x{0} {5}={0} {10}x{5},{0}
|
||||
{5}.{10}y{0} {5}={0} {10}y{5},{0}
|
||||
{5}.{10}z{0} {5}={0} {10}z{5},{0}
|
||||
{5}};{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}pub{0} {13}fn{0} {11}dot{5}({10}self{5}:{0} {16}Vec3{5},{0} {10}other{5}:{0} {16}Vec3{5}){0} {14}f32{0} {5}{{0}
|
||||
{13}return{0} {10}self{5}.{10}x{0} {5}*{0} {10}other{5}.{10}x{0} {5}+{0} {10}self{5}.{10}y{0} {5}*{0} {10}other{5}.{10}y{0} {5}+{0} {10}self{5}.{10}z{0} {5}*{0} {10}other{5}.{10}z{5};{0}
|
||||
{5}}{0}
|
||||
{5}};{0}
|
||||
|
||||
{13}fn{0} {11}LinkedList{5}({13}comptime{0} {10}T{5}:{0} {14}type{5}){0} {14}type{0} {5}{{0}
|
||||
{13}return{0} {13}struct{0} {5}{{0}
|
||||
{13}pub{0} {13}const{0} {10}Node{0} {5}={0} {13}struct{0} {5}{{0}
|
||||
{10}prev{5}:{0} {5}?*{10}Node{5},{0}
|
||||
{10}next{5}:{0} {5}?*{10}Node{5},{0}
|
||||
{10}data{5}:{0} {10}T{5},{0}
|
||||
{5}};{0}
|
||||
|
||||
{10}first{5}:{0} {5}?*{10}Node{5},{0}
|
||||
{10}last{5}:{0} {5}?*{10}Node{5},{0}
|
||||
{10}len{5}:{0} {14}usize{5},{0}
|
||||
{5}};{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}const{0} {10}Point{0} {5}={0} {13}struct{0} {5}{{0}
|
||||
{10}x{5}:{0} {14}f32{5},{0}
|
||||
{10}y{5}:{0} {14}f32{5},{0}
|
||||
{5}};{0}
|
||||
|
||||
{1}// Maybe we want to pass it to OpenGL so we want to be particular about
|
||||
// how the bytes are arranged.
|
||||
{13}const{0} {10}Point2{0} {5}={0} {13}packed{0} {13}struct{0} {5}{{0}
|
||||
{10}x{5}:{0} {14}f32{5},{0}
|
||||
{10}y{5}:{0} {14}f32{5},{0}
|
||||
{5}};{0}
|
||||
|
||||
|
||||
{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}"std"{5});{0}
|
||||
{13}const{0} {10}expect{0} {5}={0} {10}std{5}.{10}testing{5}.{10}expect{5};{0}
|
||||
|
||||
{13}const{0} {10}Color{0} {5}={0} {13}enum{0} {5}{{0}
|
||||
{10}auto{5},{0}
|
||||
{10}off{5},{0}
|
||||
{10}on{5},{0}
|
||||
{5}};{0}
|
||||
|
||||
{13}const{0} {10}std{0} {5}={0} {12}@import{5}({7}"std"{5});{0}
|
||||
{13}const{0} {10}builtin{0} {5}={0} {12}@import{5}({7}"builtin"{5});{0}
|
||||
{13}const{0} {10}expect{0} {5}={0} {10}std{5}.{10}testing{5}.{10}expect{5};{0}
|
||||
|
||||
{13}test{0} {7}"switch simple"{0} {5}{{0}
|
||||
{13}const{0} {10}a{5}:{0} {14}u64{0} {5}={0} {4}10{5};{0}
|
||||
{13}const{0} {10}zz{5}:{0} {14}u64{0} {5}={0} {4}103{5};{0}
|
||||
|
||||
{1}// All branches of a switch expression must be able to be coerced to a
|
||||
{0} {1}// common type.
|
||||
{0} {1}//
|
||||
{0} {1}// Branches cannot fallthrough. If fallthrough behavior is desired, combine
|
||||
{0} {1}// the cases and use an if.
|
||||
{0} {13}const{0} {10}b{0} {5}={0} {13}switch{0} {5}({10}a{5}){0} {5}{{0}
|
||||
{1}// Multiple cases can be combined via a ','
|
||||
{0} {4}1{5},{0} {4}2{5},{0} {4}3{0} {5}=>{0} {4}0{5},{0}
|
||||
|
||||
{1}// Ranges can be specified using the ... syntax. These are inclusive
|
||||
{0} {1}// of both ends.
|
||||
{0} {4}5{5}..{4}.100{0} {5}=>{0} {4}1{5},{0}
|
||||
|
||||
{1}// Branches can be arbitrarily complex.
|
||||
{0} {4}101{0} {5}=>{0} {10}blk{5}:{0} {5}{{0}
|
||||
{13}const{0} {10}c{5}:{0} {14}u64{0} {5}={0} {4}5{5};{0}
|
||||
{13}break{0} {5}:{10}blk{0} {10}c{0} {5}*{0} {4}2{0} {5}+{0} {4}1{5};{0}
|
||||
{5}},{0}
|
||||
|
||||
{1}// Switching on arbitrary expressions is allowed as long as the
|
||||
{0} {1}// expression is known at compile-time.
|
||||
{0} {10}zz{0} {5}=>{0} {10}zz{5},{0}
|
||||
{10}blk{5}:{0} {5}{{0}
|
||||
{13}const{0} {10}d{5}:{0} {14}u32{0} {5}={0} {4}5{5};{0}
|
||||
{13}const{0} {10}e{5}:{0} {14}u32{0} {5}={0} {4}100{5};{0}
|
||||
{13}break{0} {5}:{10}blk{0} {10}d{0} {5}+{0} {10}e{5};{0}
|
||||
{5}}{0} {5}=>{0} {4}107{5},{0}
|
||||
|
||||
{1}// The else branch catches everything not already captured.
|
||||
{0} {1}// Else branches are mandatory unless the entire range of values
|
||||
{0} {1}// is handled.
|
||||
{0} {13}else{0} {5}=>{0} {4}9{5},{0}
|
||||
{5}};{0}
|
||||
|
||||
{13}try{0} {10}expect{5}({10}b{0} {5}=={0} {4}1{5});{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}fn{0} {11}charToDigit{5}({10}c{5}:{0} {14}u8{5}){0} {14}u8{0} {5}{{0}
|
||||
{13}return{0} {13}switch{0} {5}({10}c{5}){0} {5}{{0}
|
||||
{6}'0'{5}...{6}'9'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'0'{5},{0}
|
||||
{6}'A'{5}...{6}'Z'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'A'{0} {5}+{0} {4}10{5},{0}
|
||||
{6}'a'{5}...{6}'z'{0} {5}=>{0} {10}c{0} {5}-{0} {6}'a'{0} {5}+{0} {4}10{5},{0}
|
||||
{13}else{0} {5}=>{0} {10}maxInt{5}({14}u8{5}),{0}
|
||||
{5}};{0}
|
||||
{5}}{0}
|
||||
|
||||
{13}const{0} {10}optional_value{5}:{0} {5}?{14}i32{0} {5}={0} {13}null{5};{0}
|
||||
|
||||
{3}//! This module provides functions for retrieving the current date and
|
||||
//! time with varying degrees of precision and accuracy. It does not
|
||||
//! depend on libc, but will use functions from it if available.
|
6
lexilla/test/examples/zig/SciTE.properties
Normal file
6
lexilla/test/examples/zig/SciTE.properties
Normal file
@ -0,0 +1,6 @@
|
||||
lexer.*.zig=zig
|
||||
fold=1
|
||||
keywords.*.zig=False None True _ and as assert async await break case class continue def del elif else except finally for from global if import in is lambda match nonlocal not or pass raise return try while with yield addrspace align allowzero and anyframe anytype asm async await break callconv catch comptime const continue defer else enum errdefer error export extern false fn for if inline linksection noalias noinline nosuspend null opaque or orelse packed pub resume return struct suspend switch test threadlocal true try undefined union unreachable usingnamespace var volatile while
|
||||
keywords2.*.zig=anyerror anyopaque bool f128 f16 f32 f64 f80 i128 i16 i32 i64 i8 isize noreturn type u128 u16 u32 u64 u8 usize void
|
||||
keywords3.*.zig=Timestamp
|
||||
keywords4.*.zig=Vec3
|
@ -1 +1 @@
|
||||
540
|
||||
541
|
@ -67,7 +67,7 @@ Mingw-w64 is known to work. Other compilers will probably not work.
|
||||
Only Scintilla will build with GTK+ on Windows. SciTE will not work.
|
||||
|
||||
Make builds both a static library version of Scintilla with lexers (scintilla.a) and
|
||||
a shared library without lexers (libscintilla.so or or libscintilla.dll).
|
||||
a shared library without lexers (libscintilla.so or libscintilla.dll).
|
||||
|
||||
To build Scintilla, make in the scintilla/gtk directory
|
||||
cd scintilla\gtk
|
||||
|
@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.5.2</string>
|
||||
<string>5.5.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
@ -586,7 +586,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.5.2;
|
||||
CURRENT_PROJECT_VERSION = 5.5.3;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@ -610,7 +610,6 @@
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
"OTHER_LDFLAGS[arch=*]" = "-Wl,-ld_classic";
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -651,7 +650,7 @@
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.5.2;
|
||||
CURRENT_PROJECT_VERSION = 5.5.3;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
@ -669,7 +668,6 @@
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
"OTHER_LDFLAGS[arch=*]" = "-Wl,-ld_classic";
|
||||
SDKROOT = macosx;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
@ -684,7 +682,7 @@
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 5.5.2;
|
||||
CURRENT_PROJECT_VERSION = 5.5.3;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
@ -719,7 +717,7 @@
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 5.5.2;
|
||||
CURRENT_PROJECT_VERSION = 5.5.3;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
|
@ -1102,11 +1102,12 @@ void ScintillaCocoa::Paste(bool forceRectangular) {
|
||||
// No data or no flavor we support.
|
||||
return;
|
||||
|
||||
pdoc->BeginUndoAction();
|
||||
ClearSelection(false);
|
||||
InsertPasteShape(selectedText.Data(), selectedText.Length(),
|
||||
selectedText.rectangular ? PasteShape::rectangular : PasteShape::stream);
|
||||
pdoc->EndUndoAction();
|
||||
{
|
||||
UndoGroup ug(pdoc);
|
||||
ClearSelection(false);
|
||||
InsertPasteShape(selectedText.Data(), selectedText.Length(),
|
||||
selectedText.rectangular ? PasteShape::rectangular : PasteShape::stream);
|
||||
}
|
||||
|
||||
Redraw();
|
||||
EnsureCaretVisible();
|
||||
@ -1515,7 +1516,8 @@ void ScintillaCocoa::StartDrag() {
|
||||
CGImageRelease(imagePixmap);
|
||||
|
||||
NSImage *image = [[NSImage alloc] initWithSize: selectionRectangle.size];
|
||||
[image addRepresentation: bitmap];
|
||||
if (bitmap)
|
||||
[image addRepresentation: bitmap];
|
||||
|
||||
NSImage *dragImage = [[NSImage alloc] initWithSize: selectionRectangle.size];
|
||||
dragImage.backgroundColor = [NSColor clearColor];
|
||||
|
@ -1,6 +1,12 @@
|
||||
// File to suppress cppcheck warnings for files that will not be fixed.
|
||||
// Does not suppress warnings where an additional occurrence of the warning may be of interest.
|
||||
// Configured for cppcheck 2.11
|
||||
// Configured for cppcheck 2.15
|
||||
|
||||
// Just a report of how many checkers are run
|
||||
checkersReport
|
||||
|
||||
// This just warns that cppcheck isn't exhaustive and it still appears in exhaustive mode
|
||||
normalCheckLevelMaxBranches
|
||||
|
||||
// Coding style is to use assignments in constructor when there are many
|
||||
// members to initialize or the initialization is complex or has comments.
|
||||
@ -37,12 +43,6 @@ returnByReference:scintilla/src/Selection.h
|
||||
// MarginView access to all bits is safe and is better defined in later versions of C++
|
||||
shiftTooManyBitsSigned:scintilla/src/MarginView.cxx
|
||||
|
||||
// DLL entry points are unused inside Scintilla
|
||||
unusedFunction:scintilla/win32/ScintillaDLL.cxx
|
||||
|
||||
// ScintillaDocument is providing an API and there are no consumers of the API inside Scintilla
|
||||
unusedFunction:scintilla/qt/ScintillaEdit/ScintillaDocument.cpp
|
||||
|
||||
// Doesn't understand changing dropWentOutside in Editor
|
||||
knownConditionTrueFalse:scintilla/win32/ScintillaWin.cxx
|
||||
|
||||
@ -53,19 +53,10 @@ constParameterPointer:scintilla/win32/ScintillaWin.cxx
|
||||
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
|
||||
|
||||
// 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
|
||||
// G_END_DECLS
|
||||
unknownMacro:scintilla/gtk/scintilla-marshal.h
|
||||
|
||||
// Difficult to test accessibility so don't change
|
||||
constParameterPointer:scintilla/gtk/ScintillaGTKAccessible.cxx
|
||||
|
@ -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/scintilla552.zip">
|
||||
<font size="4"> <a href="https://www.scintilla.org/scintilla553.zip">
|
||||
Windows</a>
|
||||
<a href="https://www.scintilla.org/scintilla552.tgz">
|
||||
<a href="https://www.scintilla.org/scintilla553.tgz">
|
||||
GTK/Linux</a>
|
||||
</font>
|
||||
</td>
|
||||
@ -42,7 +42,7 @@
|
||||
containing very few restrictions.
|
||||
</p>
|
||||
<h3>
|
||||
Release 5.5.2
|
||||
Release 5.5.3
|
||||
</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/scintilla552.zip">zip format</a> (1.8M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla552.tgz">tgz format</a> (1.7M) commonly used on Linux and compatible operating systems</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla553.zip">zip format</a> (1.8M) commonly used on Windows</li>
|
||||
<li><a href="https://www.scintilla.org/scintilla553.tgz">tgz format</a> (1.7M) commonly used on Linux and compatible operating systems</li>
|
||||
</ul>
|
||||
Instructions for building on both Windows and Linux are included in the readme file.
|
||||
<h4>
|
||||
|
@ -585,6 +585,18 @@
|
||||
</tr>
|
||||
</table>
|
||||
<h2>Releases</h2>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/scintilla553.zip">Release 5.5.3</a>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Released 19 October 2024.
|
||||
</li>
|
||||
<li>
|
||||
On Win32 change direction of horizontal mouse wheel and touchpad scrolling to match other applications.
|
||||
<a href="https://sourceforge.net/p/scintilla/bugs/2449/">Bug #2449</a>.
|
||||
</li>
|
||||
</ul>
|
||||
<h3>
|
||||
<a href="https://www.scintilla.org/scintilla552.zip">Release 5.5.2</a>
|
||||
</h3>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<meta name="keywords" content="Scintilla, SciTE, Editing Component, Text Editor" />
|
||||
<meta name="Description"
|
||||
content="www.scintilla.org is the home of the Scintilla editing component and SciTE text editor application." />
|
||||
<meta name="Date.Modified" content="20240821" />
|
||||
<meta name="Date.Modified" content="20241019" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type="text/css">
|
||||
.logo {
|
||||
@ -61,8 +61,8 @@
|
||||
GTK, and macOS</font>
|
||||
</td>
|
||||
<td width="40%" align="right">
|
||||
<font color="#FFCC99" size="3"> Release version 5.5.2<br />
|
||||
Site last modified August 21 2024</font>
|
||||
<font color="#FFCC99" size="3"> Release version 5.5.3<br />
|
||||
Site last modified October 19 2024</font>
|
||||
</td>
|
||||
<td width="20%">
|
||||
|
||||
@ -77,11 +77,11 @@
|
||||
</tr>
|
||||
</table>
|
||||
<ul id="versionlist">
|
||||
<li>Version 5.5.3 fixes horizontal scrolling with a touchpad on Win32.</li>
|
||||
<li>Version 5.5.2 adds multiple selection copy with separator, a font stretch setting, and access to whether an undo sequence is active.</li>
|
||||
<li>Version 5.5.1 adds SCI_CUTALLOWLINE and fixes a Win32 bug that caused the cursor to flicker.</li>
|
||||
<li>Version 5.5.0 adds elements for inactive additional selections.</li>
|
||||
<li>Version 5.4.3 fixes a redo bug.</li>
|
||||
<li>Version 5.4.2 can save and restore undo history.</li>
|
||||
</ul>
|
||||
<ul id="menu">
|
||||
<li id="remote1"><a href="https://www.scintilla.org/SciTEImage.html">Screenshot</a></li>
|
||||
|
@ -13,7 +13,7 @@ TEMPLATE = lib
|
||||
CONFIG += lib_bundle
|
||||
CONFIG += c++1z
|
||||
|
||||
VERSION = 5.5.2
|
||||
VERSION = 5.5.3
|
||||
|
||||
SOURCES += \
|
||||
ScintillaEdit.cpp \
|
||||
|
@ -13,7 +13,7 @@ TEMPLATE = lib
|
||||
CONFIG += lib_bundle
|
||||
CONFIG += c++1z
|
||||
|
||||
VERSION = 5.5.2
|
||||
VERSION = 5.5.3
|
||||
|
||||
SOURCES += \
|
||||
PlatQt.cpp \
|
||||
|
@ -144,30 +144,28 @@ CharacterExtracted::CharacterExtracted(const unsigned char *charBytes, size_t wi
|
||||
}
|
||||
|
||||
Document::Document(DocumentOption options) :
|
||||
refCount(0),
|
||||
cb(!FlagSet(options, DocumentOption::StylesNone), FlagSet(options, DocumentOption::TextLarge)),
|
||||
durationStyleOneByte(0.000001, 0.0000001, 0.00001) {
|
||||
refCount = 0;
|
||||
endStyled(0),
|
||||
styleClock(0),
|
||||
enteredModification(0),
|
||||
enteredStyling(0),
|
||||
enteredReadOnlyCount(0),
|
||||
insertionSet(false),
|
||||
#ifdef _WIN32
|
||||
eolMode = EndOfLine::CrLf;
|
||||
eolMode(EndOfLine::CrLf),
|
||||
#else
|
||||
eolMode = EndOfLine::Lf;
|
||||
eolMode(EndOfLine::Lf),
|
||||
#endif
|
||||
dbcsCodePage = CpUtf8;
|
||||
lineEndBitSet = LineEndType::Default;
|
||||
endStyled = 0;
|
||||
styleClock = 0;
|
||||
enteredModification = 0;
|
||||
enteredStyling = 0;
|
||||
enteredReadOnlyCount = 0;
|
||||
insertionSet = false;
|
||||
tabInChars = 8;
|
||||
indentInChars = 0;
|
||||
actualIndentInChars = 8;
|
||||
useTabs = true;
|
||||
tabIndents = true;
|
||||
backspaceUnindents = false;
|
||||
|
||||
matchesValid = false;
|
||||
dbcsCodePage(CpUtf8),
|
||||
lineEndBitSet(LineEndType::Default),
|
||||
tabInChars(8),
|
||||
indentInChars(0),
|
||||
actualIndentInChars(8),
|
||||
useTabs(true),
|
||||
tabIndents(true),
|
||||
backspaceUnindents(false),
|
||||
durationStyleOneByte(0.000001, 0.0000001, 0.00001) {
|
||||
|
||||
perLineData[ldMarkers] = std::make_unique<LineMarkers>();
|
||||
perLineData[ldLevels] = std::make_unique<LineLevels>();
|
||||
|
@ -301,7 +301,6 @@ private:
|
||||
LineAnnotation *Annotations() const noexcept;
|
||||
LineAnnotation *EOLAnnotations() const noexcept;
|
||||
|
||||
bool matchesValid;
|
||||
std::unique_ptr<RegexSearchBase> regex;
|
||||
std::unique_ptr<LexInterface> pli;
|
||||
|
||||
|
@ -774,10 +774,13 @@ bool Editor::RangeContainsProtected(Sci::Position start, Sci::Position end) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Editor::RangeContainsProtected(const SelectionRange &range) const noexcept {
|
||||
return RangeContainsProtected(range.Start().Position(), range.End().Position());
|
||||
}
|
||||
|
||||
bool Editor::SelectionContainsProtected() const noexcept {
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
if (RangeContainsProtected(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).End().Position())) {
|
||||
if (RangeContainsProtected(sel.Range(r))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2045,17 +2048,10 @@ void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) {
|
||||
for (std::vector<SelectionRange *>::reverse_iterator rit = selPtrs.rbegin();
|
||||
rit != selPtrs.rend(); ++rit) {
|
||||
SelectionRange *currentSel = *rit;
|
||||
if (!RangeContainsProtected(currentSel->Start().Position(),
|
||||
currentSel->End().Position())) {
|
||||
if (!RangeContainsProtected(*currentSel)) {
|
||||
Sci::Position positionInsert = currentSel->Start().Position();
|
||||
if (!currentSel->Empty()) {
|
||||
if (currentSel->Length()) {
|
||||
pdoc->DeleteChars(positionInsert, currentSel->Length());
|
||||
currentSel->ClearVirtualSpace();
|
||||
} else {
|
||||
// Range is all virtual so collapse to start of virtual space
|
||||
currentSel->MinimizeVirtualSpace();
|
||||
}
|
||||
ClearSelectionRange(*currentSel);
|
||||
} else if (inOverstrike) {
|
||||
if (positionInsert < pdoc->Length()) {
|
||||
if (!pdoc->IsPositionInLineEnd(positionInsert)) {
|
||||
@ -2123,24 +2119,26 @@ void Editor::InsertCharacter(std::string_view sv, CharacterSource charSource) {
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::ClearSelectionRange(SelectionRange &range) {
|
||||
if (!range.Empty()) {
|
||||
if (range.Length()) {
|
||||
pdoc->DeleteChars(range.Start().Position(), range.Length());
|
||||
range.ClearVirtualSpace();
|
||||
} else {
|
||||
// Range is all virtual so collapse to start of virtual space
|
||||
range.MinimizeVirtualSpace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::ClearBeforeTentativeStart() {
|
||||
// Make positions for the first composition string.
|
||||
FilterSelections();
|
||||
UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
|
||||
for (size_t r = 0; r<sel.Count(); r++) {
|
||||
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).End().Position())) {
|
||||
const Sci::Position positionInsert = sel.Range(r).Start().Position();
|
||||
if (!sel.Range(r).Empty()) {
|
||||
if (sel.Range(r).Length()) {
|
||||
pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
|
||||
sel.Range(r).ClearVirtualSpace();
|
||||
} else {
|
||||
// Range is all virtual so collapse to start of virtual space
|
||||
sel.Range(r).MinimizeVirtualSpace();
|
||||
}
|
||||
}
|
||||
RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
|
||||
if (!RangeContainsProtected(sel.Range(r))) {
|
||||
ClearSelectionRange(sel.Range(r));
|
||||
RealizeVirtualSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace());
|
||||
sel.Range(r).ClearVirtualSpace();
|
||||
}
|
||||
}
|
||||
@ -2157,18 +2155,9 @@ void Editor::InsertPaste(const char *text, Sci::Position len) {
|
||||
} else {
|
||||
// MultiPaste::Each
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).End().Position())) {
|
||||
if (!RangeContainsProtected(sel.Range(r))) {
|
||||
Sci::Position positionInsert = sel.Range(r).Start().Position();
|
||||
if (!sel.Range(r).Empty()) {
|
||||
if (sel.Range(r).Length()) {
|
||||
pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
|
||||
sel.Range(r).ClearVirtualSpace();
|
||||
} else {
|
||||
// Range is all virtual so collapse to start of virtual space
|
||||
sel.Range(r).MinimizeVirtualSpace();
|
||||
}
|
||||
}
|
||||
ClearSelectionRange(sel.Range(r));
|
||||
positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
|
||||
const Sci::Position lengthInserted = pdoc->InsertString(positionInsert, text, len);
|
||||
if (lengthInserted > 0) {
|
||||
@ -2214,8 +2203,7 @@ void Editor::ClearSelection(bool retainMultipleSelections) {
|
||||
UndoGroup ug(pdoc);
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
if (!sel.Range(r).Empty()) {
|
||||
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).End().Position())) {
|
||||
if (!RangeContainsProtected(sel.Range(r))) {
|
||||
pdoc->DeleteChars(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).Length());
|
||||
sel.Range(r) = SelectionRange(sel.Range(r).Start());
|
||||
|
@ -355,6 +355,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
enum class AddNumber { one, each };
|
||||
void MultipleSelectAdd(AddNumber addNumber);
|
||||
bool RangeContainsProtected(Sci::Position start, Sci::Position end) const noexcept;
|
||||
bool RangeContainsProtected(const SelectionRange &range) const noexcept;
|
||||
bool SelectionContainsProtected() const noexcept;
|
||||
Sci::Position MovePositionOutsideChar(Sci::Position pos, Sci::Position moveDir, bool checkLineEnd=true) const;
|
||||
SelectionPosition MovePositionOutsideChar(SelectionPosition pos, Sci::Position moveDir, bool checkLineEnd=true) const;
|
||||
@ -425,6 +426,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
SelectionPosition RealizeVirtualSpace(const SelectionPosition &position);
|
||||
void AddChar(char ch);
|
||||
virtual void InsertCharacter(std::string_view sv, Scintilla::CharacterSource charSource);
|
||||
void ClearSelectionRange(SelectionRange &range);
|
||||
void ClearBeforeTentativeStart();
|
||||
void InsertPaste(const char *text, Sci::Position len);
|
||||
enum class PasteShape { stream=0, rectangular = 1, line = 2 };
|
||||
@ -505,7 +507,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
|
||||
virtual int KeyDefault(Scintilla::Keys /* key */, Scintilla::KeyMod /*modifiers*/);
|
||||
int KeyDownWithModifiers(Scintilla::Keys key, Scintilla::KeyMod modifiers, bool *consumed);
|
||||
|
||||
void Indent(bool forwards, bool lineTab);
|
||||
void Indent(bool forwards, bool lineIndent);
|
||||
|
||||
virtual std::unique_ptr<CaseFolder> CaseFolderForEncoding();
|
||||
Sci::Position FindText(Scintilla::uptr_t wParam, Scintilla::sptr_t lParam);
|
||||
|
@ -222,8 +222,7 @@ void ScintillaBase::AutoCompleteInsert(Sci::Position startPos, Sci::Position rem
|
||||
} else {
|
||||
// MultiAutoComplete::Each
|
||||
for (size_t r=0; r<sel.Count(); r++) {
|
||||
if (!RangeContainsProtected(sel.Range(r).Start().Position(),
|
||||
sel.Range(r).End().Position())) {
|
||||
if (!RangeContainsProtected(sel.Range(r))) {
|
||||
Sci::Position positionInsert = sel.Range(r).Start().Position();
|
||||
positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
|
||||
if (positionInsert - removeLen >= 0) {
|
||||
|
@ -1 +1 @@
|
||||
552
|
||||
553
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define VERSION_SCINTILLA "5.5.2"
|
||||
#define VERSION_WORDS 5, 5, 2, 0
|
||||
#define VERSION_SCINTILLA "5.5.3"
|
||||
#define VERSION_WORDS 5, 5, 3, 0
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_WORDS
|
||||
|
@ -1200,10 +1200,9 @@ void ScintillaWin::SelectionToHangul() {
|
||||
|
||||
if (converted) {
|
||||
documentStr = StringEncode(uniStr, CodePageOfDocument());
|
||||
pdoc->BeginUndoAction();
|
||||
UndoGroup ug(pdoc);
|
||||
ClearSelection();
|
||||
InsertPaste(&documentStr[0], documentStr.size());
|
||||
pdoc->EndUndoAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1688,11 +1687,16 @@ sptr_t ScintillaWin::MouseMessage(unsigned int iMessage, uptr_t wParam, sptr_t l
|
||||
|
||||
MouseWheelDelta &wheelDelta = (iMessage == WM_MOUSEHWHEEL) ? horizontalWheelDelta : verticalWheelDelta;
|
||||
if (wheelDelta.Accumulate(wParam)) {
|
||||
const int charsToScroll = charsPerScroll * wheelDelta.Actions();
|
||||
int charsToScroll = charsPerScroll * wheelDelta.Actions();
|
||||
if (iMessage == WM_MOUSEHWHEEL) {
|
||||
// horizontal scroll is in reverse direction
|
||||
charsToScroll = -charsToScroll;
|
||||
}
|
||||
const int widthToScroll = static_cast<int>(std::lround(charsToScroll * vs.aveCharWidth));
|
||||
HorizontalScrollToClamped(xOffset + widthToScroll);
|
||||
}
|
||||
return 0;
|
||||
// return 1 for Logitech mouse, https://www.pretentiousname.com/setpoint_hwheel/index.html
|
||||
return (iMessage == WM_MOUSEHWHEEL) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Either SCROLL vertically or ZOOM. We handle the wheel steppings calculation
|
||||
|
Loading…
x
Reference in New Issue
Block a user