mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[command-completion] IDEA-369839 part of Support intention preview for all commands in command completion
GitOrigin-RevId: ece703b31a5e8ef765802e69b09f4629811deeb4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d7600f6acd
commit
8e4ed43a3f
@@ -1509,7 +1509,7 @@
|
||||
implementationClass="com.intellij.codeInsight.completion.commands.JavaCommandCompletionFactory$JavaIntentionCommandOffsetProvider"/>
|
||||
<!--<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.command.commands.SimpleRunMarkerCommandProvider" />-->
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaGenerateCommandCompletion" />
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaInlineVariableCompletionCommand" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaInlineVariableCompletionCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaGoToDeclarationCommandCompletionProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA"
|
||||
implementationClass="com.intellij.codeInsight.completion.command.commands.RenameActionCommandProvider"/>
|
||||
@@ -1520,12 +1520,10 @@
|
||||
implementationClass="com.intellij.codeInsight.completion.command.commands.PsiElementCommentByLineCompletionCommandProvider"/>
|
||||
<codeInsight.completion.command.provider language="JAVA"
|
||||
implementationClass="com.intellij.codeInsight.completion.command.commands.PsiElementCommentByBlockCompletionCommandProvider"/>
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaIntroduceVariableCommand" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaIntroduceVariableCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaShowUsagesActionCompletionCommandProvider" />
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.GenerateGetterSetterHandleCompletionCommand" />
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.GenerateSetterHandleCompletionCommand" />
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.GenerateGetterHandleCompletionCommand" />
|
||||
<codeInsight.completion.applicable.command language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaDeleteCompletionCommand" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.GenerateGetterSetterHandleCompletionCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaDeleteCompletionCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaCopyFQNCompletionCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaGoToImplementationCommandCompletionProvider" />
|
||||
<codeInsight.completion.command.provider language="JAVA" implementationClass="com.intellij.codeInsight.completion.commands.impl.JavaChangeSignatureCompletionCommandProvider" />
|
||||
|
||||
+45
-22
@@ -1,50 +1,69 @@
|
||||
// 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.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommandWithPreview
|
||||
import com.intellij.codeInsight.completion.command.HighlightInfoLookup
|
||||
import com.intellij.codeInsight.completion.command.getCommandContext
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComputable
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.modcommand.ActionContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.EditorColors
|
||||
import com.intellij.psi.PsiField
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiIdentifier
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import javax.swing.Icon
|
||||
|
||||
internal class GenerateGetterSetterHandleCompletionCommandProvider : CommandProvider {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
val element = getCommandContext(context.offset, context.psiFile) ?: return emptyList()
|
||||
if (element !is PsiIdentifier) return emptyList()
|
||||
val field = PsiTreeUtil.getParentOfType(element, PsiField::class.java) ?: return emptyList()
|
||||
|
||||
internal class GenerateGetterSetterHandleCompletionCommand :
|
||||
BaseGenerateGetterSetterHandleCompletionCommand(true, true, "Generate 'Getter/Setter'",
|
||||
QuickFixBundle.message("create.getter.setter"))
|
||||
val result = mutableListOf<CompletionCommand>()
|
||||
val possibleCases = listOf(
|
||||
GetterSetterCase(true, true, "Generate 'Getter/Setter'", QuickFixBundle.message("create.getter.setter")),
|
||||
GetterSetterCase(false, true, "Generate 'Setter'", QuickFixBundle.message("create.setter")),
|
||||
GetterSetterCase(true, false, "Generate 'Getter'", QuickFixBundle.message("create.getter")),
|
||||
)
|
||||
for (case in possibleCases) {
|
||||
val action = QuickFixFactory.getInstance()
|
||||
.createCreateGetterOrSetterFix(case.generateGetter, case.generateSetter, field)
|
||||
val actionContext = ActionContext.from(context.editor, context.psiFile).withElement(field)
|
||||
val modCommandAction = action.asModCommandAction()
|
||||
if (modCommandAction == null || modCommandAction.getPresentation(actionContext) == null) continue
|
||||
result.add(BaseGenerateGetterSetterHandleCompletionCommand(case.generateGetter,
|
||||
case.generateSetter,
|
||||
case.name,
|
||||
case.i18nName,
|
||||
HighlightInfoLookup(field.textRange, EditorColors.SEARCH_RESULT_ATTRIBUTES, 0)) {
|
||||
IntentionPreviewComputable(context.project, action, context.psiFile, context.editor, context.offset).call()
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
internal class GenerateSetterHandleCompletionCommand :
|
||||
BaseGenerateGetterSetterHandleCompletionCommand(false, true, "Generate 'Setter'",
|
||||
QuickFixBundle.message("create.setter"))
|
||||
private data class GetterSetterCase(val generateGetter: Boolean, val generateSetter: Boolean, val name: String, val i18nName: String)
|
||||
|
||||
internal class GenerateGetterHandleCompletionCommand :
|
||||
BaseGenerateGetterSetterHandleCompletionCommand(true, false, "Generate 'Getter'",
|
||||
QuickFixBundle.message("create.getter"))
|
||||
|
||||
abstract class BaseGenerateGetterSetterHandleCompletionCommand(
|
||||
private class BaseGenerateGetterSetterHandleCompletionCommand(
|
||||
val generateGetter: Boolean,
|
||||
val generateSetter: Boolean,
|
||||
override val name: String,
|
||||
override val i18nName: String,
|
||||
) : ApplicableCompletionCommand() {
|
||||
override val highlightInfo: HighlightInfoLookup?,
|
||||
private val preview: () -> IntentionPreviewInfo?,
|
||||
) : CompletionCommand(), CompletionCommandWithPreview {
|
||||
|
||||
override val icon: Icon? = null
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
val element = getCommandContext(offset, psiFile) ?: return false
|
||||
if (element !is PsiIdentifier) return false
|
||||
val field = PsiTreeUtil.getParentOfType(element, PsiField::class.java) ?: return false
|
||||
val action = QuickFixFactory.getInstance().createCreateGetterOrSetterFix(generateGetter, generateSetter, field)
|
||||
val context = ActionContext.from(editor, psiFile).withElement(field)
|
||||
return action.asModCommandAction()?.getPresentation(context) != null
|
||||
}
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val element = getCommandContext(offset, psiFile) ?: return
|
||||
val field = PsiTreeUtil.getParentOfType(element, PsiField::class.java) ?: return
|
||||
@@ -53,4 +72,8 @@ abstract class BaseGenerateGetterSetterHandleCompletionCommand(
|
||||
@Suppress("DialogTitleCapitalization")
|
||||
ShowIntentionActionsHandler.chooseActionAndInvoke(psiFile, editor, action, action.text)
|
||||
}
|
||||
|
||||
override fun getPreview(): IntentionPreviewInfo? {
|
||||
return preview()
|
||||
}
|
||||
}
|
||||
+40
-25
@@ -2,9 +2,14 @@
|
||||
package com.intellij.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommandWithPreview
|
||||
import com.intellij.codeInsight.completion.command.HighlightInfoLookup
|
||||
import com.intellij.codeInsight.completion.command.getCommandContext
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.java.JavaBundle
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
@@ -21,27 +26,42 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
internal class JavaDeleteCompletionCommand : ApplicableCompletionCommand(), DumbAware {
|
||||
private var _highlightInfo: HighlightInfoLookup? = null
|
||||
internal class JavaDeleteCompletionCommandProvider : CommandProvider {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
val element = getCommandContext(context.offset, context.psiFile) ?: return emptyList()
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java, PsiMember::class.java) ?: return emptyList()
|
||||
val hasTheSameOffset = psiElement.textRange.endOffset == context.offset
|
||||
if (!hasTheSameOffset) return emptyList()
|
||||
psiElement = getTopWithTheSameOffset(psiElement, context.offset)
|
||||
val highlightInfo = HighlightInfoLookup(psiElement.textRange, EditorColors.SEARCH_RESULT_ATTRIBUTES, 0)
|
||||
return listOf(createCommand(highlightInfo, psiElement))
|
||||
}
|
||||
|
||||
private fun createCommand(highlightInfo: HighlightInfoLookup, psiElement: PsiElement): CompletionCommand {
|
||||
return JavaDeleteCompletionCommand(highlightInfo, psiElement.text)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTopWithTheSameOffset(psiElement: PsiElement, offset: Int): PsiElement {
|
||||
var psiElement1 = psiElement
|
||||
var curElement = psiElement1
|
||||
while (curElement.textRange.endOffset == offset) {
|
||||
psiElement1 = curElement
|
||||
curElement = PsiTreeUtil.getParentOfType(curElement, PsiStatement::class.java, PsiMember::class.java) ?: break
|
||||
}
|
||||
return psiElement1
|
||||
}
|
||||
|
||||
private class JavaDeleteCompletionCommand(
|
||||
override val highlightInfo: HighlightInfoLookup?,
|
||||
private val originalText: String,
|
||||
) : CompletionCommand(), CompletionCommandWithPreview, DumbAware {
|
||||
override val name: String
|
||||
get() = "Delete element"
|
||||
override val i18nName: @Nls String
|
||||
get() = JavaBundle.message("command.completion.delete.element.text")
|
||||
override val icon: Icon?
|
||||
get() = null
|
||||
override val highlightInfo: HighlightInfoLookup?
|
||||
get() = _highlightInfo
|
||||
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
val element = getCommandContext(offset, psiFile) ?: return false
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java, PsiMember::class.java) ?: return false
|
||||
val hasTheSameOffset = psiElement.textRange.endOffset == offset
|
||||
if (!hasTheSameOffset) return false
|
||||
psiElement = getTopWithTheSameOffset(psiElement, offset)
|
||||
_highlightInfo = HighlightInfoLookup(psiElement.textRange, EditorColors.DELETED_TEXT_ATTRIBUTES, 0)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val element = getCommandContext(offset, psiFile) ?: return
|
||||
@@ -54,15 +74,10 @@ internal class JavaDeleteCompletionCommand : ApplicableCompletionCommand(), Dumb
|
||||
parent.element?.let {
|
||||
ReformatCodeProcessor(psiFile, arrayOf(it.textRange)).run()
|
||||
}
|
||||
}, psiFile) }
|
||||
}, psiFile)
|
||||
}
|
||||
|
||||
private fun getTopWithTheSameOffset(psiElement: PsiElement, offset: Int): PsiElement {
|
||||
var psiElement1 = psiElement
|
||||
var curElement = psiElement1
|
||||
while (curElement.textRange.endOffset == offset) {
|
||||
psiElement1 = curElement
|
||||
curElement = PsiTreeUtil.getParentOfType(curElement, PsiStatement::class.java, PsiMember::class.java) ?: break
|
||||
}
|
||||
return psiElement1
|
||||
override fun getPreview(): IntentionPreviewInfo? {
|
||||
return IntentionPreviewInfo.CustomDiff(JavaFileType.INSTANCE, originalText, "")
|
||||
}
|
||||
}
|
||||
+45
-27
@@ -1,12 +1,20 @@
|
||||
// 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.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommandWithPreview
|
||||
import com.intellij.codeInsight.completion.command.HighlightInfoLookup
|
||||
import com.intellij.codeInsight.completion.command.getCommandContext
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.java.JavaBundle
|
||||
import com.intellij.lang.refactoring.InlineActionHandler
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.EditorColors
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiIdentifier
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||
@@ -14,47 +22,55 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
internal class JavaInlineVariableCompletionCommand : ApplicableCompletionCommand() {
|
||||
override val name: String
|
||||
get() = "Inline"
|
||||
internal class JavaInlineVariableCompletionCommandProvider : CommandProvider {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
val element = getCommandContext(context.offset, context.psiFile) ?: return emptyList()
|
||||
if (element !is PsiIdentifier) return emptyList()
|
||||
|
||||
override val i18nName: @Nls String
|
||||
get() = JavaBundle.message("command.completion.inline.text")
|
||||
val javaRef = PsiTreeUtil.getParentOfType(element, PsiJavaCodeReferenceElement::class.java) ?: return emptyList()
|
||||
val psiElement = javaRef.resolve() ?: return emptyList()
|
||||
|
||||
override val icon: Icon
|
||||
get() = AllIcons.Actions.RefactoringBulb // Use an appropriate icon from IntelliJ's icon set
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
if (editor == null) return false
|
||||
val context = getCommandContext(offset, psiFile)
|
||||
if (context !is PsiIdentifier) {
|
||||
return false
|
||||
}
|
||||
val javaRef = PsiTreeUtil.getParentOfType(context, PsiJavaCodeReferenceElement::class.java)
|
||||
|
||||
val psiElement = javaRef?.resolve() ?: return false
|
||||
// Check if any inline handler can handle this element
|
||||
val editor = context.editor
|
||||
val extensionList = InlineActionHandler.EP_NAME.extensionList
|
||||
for (extension in extensionList) {
|
||||
try {
|
||||
if (extension.canInlineElementInEditor(psiElement, editor)) {
|
||||
return true
|
||||
val highlightInfo = element.textRange?.let {
|
||||
HighlightInfoLookup(it, EditorColors.SEARCH_RESULT_ATTRIBUTES, 0)
|
||||
}
|
||||
return listOf(JavaInlineVariableCompletionCommand(highlightInfo))
|
||||
}
|
||||
}
|
||||
catch (_: Exception) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private class JavaInlineVariableCompletionCommand(
|
||||
override val highlightInfo: HighlightInfoLookup?,
|
||||
) : CompletionCommand(), DumbAware, CompletionCommandWithPreview {
|
||||
override val name: String
|
||||
get() = "Inline"
|
||||
|
||||
override val i18nName: @Nls String
|
||||
get() = JavaBundle.message("command.completion.inline.text")
|
||||
|
||||
|
||||
override val icon: Icon?
|
||||
get() = AllIcons.Actions.RefactoringBulb // Use an appropriate icon from IntelliJ's icon set
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val context = getCommandContext(offset, psiFile)
|
||||
if (context !is PsiIdentifier) {
|
||||
return
|
||||
}
|
||||
val javaRef = PsiTreeUtil.getParentOfType(context, PsiJavaCodeReferenceElement::class.java)
|
||||
if (editor == null) return
|
||||
val element = getCommandContext(offset, psiFile) ?: return
|
||||
if (element !is PsiIdentifier) return
|
||||
|
||||
val psiElement = javaRef?.resolve() ?: return
|
||||
val javaRef = PsiTreeUtil.getParentOfType(element, PsiJavaCodeReferenceElement::class.java) ?: return
|
||||
val psiElement = javaRef.resolve() ?: return
|
||||
|
||||
val extensionList = InlineActionHandler.EP_NAME.extensionList
|
||||
for (extension in extensionList) {
|
||||
@@ -63,7 +79,9 @@ internal class JavaInlineVariableCompletionCommand : ApplicableCompletionCommand
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
override fun getPreview(): IntentionPreviewInfo? {
|
||||
return IntentionPreviewInfo.Html(ActionsBundle.message("action.Inline.description"))
|
||||
}
|
||||
}
|
||||
+30
-12
@@ -1,11 +1,16 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommandWithPreview
|
||||
import com.intellij.codeInsight.completion.command.getDataContext
|
||||
import com.intellij.codeInsight.completion.command.getTargetContext
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.lang.ContextAwareActionHandler
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||
import com.intellij.openapi.actionSystem.ActionUiKind
|
||||
@@ -20,7 +25,26 @@ import com.intellij.refactoring.actions.IntroduceVariableAction
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
internal class JavaIntroduceVariableCommand : ApplicableCompletionCommand() {
|
||||
internal class JavaIntroduceVariableCommandProvider : CommandProvider {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
val editor = context.editor
|
||||
val psiFile = context.psiFile
|
||||
val offset = context.offset
|
||||
val factory = JavaRefactoringActionHandlerFactory.getInstance()
|
||||
val variableHandler = factory.createIntroduceVariableHandler()
|
||||
if (variableHandler is ContextAwareActionHandler &&
|
||||
variableHandler.isAvailableForQuickList(editor, psiFile, getDataContext(psiFile, editor, getTargetContext(offset, editor)))) {
|
||||
return listOf(createCommand())
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun createCommand(): CompletionCommand {
|
||||
return JavaIntroduceVariableCommand()
|
||||
}
|
||||
}
|
||||
|
||||
internal class JavaIntroduceVariableCommand : CompletionCommand(), CompletionCommandWithPreview {
|
||||
override val name: String
|
||||
get() = "Introduce variable"
|
||||
|
||||
@@ -30,16 +54,6 @@ internal class JavaIntroduceVariableCommand : ApplicableCompletionCommand() {
|
||||
override val icon: Icon
|
||||
get() = AllIcons.Nodes.Variable
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
if (editor == null) return false
|
||||
val factory = JavaRefactoringActionHandlerFactory.getInstance()
|
||||
val variableHandler = factory.createIntroduceVariableHandler()
|
||||
if (variableHandler is ContextAwareActionHandler) {
|
||||
return variableHandler.isAvailableForQuickList(editor, psiFile, getDataContext(psiFile, editor, getTargetContext(offset, editor)))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val action = IntroduceVariableAction()
|
||||
if (editor == null) return
|
||||
@@ -51,4 +65,8 @@ internal class JavaIntroduceVariableCommand : ApplicableCompletionCommand() {
|
||||
ActionUtil.performActionDumbAwareWithCallbacks(action, event)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPreview(): IntentionPreviewInfo? {
|
||||
return IntentionPreviewInfo.Html(ActionsBundle.message("action.IntroduceVariable.description"))
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,3 @@
|
||||
*a:com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
- com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
- com.intellij.openapi.project.PossiblyDumbAware
|
||||
- <init>():V
|
||||
- a:isApplicable(I,com.intellij.psi.PsiFile,com.intellij.openapi.editor.Editor):Z
|
||||
- supportsReadOnly():Z
|
||||
*:com.intellij.codeInsight.completion.command.CommandCompletionFactory
|
||||
- com.intellij.openapi.project.PossiblyDumbAware
|
||||
- commandProviders(com.intellij.openapi.project.Project,com.intellij.lang.Language):java.util.List
|
||||
|
||||
+12
-34
@@ -5,12 +5,10 @@ import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.openapi.project.PossiblyDumbAware
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||
import com.intellij.util.concurrency.annotations.RequiresReadLock
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
@@ -42,7 +40,19 @@ abstract class CompletionCommand {
|
||||
* can be left null, in which case a default priority will be assumed.
|
||||
*/
|
||||
open val priority: Int? = null
|
||||
|
||||
/**
|
||||
* Provides additional information about the command that can be displayed
|
||||
* in the completion popup. This information helps users understand the
|
||||
* purpose or effect of the command.
|
||||
*/
|
||||
open val additionalInfo: String? = null
|
||||
|
||||
/**
|
||||
* Specifies how the command should be highlighted in the editor.
|
||||
* Contains information about the text range to highlight, the highlighting style,
|
||||
* and the priority of the highlight effect.
|
||||
*/
|
||||
open val highlightInfo: HighlightInfoLookup? = null
|
||||
|
||||
/**
|
||||
@@ -85,38 +95,6 @@ fun getCommandContext(offset: Int, psiFile: PsiFile): PsiElement? {
|
||||
return (if (offset == 0) psiFile.findElementAt(offset) else psiFile.findElementAt(offset - 1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an abstract base class for completion commands that are applicable under specific conditions.
|
||||
* This class extends the functionality of `CompletionCommand` and introduces methods to evaluate the
|
||||
* applicability of the command in a given context.
|
||||
*
|
||||
* Should be stateless and can be applied either to physical and non-physical classes
|
||||
* Should implement DumbAware to support DumbMode
|
||||
*/
|
||||
@Deprecated("Use providers instead")
|
||||
abstract class ApplicableCompletionCommand : CompletionCommand(), PossiblyDumbAware {
|
||||
|
||||
/**
|
||||
* Indicates whether the implementation supports non-written files.
|
||||
* (For example, a command can navigate to another file)
|
||||
*
|
||||
* @return true if non-written files are supported; false otherwise.
|
||||
*/
|
||||
@Deprecated("Use providers instead")
|
||||
open fun supportsReadOnly(): Boolean = false
|
||||
|
||||
/**
|
||||
* Determines whether the command is applicable based on the given context.
|
||||
* Can be called on non-physical classes and imaginary editors
|
||||
*
|
||||
* @param offset The offset in the file where the applicability should be checked.
|
||||
* @param psiFile The PSI file where the applicability should be evaluated.
|
||||
* @param editor The editor. Can be null. Used only for compatibility with old actions
|
||||
*/
|
||||
@RequiresReadLock
|
||||
abstract fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean
|
||||
}
|
||||
|
||||
data class HighlightInfoLookup(
|
||||
val range: TextRange,
|
||||
val attributesKey: TextAttributesKey,
|
||||
|
||||
@@ -149,21 +149,6 @@ c:com.intellij.codeInsight.actions.VcsFacade
|
||||
- documentationTarget(com.intellij.psi.PsiFile,com.intellij.codeInsight.lookup.LookupElement,I):com.intellij.platform.backend.documentation.DocumentationTarget
|
||||
*f:com.intellij.codeInsight.completion.command.CommandCompletionDocumentationProviderKt
|
||||
- sf:combineFragments(java.util.List,java.util.List):java.util.List
|
||||
*a:com.intellij.codeInsight.completion.command.commands.AbstractActionCompletionCommand
|
||||
- com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
- com.intellij.openapi.project.DumbAware
|
||||
- <init>(java.lang.String,java.lang.String,java.lang.String,javax.swing.Icon,java.lang.Integer):V
|
||||
- b:<init>(java.lang.String,java.lang.String,java.lang.String,javax.swing.Icon,java.lang.Integer,I,kotlin.jvm.internal.DefaultConstructorMarker):V
|
||||
- execute(I,com.intellij.psi.PsiFile,com.intellij.openapi.editor.Editor):V
|
||||
- f:getActionId():java.lang.String
|
||||
- getAdditionalInfo():java.lang.String
|
||||
- getI18nName():java.lang.String
|
||||
- getIcon():javax.swing.Icon
|
||||
- getName():java.lang.String
|
||||
- getPriority():java.lang.Integer
|
||||
- isApplicable(I,com.intellij.psi.PsiFile,com.intellij.openapi.editor.Editor):Z
|
||||
- pf:isApplicableToProject(I,com.intellij.psi.PsiFile):Z
|
||||
- f:setActionId(java.lang.String):V
|
||||
*a:com.intellij.codeInsight.completion.command.commands.AbstractChangeSignatureCompletionCommandProvider
|
||||
- com.intellij.codeInsight.completion.command.commands.ActionCommandProvider
|
||||
- <init>():V
|
||||
|
||||
+37
-73
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.completion.command.commands
|
||||
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
@@ -29,6 +28,18 @@ import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
|
||||
/**
|
||||
* Provides completion commands that execute IDE actions identified by their action IDs.
|
||||
* This provider creates commands that integrate with IntelliJ Platform's action system,
|
||||
* allowing actions to be triggered through code completion features.
|
||||
*
|
||||
* @property actionId The unique identifier of the IDE action to be executed
|
||||
* @property name The display name of the command
|
||||
* @property i18nName The internationalized name of the command
|
||||
* @property icon Optional icon to be displayed with the command
|
||||
* @property priority Optional priority value affecting command ordering
|
||||
* @property previewText Optional preview text shown when the command is selected
|
||||
*/
|
||||
open class ActionCommandProvider(
|
||||
@field:Language("devkit-action-id") var actionId: String,
|
||||
val name: String,
|
||||
@@ -38,12 +49,29 @@ open class ActionCommandProvider(
|
||||
val previewText: @Nls String?,
|
||||
) : CommandProvider, DumbAware {
|
||||
|
||||
/**
|
||||
* Creates and returns a list of completion commands based on the provided context.
|
||||
* The method checks if the action is applicable in the current context and creates
|
||||
* the appropriate command if conditions are met.
|
||||
*
|
||||
* @param context The context containing information about the completion environment
|
||||
* @return A list of completion commands, empty if the action is not applicable
|
||||
*/
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
if (!isApplicable(context.offset, context.psiFile, context.editor)) return emptyList()
|
||||
val element = createCommand(context) ?: return emptyList()
|
||||
return listOf(element)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new action completion command based on the provided context.
|
||||
* This method instantiates an [ActionCompletionCommand] with the provider's configuration
|
||||
* including action ID, name, icon, and preview settings.
|
||||
*
|
||||
* @param context The context containing information about the completion environment
|
||||
* @return A new [ActionCompletionCommand] instance, or null if the command cannot be created
|
||||
*/
|
||||
protected open fun createCommand(context: CommandCompletionProviderContext): ActionCompletionCommand? =
|
||||
ActionCompletionCommand(actionId = actionId,
|
||||
name = name,
|
||||
@@ -52,6 +80,14 @@ open class ActionCommandProvider(
|
||||
priority = priority,
|
||||
previewText = previewText)
|
||||
|
||||
/**
|
||||
* Checks whether the action associated with this provider is applicable in the current context.
|
||||
*
|
||||
* @param offset The caret offset in the editor
|
||||
* @param psiFile The PSI file being edited
|
||||
* @param editor The current editor instance, may be null
|
||||
* @return true if the action can be applied in the current context, false otherwise
|
||||
*/
|
||||
protected open fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
val action: AnAction? = ActionManager.getInstance().getAction(actionId)
|
||||
if (action == null || editor == null) return false
|
||||
@@ -129,76 +165,4 @@ open class ActionCompletionCommand(
|
||||
if (previewText == null) return null
|
||||
return IntentionPreviewInfo.Html(previewText)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an abstract action completion command that triggers a specific IDE action
|
||||
* identified by its `actionId`. This class allows integration of IntelliJ Platform actions
|
||||
* as part of code completion features, ensuring that the action is applicable and
|
||||
* executable within a given code editor context.
|
||||
*/
|
||||
@Deprecated("Use providers instead")
|
||||
abstract class AbstractActionCompletionCommand(
|
||||
@Language("devkit-action-id") var actionId: String,
|
||||
override val name: String,
|
||||
override val i18nName: @Nls String,
|
||||
override val icon: Icon?,
|
||||
override val priority: Int? = null,
|
||||
) : ApplicableCompletionCommand(), DumbAware {
|
||||
private val action: AnAction? = ActionManager.getInstance().getAction(actionId)
|
||||
|
||||
override val additionalInfo: String?
|
||||
get() {
|
||||
val shortcutText = KeymapUtil.getFirstKeyboardShortcutText(actionId)
|
||||
if (shortcutText.isNotEmpty()) {
|
||||
return shortcutText
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
val action = action ?: return false
|
||||
if (editor == null) return false
|
||||
if (!DumbService.Companion.getInstance(psiFile.project).isUsableInCurrentContext(action)) return false
|
||||
val context = getTargetContext(offset, editor)
|
||||
val dataContext = getDataContext(psiFile, editor, context)
|
||||
val presentation: Presentation = action.templatePresentation.clone()
|
||||
val event = AnActionEvent.createEvent(action, dataContext, presentation, ActionPlaces.ACTION_PLACE_QUICK_LIST_POPUP_ACTION,
|
||||
ActionUiKind.Companion.NONE, null)
|
||||
if (ActionUtil.performDumbAwareUpdate(action, event, false)) {
|
||||
return false
|
||||
}
|
||||
return event.presentation.isEnabled && event.presentation.isVisible
|
||||
}
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val action = action ?: return
|
||||
if (editor == null) return
|
||||
val dataContext = DataManager.getInstance().getDataContext(editor.getComponent())
|
||||
val presentation: Presentation = action.templatePresentation.clone()
|
||||
val event = AnActionEvent.createEvent(action, dataContext, presentation, ActionPlaces.ACTION_PLACE_QUICK_LIST_POPUP_ACTION,
|
||||
ActionUiKind.Companion.NONE, null)
|
||||
if (ActionUtil.lastUpdateAndCheckDumb(action, event, false)) {
|
||||
ActionUtil.performActionDumbAwareWithCallbacks(action, event)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the action associated with this command can be applied to the given project context
|
||||
* by analyzing the specified offset and the PsiFile structure.
|
||||
* It is expected to be called outside any meaningful PsiElements
|
||||
*/
|
||||
protected fun isApplicableToProject(offset: Int, psiFile: PsiFile): Boolean {
|
||||
if (offset - 1 < 0) return true
|
||||
val element = psiFile.findElementAt(offset - 1)
|
||||
if (element is PsiComment) return true
|
||||
val fileDocument = psiFile.fileDocument
|
||||
val lineNumber = fileDocument.getLineNumber(offset)
|
||||
val lineStartOffset = fileDocument.getLineStartOffset(lineNumber)
|
||||
for (ch in fileDocument.immutableCharSequence.subSequence(lineStartOffset, offset)) {
|
||||
if (!ch.isWhitespace()) return false
|
||||
if (ch == '\n') return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
+23
-4
@@ -1,12 +1,28 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.completion.command.commands
|
||||
|
||||
import com.intellij.codeInsight.completion.command.*
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionUnsupportedOperationException
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.HighlightInfoLookup
|
||||
import com.intellij.codeInsight.completion.command.MyEditor
|
||||
import com.intellij.codeInsight.completion.command.commandCompletionEnabled
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey
|
||||
import com.intellij.codeInsight.daemon.impl.*
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo.IntentionActionDescriptor
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightVisitorBasedInspection
|
||||
import com.intellij.codeInsight.daemon.impl.IntentionActionFilter
|
||||
import com.intellij.codeInsight.daemon.impl.IntentionMenuContributor
|
||||
import com.intellij.codeInsight.daemon.impl.SeverityRegistrar
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass.IntentionsInfo
|
||||
import com.intellij.codeInsight.intention.*
|
||||
import com.intellij.codeInsight.intention.CommonIntentionAction
|
||||
import com.intellij.codeInsight.intention.EmptyIntentionAction
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.IntentionActionDelegate
|
||||
import com.intellij.codeInsight.intention.IntentionManager
|
||||
import com.intellij.codeInsight.intention.impl.CachedIntentions
|
||||
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler
|
||||
import com.intellij.codeInsight.intention.impl.preview.IntentionPreviewComputable
|
||||
@@ -25,6 +41,7 @@ import com.intellij.lang.LanguageExtension
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.lang.annotation.HighlightSeverity.INFORMATION
|
||||
import com.intellij.lang.injection.InjectedLanguageManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
@@ -258,7 +275,9 @@ internal class DirectIntentionCommandProvider : CommandProvider {
|
||||
val isInjected = topLevelFile != psiFile
|
||||
val indicator = DaemonProgressIndicator()
|
||||
val errorHighlightings: List<HighlightInfo?>? = jobToIndicator(coroutineContext.job, indicator) {
|
||||
HighlightVisitorBasedInspection.runAnnotatorsInGeneralHighlighting(topLevelFile, true, true, true)
|
||||
ApplicationManager.getApplication().runReadAction<List<HighlightInfo?>?> {
|
||||
HighlightVisitorBasedInspection.runAnnotatorsInGeneralHighlighting(topLevelFile, true, true, true)
|
||||
}
|
||||
}
|
||||
if (errorHighlightings == null) return@readAction
|
||||
var insideRange = getLineRange(topLevelFile, topLevelOffset)
|
||||
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.completion.command.commands
|
||||
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.CommandCompletionProviderContext
|
||||
import com.intellij.codeInsight.completion.command.CommandProvider
|
||||
import com.intellij.codeInsight.completion.command.CompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.commandCompletionEnabled
|
||||
import com.intellij.lang.LanguageExtension
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.DumbService
|
||||
|
||||
/**
|
||||
* An implementation of the CommandProvider interface that supplies completion commands
|
||||
* registered through extension points ('com.intellij.codeInsight.completion.applicable.command') for specific programming languages.
|
||||
*/
|
||||
@Deprecated("use providers")
|
||||
internal class ExtensionPointCommandProvider : CommandProvider, DumbAware {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
if (!commandCompletionEnabled()) return emptyList()
|
||||
val completionCommands =
|
||||
DumbService.getInstance(context.project)
|
||||
.filterByDumbAwareness(EP_NAME.allForLanguage(context.psiFile.language))
|
||||
return completionCommands.filter {
|
||||
!(context.isReadOnly && !it.supportsReadOnly()) && it.isApplicable(context.offset, context.psiFile, context.editor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun supportsReadOnly(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private val EP_NAME: LanguageExtension<ApplicableCompletionCommand> = LanguageExtension<ApplicableCompletionCommand>("com.intellij.codeInsight.completion.applicable.command")
|
||||
@@ -763,10 +763,6 @@
|
||||
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
<with attribute="implementationClass" implements="com.intellij.codeInsight.completion.command.CommandProvider"/>
|
||||
</extensionPoint>
|
||||
<extensionPoint qualifiedName="com.intellij.codeInsight.completion.applicable.command"
|
||||
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
<with attribute="implementationClass" implements="com.intellij.codeInsight.completion.command.ApplicableCompletionCommand"/>
|
||||
</extensionPoint>
|
||||
<extensionPoint qualifiedName="com.intellij.codeInsight.completion.intention.skipper"
|
||||
beanClass="com.intellij.lang.LanguageExtensionPoint" dynamic="true">
|
||||
<with attribute="implementationClass" implements="com.intellij.codeInsight.completion.command.commands.IntentionCommandSkipper"/>
|
||||
|
||||
@@ -755,7 +755,6 @@
|
||||
<lookup.charFilter implementation="com.intellij.codeInsight.completion.command.CommandCompletionCharFilter" order="first" id="commandCompletion"/>
|
||||
<lookup.customizer implementation="com.intellij.codeInsight.completion.command.CommandCompletionLookupCustomizer" order="last" id="commandCompletionLookupCustomizer"/>
|
||||
|
||||
<codeInsight.completion.command.provider language="" implementationClass="com.intellij.codeInsight.completion.command.commands.ExtensionPointCommandProvider" />
|
||||
<codeInsight.completion.command.provider language="" implementationClass="com.intellij.codeInsight.completion.command.commands.DirectIntentionCommandProvider" order="last"/>
|
||||
<platform.backend.documentation.lookupElementTargetProvider
|
||||
implementation="com.intellij.codeInsight.completion.command.CommandCompletionDocumentationProvider"/>
|
||||
|
||||
+53
-43
@@ -2,9 +2,8 @@
|
||||
package org.jetbrains.kotlin.idea.completion.impl.k2.contributors.commands
|
||||
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor
|
||||
import com.intellij.codeInsight.completion.command.ApplicableCompletionCommand
|
||||
import com.intellij.codeInsight.completion.command.HighlightInfoLookup
|
||||
import com.intellij.codeInsight.completion.command.getCommandContext
|
||||
import com.intellij.codeInsight.completion.command.*
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
@@ -13,52 +12,63 @@ import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import javax.swing.Icon
|
||||
|
||||
class KotlinDeleteCompletionCommand : ApplicableCompletionCommand(), DumbAware {
|
||||
private var _highlightInfo: HighlightInfoLookup? = null
|
||||
override val name: String
|
||||
get() = "Delete element"
|
||||
override val i18nName: @Nls String
|
||||
get() = ActionsBundle.message("action.EditorDelete.text")
|
||||
override val icon: Icon?
|
||||
get() = null
|
||||
override val highlightInfo: HighlightInfoLookup?
|
||||
get() = _highlightInfo
|
||||
internal class KotlinDeleteCompletionCommandProvider : CommandProvider {
|
||||
override fun getCommands(context: CommandCompletionProviderContext): List<CompletionCommand> {
|
||||
val element = getCommandContext(context.offset, context.psiFile) ?: return emptyList()
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, KtExpression::class.java, KtNamedDeclaration::class.java) ?: return emptyList()
|
||||
val hasTheSameOffset = psiElement.textRange.endOffset == context.offset
|
||||
if (!hasTheSameOffset) return emptyList()
|
||||
psiElement = getTopWithTheSameOffset(psiElement, context.offset)
|
||||
val highlightInfo = HighlightInfoLookup(psiElement.textRange, EditorColors.SEARCH_RESULT_ATTRIBUTES, 0)
|
||||
return listOf(createCommand(highlightInfo, psiElement))
|
||||
}
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
val element = getCommandContext(offset, psiFile) ?: return false
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, KtExpression::class.java, KtNamedDeclaration::class.java) ?: return false
|
||||
val hasTheSameOffset = psiElement.textRange.endOffset == offset
|
||||
if (!hasTheSameOffset) return false
|
||||
psiElement = getTopWithTheSameOffset(psiElement, offset)
|
||||
_highlightInfo = HighlightInfoLookup(psiElement.textRange, EditorColors.DELETED_TEXT_ATTRIBUTES, 0)
|
||||
return true
|
||||
}
|
||||
private fun createCommand(highlightInfo: HighlightInfoLookup, psiElement: PsiElement): CompletionCommand {
|
||||
return KotlinDeleteCompletionCommand(highlightInfo, psiElement.text)
|
||||
}
|
||||
}
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val element = getCommandContext(offset, psiFile) ?: return
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, KtExpression::class.java, KtNamedDeclaration::class.java) ?: return
|
||||
psiElement = getTopWithTheSameOffset(psiElement, offset)
|
||||
WriteCommandAction.runWriteCommandAction(psiFile.project, null, null, {
|
||||
val parent: SmartPsiElementPointer<PsiElement?> = SmartPointerManager.createPointer(psiElement.parent ?: psiFile)
|
||||
psiElement.delete()
|
||||
PsiDocumentManager.getInstance(psiFile.project).commitDocument(psiFile.fileDocument)
|
||||
parent.element?.let {
|
||||
ReformatCodeProcessor(psiFile, arrayOf(it.textRange)).run()
|
||||
}
|
||||
}, psiFile)
|
||||
private fun getTopWithTheSameOffset(psiElement: KtExpression, offset: Int): KtExpression {
|
||||
var psiElement1 = psiElement
|
||||
var curElement = psiElement1
|
||||
while (curElement.textRange.endOffset == offset) {
|
||||
psiElement1 = curElement
|
||||
curElement = PsiTreeUtil.getParentOfType(curElement, KtExpression::class.java, KtNamedDeclaration::class.java) ?: break
|
||||
}
|
||||
return psiElement1
|
||||
}
|
||||
|
||||
private fun getTopWithTheSameOffset(psiElement: KtExpression, offset: Int): KtExpression {
|
||||
var psiElement1 = psiElement
|
||||
var curElement = psiElement1
|
||||
while (curElement.textRange.endOffset == offset) {
|
||||
psiElement1 = curElement
|
||||
curElement = PsiTreeUtil.getParentOfType(curElement, KtExpression::class.java, KtNamedDeclaration::class.java) ?: break
|
||||
}
|
||||
return psiElement1
|
||||
}
|
||||
private class KotlinDeleteCompletionCommand(
|
||||
override val highlightInfo: HighlightInfoLookup?,
|
||||
private val originalText: String,
|
||||
) : CompletionCommand(), CompletionCommandWithPreview, DumbAware {
|
||||
override val name: String
|
||||
get() = "Delete element"
|
||||
override val i18nName: @Nls String
|
||||
get() = ActionsBundle.message("action.EditorDelete.text")
|
||||
override val icon: Icon?
|
||||
get() = null
|
||||
|
||||
override fun execute(offset: Int, psiFile: PsiFile, editor: Editor?) {
|
||||
val element = getCommandContext(offset, psiFile) ?: return
|
||||
var psiElement = PsiTreeUtil.getParentOfType(element, KtExpression::class.java, KtNamedDeclaration::class.java) ?: return
|
||||
psiElement = getTopWithTheSameOffset(psiElement, offset)
|
||||
WriteCommandAction.runWriteCommandAction(psiFile.project, null, null, {
|
||||
val parent: SmartPsiElementPointer<PsiElement?> = SmartPointerManager.createPointer(psiElement.parent ?: psiFile)
|
||||
psiElement.delete()
|
||||
PsiDocumentManager.getInstance(psiFile.project).commitDocument(psiFile.fileDocument)
|
||||
parent.element?.let {
|
||||
ReformatCodeProcessor(psiFile, arrayOf(it.textRange)).run()
|
||||
}
|
||||
}, psiFile)
|
||||
}
|
||||
|
||||
override fun getPreview(): IntentionPreviewInfo? {
|
||||
return IntentionPreviewInfo.CustomDiff(KotlinFileType.INSTANCE, originalText, "")
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,8 @@
|
||||
implementationClass="com.intellij.codeInsight.completion.command.commands.PsiElementCommentByLineCompletionCommandProvider"/>
|
||||
<codeInsight.completion.command.provider language="kotlin"
|
||||
implementationClass="com.intellij.codeInsight.completion.command.commands.PsiElementCommentByBlockCompletionCommandProvider"/>
|
||||
<codeInsight.completion.applicable.command language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.completion.impl.k2.contributors.commands.KotlinDeleteCompletionCommand"/>
|
||||
<codeInsight.completion.command.provider language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.completion.impl.k2.contributors.commands.KotlinDeleteCompletionCommandProvider"/>
|
||||
<codeInsight.completion.command.provider language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.completion.impl.k2.contributors.commands.KotlinChangeSignatureCompletionCommand"/>
|
||||
<codeInsight.completion.command.provider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.completion.impl.k2.contributors.commands.KotlinCreateFromUsagesCommandProvider" order="last"/>
|
||||
|
||||
Reference in New Issue
Block a user