diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/LazyVimCommand.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/LazyVimCommand.kt index a61d976f6..f3119d5f5 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/LazyVimCommand.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/action/change/LazyVimCommand.kt @@ -20,4 +20,24 @@ public class LazyVimCommand( classLoader: ClassLoader, ) : LazyInstance<EditorActionHandlerBase>(className, classLoader) { public val actionId: String = EditorActionHandlerBase.getActionId(className) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as LazyVimCommand + + if (keys != other.keys) return false + if (modes != other.modes) return false + if (actionId != other.actionId) return false + + return true + } + + override fun hashCode(): Int { + var result = keys.hashCode() + result = 31 * result + modes.hashCode() + result = 31 * result + actionId.hashCode() + return result + } } \ No newline at end of file diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/CommandBuilder.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/CommandBuilder.kt index 317452d40..6a79f2b42 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/CommandBuilder.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/CommandBuilder.kt @@ -191,6 +191,33 @@ public class CommandBuilder(private var currentCommandPartNode: CommandPartNode< @TestOnly public fun getCurrentTrie(): CommandPartNode<LazyVimCommand> = currentCommandPartNode + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as CommandBuilder + + if (currentCommandPartNode != other.currentCommandPartNode) return false + if (commandParts != other.commandParts) return false + if (keyList != other.keyList) return false + if (commandState != other.commandState) return false + if (count != other.count) return false + if (expectedArgumentType != other.expectedArgumentType) return false + if (prevExpectedArgumentType != other.prevExpectedArgumentType) return false + + return true + } + + override fun hashCode(): Int { + var result = currentCommandPartNode.hashCode() + result = 31 * result + commandParts.hashCode() + result = 31 * result + keyList.hashCode() + result = 31 * result + commandState.hashCode() + result = 31 * result + count + result = 31 * result + (expectedArgumentType?.hashCode() ?: 0) + result = 31 * result + (prevExpectedArgumentType?.hashCode() ?: 0) + return result + } public companion object { private val LOG = vimLogger<CommandBuilder>() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt index 5c6488fbd..770778970 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/command/MappingState.kt @@ -35,7 +35,7 @@ public class MappingState { public val keys: Iterable<KeyStroke> get() = keyList - private val timer = Timer(injector.globalOptions().timeoutlen, null) + private val timer = VimTimer(injector.globalOptions().timeoutlen) private var keyList = mutableListOf<KeyStroke>() init { @@ -72,7 +72,46 @@ public class MappingState { // NOTE: We intentionally don't reset mapping mode here } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MappingState + + if (mapDepth != other.mapDepth) return false + if (timer != other.timer) return false + if (keyList != other.keyList) return false + + return true + } + + override fun hashCode(): Int { + var result = mapDepth + result = 31 * result + timer.hashCode() + result = 31 * result + keyList.hashCode() + return result + } + public companion object { private val LOG = vimLogger<MappingState>() } -} + + public class VimTimer(delay: Int) : Timer(delay, null) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as VimTimer + + if (delay != other.delay) return false + if (initialDelay != other.initialDelay) return false + if (isRunning != other.isRunning) return false + + return true + } + + override fun hashCode(): Int { + return javaClass.hashCode() + } + } +} \ No newline at end of file diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt index ca2e49e03..4fe4b9560 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/common/DigraphSequence.kt @@ -222,6 +222,32 @@ public class DigraphSequence { codeChars = CharArray(8) } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as DigraphSequence + + if (digraphState != other.digraphState) return false + if (digraphChar != other.digraphChar) return false + if (!codeChars.contentEquals(other.codeChars)) return false + if (codeCnt != other.codeCnt) return false + if (codeType != other.codeType) return false + if (codeMax != other.codeMax) return false + + return true + } + + override fun hashCode(): Int { + var result = digraphState + result = 31 * result + digraphChar.hashCode() + result = 31 * result + codeChars.contentHashCode() + result = 31 * result + codeCnt + result = 31 * result + codeType + result = 31 * result + codeMax + return result + } + public companion object { private const val DIG_STATE_PENDING = 1 private const val DIG_STATE_DIG_ONE = 2 diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/key/Nodes.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/key/Nodes.kt index 649fe3b61..8db5bfd10 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/key/Nodes.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/key/Nodes.kt @@ -42,10 +42,21 @@ import javax.swing.KeyStroke public interface Node<T> /** Represents a complete command */ -public class CommandNode<T>(public val actionHolder: T) : Node<T> +public data class CommandNode<T>(public val actionHolder: T) : Node<T> /** Represents a part of the command */ -public open class CommandPartNode<T> : Node<T>, HashMap<KeyStroke, Node<T>>() +public open class CommandPartNode<T> : Node<T>, HashMap<KeyStroke, Node<T>>() { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + if (!super.equals(other)) return false + return true + } + + override fun hashCode(): Int { + return super.hashCode() + } +} /** Represents a root node for the mode */ public class RootNode<T> : CommandPartNode<T>() diff --git a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/state/KeyHandlerState.kt b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/state/KeyHandlerState.kt index ab72f86ec..9f58e406d 100644 --- a/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/state/KeyHandlerState.kt +++ b/vim-engine/src/main/kotlin/com/maddyhome/idea/vim/state/KeyHandlerState.kt @@ -16,10 +16,12 @@ import com.maddyhome.idea.vim.common.DigraphSequence import com.maddyhome.idea.vim.impl.state.toMappingMode import com.maddyhome.idea.vim.state.mode.Mode -public class KeyHandlerState { - public val mappingState: MappingState = MappingState() - public val digraphSequence: DigraphSequence = DigraphSequence() - public val commandBuilder: CommandBuilder = CommandBuilder(injector.keyGroup.getKeyRoot(MappingMode.NORMAL)) +public data class KeyHandlerState( + public val mappingState: MappingState, + public val digraphSequence: DigraphSequence, + public val commandBuilder: CommandBuilder, +) { + public constructor() : this(MappingState(), DigraphSequence(), CommandBuilder(injector.keyGroup.getKeyRoot(MappingMode.NORMAL))) public fun partialReset(mode: Mode) { digraphSequence.reset()