mirror of
https://github.com/chylex/IntelliJ-Keyboard-Master.git
synced 2024-11-25 10:42:46 +01:00
Compare commits
No commits in common. "48a9159c871dff67c0910880129caa2f67fd000e" and "ca075869ebc6f602bc88194ffbe2f629155ede50" have entirely different histories.
48a9159c87
...
ca075869eb
@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.chylex.intellij.keyboardmaster"
|
group = "com.chylex.intellij.keyboardmaster"
|
||||||
version = "0.5.5"
|
version = "0.5.4"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -8,7 +8,7 @@ import com.intellij.ui.popup.list.ListPopupImpl
|
|||||||
|
|
||||||
internal object PopupInterceptor : PersistentUiInterceptor<AbstractPopup>(AbstractPopup::class.java) {
|
internal object PopupInterceptor : PersistentUiInterceptor<AbstractPopup>(AbstractPopup::class.java) {
|
||||||
override fun shouldIntercept(component: AbstractPopup): Boolean {
|
override fun shouldIntercept(component: AbstractPopup): Boolean {
|
||||||
if (component is ListPopupImpl && VimNavigation.isEnabled) {
|
if (component is ListPopupImpl) {
|
||||||
VimListNavigation.install(component.list, component)
|
VimListNavigation.install(component.list, component)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,12 +18,9 @@ import javax.swing.KeyStroke
|
|||||||
import javax.swing.UIManager
|
import javax.swing.UIManager
|
||||||
|
|
||||||
object VimNavigation {
|
object VimNavigation {
|
||||||
private val isEnabledFlag = AtomicBoolean(false)
|
private val isEnabled = AtomicBoolean(false)
|
||||||
private var originalPopupBindings: Array<*>? = null
|
private var originalPopupBindings: Array<*>? = null
|
||||||
|
|
||||||
val isEnabled
|
|
||||||
get() = isEnabledFlag.get()
|
|
||||||
|
|
||||||
fun register() {
|
fun register() {
|
||||||
val disposable = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
|
val disposable = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
|
||||||
|
|
||||||
@ -32,7 +29,7 @@ object VimNavigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setEnabled(enabled: Boolean) {
|
fun setEnabled(enabled: Boolean) {
|
||||||
if (!isEnabledFlag.compareAndSet(!enabled, enabled)) {
|
if (!isEnabled.compareAndSet(!enabled, enabled)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +61,7 @@ object VimNavigation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEvent(event: AWTEvent) {
|
private fun handleEvent(event: AWTEvent) {
|
||||||
if (event is FocusEvent && event.id == FocusEvent.FOCUS_GAINED && isEnabled) {
|
if (event is FocusEvent && event.id == FocusEvent.FOCUS_GAINED && isEnabled.get()) {
|
||||||
when (val source = event.source) {
|
when (val source = event.source) {
|
||||||
is JList<*> -> VimListNavigation.install(source)
|
is JList<*> -> VimListNavigation.install(source)
|
||||||
is JTree -> VimTreeNavigation.install(source)
|
is JTree -> VimTreeNavigation.install(source)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.chylex.intellij.keyboardmaster.feature.vimNavigation
|
package com.chylex.intellij.keyboardmaster.feature.vimNavigation
|
||||||
|
|
||||||
import com.chylex.intellij.keyboardmaster.PluginDisposableService
|
import com.chylex.intellij.keyboardmaster.PluginDisposableService
|
||||||
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.VimNavigationDispatcher.WrappedAction.ForKeyListener
|
|
||||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
import com.intellij.openapi.actionSystem.AnAction
|
import com.intellij.openapi.actionSystem.AnAction
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
@ -21,18 +20,15 @@ import java.awt.event.ActionListener
|
|||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import java.beans.PropertyChangeEvent
|
import java.beans.PropertyChangeEvent
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import javax.swing.Action
|
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
|
|
||||||
internal open class VimNavigationDispatcher<T : JComponent>(final override val component: T, private val rootNode: KeyStrokeNode.Parent<VimNavigationDispatcher<T>>) : DumbAwareAction(), ComponentHolder {
|
internal open class VimNavigationDispatcher<T : JComponent>(final override val component: T, private val rootNode: KeyStrokeNode.Parent<VimNavigationDispatcher<T>>) : DumbAwareAction(), ComponentHolder {
|
||||||
companion object {
|
companion object {
|
||||||
private val DISPOSABLE = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
|
private val DISPOSABLE = ApplicationManager.getApplication().getService(PluginDisposableService::class.java)
|
||||||
|
private val ENTER_KEY = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)
|
||||||
|
|
||||||
@JvmStatic
|
private fun findOriginalEnterAction(component: JComponent): WrappedAction? {
|
||||||
protected val ENTER_KEY: KeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)
|
|
||||||
|
|
||||||
private fun findOriginalEnterAction(component: JComponent): WrappedAction {
|
|
||||||
var originalEnterAction: WrappedAction? = null
|
var originalEnterAction: WrappedAction? = null
|
||||||
|
|
||||||
for (container in JBIterable.generate<Container>(component) { it.parent }) {
|
for (container in JBIterable.generate<Container>(component) { it.parent }) {
|
||||||
@ -40,7 +36,7 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
container.getActionForKeyStroke(ENTER_KEY)?.takeUnless(::isIgnoredEnterAction)?.let {
|
container.getActionForKeyStroke(ENTER_KEY)?.let {
|
||||||
originalEnterAction = WrappedAction.ForActionListener(container, it)
|
originalEnterAction = WrappedAction.ForActionListener(container, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,11 +47,7 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return originalEnterAction ?: ForKeyListener(component)
|
return originalEnterAction
|
||||||
}
|
|
||||||
|
|
||||||
private fun isIgnoredEnterAction(action: ActionListener): Boolean {
|
|
||||||
return action is Action && action.getValue(Action.NAME) == "toggle"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
@Suppress("UnstableApiUsage")
|
||||||
@ -108,25 +100,17 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleEnterKeyPress(actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
private fun handleEnterKeyPress(actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
||||||
handleEnterKeyPress { originalEnterAction.perform(actionEvent, keyEvent) }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected inline fun handleEnterKeyPress(originalAction: () -> Unit) {
|
|
||||||
if (isSearching.compareAndSet(true, false)) {
|
if (isSearching.compareAndSet(true, false)) {
|
||||||
stopSpeedSearch()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
currentNode = rootNode
|
|
||||||
originalAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected open fun stopSpeedSearch() {
|
|
||||||
when (val supply = SpeedSearchSupply.getSupply(component)) {
|
when (val supply = SpeedSearchSupply.getSupply(component)) {
|
||||||
is SpeedSearchBase<*> -> supply.hidePopup()
|
is SpeedSearchBase<*> -> supply.hidePopup()
|
||||||
is SpeedSearch -> supply.reset()
|
is SpeedSearch -> supply.reset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
currentNode = rootNode
|
||||||
|
originalEnterAction?.perform(actionEvent, keyEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final override fun update(e: AnActionEvent) {
|
final override fun update(e: AnActionEvent) {
|
||||||
e.presentation.isEnabled = !ignoreEventDueToActiveSearch(e) && !ignoreEventDueToActiveEditing(e)
|
e.presentation.isEnabled = !ignoreEventDueToActiveSearch(e) && !ignoreEventDueToActiveEditing(e)
|
||||||
@ -148,7 +132,7 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
private sealed interface WrappedAction {
|
private sealed interface WrappedAction {
|
||||||
fun perform(actionEvent: AnActionEvent, keyEvent: KeyEvent)
|
fun perform(actionEvent: AnActionEvent, keyEvent: KeyEvent)
|
||||||
|
|
||||||
class ForActionListener(private val component: JComponent, private val listener: ActionListener) : WrappedAction {
|
class ForActionListener(val component: JComponent, val listener: ActionListener) : WrappedAction {
|
||||||
override fun perform(actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
override fun perform(actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
||||||
listener.actionPerformed(ActionEvent(component, ActionEvent.ACTION_PERFORMED, "Enter", keyEvent.`when`, keyEvent.modifiersEx))
|
listener.actionPerformed(ActionEvent(component, ActionEvent.ACTION_PERFORMED, "Enter", keyEvent.`when`, keyEvent.modifiersEx))
|
||||||
}
|
}
|
||||||
@ -159,12 +143,5 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
action.actionPerformed(actionEvent)
|
action.actionPerformed(actionEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ForKeyListener(private val component: JComponent) : WrappedAction {
|
|
||||||
override fun perform(actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
|
||||||
val unconsumedKeyEvent = KeyEvent(component, keyEvent.id, keyEvent.`when`, keyEvent.modifiersEx, keyEvent.keyCode, keyEvent.keyChar, keyEvent.keyLocation)
|
|
||||||
component.dispatchEvent(unconsumedKeyEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import com.intellij.openapi.ui.getUserData
|
|||||||
import com.intellij.openapi.ui.putUserData
|
import com.intellij.openapi.ui.putUserData
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.ui.popup.WizardPopup
|
import com.intellij.ui.popup.WizardPopup
|
||||||
import com.intellij.ui.popup.list.ListPopupImpl
|
|
||||||
import com.intellij.ui.speedSearch.SpeedSearch
|
import com.intellij.ui.speedSearch.SpeedSearch
|
||||||
import com.intellij.ui.speedSearch.SpeedSearchSupply
|
import com.intellij.ui.speedSearch.SpeedSearchSupply
|
||||||
import java.awt.event.ActionEvent
|
import java.awt.event.ActionEvent
|
||||||
@ -86,24 +85,6 @@ internal object VimListNavigation {
|
|||||||
// WizardPopup only checks key codes against its input map, but key codes may be undefined for some characters.
|
// WizardPopup only checks key codes against its input map, but key codes may be undefined for some characters.
|
||||||
popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, 0), pauseAction)
|
popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, 0), pauseAction)
|
||||||
popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, KeyEvent.SHIFT_DOWN_MASK), pauseAction)
|
popup.registerAction("KeyboardMaster-VimListNavigation-PauseSpeedSearch", KeyStroke.getKeyStroke(KeyEvent.CHAR_UNDEFINED, KeyEvent.SHIFT_DOWN_MASK), pauseAction)
|
||||||
|
|
||||||
if (popup is ListPopupImpl) {
|
|
||||||
popup.registerAction("KeyboardMaster-VimListNavigation-Enter", ENTER_KEY, object : AbstractAction() {
|
|
||||||
override fun actionPerformed(e: ActionEvent) {
|
|
||||||
handleEnterKeyPress { popup.handleSelect(true, createEnterEvent(e)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createEnterEvent(e: ActionEvent): KeyEvent {
|
|
||||||
return KeyEvent(component, KeyEvent.KEY_PRESSED, e.`when`, e.modifiers, KeyEvent.VK_ENTER, KeyEvent.CHAR_UNDEFINED)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun stopSpeedSearch() {
|
|
||||||
val selectedValue = component.selectedValue
|
|
||||||
super.stopSpeedSearch()
|
|
||||||
component.setSelectedValue(selectedValue, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PauseSpeedSearchAction(private val dispatcher: VimNavigationDispatcher<JList<*>>, private val speedSearch: SpeedSearch) : AbstractAction() {
|
private class PauseSpeedSearchAction(private val dispatcher: VimNavigationDispatcher<JList<*>>, private val speedSearch: SpeedSearch) : AbstractAction() {
|
||||||
|
Loading…
Reference in New Issue
Block a user