Skip to content

Commit

Permalink
GML: Simplify formatting and add a LineIndentProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
mattco98 committed Jan 27, 2024
1 parent d90755d commit 24ec597
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.intellij.lang.ParserDefinition
import com.intellij.openapi.project.Project
import com.intellij.psi.FileViewProvider
import com.intellij.psi.PsiElement
import com.intellij.psi.TokenType
import com.intellij.psi.tree.TokenSet

class GMLParserDefinition : ParserDefinition {
Expand All @@ -21,7 +22,7 @@ class GMLParserDefinition : ParserDefinition {
override fun getStringLiteralElements(): TokenSet = TokenSet.EMPTY

companion object {
private val WHITE_SPACES = TokenSet.create(GMLLexerBase.SPACE)
private val WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE)
private val COMMENTS = TokenSet.create(GMLTypes.COMMENT)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class GMLSyntaxHighlighter : SyntaxHighlighterBase() {
COMMENT -> Highlights.COMMENT
NUMBER -> Highlights.NUMBER
STRING -> Highlights.STRING
BOOLEAN -> Highlights.BOOLEAN

OPEN_CURLY, CLOSE_CURLY -> Highlights.BRACES
OPEN_BRACKET, CLOSE_BRACKET -> Highlights.BRACKETS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ class GMLSyntaxAnnotator : DSLAnnotator(), DumbAware {
override fun annotate(element: PsiElement, holder: Holder) = with(holder) {
when (element) {
is GMLValue -> {
if (element.boolean != null)
element.highlight(Highlights.BOOLEAN)
if (element.string != null) {
val lastChar = element.string!!.text.lastOrNull()
if (lastChar != null && lastChar != '"')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package me.mattco.serenityos.gml.formatting
import com.intellij.lang.BracePair
import com.intellij.lang.PairedBraceMatcher
import com.intellij.psi.PsiFile
import com.intellij.psi.TokenType
import com.intellij.psi.tree.IElementType
import me.mattco.serenityos.gml.GMLLexerBase
import me.mattco.serenityos.gml.GMLTypes
Expand All @@ -24,7 +25,7 @@ class GMLBraceMatcher : PairedBraceMatcher {
private val ALLOWED_CONTEXT_TOKENS = setOf(
GMLTypes.CLOSE_CURLY,
GMLTypes.COMMENT,
GMLLexerBase.SPACE,
TokenType.WHITE_SPACE,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class GMLFormattingBlock(
GMLFormattingBlock(
it,
null,
findAlignmentForGMLNode(it),
null,
findIndentForGMLNode(it),
spacingBuilder,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package me.mattco.serenityos.gml.formatting

import com.intellij.formatting.Indent
import com.intellij.lang.Language
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.impl.source.codeStyle.SemanticEditorPosition.SyntaxElement
import com.intellij.psi.impl.source.codeStyle.lineIndent.IndentCalculator
import com.intellij.psi.impl.source.codeStyle.lineIndent.JavaLikeLangLineIndentProvider
import com.intellij.psi.tree.IElementType
import me.mattco.serenityos.gml.GMLLanguage
import me.mattco.serenityos.gml.GMLTypes.*

class GMLLineIndentProvider : JavaLikeLangLineIndentProvider() {
override fun mapType(tokenType: IElementType) = when (tokenType) {
OPEN_CURLY -> GMLSyntaxElement.OpenCurly
CLOSE_CURLY -> GMLSyntaxElement.CloseCurly
CLOSE_BRACKET, NUMBER, STRING, BOOLEAN -> GMLSyntaxElement.Value
else -> null
}

override fun getIndent(project: Project, editor: Editor, language: Language?, offset: Int): IndentCalculator? {
if (getPosition(editor, offset).matchesRule { it.isAfterOnSameLine(GMLSyntaxElement.Value) }) {
return IndentCalculatorFactory(project, editor).createIndentCalculator(
Indent.Type.NONE,
IndentCalculator.LINE_BEFORE
)
} else if (getPosition(editor, offset).matchesRule { it.isAfterOnSameLine(GMLSyntaxElement.OpenCurly) }
&& !getPosition(editor, offset).matchesRule { it.isAfterOnSameLine(GMLSyntaxElement.CloseCurly) }) {
return IndentCalculatorFactory(project, editor).createIndentCalculator(
Indent.Type.NORMAL,
IndentCalculator.LINE_BEFORE
)
}

return IndentCalculatorFactory(project, editor).createIndentCalculator(
Indent.Type.NONE,
IndentCalculator.LINE_AFTER
)
}

override fun isSuitableForLanguage(language: Language) = language == GMLLanguage

enum class GMLSyntaxElement : SyntaxElement {
OpenCurly,
CloseCurly,
Value,
}
}
27 changes: 9 additions & 18 deletions src/main/kotlin/me/mattco/serenityos/gml/formatting/rules.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package me.mattco.serenityos.gml.formatting

import com.intellij.formatting.Alignment
import com.intellij.formatting.Indent
import com.intellij.lang.ASTNode
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
import me.mattco.serenityos.common.formatting.SpacingBuilder
import me.mattco.serenityos.common.formatting.elementType
import me.mattco.serenityos.gml.GMLFileStub
import me.mattco.serenityos.gml.GMLTypes.*

fun buildGMLSpacingRules(settings: CommonCodeStyleSettings) = SpacingBuilder(settings).apply {
simple {
between(OPEN_CURLY, CLOSE_CURLY).spacing(0, 0, 0, false, 0)
between(PROPERTY, CLOSE_CURLY).spacing(0, 0, 0, false, 0)
between(OPEN_CURLY, COMPONENT_BODY).spacing(0, 0, 1, false, 0)
between(COMPONENT_BODY, CLOSE_CURLY).spacing(0, 0, 1, false, 0)

after(AT).spaces(0)
before(OPEN_CURLY).spaces(1)
after(OPEN_CURLY).spaces(0)
Expand All @@ -25,6 +28,9 @@ fun buildGMLSpacingRules(settings: CommonCodeStyleSettings) = SpacingBuilder(set
around(type).spaces(0)

between(COLON, COMPONENT).spacing(1, 1, 0, false, 0)
between(PROPERTY, PROPERTY).spacing(0, 0, 1, false, 0)
between(PROPERTY, COMPONENT).spacing(0, 0, 2, false, 0)
between(COMPONENT, PROPERTY).spacing(0, 0, 2, false, 0)
}

contextual(parent = COMPONENT_BODY, right = COMPONENT) { _, left, _ ->
Expand All @@ -36,24 +42,9 @@ fun buildGMLSpacingRules(settings: CommonCodeStyleSettings) = SpacingBuilder(set
}
}

fun findAlignmentForGMLNode(node: ASTNode): Alignment? {
val parentType = node.treeParent?.elementType ?: return null
if (parentType == COMPONENT_BODY)
return Alignment.createAlignment()
return null
}

fun findIndentForGMLNode(node: ASTNode): Indent? {
if (node.elementType == PROPERTY)
if (node.elementType == COMPONENT_BODY)
return Indent.getNormalIndent()

if (node.elementType == COMPONENT) {
// Only indent if this isn't a property value
val parent = node.treeParent ?: return Indent.getNoneIndent()
val parentType = parent.elementType
if (parentType != PROPERTY && parentType != GMLFileStub.Type)
return Indent.getNormalIndent()
}

return Indent.getNoneIndent()
}
7 changes: 1 addition & 6 deletions src/main/kotlin/me/mattco/serenityos/gml/lexer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,4 @@ class GMLToken(debugName: String) : IElementType(debugName, GMLLanguage) {

class GMLElementType(debugName: String) : IElementType(debugName, GMLLanguage)

abstract class GMLLexerBase : FlexLexer {
companion object {
@JvmField
val SPACE = GMLElementType("SPACE")
}
}
abstract class GMLLexerBase : FlexLexer
3 changes: 3 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
language="SerenityOS GML"
implementationClass="me.mattco.serenityos.gml.formatting.GMLBraceMatcher"
/>
<lineIndentProvider
implementationClass="me.mattco.serenityos.gml.formatting.GMLLineIndentProvider"
/>
<lang.documentationProvider
language="SerenityOS GML"
implementationClass="me.mattco.serenityos.gml.GMLDocumentationProvider"
Expand Down
4 changes: 1 addition & 3 deletions src/main/resources/grammar/SerenityOS GML.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,10 @@ private Property_recover ::= !(IDENTIFIER | CLOSE_CURLY | AT)

PropertyIdentifier ::= IDENTIFIER
Value ::=
Boolean
BOOLEAN
| NUMBER
| STRING
| Array
| Component

Boolean ::= "true" | "false"

Array ::= OPEN_BRACKET [Value (COMMA Value)*] CLOSE_BRACKET
5 changes: 4 additions & 1 deletion src/main/resources/grammar/SerenityOS GML.flex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.psi.tree.IElementType;

import com.intellij.lexer.FlexLexer;
import static com.intellij.psi.TokenType.BAD_CHARACTER;
import static com.intellij.psi.TokenType.WHITE_SPACE;
import static me.mattco.serenityos.gml.GMLTypes.*;

%%
Expand All @@ -26,12 +27,13 @@ WHITE_SPACE=[\t\n\r ]+
NUMBER=-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)
IDENTIFIER=[A-Za-z_]\w*
COMMENT=\/\/.*|\/\*[^]*?\*
BOOLEAN=true|false

%s YYSTRING

%%
<YYINITIAL> {
{WHITE_SPACE} { return SPACE; }
{WHITE_SPACE} { return WHITE_SPACE; }
{COMMENT} { return COMMENT; }

"{" { return OPEN_CURLY; }
Expand All @@ -45,6 +47,7 @@ COMMENT=\/\/.*|\/\*[^]*?\*

"\"" { yybegin(YYSTRING); }

{BOOLEAN} { return BOOLEAN; }
{IDENTIFIER} { return IDENTIFIER; }
{NUMBER} { return NUMBER; }
}
Expand Down

0 comments on commit 24ec597

Please sign in to comment.