diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/LookupTypedActionHandler.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/LookupTypedActionHandler.kt new file mode 100644 index 0000000..688ec0d --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/LookupTypedActionHandler.kt @@ -0,0 +1,33 @@ +package com.chylex.intellij.keyboardmaster.lookup + +import com.intellij.codeInsight.lookup.LookupManager +import com.intellij.codeInsight.lookup.impl.LookupImpl +import com.intellij.codeInsight.template.impl.editorActions.TypedActionHandlerBase +import com.intellij.openapi.actionSystem.DataContext +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.actionSystem.TypedActionHandler + +/** + * When typing digits inside a code completion popup menu, selects the n-th item (or 10th item if the digit is 0) in the list. + */ +class LookupTypedActionHandler(originalHandler: TypedActionHandler?) : TypedActionHandlerBase(originalHandler) { + override fun execute(editor: Editor, charTyped: Char, dataContext: DataContext) { + if (!executeImpl(editor, charTyped)) { + myOriginalHandler?.execute(editor, charTyped, dataContext) + } + } + + private fun executeImpl(editor: Editor, charTyped: Char): Boolean { + if (charTyped !in '0'..'9') { + return false + } + + val lookup = LookupManager.getActiveLookup(editor) + if (lookup !is LookupImpl) { + return false + } + + lookup.selectedIndex = if (charTyped == '0') 9 else charTyped - '1' + return true + } +} diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/ProjectLookupListener.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/ProjectLookupListener.kt new file mode 100644 index 0000000..50a2dd6 --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/lookup/ProjectLookupListener.kt @@ -0,0 +1,41 @@ +package com.chylex.intellij.keyboardmaster.lookup + +import com.intellij.codeInsight.lookup.Lookup +import com.intellij.codeInsight.lookup.LookupElementPresentation +import com.intellij.codeInsight.lookup.LookupManagerListener +import com.intellij.codeInsight.lookup.impl.LookupImpl +import com.intellij.openapi.util.Key + +/** + * Adds hints to code completion items with the digit that selects it. + */ +class ProjectLookupListener : LookupManagerListener { + companion object { + private val IS_MODIFIED_KEY = Key.create<Boolean>("chylexKeyboardMasterModified") + private val HINT_TEXT = Array(10) { " [${(it + 1) % 10}]" } + } + + override fun activeLookupChanged(oldLookup: Lookup?, newLookup: Lookup?) { + if (newLookup !is LookupImpl || newLookup.getUserData(IS_MODIFIED_KEY) == true) { + return + } + + newLookup.putUserData(IS_MODIFIED_KEY, true) + + @Suppress("UnstableApiUsage") + newLookup.addPresentationCustomizer { item, presentation -> + val items = newLookup.list.model + + for (index in 0 until items.size.coerceAtMost(10)) { + if (item === items.getElementAt(index)) { + val customized = LookupElementPresentation() + customized.copyFrom(presentation) + customized.appendTailTextItalic(HINT_TEXT[index], true) + return@addPresentationCustomizer customized + } + } + + presentation + } + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b71f9f3..29f736b 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -5,7 +5,19 @@ <description><![CDATA[ Collection of keyboard-centric additions. + <ul> + <li>Code completion items can be jumped to using numbers.</li> + </ul> ]]></description> <depends>com.intellij.modules.platform</depends> + + <projectListeners> + <listener class="com.chylex.intellij.keyboardmaster.lookup.ProjectLookupListener" topic="com.intellij.codeInsight.lookup.LookupManagerListener" /> + </projectListeners> + + <extensions defaultExtensionNs="com.intellij"> + <!--suppress PluginXmlValidity, PluginXmlDynamicPlugin --> + <editorTypedHandler implementationClass="com.chylex.intellij.keyboardmaster.lookup.LookupTypedActionHandler" /> + </extensions> </idea-plugin>