use of com.maddyhome.idea.vim.command.CommandState in project ideavim by JetBrains.
the class EditorActionHandlerBase method execute.
public final void execute(@NotNull Editor editor, @NotNull DataContext context) {
editor = InjectedLanguageUtil.getTopLevelEditor(editor);
logger.debug("execute");
if (!VimPlugin.isEnabled()) {
return;
}
final CommandState state = CommandState.getInstance(editor);
final Command cmd = state.getCommand();
if (cmd == null || !execute(editor, context, cmd)) {
VimPlugin.indicateError();
}
}
use of com.maddyhome.idea.vim.command.CommandState in project ideavim by JetBrains.
the class KeyHandler method partialReset.
/**
* Partially resets the state of this handler. Resets the command count, clears the key list, resets the key tree
* node to the root for the current mode we are in.
*
* @param editor The editor to reset.
*/
private void partialReset(@Nullable Editor editor) {
count = 0;
keys = new ArrayList<KeyStroke>();
CommandState editorState = CommandState.getInstance(editor);
editorState.stopMappingTimer();
editorState.getMappingKeys().clear();
editorState.setCurrentNode(VimPlugin.getKey().getKeyRoot(editorState.getMappingMode()));
}
use of com.maddyhome.idea.vim.command.CommandState in project ideavim by JetBrains.
the class KeyHandler method handleKey.
public void handleKey(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull DataContext context, boolean allowKeyMappings) {
VimPlugin.clearError();
// All the editor actions should be performed with top level editor!!!
// Be careful: all the EditorActionHandler implementation should correctly process InjectedEditors
editor = InjectedLanguageUtil.getTopLevelEditor(editor);
final CommandState editorState = CommandState.getInstance(editor);
// If this is a "regular" character keystroke, get the character
char chKey = key.getKeyChar() == KeyEvent.CHAR_UNDEFINED ? 0 : key.getKeyChar();
final boolean isRecording = editorState.isRecording();
boolean shouldRecord = true;
// Check for command count before key mappings - otherwise e.g. ':map 0 ^' breaks command counts that contain a zero
if (isCommandCount(editorState, chKey)) {
// Update the count
count = count * 10 + (chKey - '0');
} else if (allowKeyMappings && handleKeyMapping(editor, key, context)) {
return;
} else // Unlike the digits, this must be checked *after* checking for key mappings
if (isDeleteCommandCount(key, editorState)) {
// "Remove" the last digit sent to us
count /= 10;
} else if (isEditorReset(key, editorState)) {
handleEditorReset(editor, key, context);
} else // First let's check to see if we are at the point of expecting a single character argument to a command.
if (currentArg == Argument.Type.CHARACTER) {
handleCharArgument(key, chKey);
} else // If we are this far, then the user must be entering a command or a non-single-character argument
// to an entered command. Let's figure out which it is
{
// For debugging purposes we track the keys entered for this command
keys.add(key);
// Ask the key/action tree if this is an appropriate key at this point in the command and if so,
// return the node matching this keystroke
final Node node = editorState.getCurrentNode().getChild(key);
if (handleDigraph(editor, key, context, node)) {
return;
}
// If this is a branch node we have entered only part of a multi-key command
if (node instanceof BranchNode) {
handleBranchNode(editor, context, editorState, chKey, (BranchNode) node);
} else // If this is a command node the user has entered a valid key sequence of a known command
if (node instanceof CommandNode) {
handleCommandNode(editor, context, (CommandNode) node);
} else // be the first keystroke of the argument of the current command
if (node instanceof ArgumentNode) {
shouldRecord = handleArgumentNode(editor, key, context, editorState, (ArgumentNode) node);
} else {
if (lastWasBS && lastChar != 0 && Options.getInstance().isSet("digraph")) {
char dig = VimPlugin.getDigraph().getDigraph(lastChar, key.getKeyChar());
key = KeyStroke.getKeyStroke(dig);
}
// If we are in insert/replace mode send this key in for processing
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
if (!VimPlugin.getChange().processKey(editor, context, key)) {
shouldRecord = false;
}
} else if (editorState.getMappingMode() == MappingMode.CMD_LINE) {
if (!VimPlugin.getProcess().processExKey(editor, key)) {
shouldRecord = false;
}
} else // If we get here then the user has entered an unrecognized series of keystrokes
{
state = State.BAD_COMMAND;
}
lastChar = key.getKeyChar();
partialReset(editor);
}
}
// Do we have a fully entered command at this point? If so, lets execute it
if (state == State.READY) {
executeCommand(editor, key, context, editorState);
} else if (state == State.BAD_COMMAND) {
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
editorState.popState();
} else {
VimPlugin.indicateError();
reset(editor);
}
} else // We had some sort of error so reset the handler and let the user know (beep)
if (state == State.ERROR) {
VimPlugin.indicateError();
fullReset(editor);
} else if (isRecording && shouldRecord) {
VimPlugin.getRegister().recordKeyStroke(key);
}
}
use of com.maddyhome.idea.vim.command.CommandState in project ideavim by JetBrains.
the class KeyHandler method handleKeyMapping.
private boolean handleKeyMapping(@NotNull final Editor editor, @NotNull final KeyStroke key, @NotNull final DataContext context) {
final CommandState commandState = CommandState.getInstance(editor);
commandState.stopMappingTimer();
final List<KeyStroke> mappingKeys = commandState.getMappingKeys();
final List<KeyStroke> fromKeys = new ArrayList<KeyStroke>(mappingKeys);
fromKeys.add(key);
final MappingMode mappingMode = commandState.getMappingMode();
if (MappingMode.NVO.contains(mappingMode) && (state != State.NEW_COMMAND || currentArg != Argument.Type.NONE)) {
return false;
}
final KeyMapping mapping = VimPlugin.getKey().getKeyMapping(mappingMode);
final MappingInfo currentMappingInfo = mapping.get(fromKeys);
final MappingInfo prevMappingInfo = mapping.get(mappingKeys);
final MappingInfo mappingInfo = currentMappingInfo != null ? currentMappingInfo : prevMappingInfo;
final Application application = ApplicationManager.getApplication();
if (mapping.isPrefix(fromKeys)) {
mappingKeys.add(key);
if (!application.isUnitTestMode() && Options.getInstance().isSet(Options.TIMEOUT)) {
commandState.startMappingTimer(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
mappingKeys.clear();
for (KeyStroke keyStroke : fromKeys) {
handleKey(editor, keyStroke, new EditorDataContext(editor), false);
}
}
});
}
return true;
} else if (mappingInfo != null) {
mappingKeys.clear();
final Runnable handleMappedKeys = new Runnable() {
@Override
public void run() {
if (editor.isDisposed()) {
return;
}
final List<KeyStroke> toKeys = mappingInfo.getToKeys();
final VimExtensionHandler extensionHandler = mappingInfo.getExtensionHandler();
final EditorDataContext currentContext = new EditorDataContext(editor);
if (toKeys != null) {
final boolean fromIsPrefix = isPrefix(mappingInfo.getFromKeys(), toKeys);
boolean first = true;
for (KeyStroke keyStroke : toKeys) {
final boolean recursive = mappingInfo.isRecursive() && !(first && fromIsPrefix);
handleKey(editor, keyStroke, currentContext, recursive);
first = false;
}
} else if (extensionHandler != null) {
RunnableHelper.runWriteCommand(editor.getProject(), new Runnable() {
@Override
public void run() {
extensionHandler.execute(editor, context);
}
}, "Vim " + extensionHandler.getClass().getSimpleName(), null);
}
if (prevMappingInfo != null) {
handleKey(editor, key, currentContext);
}
}
};
if (application.isUnitTestMode()) {
handleMappedKeys.run();
} else {
application.invokeLater(handleMappedKeys);
}
return true;
} else {
final List<KeyStroke> unhandledKeys = new ArrayList<KeyStroke>(mappingKeys);
mappingKeys.clear();
for (KeyStroke keyStroke : unhandledKeys) {
handleKey(editor, keyStroke, context, false);
}
return false;
}
}
use of com.maddyhome.idea.vim.command.CommandState in project ideavim by JetBrains.
the class MacroActionTest method testRecordMacro.
// |q|
public void testRecordMacro() {
final Editor editor = typeTextInFile(parseKeys("qa", "3l", "q"), "on<caret>e two three\n");
final CommandState commandState = CommandState.getInstance(editor);
assertFalse(commandState.isRecording());
final RegisterGroup registerGroup = VimPlugin.getRegister();
final Register register = registerGroup.getRegister('a');
assertNotNull(register);
assertEquals("3l", register.getText());
}
Aggregations