mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-02-24 08:46:00 +01:00
More obvious processing of ex-commands.
1. Now we have two parallel commandBuilders: for the editor and for the command prompt. It's done for sequence of keys like `d/foo<C-R>"<CR>` where we have two different commands that are built at the same time. 2. We simplified the CommandConsumer and made the logic more straightforward. `/`, `?` and `:` enter the command mode, while pressing final `<CR>` fires the command execution.
This commit is contained in:
parent
a6994a09c3
commit
726b885b60
src/main/java/com/maddyhome/idea/vim
vim-engine/src/main/kotlin/com/maddyhome/idea/vim
@ -11,25 +11,60 @@ import com.intellij.vim.annotations.CommandOrMotion
|
||||
import com.intellij.vim.annotations.Mode
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
import com.maddyhome.idea.vim.common.Direction
|
||||
import com.maddyhome.idea.vim.ex.ExException
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Called by KeyHandler to process the contents of the ex entry panel
|
||||
*
|
||||
* The mapping for this action means that the ex command is executed as a write action
|
||||
*/
|
||||
@CommandOrMotion(keys = ["<CR>", "<C-M>", "<C-J>"], modes = [Mode.CMD_LINE])
|
||||
public class ProcessExEntryAction : VimActionHandler.SingleExecution() {
|
||||
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||
public class ProcessExEntryAction : MotionActionHandler.AmbiguousExecution() {
|
||||
override val flags: EnumSet<CommandFlags> = EnumSet.of(CommandFlags.FLAG_SAVE_JUMP, CommandFlags.FLAG_END_EX)
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
|
||||
override val flags: EnumSet<CommandFlags> = EnumSet.of(CommandFlags.FLAG_COMPLETE_EX)
|
||||
|
||||
override fun execute(editor: VimEditor, context: ExecutionContext, cmd: Command, operatorArguments: OperatorArguments): Boolean {
|
||||
return VimPlugin.getProcess().processExEntry(editor, context)
|
||||
override fun getMotionActionHandler(argument: Argument?): MotionActionHandler {
|
||||
return if (argument?.character == ':') ProcessExCommandEntryAction() else ProcessSearchEntryAction()
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessSearchEntryAction : MotionActionHandler.ForEachCaret() {
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
|
||||
override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: ImmutableVimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments,
|
||||
): Motion {
|
||||
if (argument == null) return Motion.Error
|
||||
return when (argument.character) {
|
||||
'/' -> injector.searchGroup.processSearchCommand(editor, argument.string, caret.offset, Direction.FORWARDS).toMotionOrError()
|
||||
'?' -> injector.searchGroup.processSearchCommand(editor, argument.string, caret.offset, Direction.BACKWARDS).toMotionOrError()
|
||||
else -> throw ExException("Unexpected search label ${argument.character}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessExCommandEntryAction : MotionActionHandler.SingleExecution() {
|
||||
override val motionType: MotionType = MotionType.LINE_WISE
|
||||
|
||||
override fun getOffset(
|
||||
editor: VimEditor,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments,
|
||||
): Motion {
|
||||
VimPlugin.getProcess().processExEntry(editor, context)
|
||||
// TODO support motions for commands
|
||||
return Motion.NoMotion
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@ import com.maddyhome.idea.vim.api.VimApplication
|
||||
import com.maddyhome.idea.vim.api.VimChangeGroup
|
||||
import com.maddyhome.idea.vim.api.VimClipboardManager
|
||||
import com.maddyhome.idea.vim.api.VimCommandGroup
|
||||
import com.maddyhome.idea.vim.api.VimCommandLine
|
||||
import com.maddyhome.idea.vim.api.VimCommandLineService
|
||||
import com.maddyhome.idea.vim.api.VimDigraphGroup
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.VimEditorGroup
|
||||
@ -197,6 +199,11 @@ internal class IjVimInjector : VimInjectorBase() {
|
||||
get() = service<Executor>()
|
||||
override val vimscriptParser: VimscriptParser
|
||||
get() = com.maddyhome.idea.vim.vimscript.parser.VimscriptParser
|
||||
override val commandLine: VimCommandLineService = object : VimCommandLineService {
|
||||
override fun getActiveCommandLine(): VimCommandLine? {
|
||||
return com.maddyhome.idea.vim.ui.ex.ExEntryPanel.getInstance()
|
||||
}
|
||||
}
|
||||
|
||||
override val optionGroup: VimOptionGroup
|
||||
get() = service()
|
||||
|
@ -19,6 +19,7 @@ import com.intellij.openapi.editor.ScrollingModel;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.util.IJSwingUtilities;
|
||||
import com.maddyhome.idea.vim.VimPlugin;
|
||||
import com.maddyhome.idea.vim.api.VimCommandLine;
|
||||
import com.maddyhome.idea.vim.ex.ranges.LineRange;
|
||||
import com.maddyhome.idea.vim.helper.SearchHighlightsHelper;
|
||||
import com.maddyhome.idea.vim.helper.UiHelper;
|
||||
@ -48,7 +49,7 @@ import static com.maddyhome.idea.vim.api.VimInjectorKt.injector;
|
||||
/**
|
||||
* This is used to enter ex commands such as searches and "colon" commands
|
||||
*/
|
||||
public class ExEntryPanel extends JPanel {
|
||||
public class ExEntryPanel extends JPanel implements VimCommandLine {
|
||||
private static ExEntryPanel instance;
|
||||
private static ExEntryPanel instanceWithoutShortcuts;
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2003-2024 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.action.ex
|
||||
|
||||
import com.intellij.vim.annotations.CommandOrMotion
|
||||
import com.intellij.vim.annotations.Mode
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||
import java.util.*
|
||||
|
||||
@CommandOrMotion(keys = ["<Esc>", "<C-[>", "<C-C>"], modes = [Mode.CMD_LINE])
|
||||
public class LeaveCommandLineAction : VimActionHandler.SingleExecution() {
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_END_EX)
|
||||
override val type: Command.Type = Command.Type.OTHER_READONLY
|
||||
|
||||
override fun execute(editor: VimEditor, context: ExecutionContext, cmd: Command, operatorArguments: OperatorArguments): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
@ -10,37 +10,29 @@ package com.maddyhome.idea.vim.action.motion.search
|
||||
import com.intellij.vim.annotations.CommandOrMotion
|
||||
import com.intellij.vim.annotations.Mode
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.common.Direction
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||
import com.maddyhome.idea.vim.state.mode.ReturnableFromCmd
|
||||
import java.util.*
|
||||
|
||||
@CommandOrMotion(keys = ["/"], modes = [Mode.NORMAL, Mode.VISUAL, Mode.OP_PENDING])
|
||||
public class SearchEntryFwdAction : MotionActionHandler.ForEachCaret() {
|
||||
public class SearchEntryFwdAction : VimActionHandler.SingleExecution() {
|
||||
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||
|
||||
override val argumentType: Argument.Type = Argument.Type.EX_STRING
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_START_EX, CommandFlags.FLAG_SAVE_JUMP)
|
||||
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
|
||||
|
||||
override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: ImmutableVimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments,
|
||||
): Motion {
|
||||
if (argument == null) return Motion.Error
|
||||
return injector.searchGroup
|
||||
.processSearchCommand(editor, argument.string, caret.offset, Direction.FORWARDS).toMotionOrError()
|
||||
override fun execute( editor: VimEditor, context: ExecutionContext, cmd: Command, operatorArguments: OperatorArguments): Boolean {
|
||||
injector.processGroup.startSearchCommand(editor, context, cmd.count, '/')
|
||||
val currentMode = editor.mode
|
||||
check(currentMode is ReturnableFromCmd) { "Cannot enable command line mode $currentMode" }
|
||||
editor.mode = com.maddyhome.idea.vim.state.mode.Mode.CMD_LINE(currentMode)
|
||||
return true
|
||||
}
|
||||
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
}
|
||||
|
@ -10,37 +10,29 @@ package com.maddyhome.idea.vim.action.motion.search
|
||||
import com.intellij.vim.annotations.CommandOrMotion
|
||||
import com.intellij.vim.annotations.Mode
|
||||
import com.maddyhome.idea.vim.api.ExecutionContext
|
||||
import com.maddyhome.idea.vim.api.ImmutableVimCaret
|
||||
import com.maddyhome.idea.vim.api.VimEditor
|
||||
import com.maddyhome.idea.vim.api.injector
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.command.CommandFlags
|
||||
import com.maddyhome.idea.vim.command.MotionType
|
||||
import com.maddyhome.idea.vim.command.OperatorArguments
|
||||
import com.maddyhome.idea.vim.common.Direction
|
||||
import com.maddyhome.idea.vim.handler.Motion
|
||||
import com.maddyhome.idea.vim.handler.MotionActionHandler
|
||||
import com.maddyhome.idea.vim.handler.toMotionOrError
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
import com.maddyhome.idea.vim.helper.enumSetOf
|
||||
import com.maddyhome.idea.vim.state.mode.ReturnableFromCmd
|
||||
import java.util.*
|
||||
|
||||
@CommandOrMotion(keys = ["?"], modes = [Mode.NORMAL, Mode.VISUAL, Mode.OP_PENDING])
|
||||
public class SearchEntryRevAction : MotionActionHandler.ForEachCaret() {
|
||||
public class SearchEntryRevAction : VimActionHandler.SingleExecution() {
|
||||
override val type: Command.Type = Command.Type.OTHER_SELF_SYNCHRONIZED
|
||||
|
||||
override val argumentType: Argument.Type = Argument.Type.EX_STRING
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_START_EX, CommandFlags.FLAG_SAVE_JUMP)
|
||||
|
||||
override val flags: EnumSet<CommandFlags> = enumSetOf(CommandFlags.FLAG_SAVE_JUMP)
|
||||
|
||||
override fun getOffset(
|
||||
editor: VimEditor,
|
||||
caret: ImmutableVimCaret,
|
||||
context: ExecutionContext,
|
||||
argument: Argument?,
|
||||
operatorArguments: OperatorArguments,
|
||||
): Motion {
|
||||
if (argument == null) return Motion.Error
|
||||
return injector.searchGroup
|
||||
.processSearchCommand(editor, argument.string, caret.offset, Direction.BACKWARDS).toMotionOrError()
|
||||
override fun execute( editor: VimEditor, context: ExecutionContext, cmd: Command, operatorArguments: OperatorArguments): Boolean {
|
||||
injector.processGroup.startSearchCommand(editor, context, cmd.count, '?')
|
||||
val currentMode = editor.mode
|
||||
check(currentMode is ReturnableFromCmd) { "Cannot enable command line mode $currentMode" }
|
||||
editor.mode = com.maddyhome.idea.vim.state.mode.Mode.CMD_LINE(currentMode)
|
||||
return true
|
||||
}
|
||||
|
||||
override val motionType: MotionType = MotionType.EXCLUSIVE
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2003-2024 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.api
|
||||
|
||||
public interface VimCommandLine {
|
||||
public val label: String
|
||||
public val text: String
|
||||
|
||||
public fun deactivate(refocusOwningEditor: Boolean)
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2003-2024 The IdeaVim authors
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE.txt file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.api
|
||||
|
||||
public interface VimCommandLineService {
|
||||
public fun getActiveCommandLine(): VimCommandLine?
|
||||
}
|
@ -181,6 +181,8 @@ public interface VimInjector {
|
||||
// !! in progress
|
||||
public val variableService: VariableService
|
||||
|
||||
public val commandLine: VimCommandLineService
|
||||
|
||||
// !! in progress
|
||||
public val functionService: VimscriptFunctionService
|
||||
|
||||
|
@ -17,10 +17,14 @@ public interface VimProcessGroup {
|
||||
public val isCommandProcessing: Boolean
|
||||
public val modeBeforeCommandProcessing: Mode?
|
||||
|
||||
// TODO remove me
|
||||
public fun startSearchCommand(editor: VimEditor, context: ExecutionContext, count: Int, leader: Char)
|
||||
// TODO remove me
|
||||
public fun endSearchCommand(): String
|
||||
// TODO remove me
|
||||
public fun processExKey(editor: VimEditor, stroke: KeyStroke, processResultBuilder: KeyProcessResult.KeyProcessResultBuilder): Boolean
|
||||
public fun startFilterCommand(editor: VimEditor, context: ExecutionContext, cmd: Command)
|
||||
// TODO remove me
|
||||
public fun startExCommand(editor: VimEditor, context: ExecutionContext, cmd: Command)
|
||||
public fun processExEntry(editor: VimEditor, context: ExecutionContext): Boolean
|
||||
public fun cancelExEntry(editor: VimEditor, resetCaret: Boolean)
|
||||
|
@ -18,6 +18,7 @@ import java.util.*
|
||||
|
||||
/**
|
||||
* This represents a command argument.
|
||||
* TODO please make it a sealed class and not a giant collection of fields with default values, it's not safe
|
||||
*/
|
||||
public class Argument private constructor(
|
||||
public val character: Char = 0.toChar(),
|
||||
@ -28,7 +29,7 @@ public class Argument private constructor(
|
||||
) {
|
||||
public constructor(motionArg: Command) : this(motion = motionArg, type = Type.MOTION)
|
||||
public constructor(charArg: Char) : this(character = charArg, type = Type.CHARACTER)
|
||||
public constructor(strArg: String) : this(string = strArg, type = Type.EX_STRING)
|
||||
public constructor(label: Char, strArg: String) : this(character = label, string = strArg, type = Type.EX_STRING)
|
||||
public constructor(offsets: Map<ImmutableVimCaret, VimSelection>) : this(offsets = offsets, type = Type.OFFSETS)
|
||||
|
||||
public enum class Type {
|
||||
|
@ -73,14 +73,8 @@ public enum class CommandFlags {
|
||||
*/
|
||||
FLAG_ALLOW_DIGRAPH,
|
||||
|
||||
/**
|
||||
* Indicates that a command handles completing ex input.
|
||||
*
|
||||
* When performing a search, the search action command requires an EX_STRING as input. This is completed by a command
|
||||
* that has FLAG_COMPLETE_EX. That command isn't called and the ex string becomes an argument for the previous command
|
||||
* that started the EX_STRING.
|
||||
*/
|
||||
FLAG_COMPLETE_EX,
|
||||
FLAG_START_EX,
|
||||
FLAG_END_EX,
|
||||
|
||||
FLAG_TEXT_BLOCK,
|
||||
}
|
||||
|
@ -98,6 +98,14 @@ public class CommandConsumer : KeyConsumer {
|
||||
// The user entered a valid command. Create the command and add it to the stack.
|
||||
val action = node.actionHolder.instance
|
||||
val keyState = processBuilder.state
|
||||
|
||||
if (action.flags.contains(CommandFlags.FLAG_START_EX)) {
|
||||
keyState.enterCommandLine()
|
||||
}
|
||||
if (action.flags.contains(CommandFlags.FLAG_END_EX)) {
|
||||
keyState.leaveCommandLine()
|
||||
}
|
||||
|
||||
val commandBuilder = keyState.commandBuilder
|
||||
val expectedArgumentType = commandBuilder.expectedArgumentType
|
||||
commandBuilder.pushCommandPart(action)
|
||||
@ -122,29 +130,14 @@ public class CommandConsumer : KeyConsumer {
|
||||
}
|
||||
|
||||
processBuilder.addExecutionStep { _, lambdaEditor, _ ->
|
||||
// TODO In the name of God, get rid of EX_STRING, FLAG_COMPLETE_EX and all the related staff
|
||||
if (expectedArgumentType === Argument.Type.EX_STRING && action.flags.contains(CommandFlags.FLAG_COMPLETE_EX)) {
|
||||
/* The only action that implements FLAG_COMPLETE_EX is ProcessExEntryAction.
|
||||
* When pressing ':', ExEntryAction is chosen as the command. Since it expects no arguments, it is invoked and
|
||||
calls ProcessGroup#startExCommand, pushes CMD_LINE mode, and the action is popped. The ex handler will push
|
||||
the final <CR> through handleKey, which chooses ProcessExEntryAction. Because we're not expecting EX_STRING,
|
||||
this branch does NOT fire, and ProcessExEntryAction handles the ex cmd line entry.
|
||||
* When pressing '/' or '?', SearchEntry(Fwd|Rev)Action is chosen as the command. This expects an argument of
|
||||
EX_STRING, so startWaitingForArgument calls ProcessGroup#startSearchCommand. The ex handler pushes the final
|
||||
<CR> through handleKey, which chooses ProcessExEntryAction, and we hit this branch. We don't invoke
|
||||
ProcessExEntryAction, but pop it, set the search text as an argument on SearchEntry(Fwd|Rev)Action and invoke
|
||||
that instead.
|
||||
* When using '/' or '?' as part of a motion (e.g. "d/foo"), the above happens again, and all is good. Because
|
||||
the text has been applied as an argument on the last command, '.' will correctly repeat it.
|
||||
|
||||
It's hard to see how to improve this. Removing EX_STRING means starting ex input has to happen in ExEntryAction
|
||||
and SearchEntry(Fwd|Rev)Action, and the ex command invoked in ProcessExEntryAction, but that breaks any initial
|
||||
operator, which would be invoked first (e.g. 'd' in "d/foo").
|
||||
*/
|
||||
if (action.flags.contains(CommandFlags.FLAG_END_EX)) {
|
||||
logger.trace("Processing ex_string")
|
||||
val text = injector.processGroup.endSearchCommand()
|
||||
commandBuilder.popCommandPart() // Pop ProcessExEntryAction
|
||||
commandBuilder.completeCommandPart(Argument(text)) // Set search text on SearchEntry(Fwd|Rev)Action
|
||||
val commandLine = injector.commandLine.getActiveCommandLine()!!
|
||||
val label = commandLine.label
|
||||
val text = commandLine.text
|
||||
commandLine.deactivate(true)
|
||||
|
||||
commandBuilder.completeCommandPart(Argument(label[0], text))
|
||||
lambdaEditor.mode = lambdaEditor.mode.returnTo()
|
||||
}
|
||||
}
|
||||
|
@ -159,8 +159,7 @@ public abstract class VimRegisterGroupBase : VimRegisterGroup {
|
||||
action.id == "VimMotionSentencePreviousStartAction" ||
|
||||
action.id == "VimMotionSentenceNextStartAction" ||
|
||||
action.id == "VimMotionGotoFileMarkAction" ||
|
||||
action.id == "VimSearchEntryFwdAction" ||
|
||||
action.id == "VimSearchEntryRevAction" ||
|
||||
action.id == "VimProcessExEntryAction" ||
|
||||
action.id == "VimSearchAgainNextAction" ||
|
||||
action.id == "VimSearchAgainPreviousAction" ||
|
||||
action.id == "VimMotionParagraphNextAction" ||
|
||||
|
@ -19,9 +19,21 @@ import com.maddyhome.idea.vim.state.mode.Mode
|
||||
public data class KeyHandlerState(
|
||||
public val mappingState: MappingState,
|
||||
public val digraphSequence: DigraphSequence,
|
||||
public val commandBuilder: CommandBuilder,
|
||||
public val editorCommandBuilder: CommandBuilder,
|
||||
public var commandLineCommandBuilder: CommandBuilder?,
|
||||
): Cloneable {
|
||||
public constructor() : this(MappingState(), DigraphSequence(), CommandBuilder(injector.keyGroup.getKeyRoot(MappingMode.NORMAL)))
|
||||
public constructor() : this(MappingState(), DigraphSequence(), CommandBuilder(injector.keyGroup.getKeyRoot(MappingMode.NORMAL)), null)
|
||||
|
||||
public val commandBuilder: CommandBuilder
|
||||
get() = commandLineCommandBuilder ?: editorCommandBuilder
|
||||
|
||||
public fun enterCommandLine() {
|
||||
commandLineCommandBuilder = CommandBuilder(injector.keyGroup.getKeyRoot(MappingMode.CMD_LINE))
|
||||
}
|
||||
|
||||
public fun leaveCommandLine() {
|
||||
commandLineCommandBuilder = null
|
||||
}
|
||||
|
||||
public fun partialReset(mode: Mode) {
|
||||
mappingState.resetMappingSequence()
|
||||
@ -31,14 +43,17 @@ public data class KeyHandlerState(
|
||||
public fun reset(mode: Mode) {
|
||||
digraphSequence.reset()
|
||||
mappingState.resetMappingSequence()
|
||||
commandBuilder.resetAll(injector.keyGroup.getKeyRoot(mode.toMappingMode()))
|
||||
|
||||
commandLineCommandBuilder = null
|
||||
editorCommandBuilder.resetAll(injector.keyGroup.getKeyRoot(mode.toMappingMode()))
|
||||
}
|
||||
|
||||
public override fun clone(): KeyHandlerState {
|
||||
return KeyHandlerState(
|
||||
mappingState.clone(),
|
||||
digraphSequence.clone(),
|
||||
commandBuilder.clone()
|
||||
editorCommandBuilder.clone(),
|
||||
commandLineCommandBuilder?.clone(),
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user