diff --git a/CHANGELOG.md b/CHANGELOG.md index 48491d97..df06782b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Released on ... - TODO (see [#NNN](https://github.com/JetBrains-Research/snakecharm/issues/NNN)) ### Added +- Color Settings Page (see [#431](https://github.com/JetBrains-Research/snakecharm/issues/431)) - Weak warnings for unused 'log' sections in 'use rule' (see [#414](https://github.com/JetBrains-Research/snakecharm/issues/414)) - Weak warnings for unused 'log' sections (see [#300](https://github.com/JetBrains-Research/snakecharm/issues/300)) - Support for 'module' and 'use' keywords (see [#355](https://github.com/JetBrains-Research/snakecharm/issues/355)) diff --git a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkColorSettingsPage.kt b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkColorSettingsPage.kt index b7439f0c..62a398f4 100644 --- a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkColorSettingsPage.kt +++ b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkColorSettingsPage.kt @@ -1,12 +1,16 @@ package com.jetbrains.snakecharm.lang.highlighter +import com.intellij.codeHighlighting.RainbowHighlighter +import com.intellij.lang.Language +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors import com.intellij.openapi.editor.colors.TextAttributesKey import com.intellij.openapi.fileTypes.SyntaxHighlighter import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory import com.intellij.openapi.options.colors.AttributesDescriptor import com.intellij.openapi.options.colors.ColorDescriptor -import com.intellij.openapi.options.colors.ColorSettingsPage +import com.intellij.openapi.options.colors.RainbowColorSettingsPage import com.jetbrains.python.PythonLanguage +import com.jetbrains.python.highlighting.PyRainbowVisitor import com.jetbrains.python.psi.LanguageLevel import com.jetbrains.snakecharm.SnakemakeBundle import com.jetbrains.snakecharm.SnakemakeIcons @@ -14,21 +18,55 @@ import com.jetbrains.snakecharm.lang.SnakemakeLanguageDialect import com.jetbrains.snakecharm.stringLanguage.lang.highlighter.SmkSLSyntaxHighlighter import javax.swing.Icon -class SmkColorSettingsPage : ColorSettingsPage { +class SmkColorSettingsPage : RainbowColorSettingsPage { override fun getAttributeDescriptors(): Array = arrayOf( - AttributesDescriptor(SnakemakeBundle.message("smk.color.keyword"), SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD), - AttributesDescriptor(SnakemakeBundle.message("smk.color.definition"), SnakemakeSyntaxHighlighterFactory.SMK_FUNC_DEFINITION), - AttributesDescriptor(SnakemakeBundle.message("smk.color.subsection"), SnakemakeSyntaxHighlighterFactory.SMK_DECORATOR), - AttributesDescriptor(SnakemakeBundle.message("smk.color.run"), SnakemakeSyntaxHighlighterFactory.SMK_PREDEFINED_DEFINITION), - - AttributesDescriptor(SnakemakeBundle.message("smk.color.string.text"), SnakemakeSyntaxHighlighterFactory.SMK_TEXT), - AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.content"), SmkSLSyntaxHighlighter.STRING_CONTENT), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.keyword"), + SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.definition"), + SnakemakeSyntaxHighlighterFactory.SMK_FUNC_DEFINITION + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.subsection"), + SnakemakeSyntaxHighlighterFactory.SMK_DECORATOR + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.run"), + SnakemakeSyntaxHighlighterFactory.SMK_PREDEFINED_DEFINITION + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.keyword.arg"), + SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD_ARGUMENT + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.text"), + SnakemakeSyntaxHighlighterFactory.SMK_TEXT + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.tqs"), + SnakemakeSyntaxHighlighterFactory.SMK_TRIPLE_QUOTED_STRING + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.SL.content"), + SmkSLSyntaxHighlighter.STRING_CONTENT + ), AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.braces"), SmkSLSyntaxHighlighter.BRACES), AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.comma"), SmkSLSyntaxHighlighter.COMMA), - AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.format"), SmkSLSyntaxHighlighter.FORMAT_SPECIFIER), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.SL.format"), + SmkSLSyntaxHighlighter.FORMAT_SPECIFIER + ), AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.key"), SmkSLSyntaxHighlighter.ACCESS_KEY), - AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.reference"), SmkSLSyntaxHighlighter.IDENTIFIER), - AttributesDescriptor(SnakemakeBundle.message("smk.color.string.SL.wildcard"), SmkSLSyntaxHighlighter.HIGHLIGHTING_WILDCARDS_KEY) + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.SL.reference"), + SmkSLSyntaxHighlighter.IDENTIFIER + ), + AttributesDescriptor( + SnakemakeBundle.message("smk.color.string.SL.wildcard"), + SmkSLSyntaxHighlighter.HIGHLIGHTING_WILDCARDS_KEY + ) ) override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY @@ -47,33 +85,37 @@ class SmkColorSettingsPage : ColorSettingsPage { } override fun getDemoText(): String = - """ - rule NAME: - input: - "file_1.txt" - output: - "file_2.txt" - shell: - "touch {output}" - - number = 0.451 # Python elements are configured in Python color settings - - use rule NAME as NAME_2 with: - input: - "{name}.bin" - output: - "{name}.bin" - message: - "Float number: {number:2f}" - threads: - 1 - - rule NAME3: - output: - "file_{number, \d+}", - arg = "file_1.txt" - run: - x = 2 + "rule NAME:\n" + + " \"\"\"\n" + + " Syntax Highlighting Demo" + + RainbowHighlighter.generatePaletteExample("\n ") + + "\n \"\"\"\n" + + """ + input: + "file_1.txt" + output: + "file_2.txt" + shell: + "touch {output}" + + number = 0.451 # Python elements are configured in Python color settings + + use rule NAME as NAME_2 with: + input: + "{name}.bin" + output: + "{name}.bin" + message: + "Float number: {number:2f}" + threads: + 1 + + rule NAME3: + output: + "file_{number, }", + arg = "file_1.txt" + run: + x = 2 """.trimIndent() override fun getAdditionalHighlightingTagToDescriptorMap(): MutableMap = @@ -83,6 +125,8 @@ class SmkColorSettingsPage : ColorSettingsPage { it["sectionName"] = SnakemakeSyntaxHighlighterFactory.SMK_DECORATOR it["run"] = SnakemakeSyntaxHighlighterFactory.SMK_PREDEFINED_DEFINITION it["text"] = SnakemakeSyntaxHighlighterFactory.SMK_TEXT + it["TQS"] = SnakemakeSyntaxHighlighterFactory.SMK_TRIPLE_QUOTED_STRING + it["keywordArg"] = SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD_ARGUMENT it["injectedText"] = SmkSLSyntaxHighlighter.STRING_CONTENT it["braces"] = SmkSLSyntaxHighlighter.BRACES @@ -91,5 +135,13 @@ class SmkColorSettingsPage : ColorSettingsPage { it["accessKey"] = SmkSLSyntaxHighlighter.ACCESS_KEY it["reference"] = SmkSLSyntaxHighlighter.IDENTIFIER it["wildcard"] = SmkSLSyntaxHighlighter.HIGHLIGHTING_WILDCARDS_KEY + + it["localVar"] = DefaultLanguageHighlighterColors.LOCAL_VARIABLE + it.putAll(RainbowHighlighter.createRainbowHLM()) } + + override fun isRainbowType(type: TextAttributesKey?): Boolean = + PyRainbowVisitor.Holder.HIGHLIGHTING_KEYS.contains(type) + + override fun getLanguage(): Language = SnakemakeLanguageDialect } \ No newline at end of file diff --git a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkSyntaxAnnotator.kt b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkSyntaxAnnotator.kt index 38a72105..13d4bc7c 100644 --- a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkSyntaxAnnotator.kt +++ b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SmkSyntaxAnnotator.kt @@ -97,5 +97,15 @@ object SmkSyntaxAnnotator : SmkAnnotator() { st.getSectionKeywordNode()?.let { addHighlightingAnnotation(it, SnakemakeSyntaxHighlighterFactory.SMK_DECORATOR) } + if (st is SmkArgsSection) { + st.keywordArguments?.forEach { + it.keywordNode?.psi?.let { name -> + addHighlightingAnnotation( + name, + SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD_ARGUMENT + ) + } + } + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SnakemakeSyntaxHighlighterFactory.kt b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SnakemakeSyntaxHighlighterFactory.kt index d46a9217..e3675ddc 100644 --- a/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SnakemakeSyntaxHighlighterFactory.kt +++ b/src/main/kotlin/com/jetbrains/snakecharm/lang/highlighter/SnakemakeSyntaxHighlighterFactory.kt @@ -19,28 +19,39 @@ import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher */ class SnakemakeSyntaxHighlighterFactory : SyntaxHighlighterFactory() { companion object { - val SMK_KEYWORD = TextAttributesKey.createTextAttributesKey("SMK_KEYWORD", + val SMK_KEYWORD = TextAttributesKey.createTextAttributesKey( + "SMK_KEYWORD", DefaultLanguageHighlighterColors.KEYWORD ) - val SMK_FUNC_DEFINITION = TextAttributesKey.createTextAttributesKey("SMK_FUNC_DEFINITION", + val SMK_FUNC_DEFINITION = TextAttributesKey.createTextAttributesKey( + "SMK_FUNC_DEFINITION", DefaultLanguageHighlighterColors.FUNCTION_DECLARATION ) - val SMK_DECORATOR = TextAttributesKey.createTextAttributesKey("SMK_DECORATOR", + val SMK_DECORATOR = TextAttributesKey.createTextAttributesKey( + "SMK_DECORATOR", DefaultLanguageHighlighterColors.METADATA ) val SMK_PREDEFINED_DEFINITION: TextAttributesKey = PyHighlighter.PY_PREDEFINED_DEFINITION // IDK why, but explicit creating via '.createText...' works improperly - + val SMK_KEYWORD_ARGUMENT = TextAttributesKey.createTextAttributesKey( + "SMK_KEYWORD_ARGUMENT", + DefaultLanguageHighlighterColors.PARAMETER + ) val SMK_TEXT = TextAttributesKey.createTextAttributesKey("SMK_TEXT", DefaultLanguageHighlighterColors.STRING) + val SMK_TRIPLE_QUOTED_STRING = TextAttributesKey.createTextAttributesKey( + "SMK_TRIPLE_QUOTED_STRING", + DefaultLanguageHighlighterColors.STRING + ) } private val myMap = FactoryMap.create { key -> object : PyHighlighter(key) { override fun getTokenHighlights(tokenType: IElementType?): Array { - if (tokenType === PyTokenTypes.SINGLE_QUOTED_UNICODE) { - return arrayOf(SMK_TEXT) + return when (tokenType) { + PyTokenTypes.SINGLE_QUOTED_UNICODE -> arrayOf(SMK_TEXT) + PyTokenTypes.TRIPLE_QUOTED_UNICODE -> arrayOf(SMK_TRIPLE_QUOTED_STRING) + else -> super.getTokenHighlights(tokenType) } - return super.getTokenHighlights(tokenType) } override fun createHighlightingLexer(level: LanguageLevel) = SnakemakeHighlightingLexer(level) @@ -49,7 +60,10 @@ class SnakemakeSyntaxHighlighterFactory : SyntaxHighlighterFactory() { override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?): SyntaxHighlighter { val level = when { - project != null && virtualFile != null -> PythonLanguageLevelPusher.getLanguageLevelForVirtualFile(project, virtualFile) + project != null && virtualFile != null -> PythonLanguageLevelPusher.getLanguageLevelForVirtualFile( + project, + virtualFile + ) else -> LanguageLevel.getDefault() } diff --git a/src/main/resources/SnakemakeBundle.properties b/src/main/resources/SnakemakeBundle.properties index 3a22acf2..2cc08c99 100644 --- a/src/main/resources/SnakemakeBundle.properties +++ b/src/main/resources/SnakemakeBundle.properties @@ -279,7 +279,9 @@ smk.color.keyword=Keyword smk.color.definition=Name definition smk.color.subsection=Subsection smk.color.run=Run section +smk.color.keyword.arg=Keyword argument smk.color.string.text=String//Text +smk.color.string.tqs=String//Triple quoted string smk.color.string.SL.content=String//SnakemakeSL//String content smk.color.string.SL.braces=String//SnakemakeSL//Braces smk.color.string.SL.comma=String//SnakemakeSL//Comma diff --git a/src/test/kotlin/features/glue/ActionsSteps.kt b/src/test/kotlin/features/glue/ActionsSteps.kt index f0491006..0d0689ec 100644 --- a/src/test/kotlin/features/glue/ActionsSteps.kt +++ b/src/test/kotlin/features/glue/ActionsSteps.kt @@ -25,6 +25,9 @@ import com.intellij.util.containers.ContainerUtil import com.jetbrains.snakecharm.FakeSnakemakeInjector import com.jetbrains.snakecharm.codeInsight.completion.wrapper.SmkWrapperCrawler import com.jetbrains.snakecharm.inspections.SmkUnrecognizedSectionInspection +import com.jetbrains.snakecharm.lang.highlighter.SmkColorSettingsPage +import com.jetbrains.snakecharm.lang.highlighter.SnakemakeSyntaxHighlighterFactory +import com.jetbrains.snakecharm.stringLanguage.lang.highlighter.SmkSLSyntaxHighlighter import features.glue.SnakemakeWorld.findPsiElementUnderCaret import features.glue.SnakemakeWorld.fixture import features.glue.SnakemakeWorld.myFixture @@ -82,16 +85,16 @@ class ActionsSteps { val document = PsiDocumentManager.getInstance(fixture.project).getDocument(psiFile)!! val pos = document.text.indexOf(signature) assertTrue( - pos >= 0, - "Signature <$signature> wasn't found in the file ${psiFile.name}." + pos >= 0, + "Signature <$signature> wasn't found in the file ${psiFile.name}." ) val reference = fixture.getReferenceAtCaretPosition() assertNotNull(reference, message = "There is no reference at the caret position") assertEquals( - signature, - reference.canonicalText, - message = "Expected highlighted text wasn't equal to the actual one." + signature, + reference.canonicalText, + message = "Expected highlighted text wasn't equal to the actual one." ) } } @@ -114,6 +117,54 @@ class ActionsSteps { } } + @Then("^I expect the tag highlighting to be the same as the annotator highlighting$") + fun iExpectTheTagHighlightingToBeTheSameAsTheAnnotatorHighlighting() { + val level = "info" + val attributesToCheck = arrayOf( + // Currently, IDK how to check all used tags + // Snakemake: + SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD, + SnakemakeSyntaxHighlighterFactory.SMK_FUNC_DEFINITION, + SnakemakeSyntaxHighlighterFactory.SMK_DECORATOR, + SnakemakeSyntaxHighlighterFactory.SMK_PREDEFINED_DEFINITION, + SnakemakeSyntaxHighlighterFactory.SMK_KEYWORD_ARGUMENT, + // SnakemakeSL: + SmkSLSyntaxHighlighter.HIGHLIGHTING_WILDCARDS_KEY + ) + val page = SmkColorSettingsPage() + val fixture = fixture() + val tagPattern = Pattern.compile("<(.+)>(\\w+)") + val itemPattern = Pattern.compile(">(\\w+)<") + val linesPage = page.demoText.lines() + var problemsCounter = 0 + for (ind in 0 until linesPage.count()) { + val lineMatcher = tagPattern.matcher(linesPage[ind]) + while (lineMatcher.find()) { + val itemMatcher = itemPattern.matcher(lineMatcher.group(0)) + if (itemMatcher.find()) { + val item = itemMatcher.group(1) + val tag = lineMatcher.group(1) + val attributesKey = page.additionalHighlightingTagToDescriptorMap[tag] ?: continue + if (attributesKey in attributesToCheck) { + ++problemsCounter + wrapTextInHighlightingTags( + level, + item, + fixture.editor.document.text.lines()[ind], + attributesKey.externalName + ) + } + } + } + } + if (SnakemakeWorld.myInspectionProblemsCounts == null) { + SnakemakeWorld.myInspectionProblemsCounts = mutableMapOf(level to problemsCounter) + } else { + val counts = SnakemakeWorld.myInspectionProblemsCounts!! + counts[level] = problemsCounter + } + } + private fun updatedInspectionProblemsCounter(level: String) { if (SnakemakeWorld.myInspectionProblemsCounts == null) { SnakemakeWorld.myInspectionProblemsCounts = mutableMapOf(level to 1) @@ -125,11 +176,11 @@ class ActionsSteps { } private fun wrapTextInHighlightingTags( - highlightingLevel: String, - text: String, - signature: String, - message: String, - searchInTags: Boolean = false + highlightingLevel: String, + text: String, + signature: String, + message: String, + searchInTags: Boolean = false ) { require(!Pattern.compile("(^|[^\\\\])\"").matcher(message).find()) { "Quotes (\") should be escaped (with \\) in message: $message" @@ -151,16 +202,16 @@ class ActionsSteps { updatedInspectionProblemsCounter(highlightingLevel) ApplicationManager.getApplication().invokeAndWait { - performAction(project, { + performAction(project) { fixture.editor.document.replaceString(startPos, startPos + text.length, newText) - }) + } } } private fun findTextPositionInsideTags( - tag: String, - text: String, - fullText: String + tag: String, + text: String, + fullText: String ): Int { val textInsideTagsPattern = Pattern.compile("<$tag descr=.+?>([^<>]+)") val matcher = textInsideTagsPattern.matcher(fullText) @@ -168,15 +219,15 @@ class ActionsSteps { } private fun findTextPositionWithSignature( - text: String, - signature: String, - document: Document, - psiFile: PsiFile + text: String, + signature: String, + document: Document, + psiFile: PsiFile ): Int { val pos = document.text.indexOf(signature) assertTrue( - pos >= 0, - "Signature <$signature> wasn't found in the file ${psiFile.name}." + pos >= 0, + "Signature <$signature> wasn't found in the file ${psiFile.name}." ) val posInSignature = signature.indexOf(text) @@ -194,9 +245,10 @@ class ActionsSteps { checkHighlighting(type, true) } - fun checkHighlighting(level: String, ignoreExtra: Boolean) { + private fun checkHighlighting(level: String, ignoreExtra: Boolean) { val problemsCounts = SnakemakeWorld.myInspectionProblemsCounts - SnakemakeWorld.myInspectionProblemsCounts = null // reset counter after check in order to validate in teardown that assertion step was called + SnakemakeWorld.myInspectionProblemsCounts = + null // reset counter after check in order to validate in teardown that assertion step was called requireNotNull(problemsCounts) { "No expected inspections steps in test. Add 'I expect no inspection ..' step if no inspection" + @@ -261,15 +313,15 @@ class ActionsSteps { val docPopupText = myGeneratedDocPopupText assertNotNull(docPopupText) assertTrue( - text in docPopupText, - "Expected <$text> to be in <$docPopupText>" + text in docPopupText, + "Expected <$text> to be in <$docPopupText>" ) } @When("^I invoke rename with name \"([^\"]+)\"$") fun iInvokeRenameWithName(newName: String) { ApplicationManager.getApplication().invokeAndWait { - fixture().renameElementAtCaret(newName) + fixture().renameElementAtCaret(newName) } } @@ -312,13 +364,12 @@ class ActionsSteps { "First call step: I check highlighting ..." } val allQuickFixes = fixture().getAllQuickFixes() - val quickFix = allQuickFixes.firstOrNull { it.familyName == quickFixFamilyName } + return allQuickFixes.firstOrNull { it.familyName == quickFixFamilyName } ?: fail( "Cannot find quickfix '${quickFixFamilyName}', available quick fixes:[\n${ allQuickFixes.joinToString(separator = "\n") { it.familyName } }\n]" ) - return quickFix } @Given("^I emulate quick fix apply: ignore unresolved item '(.*)'") @@ -326,7 +377,7 @@ class ActionsSteps { val list = (LocalInspectionEP.LOCAL_INSPECTION.extensionList .first { it.shortName == "SmkUnrecognizedSectionInspection" } .instance as SmkUnrecognizedSectionInspection).ignoredItems - if (sectionName in list){ + if (sectionName in list) { fail("Section \"${sectionName}\" is already here, but it shouldn't be") } list.add(sectionName) @@ -389,19 +440,19 @@ class ActionsSteps { } @Then("^I inject SmkSL at a caret") - fun iInjectSmkSLAtCaret() { - ApplicationManager.getApplication().invokeAndWait { - val fixture = fixture() - val offsetUnderCaret = SnakemakeWorld.getOffsetUnderCaret() - val elementAtOffset = fixture.file.findElementAt(offsetUnderCaret) - requireNotNull(elementAtOffset) { "No element at a caret offset: $offsetUnderCaret" } - - // auto unregister when fixture is disposed - InjectedLanguageManager.getInstance(fixture.project).registerMultiHostInjector( - FakeSnakemakeInjector(offsetUnderCaret), fixture.projectDisposable - ) - } - } + fun iInjectSmkSLAtCaret() { + ApplicationManager.getApplication().invokeAndWait { + val fixture = fixture() + val offsetUnderCaret = SnakemakeWorld.getOffsetUnderCaret() + val elementAtOffset = fixture.file.findElementAt(offsetUnderCaret) + requireNotNull(elementAtOffset) { "No element at a caret offset: $offsetUnderCaret" } + + // auto unregister when fixture is disposed + InjectedLanguageManager.getInstance(fixture.project).registerMultiHostInjector( + FakeSnakemakeInjector(offsetUnderCaret), fixture.projectDisposable + ) + } + } @Given("^I invoke (EditorCodeBlockStart|EditorCodeBlockEnd) action$") fun iInvokeCodeBlockSelectionAction(actionId: String) { @@ -455,8 +506,8 @@ class ActionsSteps { } private fun findTargetElementFor(element: PsiElement, editor: Editor) = - DocumentationManager.getInstance(element.project) - .findTargetElement(editor, element.containingFile, element) + DocumentationManager.getInstance(element.project) + .findTargetElement(editor, element.containingFile, element) private fun generateDocumentation(generateQuickDoc: Boolean) { ApplicationManager.getApplication().invokeAndWait { @@ -469,18 +520,18 @@ class ActionsSteps { myGeneratedDocPopupText = when { generateQuickDoc -> documentationProvider.getQuickNavigateInfo( - targetElement, element + targetElement, element ) else -> documentationProvider.generateDoc( - targetElement, element + targetElement, element ) } } } @When("^Parse wrapper args for \"meta.yaml\" and \"wrapper.(py|r)\" result is:$") - fun checkWrapperArgsParsing(ext: String, text :String) { - ApplicationManager.getApplication().invokeAndWait() { + fun checkWrapperArgsParsing(ext: String, text: String) { + ApplicationManager.getApplication().invokeAndWait { val fixture = fixture() val wrapperFileContent = fixture.findFileInTempDir("wrapper.$ext")?.let { @@ -496,17 +547,17 @@ class ActionsSteps { ) val args = info.args - val mapped = args.keys.sorted().map { key -> + val mapped = args.keys.sorted().joinToString(separator = "\n") { key -> val values = args[key]!! "$key:${values.joinToString(", ", prefix = "(", postfix = ")") { "'$it'" }}" - }.joinToString(separator="\n") + } Assert.assertEquals(StringUtil.convertLineSeparators(text.trim()), mapped.trim()) } } @Then("^I check ignored element <([^>]+)>") - fun checkIgnoredElementInInspectionList(el : String){ + fun checkIgnoredElementInInspectionList(el: String) { Assert.assertTrue(el in (LocalInspectionEP.LOCAL_INSPECTION.extensionList .first { it.shortName == "SmkUnrecognizedSectionInspection" } .instance as SmkUnrecognizedSectionInspection).ignoredItems) @@ -516,7 +567,7 @@ class ActionsSteps { fun performAction(project: Project, action: Runnable) { ApplicationManager.getApplication().runWriteAction { CommandProcessor.getInstance().executeCommand( - project, action, "SnakeCharmTestCmd", null + project, action, "SnakeCharmTestCmd", null ) } } diff --git a/src/test/kotlin/features/glue/FilesSteps.kt b/src/test/kotlin/features/glue/FilesSteps.kt index f8025685..37077523 100644 --- a/src/test/kotlin/features/glue/FilesSteps.kt +++ b/src/test/kotlin/features/glue/FilesSteps.kt @@ -4,6 +4,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.util.text.StringUtil +import com.jetbrains.snakecharm.lang.highlighter.SmkColorSettingsPage import io.cucumber.java.en.Then import io.cucumber.java.en.Given import junit.framework.TestCase.assertEquals @@ -33,6 +34,13 @@ class FilesSteps { createAndAddFile(name, text) } + @Given("^I open a color settings page text$") + fun iOpenAColorSettingsPAge() { + val page = SmkColorSettingsPage() + createAndAddFile("ColorSettingsPageDemo.smk", page.demoText.replace(Regex(""), "")) + } + + @Then("^the file \"(.+)\" should have text$") fun theFileShouldHaveText(path: String, text: String) { ApplicationManager.getApplication().runReadAction { diff --git a/src/test/resources/features/highlighting/color_settings_page.feature b/src/test/resources/features/highlighting/color_settings_page.feature new file mode 100644 index 00000000..847c0ae0 --- /dev/null +++ b/src/test/resources/features/highlighting/color_settings_page.feature @@ -0,0 +1,7 @@ +Feature: Color Settings Page + + Scenario: Checks that color settings page tags have the same highlighting with Smk annotators + Given a snakemake project + Given I open a color settings page text + Then I expect the tag highlighting to be the same as the annotator highlighting + When I check highlighting infos ignoring extra highlighting \ No newline at end of file diff --git a/src/test/resources/features/highlighting/smk_syntax_annotator.feature b/src/test/resources/features/highlighting/smk_syntax_annotator.feature index 71296159..62d6dbbe 100644 --- a/src/test/resources/features/highlighting/smk_syntax_annotator.feature +++ b/src/test/resources/features/highlighting/smk_syntax_annotator.feature @@ -222,6 +222,21 @@ Feature: Annotate additional syntax """ When I check highlighting infos + Scenario: Annotate keyword argument + Given a snakemake project + Given I open a file "foo.smk" with text + """ + rule NAME: + input: + "file1", + arg = "file2" + """ + Then I expect inspection info on with message + """ + SMK_KEYWORD_ARGUMENT + """ + When I check highlighting infos ignoring extra highlighting + Scenario: 'use' section highlighting, part 2 Given a snakemake project Given I open a file "foo.smk" with text