mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-17 16:31:45 +02:00
Compare commits
80 Commits
0.54.2-EAP
...
0.55.1-EAP
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ea342a8e4f | ||
![]() |
0b67dd1d05 | ||
![]() |
1519faef81 | ||
![]() |
24f023c8b3 | ||
![]() |
3eb46114f8 | ||
![]() |
6a5fd30531 | ||
![]() |
96e83150e5 | ||
![]() |
b2b65c65b9 | ||
![]() |
5b028b4fa3 | ||
![]() |
8f4e1b3409 | ||
![]() |
3403cdf84b | ||
![]() |
4f9a6f3a7b | ||
![]() |
c8d6d233e5 | ||
![]() |
0cfb65a19a | ||
![]() |
384d917021 | ||
![]() |
f1c8c67789 | ||
![]() |
75e8f4ec6d | ||
![]() |
d1d0323112 | ||
![]() |
ab31dae582 | ||
![]() |
64f176cedb | ||
![]() |
9e921d6621 | ||
![]() |
a4b98f2848 | ||
![]() |
0d190e4a63 | ||
![]() |
13cdb7cc35 | ||
![]() |
ca60c467f3 | ||
![]() |
01abba7d2c | ||
![]() |
80074177fc | ||
![]() |
bf67f8984a | ||
![]() |
b2267c4b6c | ||
![]() |
c80d69a31c | ||
![]() |
1b7c3f0da3 | ||
![]() |
c1ff6e1498 | ||
![]() |
50c04ce71c | ||
![]() |
bc6ff6bc8e | ||
![]() |
93bcf2a7e8 | ||
![]() |
c3b503adff | ||
![]() |
ecdcbdda10 | ||
![]() |
b97c9a5ed0 | ||
![]() |
84a6843a7b | ||
![]() |
17eed7467c | ||
![]() |
310ffc849c | ||
![]() |
3e6756160a | ||
![]() |
563e809a2d | ||
![]() |
86ec3f3bcd | ||
![]() |
7b225cb824 | ||
![]() |
562e0b06df | ||
![]() |
51ce064507 | ||
![]() |
ebaeff9b4d | ||
![]() |
8889e799ca | ||
![]() |
668705e475 | ||
![]() |
e428e909bf | ||
![]() |
d755c751c2 | ||
![]() |
312c547412 | ||
![]() |
48d30f2a3c | ||
![]() |
d8ed30df14 | ||
![]() |
50176cb267 | ||
![]() |
5898d21857 | ||
![]() |
e3839bc0b2 | ||
![]() |
f97555d4a8 | ||
![]() |
79bdca9769 | ||
![]() |
138c2956ac | ||
![]() |
ced457dd94 | ||
![]() |
784fc6c6fa | ||
![]() |
b4e0ec282f | ||
![]() |
cbf7dfabcb | ||
![]() |
b8eb55d965 | ||
![]() |
f817e6cb7f | ||
![]() |
6a622565ca | ||
![]() |
23126aeb6d | ||
![]() |
61fd67472b | ||
![]() |
105c073e1f | ||
![]() |
200f3484b6 | ||
![]() |
6a40eb48fe | ||
![]() |
fb3e9ce9f3 | ||
![]() |
91865460a2 | ||
![]() |
644afe541e | ||
![]() |
232303f06a | ||
![]() |
280845610b | ||
![]() |
6108c9d6d2 | ||
![]() |
ce04e995ee |
22
CHANGES.md
22
CHANGES.md
@@ -16,13 +16,24 @@ It is important to distinguish EAP from traditional pre-release software.
|
||||
Please note that the quality of EAP versions may at times be way below even
|
||||
usual beta standards.
|
||||
|
||||
[To Be Released]
|
||||
To Be Released
|
||||
--------------
|
||||
|
||||
_Available since 0.54.1 EAP:_
|
||||
_Available since 0.55.1 EAP:_
|
||||
|
||||
**Fixes:**
|
||||
* [VIM-1284](https://youtrack.jetbrains.com/issue/VIM-1284) Fix mapping of digits
|
||||
* Fix handling of counts on both operator and motion, e.g. `3d2w` deletes 6 words, instead of 32
|
||||
* Allow mapping of `<C-K>` and `<C-V>`/`<C-Q>`
|
||||
* [VIM-1899](https://youtrack.jetbrains.com/issue/VIM-1899) Add argument to `:registers` command
|
||||
* [VIM-1835](https://youtrack.jetbrains.com/issue/VIM-1835) Macros record input keystrokes instead of mapped keystrokes
|
||||
* [VIM-1900](https://youtrack.jetbrains.com/issue/VIM-1900) Ensure non-printable output for `:registers`, `:marks` and `:jumps` is encoded correctly
|
||||
|
||||
0.55, 2020-01-20
|
||||
--------------
|
||||
|
||||
**Features:**
|
||||
* Surround and Commentary extensions can be repeated with a dot command ([VIM-1118](https://youtrack.jetbrains.com/issue/VIM-1118))
|
||||
* Surround and Commentary extensions support repeating with a dot command ([VIM-1118](https://youtrack.jetbrains.com/issue/VIM-1118))
|
||||
* Support XDG settings standard ([VIM-664](https://youtrack.jetbrains.com/issue/VIM-664))
|
||||
* Add option to remove the status bar icon ([VIM-1847](https://youtrack.jetbrains.com/issue/VIM-1847))
|
||||
|
||||
@@ -43,14 +54,11 @@ _Available since 0.54.1 EAP:_
|
||||
* [VIM-1853](https://youtrack.jetbrains.com/issue/VIM-1853) Fix marks for disposed projects
|
||||
* [VIM-1858](https://youtrack.jetbrains.com/issue/VIM-1858) Fix imap for autocomplete
|
||||
* [VIM-1362](https://youtrack.jetbrains.com/issue/VIM-1362) Search with confirm doesn't scroll down far enough
|
||||
|
||||
_To Be Released:_
|
||||
|
||||
**Fixes:**
|
||||
* [VIM-1875](https://youtrack.jetbrains.com/issue/VIM-1875) Fix `isk` in `~/.ideaivmrc`
|
||||
* [VIM-1874](https://youtrack.jetbrains.com/issue/VIM-1874) Fix `set clipboard=unnamed` execution from `~/.ideavimrc`
|
||||
* [VIM-1878](https://youtrack.jetbrains.com/issue/VIM-1878) Fix `c` command after extract method action
|
||||
* [VIM-1884](https://youtrack.jetbrains.com/issue/VIM-1884) Show quickDoc during popup with `CTRL-J`
|
||||
* [VIM-987](https://youtrack.jetbrains.com/issue/VIM-987) Fix arrow keys for the NEO keyboard
|
||||
|
||||
0.54, 2019-11-20
|
||||
--------------
|
||||
|
@@ -93,6 +93,7 @@ Supported:
|
||||
|
||||
Emulated Vim plugins:
|
||||
|
||||
* vim-easymotion
|
||||
* vim-surround
|
||||
* vim-multiple-cursors
|
||||
* vim-commentary
|
||||
@@ -128,7 +129,7 @@ have `-Duser.home=/my/alternate/home` then IdeaVim will source
|
||||
`/my/alternate/home/.ideavimrc` instead of `~/.ideavimrc`.
|
||||
|
||||
Alternatively, you can set up initialization commands using [XDG](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) standard.
|
||||
Put your settings to `$XDG_CONFIG_HOME$/ideavim/ideavimrc` file. [To Be Released]
|
||||
Put your settings to `$XDG_CONFIG_HOME$/ideavim/ideavimrc` file.
|
||||
|
||||
|
||||
Emulated Vim Plugins
|
||||
|
@@ -103,10 +103,20 @@ The following `:set` commands can appear in `~/.ideavimrc` or be set manually in
|
||||
If true, join command will be performed via IDE
|
||||
See wiki/`ideajoin` examples
|
||||
|
||||
`ideastatusbar` `ideastatusbar` Boolean (default true) [To Be Released]
|
||||
`ideastatusbar` `ideastatusbar` Boolean (default true)
|
||||
|
||||
If false, IdeaVim icon won't be shown in the status bar.
|
||||
Works only from `~/.ideavimrc` after the IDE restart.
|
||||
|
||||
`lookupkeys` `lookupkeys` List of strings
|
||||
|
||||
List of keys that should be processed by the IDE during the active lookup (autocompletion).
|
||||
For example, <Tab> and <Enter> are used by the IDE to finish the lookup,
|
||||
but <C-W> should be passed to IdeaVim.
|
||||
Default value:
|
||||
"<Tab>", "<Down>", "<Up>", "<Enter>", "<Left>", "<Right>",
|
||||
"<C-Down>", "<C-Up>", "<PageUp>", "<PageDown>",
|
||||
"<C-J>", "<C-Q>"
|
||||
|
||||
----------
|
||||
[1] - cursor keys, <End>, <Home>, <PageUp> and <PageDown>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# suppress inspection "UnusedProperty" for whole file
|
||||
|
||||
ideaVersion=2019.3
|
||||
ideaVersion=201-EAP-SNAPSHOT
|
||||
downloadIdeaSources=true
|
||||
instrumentPluginCode=true
|
||||
version=SNAPSHOT
|
||||
|
@@ -197,6 +197,8 @@
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.insert.InsertSingleCommandAction" mappingModes="I" keys="«C-O»"/>
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.insert.VisualBlockInsertAction" mappingModes="X" keys="I"/>
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.insert.VisualBlockAppendAction" mappingModes="X" keys="A"/>
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.insert.StartInsertDigraphAction" mappingModes="IC" keys="«C-K»"/>
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.insert.StartInsertLiteralAction" mappingModes="IC" keys="«C-V»,«C-Q»"/>
|
||||
|
||||
<!-- Delete -->
|
||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.delete.DeleteCharacterAction" mappingModes="N" keys="«DEL»"/>
|
@@ -3,8 +3,10 @@
|
||||
<id>IdeaVIM</id>
|
||||
<change-notes><![CDATA[
|
||||
<ul>
|
||||
<li>Fix `imap jk <ESC>` for the active autocompletion lookup</li>
|
||||
<li>Surround and Commentary extensions can be repeated with a dot command</li>
|
||||
<li>Support dot command for Surround and Commentary extensions</li>
|
||||
<li>Support XDG settings standard</li>
|
||||
<li>Add option to remove the status bar icon</li>
|
||||
<li>Various bug fixes</li>
|
||||
</ul>
|
||||
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
||||
]]></change-notes>
|
||||
@@ -29,6 +31,9 @@
|
||||
<resource-bundle xmlns="">messages</resource-bundle>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>com.maddyhome.idea.vim.DynamicLoaderStopper</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>com.maddyhome.idea.vim.VimPlugin</implementation-class>
|
||||
</component>
|
||||
@@ -45,10 +50,10 @@
|
||||
<extensionPoints>
|
||||
<extensionPoint name="vimExtension" interface="com.maddyhome.idea.vim.extension.VimExtension"/>
|
||||
|
||||
<extensionPoint name="vimExCommand" beanClass="com.maddyhome.idea.vim.ex.ExBeanClass">
|
||||
<extensionPoint name="vimExCommand" beanClass="com.maddyhome.idea.vim.ex.ExBeanClass" dynamic="true">
|
||||
<with attribute="implementation" implements="com.maddyhome.idea.vim.ex.CommandHandler"/>
|
||||
</extensionPoint>
|
||||
<extensionPoint name="vimAction" beanClass="com.maddyhome.idea.vim.handler.ActionBeanClass">
|
||||
<extensionPoint name="vimAction" beanClass="com.maddyhome.idea.vim.handler.ActionBeanClass" dynamic="true">
|
||||
<with attribute="implementation" implements="com.maddyhome.idea.vim.handler.EditorActionHandlerBase"/>
|
||||
</extensionPoint>
|
||||
</extensionPoints>
|
||||
@@ -59,11 +64,11 @@
|
||||
<statusBarWidgetProvider implementation="com.maddyhome.idea.vim.StatusBarIconProvider"/>
|
||||
</extensions>
|
||||
|
||||
<xi:include href="/META-INF/ApplicationServices.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/includes/ApplicationServices.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="/META-INF/VimActions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/VimExCommands.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/includes/VimActions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/includes/VimExCommands.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<actions>
|
||||
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction" text="Vim Emulator" description="Toggle the vim plugin On/off">
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
# Copyright (C) 2003-2019 The IdeaVim authors
|
||||
# Copyright (C) 2003-2020 The IdeaVim authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,13 +16,9 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.ex;
|
||||
package com.maddyhome.idea.vim
|
||||
|
||||
/**
|
||||
* Exception class
|
||||
* This class prevents dynamic loading of IdeaVim plugin
|
||||
*/
|
||||
public class InvalidCommandException extends ExException {
|
||||
public InvalidCommandException(String message, String cmd) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
class DynamicLoaderStopper
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -34,11 +34,8 @@ import com.intellij.openapi.editor.actionSystem.TypedActionHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.ListPopup;
|
||||
import com.maddyhome.idea.vim.action.DuplicableOperatorAction;
|
||||
import com.maddyhome.idea.vim.action.change.VimRepeater;
|
||||
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
||||
import com.maddyhome.idea.vim.action.motion.search.SearchEntryFwdAction;
|
||||
import com.maddyhome.idea.vim.action.motion.search.SearchEntryRevAction;
|
||||
import com.maddyhome.idea.vim.command.*;
|
||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
||||
import com.maddyhome.idea.vim.group.ChangeGroup;
|
||||
@@ -66,10 +63,9 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.openapi.actionSystem.CommonDataKeys.*;
|
||||
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
||||
import static com.maddyhome.idea.vim.helper.StringHelper.parseKeys;
|
||||
|
||||
/**
|
||||
* This handlers every keystroke that the user can argType except those that are still valid hotkeys for various Idea
|
||||
* This handles every keystroke that the user can argType except those that are still valid hotkeys for various Idea
|
||||
* actions. This is a singleton.
|
||||
*/
|
||||
public class KeyHandler {
|
||||
@@ -131,7 +127,7 @@ public class KeyHandler {
|
||||
ActionManager.getInstance(), 0);
|
||||
|
||||
if (action instanceof ActionGroup && !((ActionGroup)action).canBePerformed(context)) {
|
||||
// Some of the AcitonGroups should not be performed, but shown as a popup
|
||||
// Some ActionGroups should not be performed, but shown as a popup
|
||||
ListPopup popup = JBPopupFactory.getInstance()
|
||||
.createActionGroupPopup(event.getPresentation().getText(), (ActionGroup)action, context, false, null, -1);
|
||||
|
||||
@@ -147,8 +143,8 @@ public class KeyHandler {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems
|
||||
// because rider use async update method. See VIM-1819
|
||||
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems.
|
||||
// because rider use async update method. See VIM-1819.
|
||||
action.beforeActionPerformedUpdate(event);
|
||||
if (event.getPresentation().isEnabled()) {
|
||||
action.actionPerformed(event);
|
||||
@@ -158,6 +154,16 @@ public class KeyHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void startDigraphSequence(@NotNull Editor editor) {
|
||||
final CommandState editorState = CommandState.getInstance(editor);
|
||||
editorState.startDigraphSequence();
|
||||
}
|
||||
|
||||
public void startLiteralSequence(@NotNull Editor editor) {
|
||||
final CommandState editorState = CommandState.getInstance(editor);
|
||||
editorState.startLiteralSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main key handler for the Vim plugin. Every keystroke not handled directly by Idea is sent here for
|
||||
* processing.
|
||||
@@ -200,124 +206,90 @@ public class KeyHandler {
|
||||
// All the editor actions should be performed with top level editor!!!
|
||||
// Be careful: all the EditorActionHandler implementation should correctly process InjectedEditors
|
||||
editor = HelperKt.getTopLevelEditor(editor);
|
||||
|
||||
final CommandState editorState = CommandState.getInstance(editor);
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
|
||||
// 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;
|
||||
// We only record unmapped keystrokes. If we've recursed to handle mapping, don't record anything.
|
||||
boolean shouldRecord = handleKeyRecursionCount == 0 && editorState.isRecording();
|
||||
handleKeyRecursionCount++;
|
||||
|
||||
// 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 (!waitCommandFinish(editor) && allowKeyMappings && handleKeyMapping(editor, key, context)) {
|
||||
if (editorState.getMappingMode() != MappingMode.OP_PENDING ||
|
||||
currentCmd.isEmpty() ||
|
||||
currentCmd.peek().getArgument() == null ||
|
||||
Objects.requireNonNull(currentCmd.peek().getArgument()).getType() != Argument.Type.OFFSETS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Pressing delete while entering a count "removes" the last digit entered
|
||||
// Unlike the digits, this must be checked *after* checking for key mappings
|
||||
else if (isDeleteCommandCount(key, editorState)) {
|
||||
// "Remove" the last digit sent to us
|
||||
count /= 10;
|
||||
}
|
||||
else if (isEditorReset(key, editorState)) {
|
||||
handleEditorReset(editor, key, context);
|
||||
try {
|
||||
if (!allowKeyMappings || !handleKeyMapping(editor, key, context)) {
|
||||
if (isCommandCountKey(chKey, editorState)) {
|
||||
commandBuilder.addCountCharacter(chKey);
|
||||
} else if (isDeleteCommandCountKey(key, editorState)) {
|
||||
commandBuilder.deleteCountCharacter();
|
||||
} else if (isEditorReset(key, editorState)) {
|
||||
handleEditorReset(editor, key, context, editorState);
|
||||
}
|
||||
// If we got this far the user is entering a command or supplying an argument to an entered command.
|
||||
// First let's check to see if we are at the point of expecting a single character argument to a command.
|
||||
else if (currentArg == Argument.Type.CHARACTER) {
|
||||
handleCharArgument(key, chKey);
|
||||
else if (isExpectingCharArgument(commandBuilder)) {
|
||||
handleCharArgument(key, chKey, editorState);
|
||||
}
|
||||
// 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
|
||||
else {
|
||||
// For debugging purposes we track the keys entered for this command
|
||||
keys.add(key);
|
||||
// to an entered command. Let's figure out which it is.
|
||||
else if (!handleDigraph(editor, key, context, editorState)) {
|
||||
|
||||
commandBuilder.addKey(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
|
||||
Node node = editorState.getCurrentNode().get(key);
|
||||
|
||||
if (handleDigraph(editor, key, context, node)) return;
|
||||
|
||||
node = mapOpCommand(key, node, editorState);
|
||||
final Node node = mapOpCommand(key, commandBuilder.getChildNode(key), editorState);
|
||||
|
||||
if (node instanceof CommandNode) {
|
||||
handleCommandNode(editor, context, key, (CommandNode)node, editorState);
|
||||
}
|
||||
else if (node instanceof CommandPartNode) {
|
||||
editorState.setCurrentNode((CommandPartNode)node);
|
||||
}
|
||||
else {
|
||||
if (lastWasBS && lastChar != 0 && OptionsManager.INSTANCE.getDigraph().isSet()) {
|
||||
char dig = VimPlugin.getDigraph().getDigraph(lastChar, key.getKeyChar());
|
||||
key = KeyStroke.getKeyStroke(dig);
|
||||
}
|
||||
|
||||
handleCommandNode(editor, context, key, (CommandNode) node, editorState);
|
||||
} else if (node instanceof CommandPartNode) {
|
||||
commandBuilder.setCurrentCommandPartNode((CommandPartNode) node);
|
||||
} else {
|
||||
// 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.getMode() == CommandState.Mode.SELECT) {
|
||||
if (!VimPlugin.getChange().processKeyInSelectMode(editor, context, key)) {
|
||||
shouldRecord = false;
|
||||
}
|
||||
}
|
||||
else if (editorState.getMappingMode() == MappingMode.CMD_LINE) {
|
||||
if (!VimPlugin.getProcess().processExKey(editor, key)) {
|
||||
shouldRecord = false;
|
||||
}
|
||||
shouldRecord &= VimPlugin.getChange().processKey(editor, context, key);
|
||||
} else if (editorState.getMode() == CommandState.Mode.SELECT) {
|
||||
shouldRecord &= VimPlugin.getChange().processKeyInSelectMode(editor, context, key);
|
||||
} else if (editorState.getMappingState().getMappingMode() == MappingMode.CMD_LINE) {
|
||||
shouldRecord &= VimPlugin.getProcess().processExKey(editor, key);
|
||||
}
|
||||
// If we get here then the user has entered an unrecognized series of keystrokes
|
||||
else {
|
||||
state = State.BAD_COMMAND;
|
||||
commandBuilder.setCommandState(CurrentCommandState.BAD_COMMAND);
|
||||
}
|
||||
|
||||
lastChar = lastWasBS && lastChar != 0 ? 0 : key.getKeyChar();
|
||||
lastWasBS = false;
|
||||
partialReset(editor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
handleKeyRecursionCount--;
|
||||
}
|
||||
|
||||
// Do we have a fully entered command at this point? If so, lets execute it
|
||||
if (state == State.READY) {
|
||||
// Do we have a fully entered command at this point? If so, let's execute it.
|
||||
if (commandBuilder.isReady()) {
|
||||
executeCommand(editor, key, context, editorState);
|
||||
}
|
||||
else if (state == State.BAD_COMMAND) {
|
||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
|
||||
editorState.popState();
|
||||
}
|
||||
else if (commandBuilder.isBad()) {
|
||||
editorState.resetOpPending();
|
||||
VimPlugin.indicateError();
|
||||
reset(editor);
|
||||
}
|
||||
else if (isRecording && shouldRecord) {
|
||||
|
||||
// Don't record the keystroke that stops the recording (unmapped this is `q`)
|
||||
if (shouldRecord && editorState.isRecording()) {
|
||||
VimPlugin.getRegister().recordKeyStroke(key);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean waitCommandFinish(@NotNull Editor editor) {
|
||||
return !(CommandState.getInstance(editor).getCurrentNode() instanceof RootNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* See the description for {@link com.maddyhome.idea.vim.action.DuplicableOperatorAction}
|
||||
*/
|
||||
private Node mapOpCommand(KeyStroke key, Node node, @NotNull CommandState editorState) {
|
||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING && !currentCmd.empty()) {
|
||||
EditorActionHandlerBase action = currentCmd.peek().getAction();
|
||||
if (action instanceof DuplicableOperatorAction &&
|
||||
((DuplicableOperatorAction)action).getDuplicateWith() == key.getKeyChar()) {
|
||||
return editorState.getCurrentNode().get(KeyStroke.getKeyStroke('_'));
|
||||
}
|
||||
if (editorState.isDuplicateOperatorKeyStroke(key)) {
|
||||
return editorState.getCommandBuilder().getChildNode(KeyStroke.getKeyStroke('_'));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -334,8 +306,8 @@ public class KeyHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleEditorReset(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull final DataContext context) {
|
||||
if (count == 0 && currentArg == null && currentCmd.size() == 0) {
|
||||
private void handleEditorReset(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull final DataContext context, @NotNull CommandState editorState) {
|
||||
if (editorState.getCommandBuilder().isAtDefaultState()) {
|
||||
RegisterGroup register = VimPlugin.getRegister();
|
||||
if (register.getCurrentRegister() == register.getDefaultRegister()) {
|
||||
if (key.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||
@@ -352,57 +324,116 @@ public class KeyHandler {
|
||||
private boolean handleKeyMapping(@NotNull final Editor editor,
|
||||
@NotNull final KeyStroke key,
|
||||
@NotNull final DataContext context) {
|
||||
if (state == State.CHAR_OR_DIGRAPH) return false;
|
||||
|
||||
final CommandState commandState = CommandState.getInstance(editor);
|
||||
commandState.stopMappingTimer();
|
||||
final MappingState mappingState = commandState.getMappingState();
|
||||
final CommandBuilder commandBuilder = commandState.getCommandBuilder();
|
||||
|
||||
final MappingMode mappingMode = commandState.getMappingMode();
|
||||
if (commandBuilder.isAwaitingCharOrDigraphArgument()
|
||||
|| commandBuilder.isBuildingMultiKeyCommand()
|
||||
|| isMappingDisabledForKey(key, commandState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final List<KeyStroke> mappingKeys = commandState.getMappingKeys();
|
||||
final List<KeyStroke> fromKeys = new ArrayList<>(mappingKeys);
|
||||
fromKeys.add(key);
|
||||
mappingState.stopMappingTimer();
|
||||
|
||||
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;
|
||||
// Save the unhandled key strokes until we either complete or abandon the sequence.
|
||||
mappingState.addKey(key);
|
||||
|
||||
final KeyMapping mapping = VimPlugin.getKey().getKeyMapping(mappingState.getMappingMode());
|
||||
|
||||
// Returns true if any of these methods handle the key. False means that the key is unrelated to mapping and should
|
||||
// be processed as normal.
|
||||
return handleUnfinishedMappingSequence(editor, mappingState, mapping)
|
||||
|| handleCompleteMappingSequence(editor, context, commandState, mappingState, mapping, key)
|
||||
|| handleAbandonedMappingSequence(editor, mappingState, context);
|
||||
}
|
||||
|
||||
private boolean isMappingDisabledForKey(@NotNull KeyStroke key, @NotNull CommandState commandState) {
|
||||
// "0" can be mapped, but the mapping isn't applied when entering a count. Other digits are always mapped, even when
|
||||
// entering a count.
|
||||
// See `:help :map-modes`
|
||||
return key.getKeyChar() == '0' && commandState.getCommandBuilder().getCount() > 0;
|
||||
}
|
||||
|
||||
private boolean handleUnfinishedMappingSequence(@NotNull Editor editor,
|
||||
@NotNull MappingState mappingState,
|
||||
@NotNull KeyMapping mapping) {
|
||||
// Is there at least one mapping that starts with the current sequence? This does not include complete matches,
|
||||
// unless a sequence is also a prefix for another mapping. We eagerly evaluate the shortest mapping, so even if a
|
||||
// mapping is a prefix, it will get evaluated when the next character is entered.
|
||||
// Note that currentlyUnhandledKeySequence is the same as the state after commandState.getMappingKeys().add(key). It
|
||||
// would be nice to tidy ths up
|
||||
if (!mapping.isPrefix(mappingState.getKeys())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the timeout option is set, set a timer that will abandon the sequence and replay the unhandled keys unmapped.
|
||||
// Every time a key is pressed and handled, the timer is stopped. E.g. if there is a mapping for "dweri", and the
|
||||
// user has typed "dw" wait for the timeout, and then replay "d" and "w" without any mapping (which will of course
|
||||
// delete a word)
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
|
||||
if (mapping.isPrefix(fromKeys)) {
|
||||
// Okay, there is some mapping that starts with inserted key sequence. So,
|
||||
// either the user will continue to enter the mapping, or (if timeout option is set)
|
||||
// the entered command should be executed. Here we set up the times that will execute
|
||||
// typed keys after some delay.
|
||||
// E.g. there is a map for "dweri". If the user types "d", "w" they mean either "dweri" or "dw" command.
|
||||
// If the user will continue typing "e", "r" and "i", the timer will be cancelled. If the user will
|
||||
// not type anything, the "dw" command will be executed.
|
||||
mappingKeys.add(key);
|
||||
if (!application.isUnitTestMode() && OptionsManager.INSTANCE.getTimeout().isSet()) {
|
||||
commandState.startMappingTimer(actionEvent -> application.invokeLater(() -> {
|
||||
final KeyStroke firstKey = mappingKeys.get(0);
|
||||
mappingKeys.clear();
|
||||
if (editor.isDisposed() || firstKey.equals(parseKeys("<Plug>").get(0))) {
|
||||
mappingState.startMappingTimer(actionEvent -> application.invokeLater(() -> {
|
||||
|
||||
final List<KeyStroke> unhandledKeys = mappingState.detachKeys();
|
||||
|
||||
// TODO: I'm not sure why we abandon plugin commands here
|
||||
// Would be useful to have a comment or a helpfully named helper method here
|
||||
if (editor.isDisposed() || unhandledKeys.get(0).equals(StringHelper.PlugKeyStroke)) {
|
||||
return;
|
||||
}
|
||||
for (KeyStroke keyStroke : fromKeys) {
|
||||
|
||||
for (KeyStroke keyStroke : unhandledKeys) {
|
||||
handleKey(editor, keyStroke, new EditorDataContext(editor), false);
|
||||
}
|
||||
}, ModalityState.stateForComponent(editor.getComponent())));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (mappingInfo != null) {
|
||||
// Okay, there is a mapping for the entered key sequence
|
||||
// now the another key sequence should be executed, or the handler that attached to this command
|
||||
mappingKeys.clear();
|
||||
|
||||
private boolean handleCompleteMappingSequence(@NotNull Editor editor,
|
||||
@NotNull DataContext context,
|
||||
@NotNull CommandState commandState,
|
||||
@NotNull MappingState mappingState,
|
||||
@NotNull KeyMapping mapping,
|
||||
KeyStroke key) {
|
||||
|
||||
// The current sequence isn't a prefix, check to see if it's a completed sequence.
|
||||
final MappingInfo currentMappingInfo = mapping.get(mappingState.getKeys());
|
||||
MappingInfo mappingInfo = currentMappingInfo;
|
||||
if (mappingInfo == null) {
|
||||
// It's an abandoned sequence, check to see if the previous sequence was a complete sequence.
|
||||
// TODO: This is incorrect behaviour
|
||||
// What about sequences that were completed N keys ago?
|
||||
// This should really be handled as part of an abandoned key sequence. We should also consolidate the replay
|
||||
// of cached keys - this happens in timeout, here and also in abandoned sequences.
|
||||
// Extract most of this method into handleMappingInfo. If we have a complete sequence, call it and we're done.
|
||||
// If it's not a complete sequence, handleAbandonedMappingSequence should do something like call
|
||||
// mappingState.detachKeys and look for the longest complete sequence in the returned list, evaluate it, and then
|
||||
// replay any keys not yet handled. NB: The actual implementation should be compared to Vim behaviour to see what
|
||||
// should actually happen.
|
||||
final ArrayList<KeyStroke> previouslyUnhandledKeySequence = new ArrayList<>();
|
||||
mappingState.getKeys().forEach(previouslyUnhandledKeySequence::add);
|
||||
if (previouslyUnhandledKeySequence.size() > 1) {
|
||||
previouslyUnhandledKeySequence.remove(previouslyUnhandledKeySequence.size() - 1);
|
||||
mappingInfo = mapping.get(previouslyUnhandledKeySequence);
|
||||
}
|
||||
}
|
||||
|
||||
if (mappingInfo == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mappingState.resetMappingSequence();
|
||||
|
||||
final EditorDataContext currentContext = new EditorDataContext(editor);
|
||||
|
||||
final List<KeyStroke> toKeys = mappingInfo.getToKeys();
|
||||
final VimExtensionHandler extensionHandler = mappingInfo.getExtensionHandler();
|
||||
final EditorDataContext currentContext = new EditorDataContext(editor);
|
||||
|
||||
if (toKeys != null) {
|
||||
// Here is a mapping to another key sequence
|
||||
final boolean fromIsPrefix = isPrefix(mappingInfo.getFromKeys(), toKeys);
|
||||
boolean first = true;
|
||||
for (KeyStroke keyStroke : toKeys) {
|
||||
@@ -412,15 +443,20 @@ public class KeyHandler {
|
||||
}
|
||||
}
|
||||
else if (extensionHandler != null) {
|
||||
// Here is a mapping to some vim handler
|
||||
final CommandProcessor processor = CommandProcessor.getInstance();
|
||||
final boolean isPendingMode = CommandState.getInstance(editor).getMappingMode() == MappingMode.OP_PENDING;
|
||||
|
||||
// Cache isOperatorPending in case the extension changes the mode while moving the caret
|
||||
// See CommonExtensionTest
|
||||
// TODO: Is this legal? Should we assert in this case?
|
||||
final boolean shouldCalculateOffsets = commandState.isOperatorPending();
|
||||
|
||||
Map<Caret, Integer> startOffsets =
|
||||
editor.getCaretModel().getAllCarets().stream().collect(Collectors.toMap(Function.identity(), Caret::getOffset));
|
||||
|
||||
if (extensionHandler.isRepeatable()) {
|
||||
VimRepeater.Extension.INSTANCE.clean();
|
||||
}
|
||||
|
||||
processor.executeCommand(editor.getProject(), () -> extensionHandler.execute(editor, context),
|
||||
"Vim " + extensionHandler.getClass().getSimpleName(), null);
|
||||
|
||||
@@ -429,9 +465,8 @@ public class KeyHandler {
|
||||
VimRepeater.Extension.INSTANCE.setArgumentCaptured(null);
|
||||
VimRepeater.INSTANCE.setRepeatHandler(true);
|
||||
}
|
||||
if (isPendingMode &&
|
||||
!currentCmd.isEmpty() &&
|
||||
currentCmd.peek().getArgument() == null) {
|
||||
|
||||
if (shouldCalculateOffsets && !commandState.getCommandBuilder().hasCurrentCommandPartArgument()) {
|
||||
Map<Caret, VimSelection> offsets = new HashMap<>();
|
||||
|
||||
for (Caret caret : editor.getCaretModel().getAllCarets()) {
|
||||
@@ -441,7 +476,7 @@ public class KeyHandler {
|
||||
.create(UserDataManager.getVimSelectionStart(caret), caret.getOffset(),
|
||||
SelectionType.fromSubMode(CommandStateHelper.getSubMode(editor)), editor);
|
||||
offsets.put(caret, vimSelection);
|
||||
commandState.popState();
|
||||
commandState.popModes();
|
||||
}
|
||||
else if (startOffset != null && startOffset != caret.getOffset()) {
|
||||
// Command line motions are always characterwise exclusive
|
||||
@@ -464,76 +499,85 @@ public class KeyHandler {
|
||||
}
|
||||
|
||||
if (!offsets.isEmpty()) {
|
||||
currentCmd.peek().setArgument(new Argument(offsets));
|
||||
state = State.READY;
|
||||
commandState.getCommandBuilder().completeCommandPart(new Argument(offsets));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NB: mappingInfo MUST be non-null here, so if equal
|
||||
// then prevMappingInfo is also non-null; this also
|
||||
// means that the prev mapping was a prefix, but the
|
||||
// next key typed (`key`) was not part of that
|
||||
if (prevMappingInfo == mappingInfo) {
|
||||
handleKey(editor, key, currentContext);
|
||||
// If we've just evaluated the previous key sequence, make sure to also handle the current key
|
||||
if (mappingInfo != currentMappingInfo) {
|
||||
handleKey(editor, key, currentContext, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// If the user enters a command that starts with known mapping, but it is not exactly this mapping,
|
||||
// mapping handler prevents further processing of there keys.
|
||||
// E.g. if there is a mapping for "hello" and user enters command "help"
|
||||
// the processing of "h", "e" and "l" will be prevented by this handler.
|
||||
// However, these keys should be processed as usual when user enters "p"
|
||||
// and the following for loop does exactly that.
|
||||
//
|
||||
|
||||
private boolean handleAbandonedMappingSequence(@NotNull Editor editor,
|
||||
@NotNull MappingState mappingState,
|
||||
DataContext context) {
|
||||
|
||||
// The user has terminated a mapping sequence with an unexpected key
|
||||
// E.g. if there is a mapping for "hello" and user enters command "help" the processing of "h", "e" and "l" will be
|
||||
// prevented by this handler. Make sure the currently unhandled keys are processed as normal.
|
||||
|
||||
final List<KeyStroke> unhandledKeyStrokes = mappingState.detachKeys();
|
||||
|
||||
// If there is only the current key to handle, do nothing
|
||||
if (unhandledKeyStrokes.size() == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Okay, look at the code below. Why is the first key handled separately?
|
||||
// Let's assume the next mappings:
|
||||
// - map ds j
|
||||
// - map I 2l
|
||||
// If user enters `dI`, the first `d` will be caught be this handler because it's a prefix for `ds` command.
|
||||
// After the user enters `I`, the caught `d` should be processed without mapping and the rest of keys
|
||||
// After the user enters `I`, the caught `d` should be processed without mapping, and the rest of keys
|
||||
// should be processed with mappings (to make I work)
|
||||
//
|
||||
// Additionally, the <Plug>mappings are not executed if the are failed to map to somethings.
|
||||
// Additionally, the <Plug>mappings are not executed if the fail to map to something.
|
||||
// E.g.
|
||||
// - map <Plug>iA someAction
|
||||
// - map I <Plug>i
|
||||
// For `IA` someAction should be executed.
|
||||
// But if the user types `Ib`, `<Plug>i` won't be executed again. Only `b` will be passed to keyHandler.
|
||||
if (mappingKeys.isEmpty()) return false;
|
||||
|
||||
// Well, this will always be false, but just for protection
|
||||
if (fromKeys.isEmpty()) return false;
|
||||
final List<KeyStroke> unhandledKeys = new ArrayList<>(fromKeys);
|
||||
mappingKeys.clear();
|
||||
|
||||
if (unhandledKeys.get(0).equals(parseKeys("<Plug>").get(0))) {
|
||||
handleKey(editor, unhandledKeys.get(unhandledKeys.size() - 1), context);
|
||||
if (unhandledKeyStrokes.get(0).equals(StringHelper.PlugKeyStroke)) {
|
||||
handleKey(editor, unhandledKeyStrokes.get(unhandledKeyStrokes.size() - 1), context, true);
|
||||
} else {
|
||||
handleKey(editor, unhandledKeys.get(0), context, false);
|
||||
for (KeyStroke keyStroke : unhandledKeys.subList(1, unhandledKeys.size())) {
|
||||
handleKey(editor, unhandledKeyStrokes.get(0), context, false);
|
||||
|
||||
for (KeyStroke keyStroke : unhandledKeyStrokes.subList(1, unhandledKeyStrokes.size())) {
|
||||
handleKey(editor, keyStroke, context, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isCommandCountKey(char chKey, @NotNull CommandState editorState) {
|
||||
// Make sure to avoid handling '0' as the start of a count.
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL)
|
||||
&& commandBuilder.isExpectingCount() && Character.isDigit(chKey) && (commandBuilder.getCount() > 0 || chKey != '0');
|
||||
}
|
||||
|
||||
private boolean isDeleteCommandCount(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
||||
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL) &&
|
||||
state == State.NEW_COMMAND &&
|
||||
currentArg != Argument.Type.CHARACTER &&
|
||||
currentArg != Argument.Type.DIGRAPH &&
|
||||
key.getKeyCode() == KeyEvent.VK_DELETE &&
|
||||
count != 0;
|
||||
private boolean isDeleteCommandCountKey(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
||||
// See `:help N<Del>`
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL)
|
||||
&& commandBuilder.isExpectingCount() && commandBuilder.getCount() > 0 && key.getKeyCode() == KeyEvent.VK_DELETE;
|
||||
}
|
||||
|
||||
private boolean isEditorReset(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
||||
return (editorState.getMode() == CommandState.Mode.COMMAND) && StringHelper.isCloseKeyStroke(key);
|
||||
}
|
||||
|
||||
private void handleCharArgument(@NotNull KeyStroke key, char chKey) {
|
||||
private boolean isExpectingCharArgument(@NotNull CommandBuilder commandBuilder) {
|
||||
return commandBuilder.getExpectedArgumentType() == Argument.Type.CHARACTER;
|
||||
}
|
||||
|
||||
private void handleCharArgument(@NotNull KeyStroke key, char chKey, @NotNull CommandState commandState) {
|
||||
// We are expecting a character argument - is this a regular character the user typed?
|
||||
// Some special keys can be handled as character arguments - let's check for them here.
|
||||
if (chKey == 0) {
|
||||
@@ -547,57 +591,64 @@ public class KeyHandler {
|
||||
}
|
||||
}
|
||||
|
||||
final CommandBuilder commandBuilder = commandState.getCommandBuilder();
|
||||
if (chKey != 0) {
|
||||
// Create the character argument, add it to the current command, and signal we are ready to process
|
||||
// the command
|
||||
Argument arg = new Argument(chKey);
|
||||
Command cmd = currentCmd.peek();
|
||||
cmd.setArgument(arg);
|
||||
state = State.READY;
|
||||
// Create the character argument, add it to the current command, and signal we are ready to process the command
|
||||
commandBuilder.completeCommandPart(new Argument(chKey));
|
||||
}
|
||||
else {
|
||||
// Oops - this isn't a valid character argument
|
||||
state = State.BAD_COMMAND;
|
||||
commandBuilder.setCommandState(CurrentCommandState.BAD_COMMAND);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCommandCount(@NotNull CommandState editorState, char chKey) {
|
||||
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL) &&
|
||||
state == State.NEW_COMMAND &&
|
||||
currentArg != Argument.Type.CHARACTER &&
|
||||
currentArg != Argument.Type.DIGRAPH &&
|
||||
Character.isDigit(chKey) &&
|
||||
(count != 0 || chKey != '0');
|
||||
}
|
||||
|
||||
private boolean handleDigraph(@NotNull Editor editor,
|
||||
@NotNull KeyStroke key,
|
||||
@NotNull DataContext context,
|
||||
@Nullable Node node) {
|
||||
if (digraph == null && !(node instanceof CommandNode) && DigraphSequence.isDigraphStart(key)) {
|
||||
digraph = new DigraphSequence();
|
||||
@NotNull CommandState editorState) {
|
||||
|
||||
// Support starting a digraph/literal sequence if the operator accepts one as an argument, e.g. 'r' or 'f'.
|
||||
// Normally, we start the sequence (in Insert or CmdLine mode) through a VimAction that can be mapped. Our
|
||||
// VimActions don't work as arguments for operators, so we have to special case here. Helpfully, Vim appears to
|
||||
// hardcode the shortcuts, and doesn't support mapping, so everything works nicely.
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
if (commandBuilder.getExpectedArgumentType() == Argument.Type.DIGRAPH) {
|
||||
if (DigraphSequence.isDigraphStart(key)) {
|
||||
editorState.startDigraphSequence();
|
||||
return true;
|
||||
}
|
||||
if (digraph != null) {
|
||||
DigraphSequence.DigraphResult res = digraph.processKey(key, editor);
|
||||
if (DigraphSequence.isLiteralStart(key)) {
|
||||
editorState.startLiteralSequence();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
DigraphResult res = editorState.processDigraphKey(key, editor);
|
||||
switch (res.getResult()) {
|
||||
case DigraphSequence.DigraphResult.RES_OK:
|
||||
case DigraphResult.RES_HANDLED:
|
||||
case DigraphResult.RES_BAD:
|
||||
return true;
|
||||
case DigraphSequence.DigraphResult.RES_BAD:
|
||||
digraph = null;
|
||||
return true;
|
||||
case DigraphSequence.DigraphResult.RES_DONE:
|
||||
if (currentArg == Argument.Type.DIGRAPH) {
|
||||
currentArg = Argument.Type.CHARACTER;
|
||||
|
||||
case DigraphResult.RES_DONE:
|
||||
if (commandBuilder.getExpectedArgumentType() == Argument.Type.DIGRAPH) {
|
||||
commandBuilder.fallbackToCharacterArgument();
|
||||
}
|
||||
digraph = null;
|
||||
final KeyStroke stroke = res.getStroke();
|
||||
if (stroke == null) {
|
||||
return false;
|
||||
}
|
||||
handleKey(editor, stroke, context);
|
||||
return true;
|
||||
|
||||
case DigraphResult.RES_UNHANDLED:
|
||||
if (commandBuilder.getExpectedArgumentType() == Argument.Type.DIGRAPH) {
|
||||
commandBuilder.fallbackToCharacterArgument();
|
||||
handleKey(editor, key, context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -605,58 +656,28 @@ public class KeyHandler {
|
||||
@NotNull KeyStroke key,
|
||||
@NotNull DataContext context,
|
||||
@NotNull CommandState editorState) {
|
||||
// Let's go through the command stack and merge it all into one command. At this time there should never
|
||||
// be more than two commands on the stack - one is the actual command and the other would be a motion
|
||||
// command argument needed by the first command
|
||||
Command cmd = currentCmd.pop();
|
||||
while (currentCmd.size() > 0) {
|
||||
Command top = currentCmd.pop();
|
||||
top.setArgument(new Argument(cmd));
|
||||
cmd = top;
|
||||
}
|
||||
|
||||
// If we have a command and a motion command argument, both could possibly have their own counts. We
|
||||
// need to adjust the counts so the motion gets the product of both counts and the count associated with
|
||||
// the command gets reset. Example 3c2w (change 2 words, three times) becomes c6w (change 6 words)
|
||||
final Argument arg = cmd.getArgument();
|
||||
if (arg != null && arg.getType() == Argument.Type.MOTION) {
|
||||
final Command mot = arg.getMotion();
|
||||
// If no count was entered for either command then nothing changes. If either had a count then
|
||||
// the motion gets the product of both.
|
||||
int cnt = cmd.getRawCount() == 0 && mot.getRawCount() == 0 ? 0 : cmd.getCount() * mot.getCount();
|
||||
mot.setCount(cnt);
|
||||
cmd.setCount(0);
|
||||
}
|
||||
final Command command = editorState.getCommandBuilder().buildCommand();
|
||||
|
||||
// If we were in "operator pending" mode, reset back to normal mode.
|
||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
|
||||
editorState.popState();
|
||||
}
|
||||
editorState.resetOpPending();
|
||||
|
||||
// Save off the command we are about to execute
|
||||
editorState.setCommand(cmd);
|
||||
|
||||
if (lastChar != 0 && !lastWasBS) {
|
||||
lastWasBS = key.equals(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0));
|
||||
}
|
||||
else {
|
||||
lastChar = 0;
|
||||
}
|
||||
editorState.setExecutingCommand(command);
|
||||
|
||||
Project project = editor.getProject();
|
||||
final Command.Type type = cmd.getType();
|
||||
final Command.Type type = command.getType();
|
||||
if (type.isWrite() && !editor.getDocument().isWritable()) {
|
||||
VimPlugin.indicateError();
|
||||
reset(editor);
|
||||
}
|
||||
|
||||
if (!cmd.getFlags().contains(CommandFlags.FLAG_TYPEAHEAD_SELF_MANAGE)) {
|
||||
if (!command.getFlags().contains(CommandFlags.FLAG_TYPEAHEAD_SELF_MANAGE)) {
|
||||
IdeEventQueue.getInstance().flushDelayedKeyEvents();
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
Runnable action = new ActionRunner(editor, context, cmd, key);
|
||||
EditorActionHandlerBase cmdAction = cmd.getAction();
|
||||
Runnable action = new ActionRunner(editor, context, command, key);
|
||||
EditorActionHandlerBase cmdAction = command.getAction();
|
||||
String name = cmdAction.getId();
|
||||
|
||||
if (type.isWrite()) {
|
||||
@@ -676,40 +697,50 @@ public class KeyHandler {
|
||||
KeyStroke key,
|
||||
@NotNull CommandNode node,
|
||||
CommandState editorState) {
|
||||
// The user entered a valid command. Create the command and add it to the stack
|
||||
final EditorActionHandlerBase myAction = node.getActionHolder().getAction();
|
||||
Command cmd = new Command(count, myAction, myAction.getType(), myAction.getFlags(), keys);
|
||||
currentCmd.push(cmd);
|
||||
// The user entered a valid command. Create the command and add it to the stack.
|
||||
final EditorActionHandlerBase action = node.getActionHolder().getAction();
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
final Argument.Type expectedArgumentType = commandBuilder.getExpectedArgumentType();
|
||||
|
||||
if (currentArg != null && !checkArgumentCompatibility(node)) return;
|
||||
commandBuilder.pushCommandPart(action);
|
||||
|
||||
if (myAction.getArgumentType() == null || stopMacroRecord(node, editorState)) {
|
||||
state = State.READY;
|
||||
if (!checkArgumentCompatibility(expectedArgumentType, action)) {
|
||||
commandBuilder.setCommandState(CurrentCommandState.BAD_COMMAND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.getArgumentType() == null || stopMacroRecord(node, editorState)) {
|
||||
commandBuilder.setCommandState(CurrentCommandState.READY);
|
||||
}
|
||||
else {
|
||||
currentArg = myAction.getArgumentType();
|
||||
startWaitingForArgument(editor, context, key.getKeyChar(), currentArg, editorState, myAction);
|
||||
final Argument.Type argumentType = action.getArgumentType();
|
||||
startWaitingForArgument(editor, context, key.getKeyChar(), argumentType, editorState);
|
||||
partialReset(editor);
|
||||
}
|
||||
|
||||
// TODO In the name of God, get rid of EX_STRING, FLAG_COMPLETE_EX and all the related staff
|
||||
if (currentArg == Argument.Type.EX_STRING && myAction.getFlags().contains(CommandFlags.FLAG_COMPLETE_EX)) {
|
||||
EditorActionHandlerBase action;
|
||||
if (forwardSearch) {
|
||||
action = new SearchEntryFwdAction();
|
||||
}
|
||||
else {
|
||||
action = new SearchEntryRevAction();
|
||||
}
|
||||
if (expectedArgumentType == Argument.Type.EX_STRING && action.getFlags().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").
|
||||
*/
|
||||
String text = VimPlugin.getProcess().endSearchCommand(editor);
|
||||
currentCmd.pop();
|
||||
|
||||
Argument arg = new Argument(text);
|
||||
cmd = new Command(count, action, action.getType(), action.getFlags(), keys);
|
||||
cmd.setArgument(arg);
|
||||
currentCmd.push(cmd);
|
||||
CommandState.getInstance(editor).popState();
|
||||
commandBuilder.popCommandPart(); // Pop ProcessExEntryAction
|
||||
commandBuilder.completeCommandPart(new Argument(text)); // Set search text on SearchEntry(Fwd|Rev)Action
|
||||
editorState.popModes(); // Pop CMD_LINE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -721,38 +752,27 @@ public class KeyHandler {
|
||||
DataContext context,
|
||||
char key,
|
||||
@NotNull Argument.Type argument,
|
||||
CommandState editorState,
|
||||
EditorActionHandlerBase action) {
|
||||
CommandState editorState) {
|
||||
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||
switch (argument) {
|
||||
case CHARACTER:
|
||||
case DIGRAPH:
|
||||
digraph = new DigraphSequence();
|
||||
state = State.CHAR_OR_DIGRAPH;
|
||||
break;
|
||||
case MOTION:
|
||||
if (CommandState.getInstance(editor).isDotRepeatInProgress() && VimRepeater.Extension.INSTANCE.getArgumentCaptured() != null) {
|
||||
currentCmd.peek().setArgument(VimRepeater.Extension.INSTANCE.getArgumentCaptured());
|
||||
state = State.READY;
|
||||
if (editorState.isDotRepeatInProgress() && VimRepeater.Extension.INSTANCE.getArgumentCaptured() != null) {
|
||||
commandBuilder.completeCommandPart(VimRepeater.Extension.INSTANCE.getArgumentCaptured());
|
||||
}
|
||||
editorState.pushState(editorState.getMode(), editorState.getSubMode(), MappingMode.OP_PENDING);
|
||||
editorState.pushModes(editorState.getMode(), CommandState.SubMode.OP_PENDING);
|
||||
break;
|
||||
case EX_STRING:
|
||||
forwardSearch = !(action instanceof SearchEntryRevAction);
|
||||
|
||||
VimPlugin.getProcess().startSearchCommand(editor, context, count, key);
|
||||
state = State.NEW_COMMAND;
|
||||
editorState.pushState(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE, MappingMode.CMD_LINE);
|
||||
currentCmd.pop();
|
||||
// The current Command expects an EX_STRING argument. E.g. SearchEntry(Fwd|Rev)Action. This won't execute until
|
||||
// state hits READY. Start the ex input field, push CMD_LINE mode and wait for the argument.
|
||||
VimPlugin.getProcess().startSearchCommand(editor, context, commandBuilder.getCount(), key);
|
||||
commandBuilder.setCommandState(CurrentCommandState.NEW_COMMAND);
|
||||
editorState.pushModes(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkArgumentCompatibility(@NotNull CommandNode node) {
|
||||
if (currentArg == Argument.Type.MOTION &&
|
||||
node.getActionHolder().getAction().getType() != Command.Type.MOTION) {
|
||||
state = State.BAD_COMMAND;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
private boolean checkArgumentCompatibility(@Nullable Argument.Type expectedArgumentType, @NotNull EditorActionHandlerBase action) {
|
||||
return !(expectedArgumentType == Argument.Type.MOTION && action.getType() != Command.Type.MOTION);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -774,25 +794,25 @@ public class KeyHandler {
|
||||
* @param editor The editor to reset.
|
||||
*/
|
||||
public void partialReset(@Nullable Editor editor) {
|
||||
count = 0;
|
||||
keys = new ArrayList<>();
|
||||
CommandState editorState = CommandState.getInstance(editor);
|
||||
editorState.stopMappingTimer();
|
||||
editorState.getMappingKeys().clear();
|
||||
editorState.setCurrentNode(VimPlugin.getKey().getKeyRoot(editorState.getMappingMode()));
|
||||
editorState.getMappingState().resetMappingSequence();
|
||||
editorState.getCommandBuilder().resetInProgressCommandPart(getKeyRoot(editorState.getMappingState().getMappingMode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of this handler. Does a partial reset then resets the mode, the command, and the argument
|
||||
* Resets the state of this handler. Does a partial reset then resets the mode, the command, and the argument.
|
||||
*
|
||||
* @param editor The editor to reset.
|
||||
*/
|
||||
public void reset(@Nullable Editor editor) {
|
||||
partialReset(editor);
|
||||
state = State.NEW_COMMAND;
|
||||
currentCmd.clear();
|
||||
currentArg = null;
|
||||
digraph = null;
|
||||
CommandState editorState = CommandState.getInstance(editor);
|
||||
editorState.getCommandBuilder().resetAll(getKeyRoot(editorState.getMappingState().getMappingMode()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CommandPartNode getKeyRoot(MappingMode mappingMode) {
|
||||
return VimPlugin.getKey().getKeyRoot(mappingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -805,8 +825,6 @@ public class KeyHandler {
|
||||
VimPlugin.clearError();
|
||||
CommandState.getInstance(editor).reset();
|
||||
reset(editor);
|
||||
lastChar = 0;
|
||||
lastWasBS = false;
|
||||
VimPlugin.getRegister().resetRegister();
|
||||
if (editor != null) {
|
||||
VisualGroupKt.updateCaretState(editor);
|
||||
@@ -836,10 +854,12 @@ public class KeyHandler {
|
||||
|
||||
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
||||
private final static class DialogAwareDataContext implements DataContext {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, PSI_FILE};
|
||||
private final Map<String, Object> values = new HashMap<>();
|
||||
|
||||
DialogAwareDataContext(DataContext context) {
|
||||
//noinspection rawtypes
|
||||
for (DataKey key : keys) {
|
||||
values.put(key.getName(), key.getData(context));
|
||||
}
|
||||
@@ -874,17 +894,17 @@ public class KeyHandler {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandState editorState = CommandState.getInstance(editor);
|
||||
boolean wasRecording = editorState.isRecording();
|
||||
|
||||
KeyHandler.getInstance().state = State.NEW_COMMAND;
|
||||
editorState.getCommandBuilder().setCommandState(CurrentCommandState.NEW_COMMAND);
|
||||
|
||||
executeVimAction(editor, cmd.getAction(), context);
|
||||
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
|
||||
VimPlugin.getChange().processCommand(editor, cmd);
|
||||
}
|
||||
|
||||
// Now that the command has been executed let's clean up a few things.
|
||||
// Now the command has been executed let's clean up a few things.
|
||||
|
||||
// By default the "empty" register is used by all commands so we want to reset whatever the last register
|
||||
// By default, the "empty" register is used by all commands, so we want to reset whatever the last register
|
||||
// selected by the user was to the empty register - unless we just executed the "select register" command.
|
||||
if (cmd.getType() != Command.Type.SELECT_REGISTER) {
|
||||
VimPlugin.getRegister().resetRegister();
|
||||
@@ -896,14 +916,10 @@ public class KeyHandler {
|
||||
// "select register"
|
||||
if (editorState.getSubMode() == CommandState.SubMode.SINGLE_COMMAND &&
|
||||
(!cmd.getFlags().contains(CommandFlags.FLAG_EXPECT_MORE))) {
|
||||
editorState.popState();
|
||||
editorState.popModes();
|
||||
}
|
||||
|
||||
KeyHandler.getInstance().reset(editor);
|
||||
|
||||
if (wasRecording && editorState.isRecording()) {
|
||||
VimPlugin.getRegister().recordKeyStroke(key);
|
||||
}
|
||||
}
|
||||
|
||||
private final Editor editor;
|
||||
@@ -912,27 +928,8 @@ public class KeyHandler {
|
||||
private final KeyStroke key;
|
||||
}
|
||||
|
||||
private enum State {
|
||||
/** Awaiting a new command */
|
||||
NEW_COMMAND,
|
||||
// TODO This should be probably processed in some better way
|
||||
/** Awaiting for char or digraph input. In this mode mappings doesn't work (even for <C-K>) */
|
||||
CHAR_OR_DIGRAPH,
|
||||
READY,
|
||||
BAD_COMMAND
|
||||
}
|
||||
|
||||
private int count;
|
||||
private List<KeyStroke> keys = new ArrayList<>();
|
||||
private State state = State.NEW_COMMAND;
|
||||
@NotNull private final Stack<Command> currentCmd = new Stack<>();
|
||||
@Nullable private Argument.Type currentArg;
|
||||
private TypedActionHandler origHandler;
|
||||
@Nullable private DigraphSequence digraph = null;
|
||||
private char lastChar;
|
||||
private boolean lastWasBS;
|
||||
|
||||
private boolean forwardSearch = true;
|
||||
private int handleKeyRecursionCount = 0;
|
||||
|
||||
private static KeyHandler instance;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -17,11 +17,12 @@
|
||||
*/
|
||||
package com.maddyhome.idea.vim;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointListener;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.PluginDescriptor;
|
||||
import com.maddyhome.idea.vim.group.KeyGroup;
|
||||
import com.maddyhome.idea.vim.handler.ActionBeanClass;
|
||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
||||
import com.maddyhome.idea.vim.key.Shortcut;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -32,17 +33,41 @@ public class RegisterActions {
|
||||
|
||||
public static final ExtensionPointName<ActionBeanClass> VIM_ACTIONS_EP =
|
||||
ExtensionPointName.create("IdeaVIM.vimAction");
|
||||
private static boolean actionsRegistered = false;
|
||||
private static boolean initialRegistration = false;
|
||||
|
||||
static {
|
||||
// IdeaVim doesn't support contribution to VIM_ACTIONS_EP extension point, so technically we can skip this update,
|
||||
// but let's support dynamic plugins in a more classic way and reload actions on every EP change.
|
||||
// TODO: [VERSION UPDATE] since 191 use
|
||||
// ExtensionPoint.addExtensionPointListener(ExtensionPointListener<T>, boolean, Disposable)
|
||||
// TODO: [VERSION UPDATE] since 201 use
|
||||
// ExtensionPoint.addExtensionPointListener(ExtensionPointChangeListener, boolean, Disposable)
|
||||
VIM_ACTIONS_EP.getPoint(null).addExtensionPointListener(new ExtensionPointListener<ActionBeanClass>() {
|
||||
@Override
|
||||
public void extensionAdded(@NotNull ActionBeanClass extension, @NotNull PluginDescriptor pluginDescriptor) {
|
||||
// Suppress listener before the `VimPlugin.turnOn()` function execution. This logic should be rewritten after
|
||||
// version update (or earlier).
|
||||
if (!initialRegistration) return;
|
||||
unregisterActions();
|
||||
registerActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extensionRemoved(@NotNull ActionBeanClass extension, @NotNull PluginDescriptor pluginDescriptor) {
|
||||
if (!initialRegistration) return;
|
||||
unregisterActions();
|
||||
registerActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all the key/action mappings for the plugin.
|
||||
*/
|
||||
static void registerActions() {
|
||||
if (actionsRegistered) return;
|
||||
actionsRegistered = true;
|
||||
|
||||
registerVimCommandActions();
|
||||
registerEmptyShortcuts();
|
||||
initialRegistration = true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -58,6 +83,10 @@ public class RegisterActions {
|
||||
return action;
|
||||
}
|
||||
|
||||
public static void unregisterActions() {
|
||||
VimPlugin.getKey().unregisterCommandActions();
|
||||
}
|
||||
|
||||
private static void registerVimCommandActions() {
|
||||
KeyGroup parser = VimPlugin.getKey();
|
||||
VIM_ACTIONS_EP.extensions().forEach(parser::registerCommandAction);
|
||||
@@ -66,12 +95,8 @@ public class RegisterActions {
|
||||
private static void registerEmptyShortcuts() {
|
||||
final KeyGroup parser = VimPlugin.getKey();
|
||||
|
||||
// Digraph shortcuts are handled directly by KeyHandler#handleKey, so they don't have an action. But we still need to
|
||||
// register the shortcuts or the editor will swallow them. Technically, the shortcuts will be registered as part of
|
||||
// other commands, but it's best to be explicit
|
||||
parser.registerShortcutWithoutAction(new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_K, KeyEvent.CTRL_MASK)));
|
||||
parser.registerShortcutWithoutAction(new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_MASK)));
|
||||
parser.registerShortcutWithoutAction(new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_MASK)));
|
||||
parser.registerShortcutWithoutAction(new Shortcut(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0)));
|
||||
// The {char1} <BS> {char2} shortcut is handled directly by KeyHandler#handleKey, so doesn't have an action. But we
|
||||
// still need to register the shortcut, to make sure the editor doesn't swallow it.
|
||||
parser.registerShortcutWithoutAction(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0));
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim
|
||||
|
||||
import com.intellij.ide.BrowserUtil
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -33,6 +33,7 @@ import org.jdom.Element
|
||||
Storage("\$APP_CONFIG$$/vim_local_settings.xml", roamingType = RoamingType.DISABLED, deprecated = true),
|
||||
Storage("\$APP_CONFIG$/vim_local_settings.xml", roamingType = RoamingType.DISABLED)
|
||||
])
|
||||
// TODO: 27.01.2020 [VERSION UPDATE] 2019.3 https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_services.html#light-services
|
||||
class VimLocalConfig : PersistentStateComponent<Element> {
|
||||
override fun getState(): Element {
|
||||
val element = Element("ideavim-local")
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -84,6 +84,7 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
||||
private static long lastBeepTimeMillis;
|
||||
|
||||
private boolean error = false;
|
||||
private String message = null;
|
||||
|
||||
private int previousStateVersion = 0;
|
||||
private String previousKeyMap = "";
|
||||
@@ -330,6 +331,8 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
||||
}
|
||||
|
||||
public static void setEnabled(final boolean enabled) {
|
||||
if (isEnabled() == enabled) return;
|
||||
|
||||
if (!enabled) {
|
||||
getInstance().turnOffPlugin();
|
||||
}
|
||||
@@ -347,6 +350,10 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
||||
return getInstance().error;
|
||||
}
|
||||
|
||||
public static String getMessage() {
|
||||
return getInstance().message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate to the user that an error has occurred. Just beep.
|
||||
*/
|
||||
@@ -375,6 +382,9 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
||||
}
|
||||
|
||||
public static void showMessage(@Nullable String msg) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
getInstance().message = msg;
|
||||
}
|
||||
ProjectManager pm = ProjectManager.getInstance();
|
||||
Project[] projects = pm.getOpenProjects();
|
||||
for (Project project : projects) {
|
||||
@@ -418,6 +428,12 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
||||
private void turnOffPlugin() {
|
||||
KeyHandler.getInstance().fullReset(null);
|
||||
|
||||
// Unregister vim actions in command mode
|
||||
RegisterActions.unregisterActions();
|
||||
|
||||
// Unregister ex handlers
|
||||
CommandParser.getInstance().unregisterHandlers();
|
||||
|
||||
getEditor().turnOff();
|
||||
getSearch().turnOff();
|
||||
VimListenerManager.INSTANCE.turnOff();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim
|
||||
|
||||
import org.jdom.Element
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.action
|
||||
|
||||
import javax.swing.KeyStroke
|
||||
|
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.maddyhome.idea.vim.action
|
||||
|
||||
/**
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -34,7 +34,6 @@ import com.intellij.openapi.util.Key
|
||||
import com.intellij.ui.KeyStrokeAdapter
|
||||
import com.maddyhome.idea.vim.KeyHandler
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase.Companion.parseKeysSet
|
||||
import com.maddyhome.idea.vim.helper.EditorDataContext
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
import com.maddyhome.idea.vim.helper.StringHelper
|
||||
@@ -42,7 +41,7 @@ import com.maddyhome.idea.vim.helper.inInsertMode
|
||||
import com.maddyhome.idea.vim.helper.inNormalMode
|
||||
import com.maddyhome.idea.vim.key.ShortcutOwner
|
||||
import com.maddyhome.idea.vim.listener.IdeaSpecifics.aceJumpActive
|
||||
import com.maddyhome.idea.vim.option.OptionsManager.lookupKeys
|
||||
import com.maddyhome.idea.vim.option.OptionsManager
|
||||
import java.awt.event.InputEvent
|
||||
import java.awt.event.KeyEvent
|
||||
import javax.swing.KeyStroke
|
||||
@@ -90,7 +89,7 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
||||
if (aceJumpActive()) return false
|
||||
val keyCode = keyStroke.keyCode
|
||||
if (LookupManager.getActiveLookup(editor) != null) {
|
||||
return isEnabledForLookup(keyStroke)
|
||||
return LookupKeys.isEnabledForLookup(keyStroke)
|
||||
}
|
||||
if (keyCode == KeyEvent.VK_ESCAPE) {
|
||||
return isEnabledForEscape(editor)
|
||||
@@ -136,29 +135,6 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
||||
return fileEditorManager.allEditors.any { fileEditor -> editor == EditorUtil.getEditorEx(fileEditor) }
|
||||
}
|
||||
|
||||
private fun isEnabledForLookup(keyStroke: KeyStroke): Boolean {
|
||||
val notAllowedKeys = parseKeysSet(
|
||||
"<Tab>", "<Down>", "<Up>", "<Enter>", "<Left>", "<Right>",
|
||||
// New line in vim, but QuickDoc on MacOs
|
||||
"<C-J>"
|
||||
)
|
||||
for (keys in notAllowedKeys) {
|
||||
if (keyStroke == keys[0]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// We allow users to set custom keys that will work with lookup in case devs forgot something
|
||||
val popupActions = lookupKeys
|
||||
val values = popupActions.values()
|
||||
for (value in values) {
|
||||
val keys = StringHelper.parseKeys(value)
|
||||
if (keys.size >= 1 && keyStroke == keys[0]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun isShortcutConflict(keyStroke: KeyStroke): Boolean {
|
||||
return VimPlugin.getKey().getKeymapConflicts(keyStroke).isNotEmpty()
|
||||
}
|
||||
@@ -189,6 +165,29 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
||||
|
||||
private fun getEditor(e: AnActionEvent): Editor? = e.getData(PlatformDataKeys.EDITOR)
|
||||
|
||||
/**
|
||||
* Every time the key pressed with an active lookup, there is a decision:
|
||||
* should this key be processed by IdeaVim, or by IDE. For example, dot and enter should be processed by IDE, but
|
||||
* <C-W> by IdeaVim.
|
||||
*
|
||||
* The list of keys that should be processed by IDE is stored in [OptionsManager.lookupKeys]. So, we should search
|
||||
* if the pressed key is presented in this list. The caches are used to speedup the process.
|
||||
*/
|
||||
private object LookupKeys {
|
||||
private var parsedLookupKeys: Set<KeyStroke> = parseLookupKeys()
|
||||
|
||||
init {
|
||||
OptionsManager.lookupKeys.addOptionChangeListener { _, _ ->
|
||||
parsedLookupKeys = parseLookupKeys()
|
||||
}
|
||||
}
|
||||
|
||||
fun isEnabledForLookup(keyStroke: KeyStroke): Boolean = keyStroke !in parsedLookupKeys
|
||||
|
||||
private fun parseLookupKeys() = OptionsManager.lookupKeys.values()
|
||||
.map { StringHelper.parseKeys(it) }.filter { it.isNotEmpty() }.map { it.first() }.toSet()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val VIM_ONLY_EDITOR_KEYS: Set<KeyStroke> = ImmutableSet.builder<KeyStroke>().addAll(getKeyStrokes(KeyEvent.VK_ENTER, 0)).addAll(getKeyStrokes(KeyEvent.VK_ESCAPE, 0))
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -39,7 +39,7 @@ class RepeatChangeAction : VimActionHandler.SingleExecution() {
|
||||
if (lastCommand == null && VimRepeater.Extension.lastExtensionHandler == null) return false
|
||||
|
||||
// Save state
|
||||
val save = state.command
|
||||
val save = state.executingCommand
|
||||
val lastFTCmd = VimPlugin.getMotion().lastFTCmd
|
||||
val lastFTChar = VimPlugin.getMotion().lastFTChar
|
||||
val reg = VimPlugin.getRegister().currentRegister
|
||||
@@ -62,7 +62,7 @@ class RepeatChangeAction : VimActionHandler.SingleExecution() {
|
||||
mot.count = 0
|
||||
}
|
||||
}
|
||||
state.setCommand(lastCommand)
|
||||
state.setExecutingCommand(lastCommand)
|
||||
|
||||
KeyHandler.executeVimAction(editor, lastCommand.action, context)
|
||||
|
||||
@@ -74,7 +74,7 @@ class RepeatChangeAction : VimActionHandler.SingleExecution() {
|
||||
state.isDotRepeatInProgress = false
|
||||
|
||||
// Restore state
|
||||
if (save != null) state.setCommand(save)
|
||||
if (save != null) state.setExecutingCommand(save)
|
||||
VimPlugin.getMotion().setLastFTCmd(lastFTCmd, lastFTChar)
|
||||
if (lastHandler != null) VimRepeater.Extension.lastExtensionHandler = lastHandler
|
||||
VimRepeater.repeatHandler = repeatHandler
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +22,7 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.ex.LineRange
|
||||
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +22,7 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.VimPlugin
|
||||
import com.maddyhome.idea.vim.command.Argument
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.ex.LineRange
|
||||
import com.maddyhome.idea.vim.ex.ranges.LineRange
|
||||
import com.maddyhome.idea.vim.handler.ChangeEditorActionHandler
|
||||
|
||||
class ChangeLastSearchReplaceAction : ChangeEditorActionHandler.SingleExecution() {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -0,0 +1,16 @@
|
||||
package com.maddyhome.idea.vim.action.change.insert
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.KeyHandler
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
|
||||
class StartInsertDigraphAction : VimActionHandler.SingleExecution() {
|
||||
override val type: Command.Type = Command.Type.INSERT
|
||||
|
||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||
KeyHandler.getInstance().startDigraphSequence(editor)
|
||||
return true
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package com.maddyhome.idea.vim.action.change.insert
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.maddyhome.idea.vim.KeyHandler
|
||||
import com.maddyhome.idea.vim.command.Command
|
||||
import com.maddyhome.idea.vim.handler.VimActionHandler
|
||||
|
||||
class StartInsertLiteralAction : VimActionHandler.SingleExecution() {
|
||||
override val type: Command.Type = Command.Type.INSERT
|
||||
|
||||
override fun execute(editor: Editor, context: DataContext, cmd: Command): Boolean {
|
||||
KeyHandler.getInstance().startLiteralSequence(editor)
|
||||
return true
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
||||
* Copyright (C) 2003-2019 The IdeaVim authors
|
||||
* Copyright (C) 2003-2020 The IdeaVim authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user