mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-completion] IDEA-359174 command completion
- add hint - add simple i18n GitOrigin-RevId: c9a94a47dd706d6f2f23543d8b733aeb4b1467e7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
dfa683d35b
commit
708b5271f6
+2
@@ -7,6 +7,7 @@ import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@@ -16,6 +17,7 @@ abstract class CompletionCommand {
|
||||
}
|
||||
|
||||
abstract val name: String
|
||||
abstract val i18nName: @Nls String
|
||||
abstract val icon: Icon?
|
||||
open val priority: Int? = null
|
||||
abstract fun isApplicable(offset: Int, psiFile: PsiFile): Boolean
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// 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.core
|
||||
|
||||
import com.intellij.openapi.components.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
|
||||
@Service(Service.Level.APP)
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.Internal
|
||||
@State(name = "CommandCompletion", category = SettingsCategory.UI, storages = [Storage("CommandCompletion.xml", roamingType = RoamingType.DISABLED)])
|
||||
class ApplicationCommandCompletionService : PersistentStateComponent<AppCommandCompletionSettings> {
|
||||
|
||||
private var myState = AppCommandCompletionSettings()
|
||||
|
||||
override fun getState(): AppCommandCompletionSettings = myState
|
||||
|
||||
override fun loadState(state: AppCommandCompletionSettings) {
|
||||
myState = state
|
||||
}
|
||||
}
|
||||
|
||||
class AppCommandCompletionSettings(
|
||||
var showCounts: Int = 0,
|
||||
)
|
||||
+3
@@ -90,7 +90,10 @@ internal class CommandCompletionProvider : CompletionProvider<CompletionParamete
|
||||
parameters.offset,
|
||||
parameters.originalFile) { commands ->
|
||||
withPrefixMatcher.addAllElements(commands.map { command ->
|
||||
val i18nName = command.i18nName.replace("_", "").replace("...", "")
|
||||
val tailText = if (command.name.equals(i18nName, ignoreCase = true)) "" else " ($i18nName)"
|
||||
var element: LookupElement = CommandCompletionLookupElement(LookupElementBuilder.create(command.name)
|
||||
.withTypeText(tailText)
|
||||
.withIcon(command.icon ?: Lightning)
|
||||
.withInsertHandler(CommandInsertHandler(command))
|
||||
.withBoldness(true),
|
||||
|
||||
+38
@@ -5,7 +5,9 @@ import com.intellij.codeInsight.completion.commands.api.CommandCompletionFactory
|
||||
import com.intellij.codeInsight.daemon.impl.CommandCompletionServiceApi
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.HintRenderer
|
||||
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate
|
||||
import com.intellij.codeInsight.editorLineStripeHint.EditorLineStripeTextRenderer
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager
|
||||
import com.intellij.codeInsight.hints.presentation.PresentationFactory
|
||||
import com.intellij.codeInsight.hints.presentation.PresentationRenderer
|
||||
@@ -15,10 +17,12 @@ import com.intellij.codeInsight.intention.impl.IntentionActionWithTextCaching
|
||||
import com.intellij.codeInsight.lookup.*
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||
import com.intellij.codeInsight.template.impl.TemplateColors
|
||||
import com.intellij.java.JavaBundle
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.LanguageExtension
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Document
|
||||
@@ -173,6 +177,33 @@ class CommandCompletionService(
|
||||
editor.putUserData(PREVIOUS_HIGHLIGHT_CACHED_CONTAINER_INFO_CONTAINER_KEY, newList.toMutableList())
|
||||
}
|
||||
|
||||
fun setHint(lookup: LookupImpl) {
|
||||
if (lookup.getUserData(INSTALLED_HIHT_KEY) == false) return
|
||||
lookup.putUserData(INSTALLED_HIHT_KEY, false)
|
||||
val psiFile = lookup.psiFile ?: return
|
||||
val completionService = lookup.project.service<CommandCompletionService>()
|
||||
val completionFactory = completionService.getFactory(psiFile.language) ?: return
|
||||
val fullSuffix = completionFactory.suffix() + completionFactory.filterSuffix().toString()
|
||||
val index = findActualIndex(fullSuffix, lookup.editor.document.immutableCharSequence, lookup.lookupOriginalStart)
|
||||
val startOffset = lookup.lookupOriginalStart - index
|
||||
val endOffset = lookup.editor.caretModel.offset
|
||||
if (endOffset - startOffset != 1) return
|
||||
val editor = lookup.editor
|
||||
if (lookup.items.none { it.`as`(CommandCompletionLookupElement::class.java) != null }) return
|
||||
if (editor.inlayModel.getInlineElementsInRange(startOffset, endOffset).isNotEmpty()) return
|
||||
val applicationCommandCompletionService = ApplicationManager.getApplication().getService(ApplicationCommandCompletionService::class.java)
|
||||
val state = applicationCommandCompletionService.state
|
||||
if (state.showCounts > 5) return
|
||||
state.showCounts += 1
|
||||
val inlineElement: Inlay<HintRenderer?> = editor.inlayModel.addInlineElement(endOffset, true, EditorLineStripeTextRenderer(" " + JavaBundle.message("command.completion.filter.hint")))
|
||||
?: return
|
||||
Disposer.register(lookup, inlineElement)
|
||||
Disposer.register(lookup) { lookup.removeUserData(INSTALLED_HINT) }
|
||||
|
||||
lookup.putUserData(INSTALLED_HINT, inlineElement)
|
||||
lookup.putUserData(INSTALLED_HIHT_KEY, true)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
private object CommandCompletionLookupItemFilter : Condition<LookupElement> {
|
||||
override fun value(e: LookupElement?): Boolean {
|
||||
@@ -181,6 +212,8 @@ class CommandCompletionService(
|
||||
}
|
||||
}
|
||||
|
||||
private val INSTALLED_HINT: Key<Inlay<HintRenderer?>> = Key.create("completion.command.installed.hint")
|
||||
private val INSTALLED_HIHT_KEY: Key<Boolean> = Key.create("completion.command.installed.hint")
|
||||
private val INSTALLED_ADDITIONAL_MATCHER_KEY: Key<Boolean> = Key.create("completion.command.installed.additional.matcher")
|
||||
private val INSTALLED_LISTENER_KEY: Key<AtomicBoolean> = Key.create("completion.command.installed.lookup.command.listener")
|
||||
private val SUPPRESS_PREDICATE_KEY = Key.create<EditorHighlightingPredicate>("completion.command.suppress.completion.predicate")
|
||||
@@ -290,6 +323,7 @@ private class CommandCompletionHighlightingListener(
|
||||
override fun currentItemChanged(event: LookupEvent) {
|
||||
val lookup = event.lookup
|
||||
if (lookup !is LookupImpl) return
|
||||
completionService?.setHint(lookup)
|
||||
val item = event.item
|
||||
val element = item?.`as`(CommandCompletionLookupElement::class.java)
|
||||
if (element == null) {
|
||||
@@ -339,6 +373,10 @@ private class CommandCompletionCharFilter : CharFilter() {
|
||||
if (!Registry.`is`("java.completion.command.enabled")) return null
|
||||
if (lookup !is LookupImpl) return null
|
||||
val completionService = lookup.project.service<CommandCompletionService>()
|
||||
val installedHint = lookup.removeUserData(INSTALLED_HINT)
|
||||
if (installedHint != null) {
|
||||
Disposer.dispose(installedHint)
|
||||
}
|
||||
val psiFile = lookup.psiFile ?: return null
|
||||
val completionFactory = completionService.getFactory(psiFile.language) ?: return null
|
||||
val offset = lookup.editor.caretModel.offset
|
||||
|
||||
+2
@@ -11,11 +11,13 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.IndexNotReadyException
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class AbstractActionCompletionCommand(
|
||||
var actionId: String,
|
||||
override val name: String,
|
||||
override val i18nName: @Nls String,
|
||||
override val icon: Icon?,
|
||||
override val priority: Int? = null
|
||||
) : OldCompletionCommand() {
|
||||
|
||||
+3
@@ -1,6 +1,9 @@
|
||||
// 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.idea.ActionsBundle
|
||||
|
||||
class CommentCompletionCommand : AbstractActionCompletionCommand("CommentByLineComment",
|
||||
"Comment",
|
||||
ActionsBundle.actionText("CommentByLineComment"),
|
||||
null)
|
||||
+5
@@ -4,17 +4,22 @@ package com.intellij.codeInsight.completion.commands.impl
|
||||
import com.intellij.codeInsight.actions.ReformatCodeProcessor
|
||||
import com.intellij.codeInsight.completion.commands.api.CompletionCommand
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.psi.PsiCodeBlock
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.PsiStatement
|
||||
import com.intellij.psi.util.parents
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
class FormatCodeCompletionCommand : CompletionCommand() {
|
||||
override val name: String
|
||||
get() = "format"
|
||||
|
||||
override val i18nName: @Nls String
|
||||
get() = ActionsBundle.message("action.ReformatCode.text")
|
||||
|
||||
override val icon: Icon
|
||||
get() = AllIcons.Actions.ReformatCode // Use the reformat icon
|
||||
|
||||
|
||||
+7
-1
@@ -4,17 +4,23 @@ package com.intellij.codeInsight.completion.commands.impl
|
||||
import com.intellij.codeInsight.completion.commands.api.OldCompletionCommand
|
||||
import com.intellij.codeInsight.generation.actions.BaseGenerateAction
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.java.JavaBundle
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil
|
||||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
|
||||
class GenerateCompletionCommand(private val action: BaseGenerateAction) : OldCompletionCommand() {
|
||||
override val name: String
|
||||
get() = "Generate \"" + action.templateText + "\""
|
||||
get() = "Generate \'" + action.templateText + "\'"
|
||||
override val i18nName: @Nls String
|
||||
get() = JavaBundle.message(
|
||||
"completion.command.generate.name",
|
||||
action.templateText)
|
||||
override val icon: Icon?
|
||||
get() = null
|
||||
|
||||
|
||||
+6
-1
@@ -4,16 +4,21 @@ package com.intellij.codeInsight.completion.commands.impl
|
||||
import com.intellij.codeInsight.completion.commands.api.CompletionCommand
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.util.EditSourceUtil
|
||||
import com.intellij.idea.ActionsBundle
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiIdentifier
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
class GoToDeclarationCompletionCommand : CompletionCommand() {
|
||||
override val name: String
|
||||
get() = "Go to declaration"
|
||||
get() = "Go to Declaration"
|
||||
|
||||
override val i18nName: @Nls String
|
||||
get() = ActionsBundle.message("action.GotoDeclaration.text")
|
||||
|
||||
override val icon: Icon
|
||||
get() = AllIcons.Ide.ExternalLinkArrowWhite // Use the appropriate icon
|
||||
|
||||
+5
@@ -3,18 +3,23 @@ package com.intellij.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.codeInsight.completion.commands.api.OldCompletionCommand
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.java.JavaBundle
|
||||
import com.intellij.lang.refactoring.InlineActionHandler
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiIdentifier
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
class InlineVariableCompletionCommand : OldCompletionCommand() {
|
||||
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
|
||||
|
||||
|
||||
+5
-1
@@ -1,8 +1,8 @@
|
||||
// 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.commands.core.CommandCompletionService
|
||||
import com.intellij.codeInsight.completion.commands.api.OldCompletionCommand
|
||||
import com.intellij.codeInsight.completion.commands.core.CommandCompletionService
|
||||
import com.intellij.codeInsight.completion.commands.core.PREVIOUS_HIGHLIGHT_CACHED_CONTAINER_INFO_CONTAINER_KEY
|
||||
import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.ExpensivePsiIntentionAction
|
||||
@@ -16,6 +16,7 @@ import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiFile
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.Nls
|
||||
import javax.swing.Icon
|
||||
|
||||
class IntentionCompletionCommand(
|
||||
@@ -28,6 +29,9 @@ class IntentionCompletionCommand(
|
||||
override val name: String
|
||||
get() = intentionAction.text
|
||||
|
||||
override val i18nName: @Nls String
|
||||
get() = intentionAction.text
|
||||
|
||||
override fun isApplicable(offset: Int, psiFile: PsiFile, editor: Editor?): Boolean {
|
||||
if (editor == null) return false
|
||||
return intentionAction.action !is ExpensivePsiIntentionAction && runReadAction {
|
||||
|
||||
+3
@@ -1,7 +1,10 @@
|
||||
// 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.idea.ActionsBundle
|
||||
|
||||
class OptimizeImportCompletionCommand : AbstractActionCompletionCommand("OptimizeImports",
|
||||
"Optimize imports",
|
||||
ActionsBundle.message("action.OptimizeImports.text"),
|
||||
null,
|
||||
-100)
|
||||
+3
-1
@@ -2,8 +2,10 @@
|
||||
package com.intellij.codeInsight.completion.commands.impl
|
||||
|
||||
import com.intellij.ide.actions.ActivateToolWindowAction.Manager
|
||||
import com.intellij.java.JavaBundle
|
||||
|
||||
class ProjectViewCompletionCommand : AbstractActionCompletionCommand(Manager.getActionIdForToolWindow("Project"),
|
||||
"Project tree",
|
||||
"Project tool",
|
||||
JavaBundle.message("command.completion.project.tool.text"),
|
||||
null,
|
||||
-150)
|
||||
+3
@@ -1,7 +1,10 @@
|
||||
// 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.java.JavaBundle
|
||||
|
||||
class RecentFilesCompletionCommand : AbstractActionCompletionCommand("RecentFiles",
|
||||
"Recent files",
|
||||
JavaBundle.message("command.completion.recent.files.text"),
|
||||
null,
|
||||
-150)
|
||||
+3
@@ -1,7 +1,10 @@
|
||||
// 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.idea.ActionsBundle
|
||||
|
||||
class RefactorThisCompletionCommand : AbstractActionCompletionCommand("Refactorings.QuickListPopupAction",
|
||||
"Refactor",
|
||||
ActionsBundle.message("action.Refactorings.QuickListPopupAction.text"),
|
||||
null,
|
||||
-100)
|
||||
+2
@@ -1,8 +1,10 @@
|
||||
// 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.idea.ActionsBundle
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
|
||||
class RenameActionCompletionCommand : AbstractActionCompletionCommand(IdeActions.ACTION_RENAME,
|
||||
"rename",
|
||||
ActionsBundle.message("action.RenameElement.text"),
|
||||
null)
|
||||
@@ -1970,4 +1970,10 @@ checkbox.check.for.jdk.updates=Check for JDK updates
|
||||
intention.family.name.rename.to.ignored=Rename to ignored
|
||||
tooltip.variable.used=Variable ''{0}'' is used
|
||||
|
||||
command.completion.filter.hint=press '.' to show actions
|
||||
command.completion.generate.text=Generate ''{0}''
|
||||
command.completion.inline.text=Inline
|
||||
command.completion.project.tool.text=Open Project tool window
|
||||
command.completion.recent.files.text=Open recent files popup
|
||||
|
||||
advanced.setting.java.show.irrelevant.templates.in.source.roots=Show irrelevant New File templates in Java source roots
|
||||
Reference in New Issue
Block a user