port the rest of the built-in zig features

This commit is contained in:
FalsePattern 2024-10-29 10:40:45 +01:00
parent d5fc288ffd
commit 19b0b09826
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
12 changed files with 520 additions and 12 deletions

View file

@ -17,20 +17,22 @@ val rootPackagePath = "com/falsepattern/zigbrains/zig"
val parserDir = layout.buildDirectory.dir("$grammarGenRoot/parser")
val lexerDir = layout.buildDirectory.dir("$grammarGenRoot/lexer")
val lexerStringDir = layout.buildDirectory.dir("$grammarGenRoot/lexerstring")
sourceSets {
main {
java {
srcDir(parserDir)
srcDir(lexerDir)
srcDir(lexerStringDir)
}
}
}
idea {
module {
sourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile))
generatedSourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile))
sourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile, lexerStringDir.get().asFile))
generatedSourceDirs.addAll(listOf(parserDir.get().asFile, lexerDir.get().asFile, lexerStringDir.get().asFile))
}
}
@ -41,10 +43,10 @@ tasks {
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/lexer/$rootPackagePath/lexer")
}
register<GenerateLexerTask>("generateStringLexer") {
register<GenerateLexerTask>("generateLexerString") {
purgeOldFiles = true
sourceFile = file("src/main/grammar/ZigString.flex")
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/stringlexer/$rootPackagePath/stringlexer")
targetOutputDir = layout.buildDirectory.dir("$grammarGenRoot/lexerstring/$rootPackagePath/lexerstring")
}
@ -59,7 +61,7 @@ tasks {
register<DefaultTask>("generateGrammars") {
group = "grammarkit"
dependsOn("generateLexer")
dependsOn("generateStringLexer")
dependsOn("generateLexerString")
dependsOn("generateParser")
}

View file

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zig.stringlexer;
package com.falsepattern.zigbrains.zig.lexerstring;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
@ -26,15 +26,10 @@ import static com.intellij.psi.StringEscapesTokenTypes.*;
%%
%public
%class ZigStringLexer
%class ZigLexerString
%implements FlexLexer
%function advance
%type IElementType
%{
public ZigStringLexer() {
}
%}
hex=[0-9a-fA-F]

View file

@ -0,0 +1,41 @@
package com.falsepattern.zigbrains.zig.comments
import com.falsepattern.zigbrains.zig.psi.ZigTypes
import com.intellij.codeInsight.generation.IndentedCommenter
import com.intellij.lang.CodeDocumentationAwareCommenter
import com.intellij.psi.PsiComment
import com.intellij.psi.tree.IElementType
class ZigCommenter: CodeDocumentationAwareCommenter, IndentedCommenter {
override fun getLineCommentPrefix() = COMMENT
override fun getBlockCommentPrefix() = null
override fun getBlockCommentSuffix() = null
override fun getCommentedBlockCommentPrefix() = null
override fun getCommentedBlockCommentSuffix() = null
override fun forceIndentedLineComment() = true
override fun getLineCommentTokenType() = ZigTypes.LINE_COMMENT!!
override fun getBlockCommentTokenType() = null
override fun getDocumentationCommentTokenType() = ZigTypes.DOC_COMMENT!!
override fun getDocumentationCommentPrefix() = null
override fun getDocumentationCommentLinePrefix() = DOC_COMMENT
override fun getDocumentationCommentSuffix() = null
override fun isDocumentationComment(element: PsiComment?): Boolean {
val type = element?.tokenType ?: return false
return type == ZigTypes.DOC_COMMENT || type == ZigTypes.CONTAINER_DOC_COMMENT
}
}
const val COMMENT = "// "
const val DOC_COMMENT = "/// "

View file

@ -0,0 +1,136 @@
package com.falsepattern.zigbrains.zig.formatter
import com.intellij.formatting.*
import com.intellij.lang.ASTNode
import com.intellij.psi.TokenType
import com.intellij.psi.formatter.common.AbstractBlock
import com.intellij.psi.tree.IElementType
import com.falsepattern.zigbrains.zig.psi.ZigTypes.*
class ZigBlock(
node: ASTNode,
wrap: Wrap?,
alignment: Alignment?,
val spacingBuilder: SpacingBuilder
) : AbstractBlock(node, wrap, alignment) {
override fun getSpacing(child1: Block?, child2: Block) = null
override fun isLeaf() = myNode.firstChildNode == null
override fun buildChildren(): MutableList<Block> {
val blocks = ArrayList<Block>()
var child = myNode.firstChildNode
while (child != null) {
if (child.elementType != TokenType.WHITE_SPACE) {
blocks.add(ZigBlock(child, null, null, spacingBuilder))
}
child = child.treeNext
}
return blocks
}
override fun getChildIndent(): Indent {
val node = this.node
return getIndentBasedOnParentType(node, null, node.elementType, PLACEHOLDER)
}
override fun getIndent(): Indent {
val node = this.node
val parent = node.treeParent ?: return noneIndent
return getIndentBasedOnParentType(parent, node, parent.elementType, node.elementType)
}
}
private fun getIndentBasedOnParentType(
parent: ASTNode,
child: ASTNode?,
parentType: IElementType,
childType: IElementType
): Indent {
//Statement blocks
if (parentType == BLOCK && !childType.isBrace)
return normalIndent
//Struct/tuple initializers
if (parentType == INIT_LIST && !childType.isBrace)
return normalIndent
//Function call args
if (parentType == EXPR_LIST ||
parentType == FN_CALL_ARGUMENTS && childType === PLACEHOLDER
)
return normalIndent
//Function declaration parameters
if (parentType == PARAM_DECL_LIST ||
parentType == FN_PROTO && childType === PLACEHOLDER
)
return normalIndent
//Chained operations on newlines
if ((parentType == BOOL_OR_EXPR ||
parentType == BOOL_AND_EXPR ||
parentType == COMPARE_EXPR ||
parentType == BITWISE_EXPR ||
parentType == BIT_SHIFT_EXPR ||
parentType == ADDITION_EXPR ||
parentType == MULTIPLY_EXPR) &&
parent.firstChildNode != child
)
return normalIndent
//Switch prongs
if (parentType == SWITCH_PRONG_LIST ||
parentType == SWITCH_EXPR && childType == PLACEHOLDER
)
return normalIndent
//If expressions/statements
if ((parentType == IF_EXPR ||
parentType == IF_STATEMENT) &&
childType != KEYWORD_ELSE &&
childType != IF_PREFIX
)
return normalIndent
//Struct members
if (parentType == CONTAINER_DECL_AUTO &&
childType != CONTAINER_DECL_TYPE &&
childType != CONTAINER_DOC_COMMENT &&
!childType.isBrace
)
return normalIndent
//Inline assembly body
if (parentType == ASM_EXPR &&
childType != KEYWORD_ASM &&
childType != KEYWORD_VOLATILE &&
!childType.isParen)
return normalIndent
//Assembly params
if (parentType == ASM_INPUT_LIST || parentType == ASM_OUTPUT_LIST)
return spaceIndent(2)
return noneIndent
}
private val normalIndent: Indent get() = Indent.getNormalIndent()
private fun spaceIndent(spaces: Int) = Indent.getSpaceIndent(2)
private val noneIndent: Indent get() = Indent.getNoneIndent()
private val IElementType?.isBrace: Boolean
get() {
return this == LBRACE || this == RBRACE
}
private val IElementType?.isParen: Boolean
get() {
return this == LPAREN || this == RPAREN
}
private val PLACEHOLDER = IElementType("placeholder", null)

View file

@ -0,0 +1,15 @@
package com.falsepattern.zigbrains.zig.formatter
import com.falsepattern.zigbrains.zig.ZigLanguage
import com.intellij.formatting.*
class ZigFormattingModelBuilder: FormattingModelBuilder {
override fun createModel(context: FormattingContext): FormattingModel {
val settings = context.codeStyleSettings
return FormattingModelProvider.createFormattingModelForPsiFile(
context.containingFile,
ZigBlock(context.node, null, null, SpacingBuilder(settings, ZigLanguage)),
settings
)
}
}

View file

@ -0,0 +1,140 @@
package com.falsepattern.zigbrains.zig.highlighter
import com.falsepattern.zigbrains.zig.Icons
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.options.colors.AttributesDescriptor
import com.intellij.openapi.options.colors.ColorDescriptor
import com.intellij.openapi.options.colors.ColorSettingsPage
import kotlinx.collections.immutable.toImmutableMap
class ZigColorSettingsPage: ColorSettingsPage {
override fun getAttributeDescriptors() = DESCRIPTORS
override fun getColorDescriptors(): Array<ColorDescriptor> = ColorDescriptor.EMPTY_ARRAY
override fun getDisplayName() = "Zig"
override fun getIcon() = Icons.ZIG
override fun getHighlighter() = ZigSyntaxHighlighter()
override fun getDemoText() = """
///This is a documentation comment
const <ns_decl>std</ns_decl> = @import("std");
const <enum_decl>AnEnum</enum_decl> = enum {
<enum_member_decl>A</enum_member_decl>,
<enum_member_decl>B</enum_member_decl>,
<enum_member_decl>C</enum_member_decl>,
};
const <struct_decl>AStruct</struct_decl> = struct {
<property_decl>fieldA</property_decl>: <type>u32</type>,
<property_decl>fieldB</property_decl>: <type>u16</type>
};
const <type_decl>AnError</type_decl> = error {
<error_tag_decl>SomeError</error_tag_decl>
};
pub fn <function_decl>main</function_decl>() <type>AnError</type>.<error_tag>SomeError</error_tag>!<type>void</type> {
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
<namespace>std</namespace>.<namespace>debug</namespace>.<function>print</function>("All your {s} are belong to us.\n", .{"codebase"});
// stdout is for the actual output of your application, for example if you
// are implementing gzip, then only the compressed bytes should be sent to
// stdout, not any debugging messages.
const <variable_decl>stdout_file</variable_decl> = <namespace>std</namespace>.<namespace>io</namespace>.<function>getStdOut</function>().<method>writer</method>();
var <variable_decl>bw</variable_decl> = <namespace>std</namespace>.<namespace>io</namespace>.<function>bufferedWriter</function>(<variable>stdout_file</variable>);
const <variable_decl>stdout</variable_decl> = <variable>bw</variable>.<method>writer</method>();
try <variable>stdout</variable>.<method>print</method>(\\Run `zig build test` to run the tests.
\\
, .{});
_ = <enum>AnEnum</enum>.<enum_member>A</enum_member>;
try <variable>bw</variable>.<method>flush</method>(); // don't forget to flush!
}
test "simple test" {
var <variable_decl>list</variable_decl> = <namespace>std</namespace>.<type>ArrayList</type>(<type>i32</type>).<function>init</function>(<namespace>std</namespace>.<namespace>testing</namespace>.<variable>allocator</variable>);
defer <variable>list</variable>.<method>deinit</method>(); // try commenting this out and see if zig detects the memory leak!
try <variable>list</variable>.<method>append</method>(42);
try <namespace>std</namespace>.<namespace>testing</namespace>.<method_gen>expectEqual</method_gen>(@as(<type>i32</type>, 42), <variable>list</variable>.<method>pop</method>());
}
""".trimIndent()
override fun getAdditionalHighlightingTagToDescriptorMap() =
ADD_HIGHLIGHT
}
private val ADD_HIGHLIGHT = HashMap<String, TextAttributesKey>().apply {
this["enum"] = ZigSyntaxHighlighter.ENUM_REF
this["enum_decl"] = ZigSyntaxHighlighter.ENUM_DECL
this["enum_member"] = ZigSyntaxHighlighter.ENUM_MEMBER_REF
this["enum_member_decl"] = ZigSyntaxHighlighter.ENUM_MEMBER_DECL
this["error_tag"] = ZigSyntaxHighlighter.ERROR_TAG_REF
this["error_tag_decl"] = ZigSyntaxHighlighter.ERROR_TAG_DECL
this["function"] = ZigSyntaxHighlighter.FUNCTION_REF
this["function_decl"] = ZigSyntaxHighlighter.FUNCTION_DECL
this["method"] = ZigSyntaxHighlighter.METHOD_REF
this["method_gen"] = ZigSyntaxHighlighter.METHOD_REF_GEN
this["namespace"] = ZigSyntaxHighlighter.NAMESPACE_REF
this["property_decl"] = ZigSyntaxHighlighter.PROPERTY_DECL
this["struct"] = ZigSyntaxHighlighter.STRUCT_REF
this["struct_decl"] = ZigSyntaxHighlighter.STRUCT_DECL
this["type"] = ZigSyntaxHighlighter.TYPE_REF
this["type_decl"] = ZigSyntaxHighlighter.TYPE_DECL
this["variable"] = ZigSyntaxHighlighter.VARIABLE_REF
this["variable_decl"] = ZigSyntaxHighlighter.VARIABLE_DECL
}.toImmutableMap()
private val DESCRIPTORS: Array<AttributesDescriptor> = arrayOf(
AttributesDescriptor("Bad character", ZigSyntaxHighlighter.BAD_CHAR),
AttributesDescriptor("Builtin", ZigSyntaxHighlighter.BUILTIN),
AttributesDescriptor("Character literal", ZigSyntaxHighlighter.CHAR),
AttributesDescriptor("Comment//Regular", ZigSyntaxHighlighter.COMMENT),
AttributesDescriptor("Comment//Documentation", ZigSyntaxHighlighter.COMMENT_DOC),
AttributesDescriptor("Enum//Reference", ZigSyntaxHighlighter.ENUM_REF),
AttributesDescriptor("Enum//Declaration", ZigSyntaxHighlighter.ENUM_DECL),
AttributesDescriptor("Enum//Member//Declaration", ZigSyntaxHighlighter.ENUM_MEMBER_DECL),
AttributesDescriptor("Enum//Member//Reference", ZigSyntaxHighlighter.ENUM_MEMBER_REF),
AttributesDescriptor("Error tag//Declaration", ZigSyntaxHighlighter.ERROR_TAG_DECL),
AttributesDescriptor("Error tag//Reference", ZigSyntaxHighlighter.ERROR_TAG_REF),
AttributesDescriptor("Function//Declaration", ZigSyntaxHighlighter.FUNCTION_DECL),
AttributesDescriptor("Function//Declaration//Generic", ZigSyntaxHighlighter.FUNCTION_DECL_GEN),
AttributesDescriptor("Function//Reference", ZigSyntaxHighlighter.FUNCTION_REF),
AttributesDescriptor("Function//Reference//Generic", ZigSyntaxHighlighter.FUNCTION_REF_GEN),
AttributesDescriptor("Keyword", ZigSyntaxHighlighter.KEYWORD),
AttributesDescriptor("Label//Declaration", ZigSyntaxHighlighter.LABEL_REF),
AttributesDescriptor("Label//Reference", ZigSyntaxHighlighter.LABEL_REF),
AttributesDescriptor("Method//Declaration", ZigSyntaxHighlighter.METHOD_DECL),
AttributesDescriptor("Method//Declaration//Generic", ZigSyntaxHighlighter.METHOD_DECL_GEN),
AttributesDescriptor("Method//Reference", ZigSyntaxHighlighter.METHOD_REF),
AttributesDescriptor("Method//Reference//Generic", ZigSyntaxHighlighter.METHOD_REF_GEN),
AttributesDescriptor("Namespace//Declaration", ZigSyntaxHighlighter.NAMESPACE_DECL),
AttributesDescriptor("Namespace//Reference", ZigSyntaxHighlighter.NAMESPACE_REF),
AttributesDescriptor("Number", ZigSyntaxHighlighter.NUMBER),
AttributesDescriptor("Operator", ZigSyntaxHighlighter.OPERATOR),
AttributesDescriptor("Parameter", ZigSyntaxHighlighter.PARAMETER),
AttributesDescriptor("Property//Declaration", ZigSyntaxHighlighter.PROPERTY_DECL),
AttributesDescriptor("Property//Reference", ZigSyntaxHighlighter.PROPERTY_REF),
AttributesDescriptor("String", ZigSyntaxHighlighter.STRING),
AttributesDescriptor("String//Escape", ZigSyntaxHighlighter.STRING_ESC_V),
AttributesDescriptor("String//Escape//Invalid char", ZigSyntaxHighlighter.STRING_ESC_I_C),
AttributesDescriptor("String//Escape//Invalid unicode", ZigSyntaxHighlighter.STRING_ESC_I_U),
AttributesDescriptor("Struct//Declaration", ZigSyntaxHighlighter.STRUCT_DECL),
AttributesDescriptor("Struct//Reference", ZigSyntaxHighlighter.STRUCT_REF),
AttributesDescriptor("Type//Declaration", ZigSyntaxHighlighter.TYPE_DECL),
AttributesDescriptor("Type//Declaration//Generic", ZigSyntaxHighlighter.TYPE_DECL_GEN),
AttributesDescriptor("Type//Reference", ZigSyntaxHighlighter.TYPE_REF),
AttributesDescriptor("Type//Reference//Generic", ZigSyntaxHighlighter.TYPE_REF_GEN),
AttributesDescriptor("Type parameter//Reference", ZigSyntaxHighlighter.TYPE_PARAM),
AttributesDescriptor("Type parameter//Declaration", ZigSyntaxHighlighter.TYPE_PARAM_DECL),
AttributesDescriptor("Variable//Declaration", ZigSyntaxHighlighter.VARIABLE_DECL),
AttributesDescriptor("Variable//Declaration//Deprecated", ZigSyntaxHighlighter.VARIABLE_DECL_DEPR),
AttributesDescriptor("Variable//Reference", ZigSyntaxHighlighter.VARIABLE_REF),
AttributesDescriptor("Variable//Reference//Deprecated", ZigSyntaxHighlighter.VARIABLE_REF_DEPR),
)

View file

@ -0,0 +1,104 @@
package com.falsepattern.zigbrains.zig.highlighter
import com.falsepattern.zigbrains.zig.lexer.ZigHighlightingLexer
import com.falsepattern.zigbrains.zig.psi.ZigTypes
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
class ZigSyntaxHighlighter: SyntaxHighlighterBase() {
override fun getHighlightingLexer() = ZigHighlightingLexer()
override fun getTokenHighlights(tokenType: IElementType?) =
KEYMAP.getOrDefault(tokenType, EMPTY_KEYS)
companion object {
// @formatter:off
val BAD_CHAR = createKey("BAD_CHARACTER" , HighlighterColors.BAD_CHARACTER )
val BUILTIN = createKey("BUILTIN" , DefaultLanguageHighlighterColors.STATIC_METHOD )
val CHAR = createKey("CHAR" , DefaultLanguageHighlighterColors.NUMBER )
val COMMENT = createKey("COMMENT" , DefaultLanguageHighlighterColors.LINE_COMMENT )
val COMMENT_DOC = createKey("COMMENT_DOC" , DefaultLanguageHighlighterColors.DOC_COMMENT )
val ENUM_DECL = createKey("ENUM_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
val ENUM_REF = createKey("ENUM" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
val ENUM_MEMBER_DECL = createKey("ENUM_MEMBER_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
val ENUM_MEMBER_REF = createKey("ENUM_MEMBER" , ENUM_MEMBER_DECL )
val ERROR_TAG_DECL = createKey("ERROR_TAG_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
val ERROR_TAG_REF = createKey("ERROR_TAG" , ERROR_TAG_DECL )
val PROPERTY_DECL = createKey("PROPERTY_DECL" , DefaultLanguageHighlighterColors.STATIC_FIELD )
val PROPERTY_REF = createKey("PROPERTY" , PROPERTY_DECL )
val FUNCTION_DECL = createKey("FUNCTION_DECL" , DefaultLanguageHighlighterColors.FUNCTION_DECLARATION )
val FUNCTION_DECL_GEN = createKey("FUNCTION_DECL_GEN" , FUNCTION_DECL )
val FUNCTION_REF = createKey("FUNCTION" , DefaultLanguageHighlighterColors.FUNCTION_CALL )
val FUNCTION_REF_GEN = createKey("FUNCTION_GEN" , FUNCTION_REF )
val KEYWORD = createKey("KEYWORD" , DefaultLanguageHighlighterColors.KEYWORD )
val LABEL_DECL = createKey("LABEL_DECL" , DefaultLanguageHighlighterColors.LABEL )
val LABEL_REF = createKey("LABEL" , LABEL_DECL )
val METHOD_DECL = createKey("METHOD_DECL" , FUNCTION_DECL )
val METHOD_DECL_GEN = createKey("METHOD_DECL_GEN" , METHOD_DECL )
val METHOD_REF = createKey("METHOD" , FUNCTION_REF )
val METHOD_REF_GEN = createKey("METHOD_GEN" , METHOD_REF )
val NAMESPACE_DECL = createKey("NAMESPACE_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
val NAMESPACE_REF = createKey("NAMESPACE" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
val NUMBER = createKey("NUMBER" , DefaultLanguageHighlighterColors.NUMBER )
val OPERATOR = createKey("OPERATOR" , DefaultLanguageHighlighterColors.OPERATION_SIGN )
val PARAMETER = createKey("PARAMETER" , DefaultLanguageHighlighterColors.PARAMETER )
val STRING = createKey("STRING" , DefaultLanguageHighlighterColors.STRING )
val STRING_ESC_V = createKey("STRING_ESC_V" , DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE )
val STRING_ESC_I_C = createKey("STRING_ESC_I_C" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE )
val STRING_ESC_I_U = createKey("STRING_ESC_I_U" , DefaultLanguageHighlighterColors.INVALID_STRING_ESCAPE )
val STRUCT_DECL = createKey("STRUCT_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
val STRUCT_REF = createKey("STRUCT" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
val TYPE_DECL = createKey("TYPE_DECL" , DefaultLanguageHighlighterColors.CLASS_NAME )
val TYPE_DECL_GEN = createKey("TYPE_DECL_GEN" , TYPE_DECL )
val TYPE_REF = createKey("TYPE" , DefaultLanguageHighlighterColors.CLASS_REFERENCE )
val TYPE_REF_GEN = createKey("TYPE_GEN" , TYPE_REF )
val TYPE_PARAM = createKey("TYPE_PARAM" , DefaultLanguageHighlighterColors.PARAMETER )
val TYPE_PARAM_DECL = createKey("TYPE_PARAM_DECL" , TYPE_PARAM )
val VARIABLE_DECL = createKey("VARIABLE_DECL" , DefaultLanguageHighlighterColors.LOCAL_VARIABLE )
val VARIABLE_DECL_DEPR= createKey("VARIABLE_DECL_DEPR" , VARIABLE_DECL )
val VARIABLE_REF = createKey("VARIABLE" , VARIABLE_DECL )
val VARIABLE_REF_DEPR = createKey("VARIABLE_REF_DEPL" , VARIABLE_REF )
// @formatter:on
private val EMPTY_KEYS = arrayOf<TextAttributesKey>()
private val KEYMAP = HashMap<IElementType, Array<TextAttributesKey>>()
init {
addMapping(COMMENT, ZigTypes.LINE_COMMENT)
addMapping(COMMENT_DOC, ZigTypes.DOC_COMMENT, ZigTypes.CONTAINER_DOC_COMMENT)
addMapping(
KEYWORD,
*ZigTypes::class.java
.fields
.filter { it.name.startsWith("KEYWORD_") }
.map { it.get(null) as IElementType }
.toTypedArray()
)
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)
}
private fun addMapping(key: TextAttributesKey, vararg types: IElementType) {
val a = arrayOf(key)
for (type in types) {
KEYMAP[type] = a
}
}
private fun createKey(name: String, fallback: TextAttributesKey) =
TextAttributesKey.createTextAttributesKey("ZIG_$name", fallback)
}
}

View file

@ -0,0 +1,11 @@
package com.falsepattern.zigbrains.zig.highlighter
import com.intellij.openapi.fileTypes.SyntaxHighlighter
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
class ZigSyntaxHighlighterFactory: SyntaxHighlighterFactory() {
override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?) =
ZigSyntaxHighlighter()
}

View file

@ -0,0 +1,21 @@
package com.falsepattern.zigbrains.zig.lexer
import com.falsepattern.zigbrains.zig.lexerstring.ZigLexerStringAdapter
import com.falsepattern.zigbrains.zig.psi.ZigTypes
import com.intellij.lexer.LayeredLexer
import com.intellij.lexer.MergingLexerAdapter
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
class ZigHighlightingLexer: LayeredLexer(ZigLexerAdapter()) {
init {
registerSelfStoppingLayer(
MergingLexerAdapter(
ZigLexerStringAdapter(),
TokenSet.create(ZigTypes.STRING_LITERAL_SINGLE)
),
arrayOf(ZigTypes.STRING_LITERAL_SINGLE),
IElementType.EMPTY_ARRAY
)
}
}

View file

@ -0,0 +1,6 @@
package com.falsepattern.zigbrains.zig.lexerstring
import com.intellij.lexer.FlexAdapter
class ZigLexerStringAdapter: FlexAdapter(ZigLexerString(null)) {
}

View file

@ -0,0 +1,23 @@
package com.falsepattern.zigbrains.zig.pairing
import com.falsepattern.zigbrains.zig.psi.ZigTypes
import com.intellij.lang.BracePair
import com.intellij.lang.PairedBraceMatcher
import com.intellij.psi.PsiFile
import com.intellij.psi.tree.IElementType
class ZigBraceMatcher: PairedBraceMatcher {
override fun getPairs() =
PAIRS
override fun isPairedBracesAllowedBeforeType(lbraceType: IElementType, contextType: IElementType?) =
true
override fun getCodeConstructStart(file: PsiFile?, openingBraceOffset: Int) =
file?.findElementAt(openingBraceOffset)?.parent?.textOffset ?: openingBraceOffset
}
private val BRACE_PAIR = BracePair(ZigTypes.LBRACE, ZigTypes.RBRACE, true)
private val PAREN_PAIR = BracePair(ZigTypes.LPAREN, ZigTypes.RPAREN, false)
private val BRACKET_PAIR = BracePair(ZigTypes.LBRACKET, ZigTypes.RBRACKET, false)
private val PAIRS = arrayOf(BRACE_PAIR, PAREN_PAIR, BRACKET_PAIR)

View file

@ -7,15 +7,29 @@
<!-- region Zig -->
<extensions defaultExtensionNs="com.intellij">
<colorSettingsPage
implementation="com.falsepattern.zigbrains.zig.highlighter.ZigColorSettingsPage"/>
<fileType
name="Zig File"
implementationClass="com.falsepattern.zigbrains.zig.ZigFileType"
fieldName="INSTANCE"
language="Zig"
extensions="zig"/>
<lang.braceMatcher
language="Zig"
implementationClass="com.falsepattern.zigbrains.zig.pairing.ZigBraceMatcher"/>
<lang.commenter
language="Zig"
implementationClass="com.falsepattern.zigbrains.zig.comments.ZigCommenter"/>
<lang.formatter
language="Zig"
implementationClass="com.falsepattern.zigbrains.zig.formatter.ZigFormattingModelBuilder"/>
<lang.parserDefinition
language="Zig"
implementationClass="com.falsepattern.zigbrains.zig.parser.ZigParserDefinition"/>
<lang.syntaxHighlighterFactory
language="Zig"
implementationClass="com.falsepattern.zigbrains.zig.highlighter.ZigSyntaxHighlighterFactory"/>
</extensions>
<!-- endregion Zig -->