From 7d4c7044b0b6b4d3fca0bf72234656738f100fe4 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Thu, 12 Dec 2024 20:15:24 +0100 Subject: [PATCH 01/13] Update to 2024.3 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 209ff7a64..7412250e6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -96,7 +96,7 @@ dependencies { testFramework(TestFrameworkType.Platform) testFramework(TestFrameworkType.Plugin.Java) - intellijIdeaCommunity("2024.2.3") + intellijIdeaCommunity("2024.3.1") // Docs: https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties // All snapshot versions: https://www.jetbrains.com/intellij-repository/snapshots/ From ffc5181a02d7c1f48e8ed91c7903f397a8eba226 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Fri, 13 Dec 2024 10:59:34 +0100 Subject: [PATCH 02/13] Replace deprecated FileTypeDescriptor --- .../run/bibtex/BibtexSettingsEditor.kt | 6 ++++-- .../externaltool/ExternalToolSettingsEditor.kt | 6 ++++-- .../run/latex/ui/LatexSettingsEditor.kt | 17 ++++++++++------- .../run/makeindex/MakeindexSettingsEditor.kt | 6 ++++-- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/nl/hannahsten/texifyidea/run/bibtex/BibtexSettingsEditor.kt b/src/nl/hannahsten/texifyidea/run/bibtex/BibtexSettingsEditor.kt index f029f3450..0b3ea053c 100644 --- a/src/nl/hannahsten/texifyidea/run/bibtex/BibtexSettingsEditor.kt +++ b/src/nl/hannahsten/texifyidea/run/bibtex/BibtexSettingsEditor.kt @@ -2,7 +2,7 @@ package nl.hannahsten.texifyidea.run.bibtex import com.intellij.execution.configuration.EnvironmentVariablesComponent import com.intellij.openapi.fileChooser.FileChooserDescriptor -import com.intellij.openapi.fileChooser.FileTypeDescriptor +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory import com.intellij.openapi.options.SettingsEditor import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ProjectRootManager @@ -108,7 +108,9 @@ class BibtexSettingsEditor(private val project: Project) : SettingsEditor Date: Fri, 13 Dec 2024 11:10:26 +0100 Subject: [PATCH 03/13] Copy deleted MockInlineMethodOptions --- .../texifyidea/refactoring/InlineFileTest.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/nl/hannahsten/texifyidea/refactoring/InlineFileTest.kt b/test/nl/hannahsten/texifyidea/refactoring/InlineFileTest.kt index d2a3f68e9..1bc3243bc 100644 --- a/test/nl/hannahsten/texifyidea/refactoring/InlineFileTest.kt +++ b/test/nl/hannahsten/texifyidea/refactoring/InlineFileTest.kt @@ -6,10 +6,8 @@ import com.intellij.openapi.util.io.FileUtilRt import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.psi.PsiFileFactory import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException -import com.intellij.refactoring.MockInlineMethodOptions import com.intellij.refactoring.inline.InlineOptions import com.intellij.testFramework.LightPlatformCodeInsightTestCase -import junit.framework.TestCase import nl.hannahsten.texifyidea.file.LatexFileType import nl.hannahsten.texifyidea.refactoring.inlinecommand.LatexInlineCommandHandler.Util.getReference import nl.hannahsten.texifyidea.refactoring.inlinefile.LatexInlineFileHandler.Util.canInlineLatexElement @@ -127,7 +125,7 @@ class InlineFileTest : LightPlatformCodeInsightTestCase() { private fun configure(testIndex: Int? = null): String { @NonNls val fileName = getTestName(false) + (testIndex ?: "") + ".tex" configureByFile(fileName) - TestCase.assertTrue(file.parent != null) + assertTrue(file.parent != null) if (file.parent?.children?.any { it.containingFile.name == inlineFile } == false) { val ioFile = File(testDataPath + inlineFile) checkCaseSensitiveFS(testDataPath + inlineFile, ioFile) @@ -182,4 +180,12 @@ class InlineFileTest : LightPlatformCodeInsightTestCase() { ) processor.run() } + + open class MockInlineMethodOptions : InlineOptions { + override fun isInlineThisOnly() = false + + override fun close(p0: Int) {} + + override fun isPreviewUsages() = false + } } \ No newline at end of file From 512e44d79f4ee12f41eff9cab720b212eb27fcc5 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Fri, 13 Dec 2024 20:34:27 +0100 Subject: [PATCH 04/13] Add support for automatic language injection on the minted environment --- CHANGELOG.md | 1 + .../texifyidea/grammar/LatexLexer.flex | 24 ++++++++++++++----- .../grammar/LatexParserDefinition.kt | 2 +- .../texifyidea/psi/LatexLanguageInjector.kt | 6 ++++- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26b9b2944..322fa4cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Added +* Add support for automatic language injection on the minted environment * Do not fold sections in a command definition * Include optional parameters in spellcheck, if it contains text diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex index af76a5978..035ef11e0 100644 --- a/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex +++ b/src/nl/hannahsten/texifyidea/grammar/LatexLexer.flex @@ -38,9 +38,10 @@ import static nl.hannahsten.texifyidea.psi.LatexTypes.*; private int newCommandBracesNesting = 0; /** - * Also keep track of brackets of verbatim environment optional arguments. + * Also keep track of brackets of verbatim environment arguments. */ private int verbatimOptionalArgumentBracketsCount = 0; + private int verbatimRequiredArgumentBracketsCount = 0; /** * Keep track of braces in the PARTIAL_DEFINITION state. @@ -144,8 +145,8 @@ END_IFS=\\fi // States are exclusive to avoid matching expressions with an empty set of associated states, i.e. to avoid matching normal LaTeX expressions %xstates INLINE_VERBATIM_PLAIN_START INLINE_VERBATIM INLINE_VERBATIM_NORMAL_START -%states POSSIBLE_VERBATIM_BEGIN VERBATIM_OPTIONAL_ARG VERBATIM_START VERBATIM_END INLINE_VERBATIM_OPTIONAL_ARG -%xstates VERBATIM POSSIBLE_VERBATIM_OPTIONAL_ARG POSSIBLE_VERBATIM_END +%states POSSIBLE_VERBATIM_BEGIN VERBATIM_OPTIONAL_ARG VERBATIM_REQUIRED_ARG VERBATIM_START VERBATIM_END INLINE_VERBATIM_OPTIONAL_ARG +%xstates VERBATIM POSSIBLE_VERBATIM_ARG POSSIBLE_VERBATIM_END // algorithmic environment %states PSEUDOCODE POSSIBLE_PSEUDOCODE_END @@ -231,13 +232,14 @@ END_IFS=\\fi // Jump over the closing } of the \begin{verbatim} before starting verbatim state { - {CLOSE_BRACE} { yypopState(); yypushState(POSSIBLE_VERBATIM_OPTIONAL_ARG); return CLOSE_BRACE; } + {CLOSE_BRACE} { yypopState(); yypushState(POSSIBLE_VERBATIM_ARG); return CLOSE_BRACE; } } // Check if an optional argument is coming up // If you start a verbatim with an open bracket and don't close it, this won't work - { + { {OPEN_BRACKET} { verbatimOptionalArgumentBracketsCount = 1; yypopState(); yypushState(VERBATIM_OPTIONAL_ARG); return OPEN_BRACKET; } + {OPEN_BRACE} { verbatimRequiredArgumentBracketsCount = 1; yypopState(); yypushState(VERBATIM_REQUIRED_ARG); return OPEN_BRACE; } {WHITE_SPACE} { yypopState(); yypushState(VERBATIM); return com.intellij.psi.TokenType.WHITE_SPACE; } {ANY_CHAR} { yypopState(); yypushState(VERBATIM); return RAW_TEXT_TOKEN; } } @@ -248,11 +250,21 @@ END_IFS=\\fi {OPEN_BRACKET} { verbatimOptionalArgumentBracketsCount++; return OPEN_BRACKET; } {CLOSE_BRACKET} { verbatimOptionalArgumentBracketsCount--; - if (verbatimOptionalArgumentBracketsCount == 0) { yypopState(); yypushState(VERBATIM); } + // There can be a required arg coming + if (verbatimOptionalArgumentBracketsCount == 0) { yypopState(); yypushState(POSSIBLE_VERBATIM_ARG); } return CLOSE_BRACKET; } } + { + {OPEN_BRACE} { verbatimRequiredArgumentBracketsCount++; return OPEN_BRACE; } + {CLOSE_BRACE} { + verbatimRequiredArgumentBracketsCount--; + if (verbatimRequiredArgumentBracketsCount == 0) { yypopState(); yypushState(VERBATIM); } + return CLOSE_BRACE; + } +} + { // Also catch whitespace, see LatexParserUtil for more info {WHITE_SPACE} { return com.intellij.psi.TokenType.WHITE_SPACE; } diff --git a/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt b/src/nl/hannahsten/texifyidea/grammar/LatexParserDefinition.kt index fa6c6c2f3..36122d828 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 = 77 + override fun getStubVersion(): Int = 78 } } diff --git a/src/nl/hannahsten/texifyidea/psi/LatexLanguageInjector.kt b/src/nl/hannahsten/texifyidea/psi/LatexLanguageInjector.kt index d582a6442..48cad906a 100644 --- a/src/nl/hannahsten/texifyidea/psi/LatexLanguageInjector.kt +++ b/src/nl/hannahsten/texifyidea/psi/LatexLanguageInjector.kt @@ -6,6 +6,7 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.InjectedLanguagePlaces import com.intellij.psi.LanguageInjector import com.intellij.psi.PsiLanguageInjectionHost +import nl.hannahsten.texifyidea.lang.DefaultEnvironment import nl.hannahsten.texifyidea.lang.magic.DefaultMagicKeys import nl.hannahsten.texifyidea.lang.magic.magicComment import nl.hannahsten.texifyidea.util.camelCase @@ -32,9 +33,12 @@ class LatexLanguageInjector : LanguageInjector { hasMagicCommentKey -> { magicComment.value(DefaultMagicKeys.INJECT_LANGUAGE) } - host.getEnvironmentName() == "lstlisting" -> { + host.getEnvironmentName() == DefaultEnvironment.LISTINGS.environmentName -> { host.beginCommand.getOptionalParameterMap().toStringMap().getOrDefault("language", null) } + host.getEnvironmentName() == DefaultEnvironment.MINTED.environmentName -> { + host.beginCommand.getRequiredParameters().getOrNull(1) + } host.getEnvironmentName() in EnvironmentMagic.languageInjections.keys -> { EnvironmentMagic.languageInjections[host.getEnvironmentName()] } From 09bf0159076103a4f2e5557a84ef75ef5d2dbcbe Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 12:00:31 +0100 Subject: [PATCH 05/13] Move test file to avoid "VfsRootAccess$VfsRootAccessNotAllowedError: File accessed outside allowed roots" --- .../latex/probablebugs/LatexFileNotFoundInspectionTest.kt | 2 +- test/resources/completion/path/myOtherPicture.PNG | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test/resources/completion/path/myOtherPicture.PNG diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index fe159a676..5577fa4b5 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -40,7 +40,7 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testValidAbsolutePathCaps() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture.PNG}""") + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myOtherPicture.PNG}""") myFixture.checkHighlighting() } diff --git a/test/resources/completion/path/myOtherPicture.PNG b/test/resources/completion/path/myOtherPicture.PNG new file mode 100644 index 000000000..e69de29bb From 25b94024af526aa29384dcea886106accebd72fb Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 12:13:26 +0100 Subject: [PATCH 06/13] Move file to avoid other test failure --- .../latex/probablebugs/LatexFileNotFoundInspectionTest.kt | 2 +- .../completion/path/{ => filenotfound}/myOtherPicture.PNG | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/resources/completion/path/{ => filenotfound}/myOtherPicture.PNG (100%) diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index 5577fa4b5..6c744ed9b 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -40,7 +40,7 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testValidAbsolutePathCaps() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myOtherPicture.PNG}""") + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/filenotfound/myOtherPicture.PNG}""") myFixture.checkHighlighting() } diff --git a/test/resources/completion/path/myOtherPicture.PNG b/test/resources/completion/path/filenotfound/myOtherPicture.PNG similarity index 100% rename from test/resources/completion/path/myOtherPicture.PNG rename to test/resources/completion/path/filenotfound/myOtherPicture.PNG From 541ff3c5a21220bef9e300a19b17dbf1b35942a6 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 12:37:42 +0100 Subject: [PATCH 07/13] Revert "Move file to avoid other test failure" This reverts commit 25b94024af526aa29384dcea886106accebd72fb. --- .../latex/probablebugs/LatexFileNotFoundInspectionTest.kt | 2 +- .../completion/path/{filenotfound => }/myOtherPicture.PNG | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/resources/completion/path/{filenotfound => }/myOtherPicture.PNG (100%) diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index 6c744ed9b..5577fa4b5 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -40,7 +40,7 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testValidAbsolutePathCaps() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/filenotfound/myOtherPicture.PNG}""") + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myOtherPicture.PNG}""") myFixture.checkHighlighting() } diff --git a/test/resources/completion/path/filenotfound/myOtherPicture.PNG b/test/resources/completion/path/myOtherPicture.PNG similarity index 100% rename from test/resources/completion/path/filenotfound/myOtherPicture.PNG rename to test/resources/completion/path/myOtherPicture.PNG From 86c85327c13f9f4f10b07b9d6f9d71dbdd31befd Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 12:37:42 +0100 Subject: [PATCH 08/13] Revert "Move test file to avoid "VfsRootAccess$VfsRootAccessNotAllowedError: File accessed outside allowed roots"" This reverts commit 09bf0159076103a4f2e5557a84ef75ef5d2dbcbe. --- .../latex/probablebugs/LatexFileNotFoundInspectionTest.kt | 2 +- test/resources/completion/path/myOtherPicture.PNG | 0 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 test/resources/completion/path/myOtherPicture.PNG diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index 5577fa4b5..fe159a676 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -40,7 +40,7 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testValidAbsolutePathCaps() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myOtherPicture.PNG}""") + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture.PNG}""") myFixture.checkHighlighting() } diff --git a/test/resources/completion/path/myOtherPicture.PNG b/test/resources/completion/path/myOtherPicture.PNG deleted file mode 100644 index e69de29bb..000000000 From a0cf1f2fb0ce6db4247a63de200b2d9269e11322 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 14:19:06 +0100 Subject: [PATCH 09/13] Another attempt to work around gh actions failure --- .../latex/probablebugs/LatexFileNotFoundInspectionTest.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index fe159a676..9cc87d176 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -3,6 +3,7 @@ package nl.hannahsten.texifyidea.inspections.latex.probablebugs import io.mockk.every import io.mockk.mockkStatic import nl.hannahsten.texifyidea.file.LatexFileType +import nl.hannahsten.texifyidea.gutter.LatexNavigationGutter import nl.hannahsten.texifyidea.inspections.TexifyInspectionTestBase import nl.hannahsten.texifyidea.util.runCommandWithExitCode import java.io.File @@ -22,6 +23,8 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou super.setUp() mockkStatic(::runCommandWithExitCode) every { runCommandWithExitCode(*anyVararg(), workingDirectory = any(), timeout = any(), returnExceptionMessage = any()) } returns Pair(null, 0) + + mockkStatic(LatexNavigationGutter::collectNavigationMarkers) } override fun getTestDataPath(): String { From f78423e7d9abaeb01bd78c9cf61eedba61cfced7 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sat, 14 Dec 2024 15:06:09 +0100 Subject: [PATCH 10/13] Fix false positive for duplicate command definition inspection in if/else --- CHANGELOG.md | 1 + .../LatexDuplicateDefinitionInspection.kt | 5 +- .../LatexDuplicateLabelInspection.kt | 63 +++------------ .../commands/LatexGenericRegularCommand.kt | 1 + .../texifyidea/util/ConditionalCommands.kt | 76 +++++++++++++++++++ .../LatexDuplicateDefinitionInspectionTest.kt | 15 ++++ 6 files changed, 106 insertions(+), 55 deletions(-) create mode 100644 src/nl/hannahsten/texifyidea/util/ConditionalCommands.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 28bd56da3..b521ffdf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Include optional parameters in spellcheck, if it contains text ### Fixed +* Fix false positive for duplicate command definition inspection in if/else * Fix LaTeX files not showing up when choosing main file in run configuration * Fix various issues with the Grazie implementation, in particular default rules for Grazie Pro diff --git a/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspection.kt b/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspection.kt index e348ea6f1..02128df21 100644 --- a/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspection.kt +++ b/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspection.kt @@ -7,10 +7,11 @@ import com.intellij.codeInspection.ProblemHighlightType import com.intellij.psi.PsiFile import nl.hannahsten.texifyidea.inspections.InsightGroup import nl.hannahsten.texifyidea.inspections.TexifyInspectionBase -import nl.hannahsten.texifyidea.util.parser.definedCommandName import nl.hannahsten.texifyidea.util.files.definitions import nl.hannahsten.texifyidea.util.files.definitionsInFileSet +import nl.hannahsten.texifyidea.util.isInConditionalBranch import nl.hannahsten.texifyidea.util.magic.CommandMagic +import nl.hannahsten.texifyidea.util.parser.definedCommandName /** * Warns for commands that are defined twice in the same fileset. @@ -32,6 +33,7 @@ open class LatexDuplicateDefinitionInspection : TexifyInspectionBase() { val defined = HashMultiset.create() val definitions = file.definitionsInFileSet().filter { it.name in CommandMagic.regularStrictCommandDefinitions } for (command in definitions) { + if (isInConditionalBranch(command)) continue val name = command.definedCommandName() ?: continue defined.add(name) } @@ -39,6 +41,7 @@ open class LatexDuplicateDefinitionInspection : TexifyInspectionBase() { // Go monkeys. file.definitions() .forEach { + if (isInConditionalBranch(it)) return@forEach val definedCmd = it.definedCommandName() ?: return@forEach if (defined.count(definedCmd) > 1) { descriptors.add( diff --git a/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateLabelInspection.kt b/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateLabelInspection.kt index a93c42d9e..de900a7d0 100644 --- a/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateLabelInspection.kt +++ b/src/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateLabelInspection.kt @@ -6,18 +6,23 @@ import com.intellij.codeInspection.ProblemHighlightType import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.psi.util.elementType import com.intellij.psi.util.startOffset import nl.hannahsten.texifyidea.inspections.InsightGroup import nl.hannahsten.texifyidea.inspections.TexifyInspectionBase import nl.hannahsten.texifyidea.lang.alias.CommandManager import nl.hannahsten.texifyidea.lang.magic.MagicCommentScope -import nl.hannahsten.texifyidea.psi.* +import nl.hannahsten.texifyidea.psi.LatexCommands +import nl.hannahsten.texifyidea.psi.LatexEnvironment +import nl.hannahsten.texifyidea.psi.LatexParameter +import nl.hannahsten.texifyidea.psi.getEnvironmentName +import nl.hannahsten.texifyidea.util.isInConditionalBranch import nl.hannahsten.texifyidea.util.labels.findBibitemCommands import nl.hannahsten.texifyidea.util.labels.findLatexLabelingElementsInFileSet import nl.hannahsten.texifyidea.util.magic.CommandMagic import nl.hannahsten.texifyidea.util.magic.EnvironmentMagic -import nl.hannahsten.texifyidea.util.parser.* +import nl.hannahsten.texifyidea.util.parser.isDefinitionOrRedefinition +import nl.hannahsten.texifyidea.util.parser.parentOfType +import nl.hannahsten.texifyidea.util.parser.requiredParameter import java.lang.Integer.max import java.util.* @@ -125,7 +130,7 @@ open class LatexDuplicateLabelInspection : TexifyInspectionBase() { // When the label is defined in a command definition ignore it, because there could be more than one with #1 as parameter if (command.parentOfType(LatexCommands::class).isDefinitionOrRedefinition()) return@mapNotNull null // If the command is within an \if branch, ignore it because it will may appear in multiple branches of which only one will be present during compilation - if (isPreviousConditionalStart(command) && isNextConditionalEnd(command)) { + if (isInConditionalBranch(command)) { return@mapNotNull null } command.getLabelDescriptor() @@ -151,54 +156,4 @@ open class LatexDuplicateLabelInspection : TexifyInspectionBase() { isOntheFly ) } - - /** - * If the next relevant command is a \fi - */ - private fun isNextConditionalEnd(current: PsiElement): Boolean { - return isEndConditional(nextConditionalCommand(current, searchBackwards = false) ?: return false) - } - - /** - * If the previous relevant command is an \if - */ - private fun isPreviousConditionalStart(current: PsiElement): Boolean { - return isStartConditional(nextConditionalCommand(current, searchBackwards = true) ?: return false) - } - - /** - * Next relevant command. There are many ways in which this does not work, but since this is just an inspection this is much safer than trying to parse user defined \if commands in the parser, which is impossiblee - */ - private fun nextConditionalCommand(element: PsiElement, searchBackwards: Boolean): PsiElement? { - var current = element.parentOfType(LatexNoMathContent::class) - while (current != null && !isConditional(current)) { - current = if (!searchBackwards) { - current.nextSibling?.nextSiblingOfType(LatexNoMathContent::class) - } - else { - current.prevSibling?.previousSiblingOfType(LatexNoMathContent::class) - } - } - return current - } - - private fun isConditional(element: PsiElement): Boolean { - return isStartConditional(element) || isEndConditional(element) - } - - private fun isStartConditional(rootElement: PsiElement): Boolean { - // To keep it simple, only look one level down - for (element in rootElement.children + listOf(rootElement)) { - if (element is LatexCommands && element.name?.startsWith("\\if") == true) return true - if (element.elementType == LatexTypes.START_IF) return true - } - return false - } - - private fun isEndConditional(rootElement: PsiElement): Boolean { - for (element in rootElement.children + listOf(rootElement)) { - if (element.firstChild?.elementType in setOf(LatexTypes.ELSE, LatexTypes.END_IF)) return true - } - return false - } } diff --git a/src/nl/hannahsten/texifyidea/lang/commands/LatexGenericRegularCommand.kt b/src/nl/hannahsten/texifyidea/lang/commands/LatexGenericRegularCommand.kt index 3cc09bcb2..4a8ebea9b 100644 --- a/src/nl/hannahsten/texifyidea/lang/commands/LatexGenericRegularCommand.kt +++ b/src/nl/hannahsten/texifyidea/lang/commands/LatexGenericRegularCommand.kt @@ -141,6 +141,7 @@ enum class LatexGenericRegularCommand( HYPERREF("hyperref", "options".asOptional(), "label".asRequired(Argument.Type.TEXT), dependency = LatexPackage.HYPERREF), HYPHENATION("hyphenation", "words".asRequired(Argument.Type.TEXT)), I("i", display = "i (dotless)"), + IFTHENELSE("ifthenelse", "test".asRequired(), "then clause".asRequired(), "else clause".asRequired()), IMPORT("import", RequiredFolderArgument("absolute path"), RequiredFileArgument("filename", false, false, "tex"), dependency = LatexPackage.IMPORT), INCLUDE("include", RequiredFileArgument("sourcefile", false, false, "tex")), INCLUDEFROM("includefrom", RequiredFolderArgument("absolute path"), RequiredFileArgument("filename", false, false, "tex"), dependency = LatexPackage.IMPORT), diff --git a/src/nl/hannahsten/texifyidea/util/ConditionalCommands.kt b/src/nl/hannahsten/texifyidea/util/ConditionalCommands.kt new file mode 100644 index 000000000..b6d29ec88 --- /dev/null +++ b/src/nl/hannahsten/texifyidea/util/ConditionalCommands.kt @@ -0,0 +1,76 @@ +package nl.hannahsten.texifyidea.util + +import com.intellij.psi.PsiElement +import com.intellij.psi.util.elementType +import nl.hannahsten.texifyidea.lang.commands.LatexGenericRegularCommand +import nl.hannahsten.texifyidea.psi.LatexCommands +import nl.hannahsten.texifyidea.psi.LatexNoMathContent +import nl.hannahsten.texifyidea.psi.LatexParameter +import nl.hannahsten.texifyidea.psi.LatexTypes +import nl.hannahsten.texifyidea.util.parser.firstParentOfType +import nl.hannahsten.texifyidea.util.parser.nextSiblingOfType +import nl.hannahsten.texifyidea.util.parser.parentOfType +import nl.hannahsten.texifyidea.util.parser.previousSiblingOfType + +/** + * If the element is in an if/else construct + */ +fun isInConditionalBranch(element: PsiElement): Boolean { + // \ifthenelse{condition}{true}{false} + if (element.firstParentOfType()?.firstParentOfType()?.name == LatexGenericRegularCommand.IFTHENELSE.commandWithSlash) { + return true + } + + // Check for an \if...\fi combination + return isPreviousConditionalStart(element) && isNextConditionalEnd(element) +} + +/** + * If the next relevant command is a \fi + */ +private fun isNextConditionalEnd(current: PsiElement): Boolean { + return isEndConditional(nextConditionalCommand(current, searchBackwards = false) ?: return false) +} + +/** + * If the previous relevant command is an \if + */ +private fun isPreviousConditionalStart(current: PsiElement): Boolean { + return isStartConditional(nextConditionalCommand(current, searchBackwards = true) ?: return false) +} + +/** + * Next relevant command. There are many ways in which this does not work, but since this is just an inspection this is much safer than trying to parse user defined \if commands in the parser, which is impossiblee + */ +private fun nextConditionalCommand(element: PsiElement, searchBackwards: Boolean): PsiElement? { + var current = element.parentOfType(LatexNoMathContent::class) + while (current != null && !isConditional(current)) { + current = if (!searchBackwards) { + current.nextSibling?.nextSiblingOfType(LatexNoMathContent::class) + } + else { + current.prevSibling?.previousSiblingOfType(LatexNoMathContent::class) + } + } + return current +} + +private fun isConditional(element: PsiElement): Boolean { + return isStartConditional(element) || isEndConditional(element) +} + +private fun isStartConditional(rootElement: PsiElement): Boolean { + // To keep it simple, only look one level down + for (element in rootElement.children + listOf(rootElement)) { + if (element is LatexCommands && element.name?.startsWith("\\if") == true) return true + if (element.elementType == LatexTypes.START_IF) return true + } + return false +} + +private fun isEndConditional(rootElement: PsiElement): Boolean { + for (element in rootElement.children + listOf(rootElement)) { + if (element.firstChild?.elementType in setOf(LatexTypes.ELSE, LatexTypes.END_IF)) return true + } + return false +} \ No newline at end of file diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspectionTest.kt index 89212e026..f73104920 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/redundancy/LatexDuplicateDefinitionInspectionTest.kt @@ -39,4 +39,19 @@ class LatexDuplicateDefinitionInspectionTest : TexifyInspectionTestBase(LatexDup ) myFixture.checkHighlighting() } + + fun testIfthenelse() { + myFixture.configureByText( + LatexFileType, + """ + \usepackage{ifthen} + \ifthenelse {\equal{\venue}{1}}{ + \newcommand\examLocation{Building 1} + }{ + \newcommand\examLocation{Building 2} + } + """.trimIndent() + ) + myFixture.checkHighlighting() + } } \ No newline at end of file From 12512a247a873454952f574cc1644a95036b10dd Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sun, 15 Dec 2024 11:52:52 +0100 Subject: [PATCH 11/13] Disable some broken tests on Windows --- .../LatexFileNotFoundInspectionTest.kt | 50 +++++++++++++------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt index 9cc87d176..f3a7322f3 100644 --- a/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt +++ b/test/nl/hannahsten/texifyidea/inspections/latex/probablebugs/LatexFileNotFoundInspectionTest.kt @@ -1,5 +1,6 @@ package nl.hannahsten.texifyidea.inspections.latex.probablebugs +import com.intellij.openapi.util.SystemInfo import io.mockk.every import io.mockk.mockkStatic import nl.hannahsten.texifyidea.file.LatexFileType @@ -32,29 +33,40 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testMissingAbsolutePath() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture.myinvalidextension}""") - myFixture.checkHighlighting() + // Avoid "VfsRootAccess$VfsRootAccessNotAllowedError: File accessed outside allowed roots" on Windows in github actions + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture.myinvalidextension}""") + myFixture.checkHighlighting() + } } fun testValidAbsolutePath() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture.png}""") + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture.png}""") - myFixture.checkHighlighting() + myFixture.checkHighlighting() + } } fun testValidAbsolutePathCaps() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture.PNG}""") - myFixture.checkHighlighting() + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture.PNG}""") + myFixture.checkHighlighting() + } } fun testBackActionAbsolute() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/../path/../path/myPicture.png}""") - myFixture.checkHighlighting() + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/../path/../path/myPicture.png}""") + myFixture.checkHighlighting() + } } fun testCurrDirActionAbsolute() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/./resources/./././completion/path/././myPicture.png}""") - myFixture.checkHighlighting() + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/./resources/./././completion/path/././myPicture.png}""") + myFixture.checkHighlighting() + } } fun testAbsoluteGraphicsDirWithInclude() { @@ -84,19 +96,25 @@ class LatexFileNotFoundInspectionTest : TexifyInspectionTestBase(LatexFileNotFou } fun testDefaultExtensionCompletion() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture}""") - myFixture.checkHighlighting() + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myPicture}""") + myFixture.checkHighlighting() + } } fun testDefaultUpperCaseExtensionCompletion() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture}""") - myFixture.checkHighlighting() + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/inspections/latex/filenotfound/myOtherPicture}""") + myFixture.checkHighlighting() + } } fun testDefaultMixedCaseExtensionCompletion() { - myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myBadPicture}""") + if (!SystemInfo.isWindows) { + myFixture.configureByText(LatexFileType, """\includegraphics{$absoluteWorkingPath/test/resources/completion/path/myBadPicture}""") - myFixture.checkHighlighting() + myFixture.checkHighlighting() + } } fun testNoWarningInDefinition() { From 3cf4dd7a062517e11c36a923a8fc832e1c131ee0 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Sun, 15 Dec 2024 14:20:35 +0100 Subject: [PATCH 12/13] 0.9.10-alpha.3 --- CHANGELOG.md | 16 +++++++++++++++- gradle.properties | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ee144a7..674866aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,26 @@ ## [Unreleased] ### Added + +### Fixed + +## [0.9.10-alpha.3] - 2024-12-15 + +### Added + * Add support for automatic language injection on the minted environment * Add support for DeclareGraphicsExtensions * Add inspection to warn about a missing reference for a glossary occurrence * Do not fold sections in a command definition * Include optional parameters in spellcheck, if it contains text +* Improve performance of finding files to be indexed +* Show formatted file path in file not found inspection quickfix name +* Automatically index bibliography files outside the project that are included by an absolute path +* Disable quotes inspection when TeX ligatures are disabled by fontspec +* Inspections can now be suppressed for any single line, or block of text ### Fixed + * Fix LaTeX files not showing up when choosing main file in run configuration * Fix various issues with the Grazie implementation, in particular default rules for Grazie Pro @@ -460,7 +473,8 @@ Thanks to @jojo2357 and @MisterDeenis for contributing to this release! * Fix some intention previews. ([#2796](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2796)) * Other small bug fixes and improvements. ([#2776](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2776), [#2774](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2774), [#2765](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2765)-[#2773](https://github.com/Hannah-Sten/TeXiFy-IDEA/issues/2773)) -[Unreleased]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.10-alpha.2...HEAD +[Unreleased]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.10-alpha.3...HEAD +[0.9.10-alpha.3]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.10-alpha.2...v0.9.10-alpha.3 [0.9.10-alpha.2]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.9...v0.9.10-alpha.2 [0.9.9]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.8...v0.9.9 [0.9.8]: https://github.com/Hannah-Sten/TeXiFy-IDEA/compare/v0.9.7...v0.9.8 diff --git a/gradle.properties b/gradle.properties index 4c8939784..9586f2e10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -pluginVersion = 0.9.10-alpha.2 +pluginVersion = 0.9.10-alpha.3 # Info about build ranges: https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html # Note that an xyz branch corresponds to version 20xy.z and a since build of xyz.* From ad00409f9ff6841e131d4d41a391a20a0c2b3e52 Mon Sep 17 00:00:00 2001 From: Thomas Schouten Date: Mon, 16 Dec 2024 13:26:41 +0100 Subject: [PATCH 13/13] Update since build to 243 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9586f2e10..331ac6e97 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginVersion = 0.9.10-alpha.3 # Note that an xyz branch corresponds to version 20xy.z and a since build of xyz.* # means that the first possible build is the next branch number after xyz, so e.g. # a since build of 173.* is equal to 181 -pluginSinceBuild = 242.0 +pluginSinceBuild = 243.0 # Token for releasing to Jetbrains using the Gradle intellij/publishPlugin task, for more information see the Gradle build file. intellijPublishToken=mytoken