mirror of
https://github.com/chylex/IntelliJ-Keyboard-Master.git
synced 2026-10-17 08:33:59 +02:00
Compare commits
9
Commits
055b118f59
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a9a48fadb
|
||
|
|
36ecd772b1
|
||
|
|
0cb030f7ee
|
||
|
|
825f4c39fe
|
||
|
|
b616326357
|
||
|
|
e182b19428
|
||
|
|
10fe579ad2
|
||
|
|
209c1d8bfa
|
||
|
|
936faedf78
|
+3
-1
@@ -6,7 +6,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "com.chylex.intellij.keyboardmaster"
|
group = "com.chylex.intellij.keyboardmaster"
|
||||||
version = "0.6.7"
|
version = "0.6.10"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -26,6 +26,8 @@ dependencies {
|
|||||||
|
|
||||||
bundledPlugin("com.intellij.java")
|
bundledPlugin("com.intellij.java")
|
||||||
|
|
||||||
|
compatiblePlugin("com.intellij.classic.ui")
|
||||||
|
|
||||||
if (System.getenv("IDEAVIM") == "1") {
|
if (System.getenv("IDEAVIM") == "1") {
|
||||||
plugin("IdeaVIM", "2.10.2")
|
plugin("IdeaVIM", "2.10.2")
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -22,18 +22,18 @@ internal interface KeyStrokeNode<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getChild(keyEvent: KeyEvent): KeyStrokeNode<T> {
|
fun getChild(keyEvent: KeyEvent): KeyStrokeNode<T>? {
|
||||||
val keyStroke = when {
|
val keyStroke = when {
|
||||||
isCharEvent(keyEvent) -> KeyStroke.getKeyStroke(keyEvent.keyChar, keyEvent.modifiersEx and KeyEvent.SHIFT_DOWN_MASK.inv())
|
isCharEvent(keyEvent) -> KeyStroke.getKeyStroke(keyEvent.keyChar, keyEvent.modifiersEx and KeyEvent.SHIFT_DOWN_MASK.inv())
|
||||||
isCodeEvent(keyEvent) -> KeyStroke.getKeyStroke(keyEvent.keyCode, keyEvent.modifiersEx, false)
|
isCodeEvent(keyEvent) -> KeyStroke.getKeyStroke(keyEvent.keyCode, keyEvent.modifiersEx, false)
|
||||||
else -> return this
|
else -> return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return keys[keyStroke] ?: this
|
return keys[keyStroke]
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCharEvent(keyEvent: KeyEvent): Boolean {
|
private fun isCharEvent(keyEvent: KeyEvent): Boolean {
|
||||||
return keyEvent.keyChar != KeyEvent.CHAR_UNDEFINED && keyEvent.keyCode != KeyEvent.VK_ENTER && (keyEvent.modifiersEx and KeyEvent.CTRL_DOWN_MASK) == 0
|
return keyEvent.keyChar != KeyEvent.CHAR_UNDEFINED && keyEvent.keyCode != KeyEvent.VK_ENTER && (keyEvent.modifiersEx and (KeyEvent.CTRL_DOWN_MASK or KeyEvent.ALT_DOWN_MASK)) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCodeEvent(keyEvent: KeyEvent): Boolean {
|
private fun isCodeEvent(keyEvent: KeyEvent): Boolean {
|
||||||
|
|||||||
+3
-2
@@ -106,13 +106,14 @@ internal open class VimNavigationDispatcher<T : JComponent>(final override val c
|
|||||||
|
|
||||||
protected inline fun handleKeyPress(actionEvent: AnActionEvent, keyEvent: KeyEvent, fallback: () -> Unit) {
|
protected inline fun handleKeyPress(actionEvent: AnActionEvent, keyEvent: KeyEvent, fallback: () -> Unit) {
|
||||||
when (val nextNode = currentNode.getChild(keyEvent)) {
|
when (val nextNode = currentNode.getChild(keyEvent)) {
|
||||||
is KeyStrokeNode.Parent<VimNavigationDispatcher<T>> -> currentNode = nextNode
|
is KeyStrokeNode.Parent<VimNavigationDispatcher<T>> -> {
|
||||||
|
currentNode = nextNode
|
||||||
|
}
|
||||||
is KeyStrokeNode.ActionNode<VimNavigationDispatcher<T>> -> {
|
is KeyStrokeNode.ActionNode<VimNavigationDispatcher<T>> -> {
|
||||||
nextNode.performAction(this, actionEvent, keyEvent)
|
nextNode.performAction(this, actionEvent, keyEvent)
|
||||||
currentNode = rootNode
|
currentNode = rootNode
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
currentNode = rootNode
|
|
||||||
fallback()
|
fallback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-1
@@ -8,6 +8,7 @@ import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCo
|
|||||||
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.scrollBy
|
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.scrollBy
|
||||||
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.scrollByPages
|
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.scrollByPages
|
||||||
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.withShiftModifier
|
import com.chylex.intellij.keyboardmaster.feature.vimNavigation.components.VimCommonNavigation.withShiftModifier
|
||||||
|
import com.intellij.ide.IdeEventQueue
|
||||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
import com.intellij.openapi.ui.getUserData
|
import com.intellij.openapi.ui.getUserData
|
||||||
import com.intellij.openapi.ui.putUserData
|
import com.intellij.openapi.ui.putUserData
|
||||||
@@ -33,6 +34,9 @@ internal object VimTableNavigation {
|
|||||||
KeyStroke.getKeyStroke('K') to IdeaAction("Table-selectPreviousRowExtendSelection"),
|
KeyStroke.getKeyStroke('K') to IdeaAction("Table-selectPreviousRowExtendSelection"),
|
||||||
KeyStroke.getKeyStroke('l') to IdeaAction("Table-selectNextColumn"),
|
KeyStroke.getKeyStroke('l') to IdeaAction("Table-selectNextColumn"),
|
||||||
KeyStroke.getKeyStroke('L') to IdeaAction("Table-selectNextColumnExtendSelection"),
|
KeyStroke.getKeyStroke('L') to IdeaAction("Table-selectNextColumnExtendSelection"),
|
||||||
|
KeyStroke.getKeyStroke(' ') to StartEditingSelectedCell,
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_J, KeyEvent.ALT_DOWN_MASK) to DispatchKeyEvent(KeyEvent.VK_DOWN, KeyEvent.CHAR_UNDEFINED, KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke(KeyEvent.VK_K, KeyEvent.ALT_DOWN_MASK) to DispatchKeyEvent(KeyEvent.VK_UP, KeyEvent.CHAR_UNDEFINED, KeyEvent.ALT_DOWN_MASK),
|
||||||
*withShiftModifier(KeyEvent.VK_B, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = -1.0F, extendSelection = it) },
|
*withShiftModifier(KeyEvent.VK_B, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = -1.0F, extendSelection = it) },
|
||||||
*withShiftModifier(KeyEvent.VK_D, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = +0.5F, extendSelection = it) },
|
*withShiftModifier(KeyEvent.VK_D, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = +0.5F, extendSelection = it) },
|
||||||
*withShiftModifier(KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = +1.0F, extendSelection = it) },
|
*withShiftModifier(KeyEvent.VK_F, KeyEvent.CTRL_DOWN_MASK) { ScrollVerticallyAndSelect(pages = +1.0F, extendSelection = it) },
|
||||||
@@ -52,15 +56,30 @@ internal object VimTableNavigation {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val GIT_REBASE_TABLE_ROOT_NODE = BASIC_ROOT_NODE + Parent(
|
||||||
|
mapOf(
|
||||||
|
KeyStroke.getKeyStroke('d') to DispatchKeyEvent(KeyEvent.VK_D, 'd', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke('e') to DispatchKeyEvent(KeyEvent.VK_E, 'e', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke('f') to DispatchKeyEvent(KeyEvent.VK_F, 'f', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke('p') to DispatchKeyEvent(KeyEvent.VK_P, 'p', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke('r') to DispatchKeyEvent(KeyEvent.VK_R, 'r', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
KeyStroke.getKeyStroke('s') to DispatchKeyEvent(KeyEvent.VK_S, 's', KeyEvent.ALT_DOWN_MASK),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fun install(component: JTable) {
|
fun install(component: JTable) {
|
||||||
if (component.getUserData(KEY) == null) {
|
if (component.getUserData(KEY) == null) {
|
||||||
component.putUserData(KEY, VimNavigationDispatcher(component, pickRootNode(component)))
|
component.putUserData(KEY, VimNavigationDispatcher(component, pickRootNode(component)))
|
||||||
|
component.putClientProperty("JTable.autoStartsEdit", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pickRootNode(component: JTable) = when (component) {
|
private fun pickRootNode(component: JTable) = when (component) {
|
||||||
is VcsLogGraphTable -> GIT_LOG_TABLE_ROOT_NODE
|
is VcsLogGraphTable -> GIT_LOG_TABLE_ROOT_NODE
|
||||||
else -> BASIC_ROOT_NODE
|
else -> when {
|
||||||
|
component::class.java.name.contains("GitInteractiveRebase") -> GIT_REBASE_TABLE_ROOT_NODE
|
||||||
|
else -> BASIC_ROOT_NODE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class ScrollVerticallyAndSelect(private val pages: Float, private val extendSelection: Boolean) : ActionNode<VimNavigationDispatcher<JTable>> {
|
private data class ScrollVerticallyAndSelect(private val pages: Float, private val extendSelection: Boolean) : ActionNode<VimNavigationDispatcher<JTable>> {
|
||||||
@@ -87,4 +106,26 @@ internal object VimTableNavigation {
|
|||||||
table.scrollRectToVisible(adjustedRect)
|
table.scrollRectToVisible(adjustedRect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object StartEditingSelectedCell : ActionNode<VimNavigationDispatcher<JTable>> {
|
||||||
|
override fun performAction(holder: VimNavigationDispatcher<JTable>, actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
||||||
|
val table = holder.component
|
||||||
|
if (table.isEditing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val rowIndex = table.selectionModel.leadSelectionIndex
|
||||||
|
val columnIndex = table.columnModel.selectionModel.leadSelectionIndex
|
||||||
|
table.editCellAt(rowIndex, columnIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private data class DispatchKeyEvent(private val keyCode: Int, private val keyChar: Char, private val modifiers: Int) : ActionNode<VimNavigationDispatcher<JTable>> {
|
||||||
|
override fun performAction(holder: VimNavigationDispatcher<JTable>, actionEvent: AnActionEvent, keyEvent: KeyEvent) {
|
||||||
|
with(IdeEventQueue.getInstance().keyEventDispatcher) {
|
||||||
|
dispatchKeyEvent(KeyEvent(holder.component, KeyEvent.KEY_PRESSED, keyEvent.`when`, modifiers, keyCode, keyChar))
|
||||||
|
dispatchKeyEvent(KeyEvent(holder.component, KeyEvent.KEY_RELEASED, keyEvent.`when`, modifiers, keyCode, keyChar))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-14
@@ -13,6 +13,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent
|
|||||||
import com.intellij.openapi.ui.getUserData
|
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.openapi.vcs.changes.ui.ChangesListView
|
||||||
import com.intellij.openapi.vcs.changes.ui.ChangesTree
|
import com.intellij.openapi.vcs.changes.ui.ChangesTree
|
||||||
import com.intellij.ui.ClientProperty
|
import com.intellij.ui.ClientProperty
|
||||||
import com.intellij.ui.tree.ui.DefaultTreeUI
|
import com.intellij.ui.tree.ui.DefaultTreeUI
|
||||||
@@ -73,22 +74,37 @@ internal object VimTreeNavigation {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val GIT_CHANGES_ROOT_NODE = BASIC_ROOT_NODE + Parent(
|
private val GIT_CHANGES_BASIC_ROOT_NODE = BASIC_ROOT_NODE + Parent(
|
||||||
mapOf(
|
mapOf(
|
||||||
|
KeyStroke.getKeyStroke('d') to IdeaAction("Vcs.ShowDiffWithLocal"),
|
||||||
KeyStroke.getKeyStroke('e') to IdeaAction("EditSource"),
|
KeyStroke.getKeyStroke('e') to IdeaAction("EditSource"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val GIT_LOCAL_CHANGES_ROOT_NODE = GIT_CHANGES_BASIC_ROOT_NODE + Parent(
|
||||||
|
mapOf(
|
||||||
KeyStroke.getKeyStroke('r') to IdeaAction("ChangesView.Revert"),
|
KeyStroke.getKeyStroke('r') to IdeaAction("ChangesView.Revert"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val GIT_OTHER_CHANGES_ROOT_NODE = GIT_CHANGES_BASIC_ROOT_NODE + Parent(
|
||||||
|
mapOf(
|
||||||
|
KeyStroke.getKeyStroke('c') to IdeaAction("Vcs.ApplySelectedChanges"),
|
||||||
|
KeyStroke.getKeyStroke('r') to IdeaAction("Vcs.RevertSelectedChanges"),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
fun install(component: JTree) {
|
fun install(component: JTree) {
|
||||||
if (component.getUserData(KEY) == null) {
|
if (component.getUserData(KEY) == null) {
|
||||||
component.putUserData(KEY, VimNavigationDispatcher(component, pickRootNode(component)))
|
component.putUserData(KEY, VimNavigationDispatcher(component, pickRootNode(component)))
|
||||||
|
ClientProperty.put(component, DefaultTreeUI.AUTO_EXPAND_ALLOWED, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pickRootNode(component: JTree) = when (component) {
|
private fun pickRootNode(component: JTree) = when (component) {
|
||||||
is ProjectViewTree -> PROJECT_FILE_TREE_ROOT_NODE
|
is ProjectViewTree -> PROJECT_FILE_TREE_ROOT_NODE
|
||||||
is ChangesTree -> GIT_CHANGES_ROOT_NODE
|
is ChangesListView -> GIT_LOCAL_CHANGES_ROOT_NODE
|
||||||
|
is ChangesTree -> GIT_OTHER_CHANGES_ROOT_NODE
|
||||||
else -> BASIC_ROOT_NODE
|
else -> BASIC_ROOT_NODE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +255,7 @@ internal object VimTreeNavigation {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
if (pathsToExpand.any(tree::isCollapsed)) {
|
if (pathsToExpand.any(tree::isCollapsed)) {
|
||||||
runWithoutAutoExpand(tree) { pathsToExpand.forEach(tree::expandPath) }
|
pathsToExpand.forEach(tree::expandPath)
|
||||||
|
|
||||||
for (path in pathsToExpand) {
|
for (path in pathsToExpand) {
|
||||||
forEachChild(model, path) { tree.collapsePath(path.pathByAddingChild(it)) }
|
forEachChild(model, path) { tree.collapsePath(path.pathByAddingChild(it)) }
|
||||||
@@ -272,7 +288,7 @@ internal object VimTreeNavigation {
|
|||||||
selectRow(tree, getFirstChild(tree, path))
|
selectRow(tree, getFirstChild(tree, path))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
runWithoutAutoExpand(tree) { tree.expandPath(path) }
|
tree.expandPath(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,16 +355,6 @@ internal object VimTreeNavigation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun runWithoutAutoExpand(tree: JTree, action: () -> Unit) {
|
|
||||||
val previousAutoExpandValue = ClientProperty.get(tree, DefaultTreeUI.AUTO_EXPAND_ALLOWED)
|
|
||||||
ClientProperty.put(tree, DefaultTreeUI.AUTO_EXPAND_ALLOWED, false)
|
|
||||||
try {
|
|
||||||
action()
|
|
||||||
} finally {
|
|
||||||
ClientProperty.put(tree, DefaultTreeUI.AUTO_EXPAND_ALLOWED, previousAutoExpandValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun selectRow(tree: JTree, row: Int) {
|
private fun selectRow(tree: JTree, row: Int) {
|
||||||
tree.setSelectionRow(row)
|
tree.setSelectionRow(row)
|
||||||
tree.scrollRowToVisible(row)
|
tree.scrollRowToVisible(row)
|
||||||
|
|||||||
Reference in New Issue
Block a user