feat: String escape sequence highlighting
This commit is contained in:
parent
0d915f921e
commit
9d0f81bd8d
7 changed files with 150 additions and 45 deletions
|
@ -17,6 +17,11 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Zig
|
||||
- Syntax highlighting for escape sequences in strings
|
||||
|
||||
### Fixed
|
||||
|
||||
- Zig
|
||||
|
|
|
@ -2,6 +2,7 @@ import de.undercouch.gradle.tasks.download.Download
|
|||
import groovy.xml.XmlParser
|
||||
import org.jetbrains.changelog.Changelog
|
||||
import org.jetbrains.changelog.markdownToHTML
|
||||
import org.jetbrains.grammarkit.tasks.GenerateLexerTask
|
||||
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
|
||||
import org.jetbrains.intellij.platform.gradle.tasks.PatchPluginXmlTask
|
||||
import org.jetbrains.intellij.platform.gradle.tasks.PublishPluginTask
|
||||
|
@ -204,11 +205,21 @@ project(":zig") {
|
|||
targetOutputDir = file("${grammarKitGenDir}/lexer/${rootPackagePath}/zig/lexer")
|
||||
}
|
||||
|
||||
register<GenerateLexerTask>("generateStringLexer") {
|
||||
sourceFile = file("src/main/grammar/ZigString.flex")
|
||||
targetOutputDir = file("${grammarKitGenDir}/lexer/${rootPackagePath}/zig/stringlexer")
|
||||
purgeOldFiles = true
|
||||
}
|
||||
|
||||
generateParser {
|
||||
sourceFile = file("src/main/grammar/Zig.bnf")
|
||||
pathToParser = "${rootPackagePath}/zig/psi/ZigParser.java"
|
||||
pathToPsiRoot = "${rootPackagePath}/zig/psi"
|
||||
}
|
||||
|
||||
named("generateGrammars") {
|
||||
dependsOn("generateStringLexer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@ char_char= {mb_utf8_literal}
|
|||
| {char_escape}
|
||||
| {ascii_char_not_nl_slash_squote}
|
||||
|
||||
string_char= {char_escape}
|
||||
| [^\\\"\n]
|
||||
string_char= \\ .
|
||||
| [^\"\n]
|
||||
|
||||
all_nl_wrap=[^\n]* [ \n]*
|
||||
all_nl_nowrap=[^\n]* \n
|
||||
|
|
60
modules/zig/src/main/grammar/ZigString.flex
Normal file
60
modules/zig/src/main/grammar/ZigString.flex
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.falsepattern.zigbrains.zig.stringlexer;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import static com.intellij.psi.TokenType.WHITE_SPACE;
|
||||
import static com.intellij.psi.TokenType.BAD_CHARACTER;
|
||||
import static com.falsepattern.zigbrains.zig.psi.ZigTypes.*;
|
||||
import static com.intellij.psi.StringEscapesTokenTypes.*;
|
||||
|
||||
%%
|
||||
|
||||
%public
|
||||
%class ZigStringLexer
|
||||
%implements FlexLexer
|
||||
%function advance
|
||||
%type IElementType
|
||||
|
||||
hex=[0-9a-fA-F]
|
||||
|
||||
char_escape_unicode= "\\x" {hex} {hex} | "\\u{" {hex}+ "}"
|
||||
char_escape_unicode_invalid= "\\x" | "\\u"
|
||||
|
||||
char_escape_single_valid= "\\" [nr\\t'\"]
|
||||
char_escape_single_invalid= "\\" [^nr\\t'\"]
|
||||
|
||||
non_escape= [^\\\"\n]
|
||||
|
||||
|
||||
%state STR
|
||||
%%
|
||||
|
||||
|
||||
<YYINITIAL> {
|
||||
"\"" { yybegin(STR); return STRING_LITERAL_SINGLE; }
|
||||
[^] { return STRING_LITERAL_SINGLE; }
|
||||
}
|
||||
|
||||
<STR> {
|
||||
{char_escape_unicode} { return VALID_STRING_ESCAPE_TOKEN; }
|
||||
{char_escape_unicode_invalid} { return INVALID_UNICODE_ESCAPE_TOKEN; }
|
||||
{char_escape_single_valid} { return VALID_STRING_ESCAPE_TOKEN; }
|
||||
{char_escape_single_invalid} { return INVALID_CHARACTER_ESCAPE_TOKEN; }
|
||||
[^] { return STRING_LITERAL_SINGLE; }
|
||||
}
|
|
@ -63,6 +63,9 @@ public class ZigColorSettingsPage implements ColorSettingsPage {
|
|||
new AttributesDescriptor("Property//Declaration", ZigSyntaxHighlighter.PROPERTY_DECL),
|
||||
new AttributesDescriptor("Property//Reference", ZigSyntaxHighlighter.PROPERTY_REF),
|
||||
new AttributesDescriptor("String", ZigSyntaxHighlighter.STRING),
|
||||
new AttributesDescriptor("String//Escape", ZigSyntaxHighlighter.STRING_ESC_V),
|
||||
new AttributesDescriptor("String//Escape//Invalid char", ZigSyntaxHighlighter.STRING_ESC_I_C),
|
||||
new AttributesDescriptor("String//Escape//Invalid unicode", ZigSyntaxHighlighter.STRING_ESC_I_U),
|
||||
new AttributesDescriptor("Struct//Declaration", ZigSyntaxHighlighter.STRUCT_DECL),
|
||||
new AttributesDescriptor("Struct//Reference", ZigSyntaxHighlighter.STRUCT_REF),
|
||||
new AttributesDescriptor("Type//Declaration", ZigSyntaxHighlighter.TYPE_DECL),
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.falsepattern.zigbrains.zig.highlighter;
|
||||
|
||||
import com.falsepattern.zigbrains.zig.lexer.ZigHighlightingLexer;
|
||||
import com.falsepattern.zigbrains.zig.lexer.ZigLexerAdapter;
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes;
|
||||
import com.intellij.lexer.Lexer;
|
||||
|
@ -23,6 +24,7 @@ import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
|
|||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.redhat.devtools.lsp4ij.features.semanticTokens.SemanticTokensHighlightingColors;
|
||||
|
@ -35,48 +37,51 @@ import java.util.Map;
|
|||
public class ZigSyntaxHighlighter extends SyntaxHighlighterBase {
|
||||
// @formatter:off
|
||||
public static final TextAttributesKey
|
||||
BAD_CHAR = createKey("BAD_CHARACTER" , HighlighterColors.BAD_CHARACTER ),
|
||||
BUILTIN = createKey("BUILTIN" , SemanticTokensHighlightingColors.STATIC_METHOD ),
|
||||
CHAR = createKey("CHAR" , SemanticTokensHighlightingColors.NUMBER ),
|
||||
COMMENT = createKey("COMMENT" , SemanticTokensHighlightingColors.COMMENT ),
|
||||
COMMENT_DOC = createKey("COMMENT_DOC" , DefaultLanguageHighlighterColors.DOC_COMMENT ),
|
||||
ENUM_DECL = createKey("ENUM_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
ENUM_REF = createKey("ENUM" , SemanticTokensHighlightingColors.CLASS ),
|
||||
ENUM_MEMBER_DECL = createKey("ENUM_MEMBER_DECL" , SemanticTokensHighlightingColors.STATIC_PROPERTY ),
|
||||
ENUM_MEMBER_REF = createKey("ENUM_MEMBER" , ENUM_MEMBER_DECL ),
|
||||
ERROR_TAG_DECL = createKey("ERROR_TAG_DECL" , SemanticTokensHighlightingColors.STATIC_PROPERTY ),
|
||||
ERROR_TAG_REF = createKey("ERROR_TAG" , ERROR_TAG_DECL ),
|
||||
PROPERTY_DECL = createKey("PROPERTY_DECL" , SemanticTokensHighlightingColors.PROPERTY ),
|
||||
PROPERTY_REF = createKey("PROPERTY" , PROPERTY_DECL ),
|
||||
FUNCTION_DECL = createKey("FUNCTION_DECL" , SemanticTokensHighlightingColors.FUNCTION_DECLARATION),
|
||||
FUNCTION_DECL_GEN = createKey("FUNCTION_DECL_GEN" , FUNCTION_DECL ),
|
||||
FUNCTION_REF = createKey("FUNCTION" , SemanticTokensHighlightingColors.FUNCTION ),
|
||||
FUNCTION_REF_GEN = createKey("FUNCTION_GEN" , FUNCTION_REF ),
|
||||
KEYWORD = createKey("KEYWORD" , SemanticTokensHighlightingColors.KEYWORD ),
|
||||
LABEL_DECL = createKey("LABEL_DECL" , SemanticTokensHighlightingColors.LABEL ),
|
||||
LABEL_REF = createKey("LABEL" , LABEL_DECL ),
|
||||
METHOD_DECL = createKey("METHOD_DECL" , FUNCTION_DECL ),
|
||||
METHOD_DECL_GEN = createKey("METHOD_DECL_GEN" , METHOD_DECL ),
|
||||
METHOD_REF = createKey("METHOD" , FUNCTION_REF ),
|
||||
METHOD_REF_GEN = createKey("METHOD_GEN" , METHOD_REF ),
|
||||
NAMESPACE_DECL = createKey("NAMESPACE_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
NAMESPACE_REF = createKey("NAMESPACE" , SemanticTokensHighlightingColors.CLASS ),
|
||||
NUMBER = createKey("NUMBER" , SemanticTokensHighlightingColors.NUMBER ),
|
||||
OPERATOR = createKey("OPERATOR" , SemanticTokensHighlightingColors.OPERATOR ),
|
||||
PARAMETER = createKey("PARAMETER" , SemanticTokensHighlightingColors.PARAMETER ),
|
||||
STRING = createKey("STRING" , SemanticTokensHighlightingColors.STRING ),
|
||||
STRUCT_DECL = createKey("STRUCT_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
STRUCT_REF = createKey("STRUCT" , SemanticTokensHighlightingColors.CLASS ),
|
||||
TYPE_DECL = createKey("TYPE_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
TYPE_DECL_GEN = createKey("TYPE_DECL_GEN" , TYPE_DECL ),
|
||||
TYPE_REF = createKey("TYPE" , SemanticTokensHighlightingColors.TYPE ),
|
||||
TYPE_REF_GEN = createKey("TYPE_GEN" , TYPE_REF ),
|
||||
TYPE_PARAM = createKey("TYPE_PARAM" , SemanticTokensHighlightingColors.TYPE_PARAMETER ),
|
||||
TYPE_PARAM_DECL = createKey("TYPE_PARAM_DECL" , TYPE_PARAM ),
|
||||
VARIABLE_DECL = createKey("VARIABLE_DECL" , DefaultLanguageHighlighterColors.LOCAL_VARIABLE ),
|
||||
VARIABLE_DECL_DEPR= createKey("VARIABLE_DECL_DEPR" , VARIABLE_DECL ),
|
||||
VARIABLE_REF = createKey("VARIABLE" , VARIABLE_DECL ),
|
||||
VARIABLE_REF_DEPR = createKey("VARIABLE_REF_DEPL" , VARIABLE_REF );
|
||||
BAD_CHAR = createKey("BAD_CHARACTER" , HighlighterColors.BAD_CHARACTER ),
|
||||
BUILTIN = createKey("BUILTIN" , SemanticTokensHighlightingColors.STATIC_METHOD ),
|
||||
CHAR = createKey("CHAR" , SemanticTokensHighlightingColors.NUMBER ),
|
||||
COMMENT = createKey("COMMENT" , SemanticTokensHighlightingColors.COMMENT ),
|
||||
COMMENT_DOC = createKey("COMMENT_DOC" , DefaultLanguageHighlighterColors.DOC_COMMENT ),
|
||||
ENUM_DECL = createKey("ENUM_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
ENUM_REF = createKey("ENUM" , SemanticTokensHighlightingColors.CLASS ),
|
||||
ENUM_MEMBER_DECL = createKey("ENUM_MEMBER_DECL" , SemanticTokensHighlightingColors.STATIC_PROPERTY ),
|
||||
ENUM_MEMBER_REF = createKey("ENUM_MEMBER" , ENUM_MEMBER_DECL ),
|
||||
ERROR_TAG_DECL = createKey("ERROR_TAG_DECL" , SemanticTokensHighlightingColors.STATIC_PROPERTY ),
|
||||
ERROR_TAG_REF = createKey("ERROR_TAG" , ERROR_TAG_DECL ),
|
||||
PROPERTY_DECL = createKey("PROPERTY_DECL" , SemanticTokensHighlightingColors.PROPERTY ),
|
||||
PROPERTY_REF = createKey("PROPERTY" , PROPERTY_DECL ),
|
||||
FUNCTION_DECL = createKey("FUNCTION_DECL" , SemanticTokensHighlightingColors.FUNCTION_DECLARATION ),
|
||||
FUNCTION_DECL_GEN = createKey("FUNCTION_DECL_GEN" , FUNCTION_DECL ),
|
||||
FUNCTION_REF = createKey("FUNCTION" , SemanticTokensHighlightingColors.FUNCTION ),
|
||||
FUNCTION_REF_GEN = createKey("FUNCTION_GEN" , FUNCTION_REF ),
|
||||
KEYWORD = createKey("KEYWORD" , SemanticTokensHighlightingColors.KEYWORD ),
|
||||
LABEL_DECL = createKey("LABEL_DECL" , SemanticTokensHighlightingColors.LABEL ),
|
||||
LABEL_REF = createKey("LABEL" , LABEL_DECL ),
|
||||
METHOD_DECL = createKey("METHOD_DECL" , FUNCTION_DECL ),
|
||||
METHOD_DECL_GEN = createKey("METHOD_DECL_GEN" , METHOD_DECL ),
|
||||
METHOD_REF = createKey("METHOD" , FUNCTION_REF ),
|
||||
METHOD_REF_GEN = createKey("METHOD_GEN" , METHOD_REF ),
|
||||
NAMESPACE_DECL = createKey("NAMESPACE_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
NAMESPACE_REF = createKey("NAMESPACE" , SemanticTokensHighlightingColors.CLASS ),
|
||||
NUMBER = createKey("NUMBER" , SemanticTokensHighlightingColors.NUMBER ),
|
||||
OPERATOR = createKey("OPERATOR" , SemanticTokensHighlightingColors.OPERATOR ),
|
||||
PARAMETER = createKey("PARAMETER" , SemanticTokensHighlightingColors.PARAMETER ),
|
||||
STRING = createKey("STRING" , SemanticTokensHighlightingColors.STRING ),
|
||||
STRING_ESC_V = createKey("STRING_ESC_V" , DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE ),
|
||||
STRING_ESC_I_C = createKey("STRING_ESC_I_C" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE ),
|
||||
STRING_ESC_I_U = createKey("STRING_ESC_I_U" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE ),
|
||||
STRUCT_DECL = createKey("STRUCT_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
STRUCT_REF = createKey("STRUCT" , SemanticTokensHighlightingColors.CLASS ),
|
||||
TYPE_DECL = createKey("TYPE_DECL" , SemanticTokensHighlightingColors.CLASS_DECLARATION ),
|
||||
TYPE_DECL_GEN = createKey("TYPE_DECL_GEN" , TYPE_DECL ),
|
||||
TYPE_REF = createKey("TYPE" , SemanticTokensHighlightingColors.TYPE ),
|
||||
TYPE_REF_GEN = createKey("TYPE_GEN" , TYPE_REF ),
|
||||
TYPE_PARAM = createKey("TYPE_PARAM" , SemanticTokensHighlightingColors.TYPE_PARAMETER ),
|
||||
TYPE_PARAM_DECL = createKey("TYPE_PARAM_DECL" , TYPE_PARAM ),
|
||||
VARIABLE_DECL = createKey("VARIABLE_DECL" , DefaultLanguageHighlighterColors.LOCAL_VARIABLE ),
|
||||
VARIABLE_DECL_DEPR= createKey("VARIABLE_DECL_DEPR" , VARIABLE_DECL ),
|
||||
VARIABLE_REF = createKey("VARIABLE" , VARIABLE_DECL ),
|
||||
VARIABLE_REF_DEPR = createKey("VARIABLE_REF_DEPL" , VARIABLE_REF );
|
||||
// @formatter:on
|
||||
private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0];
|
||||
private static final Map<IElementType, TextAttributesKey[]> KEYMAP = new HashMap<>();
|
||||
|
@ -102,6 +107,9 @@ public class ZigSyntaxHighlighter extends SyntaxHighlighterBase {
|
|||
}
|
||||
addMapping(BUILTIN, ZigTypes.BUILTINIDENTIFIER);
|
||||
addMapping(STRING, ZigTypes.STRING_LITERAL_SINGLE, ZigTypes.STRING_LITERAL_MULTI);
|
||||
addMapping(STRING_ESC_V, StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN);
|
||||
addMapping(STRING_ESC_I_C, StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN);
|
||||
addMapping(STRING_ESC_I_U, StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN);
|
||||
addMapping(BAD_CHAR, TokenType.BAD_CHARACTER);
|
||||
addMapping(NUMBER, ZigTypes.INTEGER, ZigTypes.FLOAT);
|
||||
addMapping(CHAR, ZigTypes.CHAR_LITERAL);
|
||||
|
@ -120,7 +128,7 @@ public class ZigSyntaxHighlighter extends SyntaxHighlighterBase {
|
|||
|
||||
@Override
|
||||
public @NotNull Lexer getHighlightingLexer() {
|
||||
return new ZigLexerAdapter();
|
||||
return new ZigHighlightingLexer();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package com.falsepattern.zigbrains.zig.lexer;
|
||||
|
||||
import com.falsepattern.zigbrains.zig.psi.ZigTypes;
|
||||
import com.intellij.lexer.FlexAdapter;
|
||||
import com.intellij.lexer.LayeredLexer;
|
||||
import com.intellij.lexer.MergingLexerAdapter;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import lombok.val;
|
||||
|
||||
public class ZigHighlightingLexer extends LayeredLexer {
|
||||
public ZigHighlightingLexer() {
|
||||
super(new ZigLexerAdapter());
|
||||
val stringLexer = new MergingLexerAdapter(new FlexAdapter(new com.falsepattern.zigbrains.zig.stringlexer.ZigStringLexer(null)), TokenSet.create(
|
||||
ZigTypes.STRING_LITERAL_SINGLE));
|
||||
registerSelfStoppingLayer(stringLexer, new IElementType[]{ZigTypes.STRING_LITERAL_SINGLE}, IElementType.EMPTY_ARRAY);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue