mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-13 06:16:58 +02:00
Allow sneak plugin to be registered with the original mappings from the sneak plugin
This commit is contained in:
src
main
java
com
maddyhome
idea
vim
extension
test
java
org
jetbrains
plugins
ideavim
extension
sneak
vim-engine/src/main/kotlin/com/maddyhome/idea/vim
@@ -9,7 +9,6 @@
|
||||
package com.maddyhome.idea.vim.extension.sneak
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.ScrollType
|
||||
import com.intellij.openapi.editor.colors.EditorColors
|
||||
@@ -19,6 +18,7 @@ import com.intellij.openapi.editor.markup.HighlighterTargetArea
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter
|
||||
import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.VimProjectService
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
@@ -30,16 +30,16 @@ import com.maddyhome.idea.vim.common.TextRange
|
||||
import com.maddyhome.idea.vim.extension.ExtensionHandler
|
||||
import com.maddyhome.idea.vim.extension.VimExtension
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionFacade.putKeyMapping
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler
|
||||
import com.maddyhome.idea.vim.helper.StrictMode
|
||||
import com.maddyhome.idea.vim.newapi.ij
|
||||
import java.awt.Font
|
||||
import java.awt.event.KeyEvent
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.swing.Timer
|
||||
|
||||
|
||||
private const val DEFAULT_HIGHLIGHT_DURATION_SNEAK: Long = 300
|
||||
private const val DEFAULT_HIGHLIGHT_DURATION_SNEAK = 300
|
||||
|
||||
// By [Mikhail Levchenko](https://github.com/Mishkun)
|
||||
// Original repository with the plugin: https://github.com/Mishkun/ideavim-sneak
|
||||
@@ -250,11 +250,13 @@ internal class IdeaVimSneakExtension : VimExtension {
|
||||
}
|
||||
|
||||
private fun setClearHighlightRangeTimer(highlighter: RangeHighlighter) {
|
||||
Executors.newSingleThreadScheduledExecutor().schedule({
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
editor?.markupModel?.removeHighlighter(highlighter) ?: StrictMode.fail("Highlighters without an editor")
|
||||
val timer = Timer(DEFAULT_HIGHLIGHT_DURATION_SNEAK) {
|
||||
if (editor?.isDisposed != true) {
|
||||
editor?.markupModel?.removeHighlighter(highlighter)
|
||||
}
|
||||
}, DEFAULT_HIGHLIGHT_DURATION_SNEAK, TimeUnit.MILLISECONDS)
|
||||
}
|
||||
timer.isRepeats = false
|
||||
timer.start()
|
||||
}
|
||||
|
||||
private fun getHighlightTextAttributes() = TextAttributes(
|
||||
@@ -279,13 +281,41 @@ private fun VimExtension.mapToFunctionAndProvideKeys(keys: String, handler: Exte
|
||||
handler,
|
||||
false
|
||||
)
|
||||
VimExtensionFacade.putKeyMapping(
|
||||
VimExtensionFacade.putExtensionHandlerMapping(
|
||||
MappingMode.NXO,
|
||||
injector.parser.parseKeys(keys),
|
||||
injector.parser.parseKeys(commandFromOriginalPlugin(keys)),
|
||||
owner,
|
||||
injector.parser.parseKeys(command(keys)),
|
||||
handler,
|
||||
false
|
||||
)
|
||||
|
||||
// This is a combination to meet the following requirements:
|
||||
// - Now we should support mappings from sneak `Sneak_s` and mappings from the previous version of the plugin `(sneak-s)`
|
||||
// - The shortcut should not be registered if any of these mappings is overridden in .ideavimrc
|
||||
// - The shortcut should not be registered if some other shortcut for this key exists
|
||||
val fromKeys = injector.parser.parseKeys(keys)
|
||||
val filteredModes = MappingMode.NXO.filterNotTo(HashSet()) {
|
||||
VimPlugin.getKey().hasmapto(it, injector.parser.parseKeys(command(keys)))
|
||||
}
|
||||
val filteredModes2 = MappingMode.NXO.filterNotTo(HashSet()) {
|
||||
VimPlugin.getKey().hasmapto(it, injector.parser.parseKeys(commandFromOriginalPlugin(keys)))
|
||||
}
|
||||
val filteredFromModes = MappingMode.NXO.filterNotTo(HashSet()) {
|
||||
injector.keyGroup.hasmapfrom(it, fromKeys)
|
||||
}
|
||||
|
||||
val doubleFiltered = MappingMode.NXO
|
||||
.filter { it in filteredModes2 && it in filteredModes && it in filteredFromModes }
|
||||
.toSet()
|
||||
putKeyMapping(doubleFiltered, fromKeys, owner, injector.parser.parseKeys(command(keys)), true)
|
||||
putKeyMapping(
|
||||
doubleFiltered,
|
||||
fromKeys,
|
||||
owner,
|
||||
injector.parser.parseKeys(commandFromOriginalPlugin(keys)),
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
private fun command(keys: String) = "<Plug>(sneak-$keys)"
|
||||
private fun commandFromOriginalPlugin(keys: String) = "<Plug>Sneak_$keys"
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
package org.jetbrains.plugins.ideavim.extension.sneak
|
||||
|
||||
import com.maddyhome.idea.vim.api.keys
|
||||
import com.maddyhome.idea.vim.state.mode.Mode
|
||||
import org.jetbrains.plugins.ideavim.VimTestCase
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -162,4 +163,26 @@ class IdeaVimSneakTest : VimTestCase() {
|
||||
|
||||
doTest("sa<ESC>sdw", before, after, Mode.NORMAL())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSneakForwardFromMapping() {
|
||||
val before = "som${c}e text"
|
||||
val after = "some te${c}xt"
|
||||
|
||||
doTest("fxt", before, after, Mode.NORMAL()) {
|
||||
// This should be fixed, but now we process `<Plug>` as a single key
|
||||
typeText(keys(":map f <") + keys("Plug>Sneak_s<CR>"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSneakForwardFromMappingWithOldMappings() {
|
||||
val before = "som${c}e text"
|
||||
val after = "some te${c}xt"
|
||||
|
||||
doTest("fxt", before, after, Mode.NORMAL()) {
|
||||
// This should be fixed, but now we process `<Plug>` as a single key
|
||||
typeText(keys(":map f <") + keys("Plug>(sneak-s)<CR>"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ public interface VimKeyGroup {
|
||||
public fun unregisterCommandActions()
|
||||
public fun resetKeyMappings()
|
||||
public fun hasmapto(mode: MappingMode, toKeys: List<KeyStroke>): Boolean
|
||||
public fun hasmapfrom(mode: MappingMode, fromKeys: List<KeyStroke>): Boolean
|
||||
|
||||
public val shortcutConflicts: MutableMap<KeyStroke, ShortcutOwnerInfo>
|
||||
public val savedShortcutConflicts: MutableMap<KeyStroke, ShortcutOwnerInfo>
|
||||
|
@@ -48,6 +48,10 @@ public abstract class VimKeyGroupBase : VimKeyGroup {
|
||||
return this.getKeyMapping(mode).hasmapto(toKeys)
|
||||
}
|
||||
|
||||
override fun hasmapfrom(mode: MappingMode, fromKeys: List<KeyStroke>): Boolean {
|
||||
return this.getKeyMapping(mode).hasmapfrom(fromKeys)
|
||||
}
|
||||
|
||||
override fun getKeyMapping(mode: MappingMode): KeyMapping {
|
||||
return keyMappings.getOrPut(mode) { KeyMapping() }
|
||||
}
|
||||
|
@@ -163,6 +163,11 @@ public class KeyMapping : Iterable<List<KeyStroke?>?>, KeyMappingLayer {
|
||||
.anyMatch { o: MappingInfo? -> o is ToKeysMappingInfo && o.toKeys == toKeys }
|
||||
}
|
||||
|
||||
public fun hasmapfrom(fromKeys: List<KeyStroke?>): Boolean {
|
||||
return myKeys.values.stream()
|
||||
.anyMatch { o: MappingInfo? -> o is ToKeysMappingInfo && o.fromKeys == fromKeys }
|
||||
}
|
||||
|
||||
public fun getMapTo(toKeys: List<KeyStroke?>): List<Pair<List<KeyStroke>, MappingInfo>> {
|
||||
return myKeys.entries.stream()
|
||||
.filter { (_, value): Map.Entry<List<KeyStroke>, MappingInfo> -> value is ToKeysMappingInfo && value.toKeys == toKeys }
|
||||
|
@@ -106,6 +106,10 @@ public class ToKeysMappingInfo(
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Mapping[$fromKeys -> $toKeys]"
|
||||
}
|
||||
|
||||
public companion object {
|
||||
private val LOG = vimLogger<ToKeysMappingInfo>()
|
||||
}
|
||||
|
Reference in New Issue
Block a user