diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/NextMenuItemAction.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/NextMenuItemAction.kt new file mode 100644 index 0000000..13987c7 --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/NextMenuItemAction.kt @@ -0,0 +1,9 @@ +package com.chylex.intellij.keyboardmaster.feature.actions + +import javax.swing.JList + +class NextMenuItemAction : SelectMenuItemBaseAction() { + override fun updateSelection(list: JList<*>) { + setSelectedIndex(list, list.selectedIndex + 1) + } +} diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/PrevMenuItemAction.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/PrevMenuItemAction.kt new file mode 100644 index 0000000..c8faf62 --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/PrevMenuItemAction.kt @@ -0,0 +1,15 @@ +package com.chylex.intellij.keyboardmaster.feature.actions + +import javax.swing.JList + +class PrevMenuItemAction : SelectMenuItemBaseAction() { + override fun updateSelection(list: JList<*>) { + val index = list.selectedIndex + if (index == -1) { + setSelectedIndex(list, list.model.size - 1) + } + else { + setSelectedIndex(list, index - 1) + } + } +} diff --git a/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/SelectMenuItemBaseAction.kt b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/SelectMenuItemBaseAction.kt new file mode 100644 index 0000000..4bc1245 --- /dev/null +++ b/src/main/kotlin/com/chylex/intellij/keyboardmaster/feature/actions/SelectMenuItemBaseAction.kt @@ -0,0 +1,54 @@ +package com.chylex.intellij.keyboardmaster.feature.actions + +import com.intellij.codeInsight.lookup.LookupManager +import com.intellij.codeInsight.lookup.impl.LookupImpl +import com.intellij.ide.actions.BigPopupUI +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.ui.ComponentUtil +import java.awt.KeyboardFocusManager +import javax.swing.JList + +abstract class SelectMenuItemBaseAction internal constructor(): DumbAwareAction() { + init { + isEnabledInModalContext = true + } + + final override fun actionPerformed(e: AnActionEvent) { + val editor = e.getData(CommonDataKeys.EDITOR) + if (editor != null) { + val lookup = LookupManager.getActiveLookup(editor) + if (lookup is LookupImpl) { + updateSelection(lookup.list) + return + } + } + + var focused = KeyboardFocusManager.getCurrentKeyboardFocusManager().focusOwner + while (focused != null) { + if (focused is JList<*>) { + updateSelection(focused) + break + } + else if (focused is BigPopupUI) { + val list = ComponentUtil.findComponentsOfType(focused, JList::class.java).singleOrNull() + if (list != null) { + updateSelection(list) + break + } + } + + focused = focused.parent + } + } + + protected abstract fun updateSelection(list: JList<*>) + + protected fun setSelectedIndex(list: JList<*>, newIndex: Int) { + if (newIndex in 0 until list.model.size) { + list.selectedIndex = newIndex + list.ensureIndexIsVisible(newIndex) + } + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index b667f9a..6164bbc 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -8,6 +8,7 @@ Collection of keyboard-centric additions. <ul> <li>Code completion items can be jumped to using customizable characters (numbers by default).</li> + <li>Keyboard shortcuts to select next/previous item in focused menu.</li> </ul> ]]></description> @@ -22,4 +23,9 @@ <applicationConfigurable parentId="tools" instance="com.chylex.intellij.keyboardmaster.configuration.PluginConfigurable" id="com.chylex.keyboardmaster" /> <postStartupActivity implementation="com.chylex.intellij.keyboardmaster.PluginStartup" order="last" /> </extensions> + + <actions> + <action id="com.chylex.intellij.keyboardmaster.feature.actions.NextMenuItemAction" class="com.chylex.intellij.keyboardmaster.feature.actions.NextMenuItemAction" text="Next Menu Item" /> + <action id="com.chylex.intellij.keyboardmaster.feature.actions.PrevMenuItemAction" class="com.chylex.intellij.keyboardmaster.feature.actions.PrevMenuItemAction" text="Previous Menu Item" /> + </actions> </idea-plugin>