diff --git a/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintExternalAnnotator.kt b/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintExternalAnnotator.kt index a69163bc..3d664919 100644 --- a/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintExternalAnnotator.kt +++ b/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintExternalAnnotator.kt @@ -10,6 +10,7 @@ import com.intellij.lang.javascript.psi.JSFile import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project +import com.intellij.util.containers.ContainerUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiDocumentManager @@ -69,8 +70,29 @@ class TemplateLintExternalAnnotator(onTheFly: Boolean = true) : JSLinterExternal val prefix = TemplateLintBundle.message("hbs.lint.message.prefix") + " " annotationResult.errors.removeIf { it.code?.startsWith("glint") == true } val configurable = TemplateLintConfigurable(file.project, true) + val document = PsiDocumentManager.getInstance(file.project).getDocument(file) + val documentModificationStamp = document?.modificationStamp ?: -1L val fixes = JSLinterStandardFixes() .setEditSettingsAction(JSLinterEditSettingsAction(configurable, EmberIcons.TEMPLATE_LINT_16)) + .setErrorToIntentionConverter { error: JSLinterErrorBase -> + val result: MutableList = mutableListOf() + if (!holder.isBatchMode) { + // Offer a suppression comment insertion for the specific rule + ContainerUtil.addIfNotNull(result, TemplateLintSuppressionUtil.getSuppressForLineAction(error, documentModificationStamp)) + } + result + } + .setProblemGroup { error: JSLinterErrorBase? -> + if (holder.isBatchMode) { + null + } else if (error is com.intellij.lang.javascript.linter.JSLinterError) { + val intentions = TemplateLintSuppressionUtil.getSuppressionsForError(error, documentModificationStamp) + com.intellij.lang.javascript.validation.JSAnnotatorProblemGroup(intentions, null as String?) + } else { + null + } + } + JSLinterAnnotationsBuilder(file, annotationResult, holder, configurable, prefix, this.inspectionClass, fixes) .setHighlightingGranularity(HighlightingGranularity.element) .setDefaultFileLevelErrorIcon(EmberIcons.TEMPLATE_LINT_16) diff --git a/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintSuppressionUtil.kt b/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintSuppressionUtil.kt new file mode 100644 index 00000000..5bcd5578 --- /dev/null +++ b/src/main/kotlin/com/emberjs/hbs/linter/ember-template-lint/TemplateLintSuppressionUtil.kt @@ -0,0 +1,55 @@ +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.codeInsight.intention.impl.BaseIntentionAction +import com.intellij.lang.javascript.linter.JSLinterError +import com.intellij.lang.javascript.linter.JSLinterErrorBase +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiDocumentManager + +object TemplateLintSuppressionUtil { + fun getSuppressForLineAction(error: JSLinterErrorBase, modificationStamp: Long): IntentionAction? { + if (error !is JSLinterError) return null + val rule = error.code ?: return null + + return object : BaseIntentionAction() { + override fun getFamilyName(): String { + return "Disable template-lint rule" + } + + override fun getText(): String { + return "Disable template-lint rule $rule" + } + + override fun isAvailable(project: Project, editor: Editor?, file: com.intellij.psi.PsiFile?): Boolean { + return editor != null && editor.document.modificationStamp == modificationStamp + } + + override fun invoke(project: Project, editor: Editor?, file: com.intellij.psi.PsiFile?) { + if (editor == null) return + val document = editor.document + val line = Math.max(0, error.line - 1) + try { + val lineStart = document.getLineStartOffset(line) + val comment = "{{!-- template-lint-disable $rule --}}\n" + WriteCommandAction.runWriteCommandAction(project) { + document.insertString(lineStart, comment) + PsiDocumentManager.getInstance(project).commitDocument(document) + } + } catch (e: Exception) { + // ignore + } + } + + override fun startInWriteAction(): Boolean { + return true + } + } + } + + fun getSuppressionsForError(error: JSLinterError, modificationStamp: Long): List { + val a = getSuppressForLineAction(error, modificationStamp) + return if (a != null) listOf(a) else emptyList() + } +}