diff --git a/spellchecker/src/META-INF/SpellCheckerPlugin.xml b/spellchecker/src/META-INF/SpellCheckerPlugin.xml
index d9e1321cbcb0..571cd4c8db69 100644
--- a/spellchecker/src/META-INF/SpellCheckerPlugin.xml
+++ b/spellchecker/src/META-INF/SpellCheckerPlugin.xml
@@ -9,6 +9,7 @@
+
diff --git a/spellchecker/src/com/intellij/spellchecker/quickfixes/SpellCheckerQuickFixFactory.kt b/spellchecker/src/com/intellij/spellchecker/quickfixes/SpellCheckerQuickFixFactory.kt
new file mode 100644
index 000000000000..5bcb02293f91
--- /dev/null
+++ b/spellchecker/src/com/intellij/spellchecker/quickfixes/SpellCheckerQuickFixFactory.kt
@@ -0,0 +1,39 @@
+// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package com.intellij.spellchecker.quickfixes
+
+import com.intellij.codeInspection.LocalQuickFix
+import com.intellij.openapi.extensions.ExtensionPointName
+import com.intellij.openapi.util.TextRange
+import com.intellij.psi.PsiElement
+import com.intellij.spellchecker.DictionaryLayer
+import org.jetbrains.annotations.ApiStatus
+
+abstract class SpellCheckerQuickFixFactory {
+ companion object {
+ val EP_NAME = ExtensionPointName.create("com.intellij.spellchecker.quickFixFactory")
+
+ @JvmStatic
+ fun rename(element: PsiElement): LocalQuickFix {
+ return EP_NAME.extensionList.firstNotNullOfOrNull { it.createRename(element) } ?: RenameTo()
+ }
+
+ @JvmStatic
+ fun changeToVariants(element: PsiElement, rangeInElement: TextRange, word: String): List {
+ return EP_NAME.extensionList.firstNotNullOfOrNull { it.createChangeToVariantsFixes(element, rangeInElement, word) } ?: ChangeTo(word, element, rangeInElement).getAllAsFixes()
+ }
+
+ @JvmStatic
+ fun saveTo(element: PsiElement, rangeInElement: TextRange, word: String): LocalQuickFix {
+ return saveTo(element, rangeInElement, word, null)
+ }
+
+ @JvmStatic
+ fun saveTo(element: PsiElement, rangeInElement: TextRange, word: String, layer: DictionaryLayer?): LocalQuickFix {
+ return EP_NAME.extensionList.firstNotNullOfOrNull { it.createSaveToFix(element, rangeInElement, word, layer) } ?: SaveTo(word, layer)
+ }
+ }
+
+ open fun createRename(element: PsiElement): LocalQuickFix? = null
+ open fun createChangeToVariantsFixes(element: PsiElement, rangeInElement: TextRange, word: String): List? = null
+ open fun createSaveToFix(element: PsiElement, rangeInElement: TextRange, word: String, layer: DictionaryLayer?): LocalQuickFix? = null
+}
\ No newline at end of file