From 4fd13e59f332acac3f0b4ca1a8ec236ff91731f9 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sun, 17 Nov 2024 14:52:49 +0100 Subject: [PATCH 1/5] Indent content between \left and \right --- .../editor/typedhandlers/LatexEnterHandler.kt | 7 +++- .../texifyidea/formatting/LatexBlock.kt | 4 ++ .../hannahsten/texifyidea/grammar/Latex.bnf | 17 ++++++--- .../texifyidea/grammar/LatexLexer.flex | 5 +++ .../grammar/LatexParserDefinition.kt | 2 +- .../texifyidea/highlighting/LatexAnnotator.kt | 7 ++++ .../highlighting/LatexSyntaxHighlighter.kt | 2 + .../inspections/LatexSpellcheckingStrategy.kt | 2 + .../typesetting/LatexDiacriticIJInspection.kt | 4 +- .../reference/LatexUsagesProvider.kt | 3 +- .../hannahsten/texifyidea/util/parser/Psi.kt | 11 +----- .../formatting/LatexFormattingTest.kt | 38 +++++++++++++++++++ 12 files changed, 81 insertions(+), 21 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt b/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt index 709ec363c3..c7be5ea961 100644 --- a/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt +++ b/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt @@ -6,7 +6,10 @@ import com.intellij.formatting.ChildAttributes import com.intellij.formatting.Indent import com.intellij.lang.ASTNode import nl.hannahsten.texifyidea.formatting.LatexBlock -import nl.hannahsten.texifyidea.psi.* +import nl.hannahsten.texifyidea.psi.LatexBeginCommand +import nl.hannahsten.texifyidea.psi.LatexEnvironment +import nl.hannahsten.texifyidea.psi.LatexParameterText +import nl.hannahsten.texifyidea.psi.LatexTypes import nl.hannahsten.texifyidea.settings.codestyle.LatexCodeStyleSettings import nl.hannahsten.texifyidea.util.parser.firstChildOfType @@ -30,7 +33,7 @@ object LatexEnterHandler { } val type = node.elementType - if (type === LatexTypes.DISPLAY_MATH || shouldIndentEnvironment) { + if (type == LatexTypes.DISPLAY_MATH || shouldIndentEnvironment || type == LatexTypes.LEFT_RIGHT || type == LatexTypes.LEFT_RIGHT_CONTENT) { return ChildAttributes(Indent.getNormalIndent(true), null) } val indentSections = CodeStyle.getCustomSettings(node.psi.containingFile, LatexCodeStyleSettings::class.java).INDENT_SECTIONS diff --git a/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt b/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt index a74cd27bc2..eb94f6aad2 100644 --- a/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt +++ b/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt @@ -194,6 +194,10 @@ class LatexBlock( return Indent.getNormalIndent(false) } + if (myNode.elementType == LatexTypes.LEFT_RIGHT_CONTENT) { + return Indent.getNormalIndent(false) + } + // Display math return if ((myNode.elementType === LatexTypes.MATH_CONTENT || myNode.elementType === LatexTypes.COMMENT_TOKEN) && myNode.treeParent?.elementType === LatexTypes.DISPLAY_MATH diff --git a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf index a822c1b953..c471adf12c 100644 --- a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf +++ b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf @@ -57,7 +57,7 @@ latexFile ::= content content ::= no_math_content* // When updating this list, consider updating other _content lists -no_math_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | group | normal_text | END_IF +no_math_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text | END_IF normal_text ::= (NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | OPEN_PAREN | CLOSE_PAREN | OPEN_BRACKET | CLOSE_BRACKET | PIPE | EXCLAMATION_MARK | BACKSLASH | EQUALS | COMMA | ANGLE_PARAM)+ @@ -80,7 +80,7 @@ pseudocode_block_content ::= no_math_content* if_block ::= START_IF if_block_content? (ELSE if_block_content?)* END_IF { pin=1 } // no_math_content without end_if -if_block_content ::= (raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | group | normal_text)* +if_block_content ::= (raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text)* commands ::= COMMAND_TOKEN STAR? parameter* { pin=1 @@ -91,6 +91,10 @@ commands ::= COMMAND_TOKEN STAR? parameter* { implements=["com.intellij.psi.PsiNameIdentifierOwner" "nl.hannahsten.texifyidea.psi.LatexCommandWithParams"] } +// To allow indenting the content between left( and right), we need it as a separate element +left_right_content ::= no_math_content* +// Allow unmatched left and right +left_right ::= LEFT left_right_content RIGHT? begin_command ::= BEGIN_TOKEN STAR? parameter* { pin=1 @@ -120,15 +124,16 @@ optional_key_val_key ::= optional_param_content+ { // a key and a value. required_param ::= OPEN_BRACE (strict_key_val_pair (COMMA strict_key_val_pair)* CLOSE_BRACE | required_param_content* CLOSE_BRACE) { pin=1 } +// Picture environment (and derived environments) from beamer uses parentheses for arguments picture_param ::= OPEN_PAREN picture_param_content* CLOSE_PAREN { pin=3 } // These are like content, but no brackets and with parameter_text instead of normal_text // We have to separate optional and required parameter content, because required parameter content // can contain mismatched brackets, but optional parameters not (then we wouldn't know what to match) -optional_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF +optional_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF required_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF // Cannot contain ( or ) -picture_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | group | parameter_text | BACKSLASH | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF +picture_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | parameter_text | BACKSLASH | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF strict_key_val_pair ::= key_val_key EQUALS key_val_value? @@ -139,7 +144,7 @@ key_val_key ::= (group | NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | key_val_value ::= key_val_content+ { mixin="nl.hannahsten.texifyidea.psi.impl.LatexKeyValValueImplMixin" } -key_val_content ::= parameter_text | parameter_group | OPEN_PAREN | CLOSE_PAREN | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | commands | math_environment +key_val_content ::= parameter_text | parameter_group | OPEN_PAREN | CLOSE_PAREN | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | commands | left_right | math_environment // The lowest level of a parameter must have the getReferences etc. implemented @@ -147,7 +152,7 @@ key_val_content ::= parameter_text | parameter_group | OPEN_PAREN | CLOSE_PAREN // So, the following is like normal_text // This assumes that parameter text which is a reference, appears directly under param_content // Commands is here instead of in required_param_content because it can be part of reference text for example to a file -parameter_text ::= (commands | NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | PIPE | EXCLAMATION_MARK)+ { +parameter_text ::= (commands | left_right | NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | PIPE | EXCLAMATION_MARK)+ { mixin="nl.hannahsten.texifyidea.psi.impl.LatexParameterTextImplMixin" } diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex index 08ead29dfb..09c4c03fb5 100644 --- a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex +++ b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex @@ -86,6 +86,9 @@ NEWENVIRONMENT=\\(re)?newenvironment // BeforeBegin/AfterEnd are from etoolbox, and just happen to also have two parameters where the second can contain loose \begin or \end NEWCOMMAND=\\(new|provide)command | \\BeforeBeginEnvironment | \\AfterEndEnvironment NEWDOCUMENTENVIRONMENT=\\(New|Renew|Provide|Declare)DocumentEnvironment +// These are separate to support formatting +LEFT=\\left(\[|\(|\\\{) +RIGHT=\\right(\]|\)|\\\}) // Verbatim commands which will be delimited by the same character // \path from the 'path' package @@ -524,6 +527,8 @@ END_IFS=\\fi {CLOSE_BRACE} { return CLOSE_BRACE; } {OPEN_PAREN} { return OPEN_PAREN; } {CLOSE_PAREN} { return CLOSE_PAREN; } +{LEFT} { return LEFT; } +{RIGHT} { return RIGHT; } {LEXER_OFF_TOKEN} { yypushState(OFF); return COMMENT_TOKEN; } {ENDINPUT} { yypushState(OFF); return COMMAND_TOKEN; } diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt b/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt index 3b759b3168..ba74ba32f5 100644 --- a/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt +++ b/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt @@ -48,7 +48,7 @@ class LatexParserDefinition : ParserDefinition { val FILE: IStubFileElementType<*> = object : IStubFileElementType( "LatexStubFileElementType", Language.findInstance(LatexLanguage::class.java) ) { - override fun getStubVersion(): Int = 75 + override fun getStubVersion(): Int = 76 } } diff --git a/src/nl/hannahsten/texifyidea/highlighting/LatexAnnotator.kt b/src/nl/hannahsten/texifyidea/highlighting/LatexAnnotator.kt index 51aefa44c4..959f8181aa 100644 --- a/src/nl/hannahsten/texifyidea/highlighting/LatexAnnotator.kt +++ b/src/nl/hannahsten/texifyidea/highlighting/LatexAnnotator.kt @@ -7,6 +7,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement +import com.intellij.psi.util.elementType import com.intellij.psi.util.endOffset import com.intellij.psi.util.startOffset import nl.hannahsten.texifyidea.index.LatexDefinitionIndex @@ -69,6 +70,12 @@ open class LatexAnnotator : Annotator { else if (psiElement is LatexCommands) { annotateCommands(psiElement, annotationHolder) } + else if (psiElement.elementType == LatexTypes.LEFT || psiElement.elementType == LatexTypes.RIGHT) { + annotationHolder.newAnnotation(HighlightSeverity.INFORMATION, "") + .range(psiElement) + .textAttributes(LatexSyntaxHighlighter.COMMAND_MATH_DISPLAY) + .create() + } else if (psiElement.isComment()) { annotationHolder.newSilentAnnotation(HighlightSeverity.INFORMATION) .range(psiElement.textRange) diff --git a/src/nl/hannahsten/texifyidea/highlighting/LatexSyntaxHighlighter.kt b/src/nl/hannahsten/texifyidea/highlighting/LatexSyntaxHighlighter.kt index 84411fb7c9..d93ec783b2 100644 --- a/src/nl/hannahsten/texifyidea/highlighting/LatexSyntaxHighlighter.kt +++ b/src/nl/hannahsten/texifyidea/highlighting/LatexSyntaxHighlighter.kt @@ -87,6 +87,8 @@ class LatexSyntaxHighlighter : SyntaxHighlighterBase() { LatexTypes.START_IF, LatexTypes.ELSE, LatexTypes.END_IF, + LatexTypes.LEFT, + LatexTypes.RIGHT, ) /* diff --git a/src/nl/hannahsten/texifyidea/inspections/LatexSpellcheckingStrategy.kt b/src/nl/hannahsten/texifyidea/inspections/LatexSpellcheckingStrategy.kt index 60d3ca553d..0a0fdb8e5e 100644 --- a/src/nl/hannahsten/texifyidea/inspections/LatexSpellcheckingStrategy.kt +++ b/src/nl/hannahsten/texifyidea/inspections/LatexSpellcheckingStrategy.kt @@ -31,6 +31,8 @@ class LatexSpellcheckingStrategy : SpellcheckingStrategy() { if (psiElement.elementType == LatexTypes.COMMAND_TOKEN || psiElement.elementType == LatexTypes.COMMAND_IFNEXTCHAR || psiElement.elementType == LatexTypes.COMMENT_TOKEN || + psiElement.elementType == LatexTypes.LEFT || + psiElement.elementType == LatexTypes.RIGHT || isBeginEnd(psiElement) || psiElement.hasParent(LatexOptionalParam::class) ) { diff --git a/src/nl/hannahsten/texifyidea/inspections/latex/typesetting/LatexDiacriticIJInspection.kt b/src/nl/hannahsten/texifyidea/inspections/latex/typesetting/LatexDiacriticIJInspection.kt index 7506346f8b..268a940f93 100644 --- a/src/nl/hannahsten/texifyidea/inspections/latex/typesetting/LatexDiacriticIJInspection.kt +++ b/src/nl/hannahsten/texifyidea/inspections/latex/typesetting/LatexDiacriticIJInspection.kt @@ -9,7 +9,7 @@ import nl.hannahsten.texifyidea.lang.Diacritic import nl.hannahsten.texifyidea.lang.magic.MagicCommentScope import nl.hannahsten.texifyidea.psi.LatexMathContent import nl.hannahsten.texifyidea.psi.LatexNormalText -import nl.hannahsten.texifyidea.psi.LatexTypes +import nl.hannahsten.texifyidea.util.parser.commandTokens import nl.hannahsten.texifyidea.util.parser.hasParent import nl.hannahsten.texifyidea.util.parser.inMathContext import nl.hannahsten.texifyidea.util.parser.isComment @@ -70,7 +70,7 @@ open class LatexDiacriticIJInspection : TexifyRegexInspection( val offset = matcher.end() val foundAhead = file.findElementAt(offset) - if (foundAhead is LeafPsiElement && foundAhead.elementType == LatexTypes.COMMAND_TOKEN) { + if (foundAhead is LeafPsiElement && commandTokens.contains(foundAhead.elementType)) { return false } diff --git a/src/nl/hannahsten/texifyidea/reference/LatexUsagesProvider.kt b/src/nl/hannahsten/texifyidea/reference/LatexUsagesProvider.kt index 889f0f142f..bbb92ce013 100644 --- a/src/nl/hannahsten/texifyidea/reference/LatexUsagesProvider.kt +++ b/src/nl/hannahsten/texifyidea/reference/LatexUsagesProvider.kt @@ -20,7 +20,8 @@ class LatexUsagesProvider : FindUsagesProvider { LatexTypes.BEGIN_COMMAND, LatexTypes.BEGIN_TOKEN, LatexTypes.END_COMMAND, LatexTypes.END_TOKEN, LatexTypes.PARAMETER_TEXT, LatexTypes.PARAMETER, - LatexTypes.REQUIRED_PARAM, LatexTypes.OPTIONAL_PARAM + LatexTypes.REQUIRED_PARAM, LatexTypes.OPTIONAL_PARAM, + LatexTypes.LEFT, LatexTypes.RIGHT, ), // Comments. TokenSet.create(LatexTypes.COMMENT_TOKEN, LatexTypes.COMMENT), diff --git a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt index b546c19264..c529cd881d 100644 --- a/src/nl/hannahsten/texifyidea/util/parser/Psi.kt +++ b/src/nl/hannahsten/texifyidea/util/parser/Psi.kt @@ -7,7 +7,6 @@ import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.PsiWhiteSpace -import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.nextLeaf import com.intellij.util.ProcessingContext @@ -192,14 +191,6 @@ fun PsiElement?.findOuterMathEnvironment(): PsiElement? { return outerMathEnvironment } -/** - * Check if the element is in a comment or not. - */ -fun PsiElement.inComment() = inDirectEnvironmentContext(Environment.Context.COMMENT) || when (this) { - is PsiComment -> true - else -> this is LeafPsiElement && elementType == LatexTypes.COMMAND_TOKEN -} - /** * Checks if the element is inside a verbatim context. */ @@ -321,6 +312,8 @@ inline fun PsiElement.hasParentMatching(maxDepth: Int, predicate: (PsiElement) - return false } +val commandTokens = setOf(LatexTypes.COMMAND_TOKEN, LatexTypes.LEFT, LatexTypes.RIGHT) + /** * Checks whether the psi element is part of a comment or not. */ diff --git a/test/nl/hannahsten/texifyidea/formatting/LatexFormattingTest.kt b/test/nl/hannahsten/texifyidea/formatting/LatexFormattingTest.kt index 828b987701..923c068f9e 100644 --- a/test/nl/hannahsten/texifyidea/formatting/LatexFormattingTest.kt +++ b/test/nl/hannahsten/texifyidea/formatting/LatexFormattingTest.kt @@ -155,6 +155,44 @@ class LatexFormattingTest : BasePlatformTestCase() { """.trimIndent() } + fun testPictureParameter() { + """ + \begin{textblock*}{\paperwidth}[0.5,0.5](0.5\paperwidth,0.5\paperheight) + Thank you for your attention. + \end{textblock*} + """.trimIndent() `should be reformatted to` """ + \begin{textblock*}{\paperwidth}[0.5,0.5](0.5\paperwidth,0.5\paperheight) + Thank you for your attention. + \end{textblock*} + """.trimIndent() + } + + fun testLeftRight() { + """ + \[ + \left( + \xi + a + b + + c + \left[ + \frac a b + \right] + \right) + \] + """.trimIndent() `should be reformatted to` """ + \[ + \left( + \xi + a + b + + c + \left[ + \frac a b + \right] + \right) + \] + """.trimIndent() + } + fun `test formatter off and on comments`() { """ % @formatter:off From 0113d6ca378f96e2e2ee36292b85116a93aa0f46 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Mon, 18 Nov 2024 20:26:44 +0100 Subject: [PATCH 2/5] Fix double indent --- .../editor/typedhandlers/LatexEnterHandler.kt | 3 ++- .../texifyidea/formatting/LatexBlock.kt | 2 +- .../typedhandlers/LatexTypedHandlerTest.kt | 23 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt b/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt index c7be5ea961..72076a3efe 100644 --- a/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt +++ b/src/nl/hannahsten/texifyidea/editor/typedhandlers/LatexEnterHandler.kt @@ -33,9 +33,10 @@ object LatexEnterHandler { } val type = node.elementType - if (type == LatexTypes.DISPLAY_MATH || shouldIndentEnvironment || type == LatexTypes.LEFT_RIGHT || type == LatexTypes.LEFT_RIGHT_CONTENT) { + if (type == LatexTypes.DISPLAY_MATH || shouldIndentEnvironment || type == LatexTypes.LEFT_RIGHT) { return ChildAttributes(Indent.getNormalIndent(true), null) } + val indentSections = CodeStyle.getCustomSettings(node.psi.containingFile, LatexCodeStyleSettings::class.java).INDENT_SECTIONS if (indentSections) { // This function will be called on the block for which the caret is adding something in the children at the given index, diff --git a/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt b/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt index eb94f6aad2..b97e40b904 100644 --- a/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt +++ b/src/nl/hannahsten/texifyidea/formatting/LatexBlock.kt @@ -195,7 +195,7 @@ class LatexBlock( } if (myNode.elementType == LatexTypes.LEFT_RIGHT_CONTENT) { - return Indent.getNormalIndent(false) + return Indent.getNormalIndent(true) } // Display math diff --git a/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt b/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt index 4b7d4538d0..3d81174f43 100644 --- a/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt +++ b/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt @@ -60,6 +60,29 @@ class LatexTypedHandlerTest : BasePlatformTestCase() { ) } + fun testLeftRight() { + myFixture.configureByText(LatexFileType, """ + \[ + \left( + a+b + \xi + \right) + \] + """.trimIndent()) + myFixture.type("\n+c") + myFixture.checkResult( + """ + \[ + \left( + a+b + +c + \xi + \right) + \] + """.trimIndent() + ) + } + fun testBracesCompletion() { myFixture.configureByText(LatexFileType, """\mycommand""") myFixture.type("{") From 40f1b200d5798aee250fbbd5640d4e1977a47968 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Wed, 20 Nov 2024 12:09:45 +0100 Subject: [PATCH 3/5] Formatting --- .../editor/typedhandlers/LatexTypedHandlerTest.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt b/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt index 3d81174f43..ef63e233eb 100644 --- a/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt +++ b/test/nl/hannahsten/texifyidea/editor/typedhandlers/LatexTypedHandlerTest.kt @@ -61,14 +61,17 @@ class LatexTypedHandlerTest : BasePlatformTestCase() { } fun testLeftRight() { - myFixture.configureByText(LatexFileType, """ + myFixture.configureByText( + LatexFileType, + """ \[ \left( a+b \xi \right) \] - """.trimIndent()) + """.trimIndent() + ) myFixture.type("\n+c") myFixture.checkResult( """ From 3c46a2e5d6a8ba22f7da536e684ee02035a36d65 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Fri, 29 Nov 2024 21:34:25 +0100 Subject: [PATCH 4/5] Split off braces from left/right token --- src/nl/hannahsten/texifyidea/grammar/Latex.bnf | 2 +- src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf index 15aee92b82..d0b6551274 100644 --- a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf +++ b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf @@ -94,7 +94,7 @@ commands ::= COMMAND_TOKEN STAR? parameter* { // To allow indenting the content between left( and right), we need it as a separate element left_right_content ::= no_math_content* // Allow unmatched left and right -left_right ::= LEFT left_right_content RIGHT? +left_right ::= (LEFT (OPEN_PAREN | OPEN_ANGLE_BRACKET | OPEN_BRACE | OPEN_BRACKET | PIPE)? left_right_content RIGHT? (CLOSE_PAREN | CLOSE_ANGLE_BRACKET | CLOSE_BRACE | CLOSE_BRACKET | PIPE)?) | RIGHT begin_command ::= BEGIN_TOKEN STAR? parameter* { pin=1 diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex index 78ed8b5e08..af76a59785 100644 --- a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex +++ b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex @@ -88,8 +88,8 @@ NEWENVIRONMENT=\\(re)?newenvironment NEWCOMMAND=\\(new|provide)command | \\BeforeBeginEnvironment | \\AfterEndEnvironment NEWDOCUMENTENVIRONMENT=\\(New|Renew|Provide|Declare)DocumentEnvironment // These are separate to support formatting -LEFT=\\left(\[|\(|\\\{) -RIGHT=\\right(\]|\)|\\\}) +LEFT=\\left +RIGHT=\\right // Verbatim commands which will be delimited by the same character // \path from the 'path' package From 8610a142713f33619f6512044c8c40016fe98ace Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Mon, 2 Dec 2024 20:02:44 +0100 Subject: [PATCH 5/5] Fix psi structure --- src/nl/hannahsten/texifyidea/grammar/Latex.bnf | 17 +++++++++-------- .../texifyidea/grammar/LatexParserDefinition.kt | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf index d0b6551274..0c9c269d94 100644 --- a/src/nl/hannahsten/texifyidea/grammar/Latex.bnf +++ b/src/nl/hannahsten/texifyidea/grammar/Latex.bnf @@ -57,7 +57,7 @@ latexFile ::= content content ::= no_math_content* // When updating this list, consider updating other _content lists -no_math_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text | END_IF | ELSE +no_math_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text | END_IF | ELSE | LEFT | RIGHT normal_text ::= (NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | OPEN_PAREN | CLOSE_PAREN | OPEN_BRACKET | CLOSE_BRACKET | PIPE | EXCLAMATION_MARK | BACKSLASH | EQUALS | COMMA | ANGLE_PARAM)+ @@ -80,7 +80,7 @@ pseudocode_block_content ::= no_math_content* if_block ::= START_IF if_block_content? (ELSE if_block_content?)* END_IF { pin=1 } // no_math_content without end_if -if_block_content ::= (raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text)* +if_block_content ::= (raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text | LEFT | RIGHT)* commands ::= COMMAND_TOKEN STAR? parameter* { pin=1 @@ -92,9 +92,10 @@ commands ::= COMMAND_TOKEN STAR? parameter* { } // To allow indenting the content between left( and right), we need it as a separate element -left_right_content ::= no_math_content* +// This is no_math_content without the loose left and right, we need this to make sure a complete left_right situation is parsed as a left_right and not as two separate left and right +left_right_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | normal_text | END_IF | ELSE // Allow unmatched left and right -left_right ::= (LEFT (OPEN_PAREN | OPEN_ANGLE_BRACKET | OPEN_BRACE | OPEN_BRACKET | PIPE)? left_right_content RIGHT? (CLOSE_PAREN | CLOSE_ANGLE_BRACKET | CLOSE_BRACE | CLOSE_BRACKET | PIPE)?) | RIGHT +left_right ::= LEFT (OPEN_PAREN | OPEN_ANGLE_BRACKET | OPEN_BRACE | OPEN_BRACKET | PIPE)? left_right_content* RIGHT (CLOSE_PAREN | CLOSE_ANGLE_BRACKET | CLOSE_BRACE | CLOSE_BRACKET | PIPE)? begin_command ::= BEGIN_TOKEN STAR? parameter* { pin=1 @@ -130,10 +131,10 @@ picture_param ::= OPEN_PAREN picture_param_content* CLOSE_PAREN { pin=3 } // These are like content, but no brackets and with parameter_text instead of normal_text // We have to separate optional and required parameter content, because required parameter content // can contain mismatched brackets, but optional parameters not (then we wouldn't know what to match) -optional_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE -required_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE | ANGLE_PARAM +optional_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE | LEFT | RIGHT +required_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | group | OPEN_PAREN | CLOSE_PAREN | parameter_text | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | BACKSLASH | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE | ANGLE_PARAM | LEFT | RIGHT // Cannot contain ( or ) -picture_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | parameter_text | BACKSLASH | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE +picture_param_content ::= raw_text | magic_comment | comment | environment | pseudocode_block | if_block | math_environment | COMMAND_IFNEXTCHAR | commands | left_right | group | parameter_text | BACKSLASH | COMMA | EQUALS | OPEN_BRACKET | CLOSE_BRACKET | OPEN_ANGLE_BRACKET | CLOSE_ANGLE_BRACKET | END_IF | ELSE | LEFT | RIGHT strict_key_val_pair ::= key_val_key EQUALS key_val_value? @@ -152,7 +153,7 @@ key_val_content ::= parameter_text | parameter_group | OPEN_PAREN | CLOSE_PAREN // So, the following is like normal_text // This assumes that parameter text which is a reference, appears directly under param_content // Commands is here instead of in required_param_content because it can be part of reference text for example to a file -parameter_text ::= (commands | left_right | NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | PIPE | EXCLAMATION_MARK)+ { +parameter_text ::= (commands | left_right | NORMAL_TEXT_WORD | STAR | AMPERSAND | QUOTATION_MARK | PIPE | EXCLAMATION_MARK | ELSE | LEFT | RIGHT)+ { mixin="nl.hannahsten.texifyidea.psi.impl.LatexParameterTextImplMixin" } diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt b/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt index ba74ba32f5..fa6c6c2f35 100644 --- a/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt +++ b/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt @@ -48,7 +48,7 @@ class LatexParserDefinition : ParserDefinition { val FILE: IStubFileElementType<*> = object : IStubFileElementType( "LatexStubFileElementType", Language.findInstance(LatexLanguage::class.java) ) { - override fun getStubVersion(): Int = 76 + override fun getStubVersion(): Int = 77 } }