mirror of
https://github.com/chylex/IntelliJ-IdeaVim.git
synced 2025-08-18 19:24:55 +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
|
Please note that the quality of EAP versions may at times be way below even
|
||||||
usual beta standards.
|
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:**
|
**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))
|
* 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))
|
* 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-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-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
|
* [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-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-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-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-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
|
0.54, 2019-11-20
|
||||||
--------------
|
--------------
|
||||||
|
@@ -93,6 +93,7 @@ Supported:
|
|||||||
|
|
||||||
Emulated Vim plugins:
|
Emulated Vim plugins:
|
||||||
|
|
||||||
|
* vim-easymotion
|
||||||
* vim-surround
|
* vim-surround
|
||||||
* vim-multiple-cursors
|
* vim-multiple-cursors
|
||||||
* vim-commentary
|
* vim-commentary
|
||||||
@@ -128,7 +129,7 @@ have `-Duser.home=/my/alternate/home` then IdeaVim will source
|
|||||||
`/my/alternate/home/.ideavimrc` instead of `~/.ideavimrc`.
|
`/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.
|
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
|
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
|
If true, join command will be performed via IDE
|
||||||
See wiki/`ideajoin` examples
|
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.
|
If false, IdeaVim icon won't be shown in the status bar.
|
||||||
Works only from `~/.ideavimrc` after the IDE restart.
|
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] - cursor keys, <End>, <Home>, <PageUp> and <PageDown>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# suppress inspection "UnusedProperty" for whole file
|
# suppress inspection "UnusedProperty" for whole file
|
||||||
|
|
||||||
ideaVersion=2019.3
|
ideaVersion=201-EAP-SNAPSHOT
|
||||||
downloadIdeaSources=true
|
downloadIdeaSources=true
|
||||||
instrumentPluginCode=true
|
instrumentPluginCode=true
|
||||||
version=SNAPSHOT
|
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.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.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.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 -->
|
<!-- Delete -->
|
||||||
<vimAction implementation="com.maddyhome.idea.vim.action.change.delete.DeleteCharacterAction" mappingModes="N" keys="«DEL»"/>
|
<vimAction implementation="com.maddyhome.idea.vim.action.change.delete.DeleteCharacterAction" mappingModes="N" keys="«DEL»"/>
|
@@ -3,8 +3,10 @@
|
|||||||
<id>IdeaVIM</id>
|
<id>IdeaVIM</id>
|
||||||
<change-notes><![CDATA[
|
<change-notes><![CDATA[
|
||||||
<ul>
|
<ul>
|
||||||
<li>Fix `imap jk <ESC>` for the active autocompletion lookup</li>
|
<li>Support dot command for Surround and Commentary extensions</li>
|
||||||
<li>Surround and Commentary extensions can be repeated with a dot command</li>
|
<li>Support XDG settings standard</li>
|
||||||
|
<li>Add option to remove the status bar icon</li>
|
||||||
|
<li>Various bug fixes</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
<p>See also the complete <a href="https://github.com/JetBrains/ideavim/blob/master/CHANGES.md">changelog</a>.</p>
|
||||||
]]></change-notes>
|
]]></change-notes>
|
||||||
@@ -29,6 +31,9 @@
|
|||||||
<resource-bundle xmlns="">messages</resource-bundle>
|
<resource-bundle xmlns="">messages</resource-bundle>
|
||||||
|
|
||||||
<application-components>
|
<application-components>
|
||||||
|
<component>
|
||||||
|
<implementation-class>com.maddyhome.idea.vim.DynamicLoaderStopper</implementation-class>
|
||||||
|
</component>
|
||||||
<component>
|
<component>
|
||||||
<implementation-class>com.maddyhome.idea.vim.VimPlugin</implementation-class>
|
<implementation-class>com.maddyhome.idea.vim.VimPlugin</implementation-class>
|
||||||
</component>
|
</component>
|
||||||
@@ -45,10 +50,10 @@
|
|||||||
<extensionPoints>
|
<extensionPoints>
|
||||||
<extensionPoint name="vimExtension" interface="com.maddyhome.idea.vim.extension.VimExtension"/>
|
<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"/>
|
<with attribute="implementation" implements="com.maddyhome.idea.vim.ex.CommandHandler"/>
|
||||||
</extensionPoint>
|
</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"/>
|
<with attribute="implementation" implements="com.maddyhome.idea.vim.handler.EditorActionHandlerBase"/>
|
||||||
</extensionPoint>
|
</extensionPoint>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
@@ -59,11 +64,11 @@
|
|||||||
<statusBarWidgetProvider implementation="com.maddyhome.idea.vim.StatusBarIconProvider"/>
|
<statusBarWidgetProvider implementation="com.maddyhome.idea.vim.StatusBarIconProvider"/>
|
||||||
</extensions>
|
</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/includes/VimActions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
<xi:include href="/META-INF/VimExCommands.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimExCommands.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
<xi:include href="/META-INF/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
<xi:include href="/META-INF/includes/VimExtensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||||
|
|
||||||
<actions>
|
<actions>
|
||||||
<action id="VimPluginToggle" class="com.maddyhome.idea.vim.action.VimPluginToggleAction" text="Vim Emulator" description="Toggle the vim plugin On/off">
|
<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
|
# 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
|
# 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
|
# 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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/>.
|
* 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 {
|
class DynamicLoaderStopper
|
||||||
public InvalidCommandException(String message, String cmd) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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.project.Project;
|
||||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||||
import com.intellij.openapi.ui.popup.ListPopup;
|
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.change.VimRepeater;
|
||||||
import com.maddyhome.idea.vim.action.macro.ToggleRecordingAction;
|
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.command.*;
|
||||||
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
import com.maddyhome.idea.vim.extension.VimExtensionHandler;
|
||||||
import com.maddyhome.idea.vim.group.ChangeGroup;
|
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.CommonDataKeys.*;
|
||||||
import static com.intellij.openapi.actionSystem.PlatformDataKeys.PROJECT_FILE_DIRECTORY;
|
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.
|
* actions. This is a singleton.
|
||||||
*/
|
*/
|
||||||
public class KeyHandler {
|
public class KeyHandler {
|
||||||
@@ -131,7 +127,7 @@ public class KeyHandler {
|
|||||||
ActionManager.getInstance(), 0);
|
ActionManager.getInstance(), 0);
|
||||||
|
|
||||||
if (action instanceof ActionGroup && !((ActionGroup)action).canBePerformed(context)) {
|
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()
|
ListPopup popup = JBPopupFactory.getInstance()
|
||||||
.createActionGroupPopup(event.getPresentation().getText(), (ActionGroup)action, context, false, null, -1);
|
.createActionGroupPopup(event.getPresentation().getText(), (ActionGroup)action, context, false, null, -1);
|
||||||
|
|
||||||
@@ -147,8 +143,8 @@ public class KeyHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems
|
// beforeActionPerformedUpdate should be called to update the action. It fixes some rider-specific problems.
|
||||||
// because rider use async update method. See VIM-1819
|
// because rider use async update method. See VIM-1819.
|
||||||
action.beforeActionPerformedUpdate(event);
|
action.beforeActionPerformedUpdate(event);
|
||||||
if (event.getPresentation().isEnabled()) {
|
if (event.getPresentation().isEnabled()) {
|
||||||
action.actionPerformed(event);
|
action.actionPerformed(event);
|
||||||
@@ -158,6 +154,16 @@ public class KeyHandler {
|
|||||||
return false;
|
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
|
* This is the main key handler for the Vim plugin. Every keystroke not handled directly by Idea is sent here for
|
||||||
* processing.
|
* processing.
|
||||||
@@ -200,124 +206,90 @@ public class KeyHandler {
|
|||||||
// All the editor actions should be performed with top level editor!!!
|
// All the editor actions should be performed with top level editor!!!
|
||||||
// Be careful: all the EditorActionHandler implementation should correctly process InjectedEditors
|
// Be careful: all the EditorActionHandler implementation should correctly process InjectedEditors
|
||||||
editor = HelperKt.getTopLevelEditor(editor);
|
editor = HelperKt.getTopLevelEditor(editor);
|
||||||
|
|
||||||
final CommandState editorState = CommandState.getInstance(editor);
|
final CommandState editorState = CommandState.getInstance(editor);
|
||||||
|
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||||
|
|
||||||
// If this is a "regular" character keystroke, get the character
|
// If this is a "regular" character keystroke, get the character
|
||||||
char chKey = key.getKeyChar() == KeyEvent.CHAR_UNDEFINED ? 0 : key.getKeyChar();
|
char chKey = key.getKeyChar() == KeyEvent.CHAR_UNDEFINED ? 0 : key.getKeyChar();
|
||||||
|
|
||||||
final boolean isRecording = editorState.isRecording();
|
// We only record unmapped keystrokes. If we've recursed to handle mapping, don't record anything.
|
||||||
boolean shouldRecord = true;
|
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
|
try {
|
||||||
if (isCommandCount(editorState, chKey)) {
|
if (!allowKeyMappings || !handleKeyMapping(editor, key, context)) {
|
||||||
// Update the count
|
if (isCommandCountKey(chKey, editorState)) {
|
||||||
count = count * 10 + (chKey - '0');
|
commandBuilder.addCountCharacter(chKey);
|
||||||
}
|
} else if (isDeleteCommandCountKey(key, editorState)) {
|
||||||
else if (!waitCommandFinish(editor) && allowKeyMappings && handleKeyMapping(editor, key, context)) {
|
commandBuilder.deleteCountCharacter();
|
||||||
if (editorState.getMappingMode() != MappingMode.OP_PENDING ||
|
} else if (isEditorReset(key, editorState)) {
|
||||||
currentCmd.isEmpty() ||
|
handleEditorReset(editor, key, context, editorState);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
// If we got this far the user is entering a command or supplying an argument to an entered command.
|
// 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.
|
// 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) {
|
else if (isExpectingCharArgument(commandBuilder)) {
|
||||||
handleCharArgument(key, chKey);
|
handleCharArgument(key, chKey, editorState);
|
||||||
}
|
}
|
||||||
// If we are this far, then the user must be entering a command or a non-single-character argument
|
// 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
|
// to an entered command. Let's figure out which it is.
|
||||||
else {
|
else if (!handleDigraph(editor, key, context, editorState)) {
|
||||||
// For debugging purposes we track the keys entered for this command
|
|
||||||
keys.add(key);
|
commandBuilder.addKey(key);
|
||||||
|
|
||||||
// Ask the key/action tree if this is an appropriate key at this point in the command and if so,
|
// 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
|
// return the node matching this keystroke
|
||||||
Node node = editorState.getCurrentNode().get(key);
|
final Node node = mapOpCommand(key, commandBuilder.getChildNode(key), editorState);
|
||||||
|
|
||||||
if (handleDigraph(editor, key, context, node)) return;
|
|
||||||
|
|
||||||
node = mapOpCommand(key, node, editorState);
|
|
||||||
|
|
||||||
if (node instanceof CommandNode) {
|
if (node instanceof CommandNode) {
|
||||||
handleCommandNode(editor, context, key, (CommandNode) node, editorState);
|
handleCommandNode(editor, context, key, (CommandNode) node, editorState);
|
||||||
}
|
} else if (node instanceof CommandPartNode) {
|
||||||
else if (node instanceof CommandPartNode) {
|
commandBuilder.setCurrentCommandPartNode((CommandPartNode) node);
|
||||||
editorState.setCurrentNode((CommandPartNode)node);
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (lastWasBS && lastChar != 0 && OptionsManager.INSTANCE.getDigraph().isSet()) {
|
|
||||||
char dig = VimPlugin.getDigraph().getDigraph(lastChar, key.getKeyChar());
|
|
||||||
key = KeyStroke.getKeyStroke(dig);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are in insert/replace mode send this key in for processing
|
// If we are in insert/replace mode send this key in for processing
|
||||||
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
|
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
|
||||||
if (!VimPlugin.getChange().processKey(editor, context, key)) {
|
shouldRecord &= VimPlugin.getChange().processKey(editor, context, key);
|
||||||
shouldRecord = false;
|
} else if (editorState.getMode() == CommandState.Mode.SELECT) {
|
||||||
}
|
shouldRecord &= VimPlugin.getChange().processKeyInSelectMode(editor, context, key);
|
||||||
}
|
} else if (editorState.getMappingState().getMappingMode() == MappingMode.CMD_LINE) {
|
||||||
else if (editorState.getMode() == CommandState.Mode.SELECT) {
|
shouldRecord &= VimPlugin.getProcess().processExKey(editor, key);
|
||||||
if (!VimPlugin.getChange().processKeyInSelectMode(editor, context, key)) {
|
|
||||||
shouldRecord = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (editorState.getMappingMode() == MappingMode.CMD_LINE) {
|
|
||||||
if (!VimPlugin.getProcess().processExKey(editor, key)) {
|
|
||||||
shouldRecord = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// If we get here then the user has entered an unrecognized series of keystrokes
|
// If we get here then the user has entered an unrecognized series of keystrokes
|
||||||
else {
|
else {
|
||||||
state = State.BAD_COMMAND;
|
commandBuilder.setCommandState(CurrentCommandState.BAD_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastChar = lastWasBS && lastChar != 0 ? 0 : key.getKeyChar();
|
|
||||||
lastWasBS = false;
|
|
||||||
partialReset(editor);
|
partialReset(editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
handleKeyRecursionCount--;
|
||||||
|
}
|
||||||
|
|
||||||
// Do we have a fully entered command at this point? If so, lets execute it
|
// Do we have a fully entered command at this point? If so, let's execute it.
|
||||||
if (state == State.READY) {
|
if (commandBuilder.isReady()) {
|
||||||
executeCommand(editor, key, context, editorState);
|
executeCommand(editor, key, context, editorState);
|
||||||
}
|
}
|
||||||
else if (state == State.BAD_COMMAND) {
|
else if (commandBuilder.isBad()) {
|
||||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
|
editorState.resetOpPending();
|
||||||
editorState.popState();
|
|
||||||
}
|
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
reset(editor);
|
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);
|
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}
|
* See the description for {@link com.maddyhome.idea.vim.action.DuplicableOperatorAction}
|
||||||
*/
|
*/
|
||||||
private Node mapOpCommand(KeyStroke key, Node node, @NotNull CommandState editorState) {
|
private Node mapOpCommand(KeyStroke key, Node node, @NotNull CommandState editorState) {
|
||||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING && !currentCmd.empty()) {
|
if (editorState.isDuplicateOperatorKeyStroke(key)) {
|
||||||
EditorActionHandlerBase action = currentCmd.peek().getAction();
|
return editorState.getCommandBuilder().getChildNode(KeyStroke.getKeyStroke('_'));
|
||||||
if (action instanceof DuplicableOperatorAction &&
|
|
||||||
((DuplicableOperatorAction)action).getDuplicateWith() == key.getKeyChar()) {
|
|
||||||
return editorState.getCurrentNode().get(KeyStroke.getKeyStroke('_'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@@ -334,8 +306,8 @@ public class KeyHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEditorReset(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull final DataContext context) {
|
private void handleEditorReset(@NotNull Editor editor, @NotNull KeyStroke key, @NotNull final DataContext context, @NotNull CommandState editorState) {
|
||||||
if (count == 0 && currentArg == null && currentCmd.size() == 0) {
|
if (editorState.getCommandBuilder().isAtDefaultState()) {
|
||||||
RegisterGroup register = VimPlugin.getRegister();
|
RegisterGroup register = VimPlugin.getRegister();
|
||||||
if (register.getCurrentRegister() == register.getDefaultRegister()) {
|
if (register.getCurrentRegister() == register.getDefaultRegister()) {
|
||||||
if (key.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
if (key.getKeyCode() == KeyEvent.VK_ESCAPE) {
|
||||||
@@ -352,57 +324,116 @@ public class KeyHandler {
|
|||||||
private boolean handleKeyMapping(@NotNull final Editor editor,
|
private boolean handleKeyMapping(@NotNull final Editor editor,
|
||||||
@NotNull final KeyStroke key,
|
@NotNull final KeyStroke key,
|
||||||
@NotNull final DataContext context) {
|
@NotNull final DataContext context) {
|
||||||
if (state == State.CHAR_OR_DIGRAPH) return false;
|
|
||||||
|
|
||||||
final CommandState commandState = CommandState.getInstance(editor);
|
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();
|
mappingState.stopMappingTimer();
|
||||||
final List<KeyStroke> fromKeys = new ArrayList<>(mappingKeys);
|
|
||||||
fromKeys.add(key);
|
|
||||||
|
|
||||||
final KeyMapping mapping = VimPlugin.getKey().getKeyMapping(mappingMode);
|
// Save the unhandled key strokes until we either complete or abandon the sequence.
|
||||||
final MappingInfo currentMappingInfo = mapping.get(fromKeys);
|
mappingState.addKey(key);
|
||||||
final MappingInfo prevMappingInfo = mapping.get(mappingKeys);
|
|
||||||
final MappingInfo mappingInfo = currentMappingInfo != null ? currentMappingInfo : prevMappingInfo;
|
|
||||||
|
|
||||||
|
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();
|
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()) {
|
if (!application.isUnitTestMode() && OptionsManager.INSTANCE.getTimeout().isSet()) {
|
||||||
commandState.startMappingTimer(actionEvent -> application.invokeLater(() -> {
|
mappingState.startMappingTimer(actionEvent -> application.invokeLater(() -> {
|
||||||
final KeyStroke firstKey = mappingKeys.get(0);
|
|
||||||
mappingKeys.clear();
|
final List<KeyStroke> unhandledKeys = mappingState.detachKeys();
|
||||||
if (editor.isDisposed() || firstKey.equals(parseKeys("<Plug>").get(0))) {
|
|
||||||
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
for (KeyStroke keyStroke : fromKeys) {
|
|
||||||
|
for (KeyStroke keyStroke : unhandledKeys) {
|
||||||
handleKey(editor, keyStroke, new EditorDataContext(editor), false);
|
handleKey(editor, keyStroke, new EditorDataContext(editor), false);
|
||||||
}
|
}
|
||||||
}, ModalityState.stateForComponent(editor.getComponent())));
|
}, ModalityState.stateForComponent(editor.getComponent())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (mappingInfo != null) {
|
|
||||||
// Okay, there is a mapping for the entered key sequence
|
private boolean handleCompleteMappingSequence(@NotNull Editor editor,
|
||||||
// now the another key sequence should be executed, or the handler that attached to this command
|
@NotNull DataContext context,
|
||||||
mappingKeys.clear();
|
@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 List<KeyStroke> toKeys = mappingInfo.getToKeys();
|
||||||
final VimExtensionHandler extensionHandler = mappingInfo.getExtensionHandler();
|
final VimExtensionHandler extensionHandler = mappingInfo.getExtensionHandler();
|
||||||
final EditorDataContext currentContext = new EditorDataContext(editor);
|
|
||||||
if (toKeys != null) {
|
if (toKeys != null) {
|
||||||
// Here is a mapping to another key sequence
|
|
||||||
final boolean fromIsPrefix = isPrefix(mappingInfo.getFromKeys(), toKeys);
|
final boolean fromIsPrefix = isPrefix(mappingInfo.getFromKeys(), toKeys);
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (KeyStroke keyStroke : toKeys) {
|
for (KeyStroke keyStroke : toKeys) {
|
||||||
@@ -412,15 +443,20 @@ public class KeyHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (extensionHandler != null) {
|
else if (extensionHandler != null) {
|
||||||
// Here is a mapping to some vim handler
|
|
||||||
final CommandProcessor processor = CommandProcessor.getInstance();
|
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 =
|
Map<Caret, Integer> startOffsets =
|
||||||
editor.getCaretModel().getAllCarets().stream().collect(Collectors.toMap(Function.identity(), Caret::getOffset));
|
editor.getCaretModel().getAllCarets().stream().collect(Collectors.toMap(Function.identity(), Caret::getOffset));
|
||||||
|
|
||||||
if (extensionHandler.isRepeatable()) {
|
if (extensionHandler.isRepeatable()) {
|
||||||
VimRepeater.Extension.INSTANCE.clean();
|
VimRepeater.Extension.INSTANCE.clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
processor.executeCommand(editor.getProject(), () -> extensionHandler.execute(editor, context),
|
processor.executeCommand(editor.getProject(), () -> extensionHandler.execute(editor, context),
|
||||||
"Vim " + extensionHandler.getClass().getSimpleName(), null);
|
"Vim " + extensionHandler.getClass().getSimpleName(), null);
|
||||||
|
|
||||||
@@ -429,9 +465,8 @@ public class KeyHandler {
|
|||||||
VimRepeater.Extension.INSTANCE.setArgumentCaptured(null);
|
VimRepeater.Extension.INSTANCE.setArgumentCaptured(null);
|
||||||
VimRepeater.INSTANCE.setRepeatHandler(true);
|
VimRepeater.INSTANCE.setRepeatHandler(true);
|
||||||
}
|
}
|
||||||
if (isPendingMode &&
|
|
||||||
!currentCmd.isEmpty() &&
|
if (shouldCalculateOffsets && !commandState.getCommandBuilder().hasCurrentCommandPartArgument()) {
|
||||||
currentCmd.peek().getArgument() == null) {
|
|
||||||
Map<Caret, VimSelection> offsets = new HashMap<>();
|
Map<Caret, VimSelection> offsets = new HashMap<>();
|
||||||
|
|
||||||
for (Caret caret : editor.getCaretModel().getAllCarets()) {
|
for (Caret caret : editor.getCaretModel().getAllCarets()) {
|
||||||
@@ -441,7 +476,7 @@ public class KeyHandler {
|
|||||||
.create(UserDataManager.getVimSelectionStart(caret), caret.getOffset(),
|
.create(UserDataManager.getVimSelectionStart(caret), caret.getOffset(),
|
||||||
SelectionType.fromSubMode(CommandStateHelper.getSubMode(editor)), editor);
|
SelectionType.fromSubMode(CommandStateHelper.getSubMode(editor)), editor);
|
||||||
offsets.put(caret, vimSelection);
|
offsets.put(caret, vimSelection);
|
||||||
commandState.popState();
|
commandState.popModes();
|
||||||
}
|
}
|
||||||
else if (startOffset != null && startOffset != caret.getOffset()) {
|
else if (startOffset != null && startOffset != caret.getOffset()) {
|
||||||
// Command line motions are always characterwise exclusive
|
// Command line motions are always characterwise exclusive
|
||||||
@@ -464,76 +499,85 @@ public class KeyHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!offsets.isEmpty()) {
|
if (!offsets.isEmpty()) {
|
||||||
currentCmd.peek().setArgument(new Argument(offsets));
|
commandState.getCommandBuilder().completeCommandPart(new Argument(offsets));
|
||||||
state = State.READY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: mappingInfo MUST be non-null here, so if equal
|
// If we've just evaluated the previous key sequence, make sure to also handle the current key
|
||||||
// then prevMappingInfo is also non-null; this also
|
if (mappingInfo != currentMappingInfo) {
|
||||||
// means that the prev mapping was a prefix, but the
|
handleKey(editor, key, currentContext, true);
|
||||||
// next key typed (`key`) was not part of that
|
|
||||||
if (prevMappingInfo == mappingInfo) {
|
|
||||||
handleKey(editor, key, currentContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// If the user enters a command that starts with known mapping, but it is not exactly this mapping,
|
private boolean handleAbandonedMappingSequence(@NotNull Editor editor,
|
||||||
// mapping handler prevents further processing of there keys.
|
@NotNull MappingState mappingState,
|
||||||
// E.g. if there is a mapping for "hello" and user enters command "help"
|
DataContext context) {
|
||||||
// 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"
|
// The user has terminated a mapping sequence with an unexpected key
|
||||||
// and the following for loop does exactly that.
|
// 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?
|
// Okay, look at the code below. Why is the first key handled separately?
|
||||||
// Let's assume the next mappings:
|
// Let's assume the next mappings:
|
||||||
// - map ds j
|
// - map ds j
|
||||||
// - map I 2l
|
// - map I 2l
|
||||||
// If user enters `dI`, the first `d` will be caught be this handler because it's a prefix for `ds` command.
|
// 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)
|
// 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.
|
// E.g.
|
||||||
// - map <Plug>iA someAction
|
// - map <Plug>iA someAction
|
||||||
// - map I <Plug>i
|
// - map I <Plug>i
|
||||||
// For `IA` someAction should be executed.
|
// 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.
|
// 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 (unhandledKeyStrokes.get(0).equals(StringHelper.PlugKeyStroke)) {
|
||||||
if (fromKeys.isEmpty()) return false;
|
handleKey(editor, unhandledKeyStrokes.get(unhandledKeyStrokes.size() - 1), context, true);
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
handleKey(editor, unhandledKeys.get(0), context, false);
|
handleKey(editor, unhandledKeyStrokes.get(0), context, false);
|
||||||
for (KeyStroke keyStroke : unhandledKeys.subList(1, unhandledKeys.size())) {
|
|
||||||
|
for (KeyStroke keyStroke : unhandledKeyStrokes.subList(1, unhandledKeyStrokes.size())) {
|
||||||
handleKey(editor, keyStroke, context, true);
|
handleKey(editor, keyStroke, context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 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) {
|
private boolean isDeleteCommandCountKey(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
||||||
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL) &&
|
// See `:help N<Del>`
|
||||||
state == State.NEW_COMMAND &&
|
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||||
currentArg != Argument.Type.CHARACTER &&
|
return (editorState.getMode() == CommandState.Mode.COMMAND || editorState.getMode() == CommandState.Mode.VISUAL)
|
||||||
currentArg != Argument.Type.DIGRAPH &&
|
&& commandBuilder.isExpectingCount() && commandBuilder.getCount() > 0 && key.getKeyCode() == KeyEvent.VK_DELETE;
|
||||||
key.getKeyCode() == KeyEvent.VK_DELETE &&
|
|
||||||
count != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEditorReset(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
private boolean isEditorReset(@NotNull KeyStroke key, @NotNull CommandState editorState) {
|
||||||
return (editorState.getMode() == CommandState.Mode.COMMAND) && StringHelper.isCloseKeyStroke(key);
|
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?
|
// 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.
|
// Some special keys can be handled as character arguments - let's check for them here.
|
||||||
if (chKey == 0) {
|
if (chKey == 0) {
|
||||||
@@ -547,57 +591,64 @@ public class KeyHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final CommandBuilder commandBuilder = commandState.getCommandBuilder();
|
||||||
if (chKey != 0) {
|
if (chKey != 0) {
|
||||||
// Create the character argument, add it to the current command, and signal we are ready to process
|
// Create the character argument, add it to the current command, and signal we are ready to process the command
|
||||||
// the command
|
commandBuilder.completeCommandPart(new Argument(chKey));
|
||||||
Argument arg = new Argument(chKey);
|
|
||||||
Command cmd = currentCmd.peek();
|
|
||||||
cmd.setArgument(arg);
|
|
||||||
state = State.READY;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Oops - this isn't a valid character argument
|
// 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,
|
private boolean handleDigraph(@NotNull Editor editor,
|
||||||
@NotNull KeyStroke key,
|
@NotNull KeyStroke key,
|
||||||
@NotNull DataContext context,
|
@NotNull DataContext context,
|
||||||
@Nullable Node node) {
|
@NotNull CommandState editorState) {
|
||||||
if (digraph == null && !(node instanceof CommandNode) && DigraphSequence.isDigraphStart(key)) {
|
|
||||||
digraph = new DigraphSequence();
|
// 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) {
|
if (DigraphSequence.isLiteralStart(key)) {
|
||||||
DigraphSequence.DigraphResult res = digraph.processKey(key, editor);
|
editorState.startLiteralSequence();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DigraphResult res = editorState.processDigraphKey(key, editor);
|
||||||
switch (res.getResult()) {
|
switch (res.getResult()) {
|
||||||
case DigraphSequence.DigraphResult.RES_OK:
|
case DigraphResult.RES_HANDLED:
|
||||||
|
case DigraphResult.RES_BAD:
|
||||||
return true;
|
return true;
|
||||||
case DigraphSequence.DigraphResult.RES_BAD:
|
|
||||||
digraph = null;
|
case DigraphResult.RES_DONE:
|
||||||
return true;
|
if (commandBuilder.getExpectedArgumentType() == Argument.Type.DIGRAPH) {
|
||||||
case DigraphSequence.DigraphResult.RES_DONE:
|
commandBuilder.fallbackToCharacterArgument();
|
||||||
if (currentArg == Argument.Type.DIGRAPH) {
|
|
||||||
currentArg = Argument.Type.CHARACTER;
|
|
||||||
}
|
}
|
||||||
digraph = null;
|
|
||||||
final KeyStroke stroke = res.getStroke();
|
final KeyStroke stroke = res.getStroke();
|
||||||
if (stroke == null) {
|
if (stroke == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
handleKey(editor, stroke, context);
|
handleKey(editor, stroke, context);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case DigraphResult.RES_UNHANDLED:
|
||||||
|
if (commandBuilder.getExpectedArgumentType() == Argument.Type.DIGRAPH) {
|
||||||
|
commandBuilder.fallbackToCharacterArgument();
|
||||||
|
handleKey(editor, key, context);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,58 +656,28 @@ public class KeyHandler {
|
|||||||
@NotNull KeyStroke key,
|
@NotNull KeyStroke key,
|
||||||
@NotNull DataContext context,
|
@NotNull DataContext context,
|
||||||
@NotNull CommandState editorState) {
|
@NotNull CommandState editorState) {
|
||||||
// Let's go through the command stack and merge it all into one command. At this time there should never
|
final Command command = editorState.getCommandBuilder().buildCommand();
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we were in "operator pending" mode, reset back to normal mode.
|
// If we were in "operator pending" mode, reset back to normal mode.
|
||||||
if (editorState.getMappingMode() == MappingMode.OP_PENDING) {
|
editorState.resetOpPending();
|
||||||
editorState.popState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save off the command we are about to execute
|
// Save off the command we are about to execute
|
||||||
editorState.setCommand(cmd);
|
editorState.setExecutingCommand(command);
|
||||||
|
|
||||||
if (lastChar != 0 && !lastWasBS) {
|
|
||||||
lastWasBS = key.equals(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
lastChar = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Project project = editor.getProject();
|
Project project = editor.getProject();
|
||||||
final Command.Type type = cmd.getType();
|
final Command.Type type = command.getType();
|
||||||
if (type.isWrite() && !editor.getDocument().isWritable()) {
|
if (type.isWrite() && !editor.getDocument().isWritable()) {
|
||||||
VimPlugin.indicateError();
|
VimPlugin.indicateError();
|
||||||
reset(editor);
|
reset(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd.getFlags().contains(CommandFlags.FLAG_TYPEAHEAD_SELF_MANAGE)) {
|
if (!command.getFlags().contains(CommandFlags.FLAG_TYPEAHEAD_SELF_MANAGE)) {
|
||||||
IdeEventQueue.getInstance().flushDelayedKeyEvents();
|
IdeEventQueue.getInstance().flushDelayedKeyEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||||
Runnable action = new ActionRunner(editor, context, cmd, key);
|
Runnable action = new ActionRunner(editor, context, command, key);
|
||||||
EditorActionHandlerBase cmdAction = cmd.getAction();
|
EditorActionHandlerBase cmdAction = command.getAction();
|
||||||
String name = cmdAction.getId();
|
String name = cmdAction.getId();
|
||||||
|
|
||||||
if (type.isWrite()) {
|
if (type.isWrite()) {
|
||||||
@@ -676,40 +697,50 @@ public class KeyHandler {
|
|||||||
KeyStroke key,
|
KeyStroke key,
|
||||||
@NotNull CommandNode node,
|
@NotNull CommandNode node,
|
||||||
CommandState editorState) {
|
CommandState editorState) {
|
||||||
// The user entered a valid command. Create the command and add it to the stack
|
// The user entered a valid command. Create the command and add it to the stack.
|
||||||
final EditorActionHandlerBase myAction = node.getActionHolder().getAction();
|
final EditorActionHandlerBase action = node.getActionHolder().getAction();
|
||||||
Command cmd = new Command(count, myAction, myAction.getType(), myAction.getFlags(), keys);
|
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||||
currentCmd.push(cmd);
|
final Argument.Type expectedArgumentType = commandBuilder.getExpectedArgumentType();
|
||||||
|
|
||||||
if (currentArg != null && !checkArgumentCompatibility(node)) return;
|
commandBuilder.pushCommandPart(action);
|
||||||
|
|
||||||
if (myAction.getArgumentType() == null || stopMacroRecord(node, editorState)) {
|
if (!checkArgumentCompatibility(expectedArgumentType, action)) {
|
||||||
state = State.READY;
|
commandBuilder.setCommandState(CurrentCommandState.BAD_COMMAND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.getArgumentType() == null || stopMacroRecord(node, editorState)) {
|
||||||
|
commandBuilder.setCommandState(CurrentCommandState.READY);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
currentArg = myAction.getArgumentType();
|
final Argument.Type argumentType = action.getArgumentType();
|
||||||
startWaitingForArgument(editor, context, key.getKeyChar(), currentArg, editorState, myAction);
|
startWaitingForArgument(editor, context, key.getKeyChar(), argumentType, editorState);
|
||||||
partialReset(editor);
|
partialReset(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO In the name of God, get rid of EX_STRING, FLAG_COMPLETE_EX and all the related staff
|
// 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)) {
|
if (expectedArgumentType == Argument.Type.EX_STRING && action.getFlags().contains(CommandFlags.FLAG_COMPLETE_EX)) {
|
||||||
EditorActionHandlerBase action;
|
/* The only action that implements FLAG_COMPLETE_EX is ProcessExEntryAction.
|
||||||
if (forwardSearch) {
|
* When pressing ':', ExEntryAction is chosen as the command. Since it expects no arguments, it is invoked and
|
||||||
action = new SearchEntryFwdAction();
|
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,
|
||||||
else {
|
this branch does NOT fire, and ProcessExEntryAction handles the ex cmd line entry.
|
||||||
action = new SearchEntryRevAction();
|
* 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);
|
String text = VimPlugin.getProcess().endSearchCommand(editor);
|
||||||
currentCmd.pop();
|
commandBuilder.popCommandPart(); // Pop ProcessExEntryAction
|
||||||
|
commandBuilder.completeCommandPart(new Argument(text)); // Set search text on SearchEntry(Fwd|Rev)Action
|
||||||
Argument arg = new Argument(text);
|
editorState.popModes(); // Pop CMD_LINE
|
||||||
cmd = new Command(count, action, action.getType(), action.getFlags(), keys);
|
|
||||||
cmd.setArgument(arg);
|
|
||||||
currentCmd.push(cmd);
|
|
||||||
CommandState.getInstance(editor).popState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,38 +752,27 @@ public class KeyHandler {
|
|||||||
DataContext context,
|
DataContext context,
|
||||||
char key,
|
char key,
|
||||||
@NotNull Argument.Type argument,
|
@NotNull Argument.Type argument,
|
||||||
CommandState editorState,
|
CommandState editorState) {
|
||||||
EditorActionHandlerBase action) {
|
final CommandBuilder commandBuilder = editorState.getCommandBuilder();
|
||||||
switch (argument) {
|
switch (argument) {
|
||||||
case CHARACTER:
|
|
||||||
case DIGRAPH:
|
|
||||||
digraph = new DigraphSequence();
|
|
||||||
state = State.CHAR_OR_DIGRAPH;
|
|
||||||
break;
|
|
||||||
case MOTION:
|
case MOTION:
|
||||||
if (CommandState.getInstance(editor).isDotRepeatInProgress() && VimRepeater.Extension.INSTANCE.getArgumentCaptured() != null) {
|
if (editorState.isDotRepeatInProgress() && VimRepeater.Extension.INSTANCE.getArgumentCaptured() != null) {
|
||||||
currentCmd.peek().setArgument(VimRepeater.Extension.INSTANCE.getArgumentCaptured());
|
commandBuilder.completeCommandPart(VimRepeater.Extension.INSTANCE.getArgumentCaptured());
|
||||||
state = State.READY;
|
|
||||||
}
|
}
|
||||||
editorState.pushState(editorState.getMode(), editorState.getSubMode(), MappingMode.OP_PENDING);
|
editorState.pushModes(editorState.getMode(), CommandState.SubMode.OP_PENDING);
|
||||||
break;
|
break;
|
||||||
case EX_STRING:
|
case EX_STRING:
|
||||||
forwardSearch = !(action instanceof SearchEntryRevAction);
|
// 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, count, key);
|
VimPlugin.getProcess().startSearchCommand(editor, context, commandBuilder.getCount(), key);
|
||||||
state = State.NEW_COMMAND;
|
commandBuilder.setCommandState(CurrentCommandState.NEW_COMMAND);
|
||||||
editorState.pushState(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE, MappingMode.CMD_LINE);
|
editorState.pushModes(CommandState.Mode.CMD_LINE, CommandState.SubMode.NONE);
|
||||||
currentCmd.pop();
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkArgumentCompatibility(@NotNull CommandNode node) {
|
private boolean checkArgumentCompatibility(@Nullable Argument.Type expectedArgumentType, @NotNull EditorActionHandlerBase action) {
|
||||||
if (currentArg == Argument.Type.MOTION &&
|
return !(expectedArgumentType == Argument.Type.MOTION && action.getType() != Command.Type.MOTION);
|
||||||
node.getActionHolder().getAction().getType() != Command.Type.MOTION) {
|
|
||||||
state = State.BAD_COMMAND;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -774,25 +794,25 @@ public class KeyHandler {
|
|||||||
* @param editor The editor to reset.
|
* @param editor The editor to reset.
|
||||||
*/
|
*/
|
||||||
public void partialReset(@Nullable Editor editor) {
|
public void partialReset(@Nullable Editor editor) {
|
||||||
count = 0;
|
|
||||||
keys = new ArrayList<>();
|
|
||||||
CommandState editorState = CommandState.getInstance(editor);
|
CommandState editorState = CommandState.getInstance(editor);
|
||||||
editorState.stopMappingTimer();
|
editorState.getMappingState().resetMappingSequence();
|
||||||
editorState.getMappingKeys().clear();
|
editorState.getCommandBuilder().resetInProgressCommandPart(getKeyRoot(editorState.getMappingState().getMappingMode()));
|
||||||
editorState.setCurrentNode(VimPlugin.getKey().getKeyRoot(editorState.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.
|
* @param editor The editor to reset.
|
||||||
*/
|
*/
|
||||||
public void reset(@Nullable Editor editor) {
|
public void reset(@Nullable Editor editor) {
|
||||||
partialReset(editor);
|
partialReset(editor);
|
||||||
state = State.NEW_COMMAND;
|
CommandState editorState = CommandState.getInstance(editor);
|
||||||
currentCmd.clear();
|
editorState.getCommandBuilder().resetAll(getKeyRoot(editorState.getMappingState().getMappingMode()));
|
||||||
currentArg = null;
|
}
|
||||||
digraph = null;
|
|
||||||
|
@NotNull
|
||||||
|
private CommandPartNode getKeyRoot(MappingMode mappingMode) {
|
||||||
|
return VimPlugin.getKey().getKeyRoot(mappingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -805,8 +825,6 @@ public class KeyHandler {
|
|||||||
VimPlugin.clearError();
|
VimPlugin.clearError();
|
||||||
CommandState.getInstance(editor).reset();
|
CommandState.getInstance(editor).reset();
|
||||||
reset(editor);
|
reset(editor);
|
||||||
lastChar = 0;
|
|
||||||
lastWasBS = false;
|
|
||||||
VimPlugin.getRegister().resetRegister();
|
VimPlugin.getRegister().resetRegister();
|
||||||
if (editor != null) {
|
if (editor != null) {
|
||||||
VisualGroupKt.updateCaretState(editor);
|
VisualGroupKt.updateCaretState(editor);
|
||||||
@@ -836,10 +854,12 @@ public class KeyHandler {
|
|||||||
|
|
||||||
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
// This class is copied from com.intellij.openapi.editor.actionSystem.DialogAwareDataContext.DialogAwareDataContext
|
||||||
private final static class DialogAwareDataContext implements DataContext {
|
private final static class DialogAwareDataContext implements DataContext {
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, PSI_FILE};
|
private static final DataKey[] keys = {PROJECT, PROJECT_FILE_DIRECTORY, EDITOR, VIRTUAL_FILE, PSI_FILE};
|
||||||
private final Map<String, Object> values = new HashMap<>();
|
private final Map<String, Object> values = new HashMap<>();
|
||||||
|
|
||||||
DialogAwareDataContext(DataContext context) {
|
DialogAwareDataContext(DataContext context) {
|
||||||
|
//noinspection rawtypes
|
||||||
for (DataKey key : keys) {
|
for (DataKey key : keys) {
|
||||||
values.put(key.getName(), key.getData(context));
|
values.put(key.getName(), key.getData(context));
|
||||||
}
|
}
|
||||||
@@ -874,17 +894,17 @@ public class KeyHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
CommandState editorState = CommandState.getInstance(editor);
|
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);
|
executeVimAction(editor, cmd.getAction(), context);
|
||||||
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
|
if (editorState.getMode() == CommandState.Mode.INSERT || editorState.getMode() == CommandState.Mode.REPLACE) {
|
||||||
VimPlugin.getChange().processCommand(editor, cmd);
|
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.
|
// selected by the user was to the empty register - unless we just executed the "select register" command.
|
||||||
if (cmd.getType() != Command.Type.SELECT_REGISTER) {
|
if (cmd.getType() != Command.Type.SELECT_REGISTER) {
|
||||||
VimPlugin.getRegister().resetRegister();
|
VimPlugin.getRegister().resetRegister();
|
||||||
@@ -896,14 +916,10 @@ public class KeyHandler {
|
|||||||
// "select register"
|
// "select register"
|
||||||
if (editorState.getSubMode() == CommandState.SubMode.SINGLE_COMMAND &&
|
if (editorState.getSubMode() == CommandState.SubMode.SINGLE_COMMAND &&
|
||||||
(!cmd.getFlags().contains(CommandFlags.FLAG_EXPECT_MORE))) {
|
(!cmd.getFlags().contains(CommandFlags.FLAG_EXPECT_MORE))) {
|
||||||
editorState.popState();
|
editorState.popModes();
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyHandler.getInstance().reset(editor);
|
KeyHandler.getInstance().reset(editor);
|
||||||
|
|
||||||
if (wasRecording && editorState.isRecording()) {
|
|
||||||
VimPlugin.getRegister().recordKeyStroke(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Editor editor;
|
private final Editor editor;
|
||||||
@@ -912,27 +928,8 @@ public class KeyHandler {
|
|||||||
private final KeyStroke key;
|
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;
|
private TypedActionHandler origHandler;
|
||||||
@Nullable private DigraphSequence digraph = null;
|
private int handleKeyRecursionCount = 0;
|
||||||
private char lastChar;
|
|
||||||
private boolean lastWasBS;
|
|
||||||
|
|
||||||
private boolean forwardSearch = true;
|
|
||||||
|
|
||||||
private static KeyHandler instance;
|
private static KeyHandler instance;
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,11 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.maddyhome.idea.vim;
|
package com.maddyhome.idea.vim;
|
||||||
|
|
||||||
|
import com.intellij.openapi.extensions.ExtensionPointListener;
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||||
|
import com.intellij.openapi.extensions.PluginDescriptor;
|
||||||
import com.maddyhome.idea.vim.group.KeyGroup;
|
import com.maddyhome.idea.vim.group.KeyGroup;
|
||||||
import com.maddyhome.idea.vim.handler.ActionBeanClass;
|
import com.maddyhome.idea.vim.handler.ActionBeanClass;
|
||||||
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
import com.maddyhome.idea.vim.handler.EditorActionHandlerBase;
|
||||||
import com.maddyhome.idea.vim.key.Shortcut;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -32,17 +33,41 @@ public class RegisterActions {
|
|||||||
|
|
||||||
public static final ExtensionPointName<ActionBeanClass> VIM_ACTIONS_EP =
|
public static final ExtensionPointName<ActionBeanClass> VIM_ACTIONS_EP =
|
||||||
ExtensionPointName.create("IdeaVIM.vimAction");
|
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.
|
* Register all the key/action mappings for the plugin.
|
||||||
*/
|
*/
|
||||||
static void registerActions() {
|
static void registerActions() {
|
||||||
if (actionsRegistered) return;
|
|
||||||
actionsRegistered = true;
|
|
||||||
|
|
||||||
registerVimCommandActions();
|
registerVimCommandActions();
|
||||||
registerEmptyShortcuts();
|
registerEmptyShortcuts();
|
||||||
|
initialRegistration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -58,6 +83,10 @@ public class RegisterActions {
|
|||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void unregisterActions() {
|
||||||
|
VimPlugin.getKey().unregisterCommandActions();
|
||||||
|
}
|
||||||
|
|
||||||
private static void registerVimCommandActions() {
|
private static void registerVimCommandActions() {
|
||||||
KeyGroup parser = VimPlugin.getKey();
|
KeyGroup parser = VimPlugin.getKey();
|
||||||
VIM_ACTIONS_EP.extensions().forEach(parser::registerCommandAction);
|
VIM_ACTIONS_EP.extensions().forEach(parser::registerCommandAction);
|
||||||
@@ -66,12 +95,8 @@ public class RegisterActions {
|
|||||||
private static void registerEmptyShortcuts() {
|
private static void registerEmptyShortcuts() {
|
||||||
final KeyGroup parser = VimPlugin.getKey();
|
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
|
// The {char1} <BS> {char2} shortcut is handled directly by KeyHandler#handleKey, so doesn't have an action. But we
|
||||||
// register the shortcuts or the editor will swallow them. Technically, the shortcuts will be registered as part of
|
// still need to register the shortcut, to make sure the editor doesn't swallow it.
|
||||||
// other commands, but it's best to be explicit
|
parser.registerShortcutWithoutAction(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0));
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
package com.maddyhome.idea.vim
|
||||||
|
|
||||||
import com.intellij.ide.BrowserUtil
|
import com.intellij.ide.BrowserUtil
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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, deprecated = true),
|
||||||
Storage("\$APP_CONFIG$/vim_local_settings.xml", roamingType = RoamingType.DISABLED)
|
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> {
|
class VimLocalConfig : PersistentStateComponent<Element> {
|
||||||
override fun getState(): Element {
|
override fun getState(): Element {
|
||||||
val element = Element("ideavim-local")
|
val element = Element("ideavim-local")
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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 static long lastBeepTimeMillis;
|
||||||
|
|
||||||
private boolean error = false;
|
private boolean error = false;
|
||||||
|
private String message = null;
|
||||||
|
|
||||||
private int previousStateVersion = 0;
|
private int previousStateVersion = 0;
|
||||||
private String previousKeyMap = "";
|
private String previousKeyMap = "";
|
||||||
@@ -330,6 +331,8 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setEnabled(final boolean enabled) {
|
public static void setEnabled(final boolean enabled) {
|
||||||
|
if (isEnabled() == enabled) return;
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
getInstance().turnOffPlugin();
|
getInstance().turnOffPlugin();
|
||||||
}
|
}
|
||||||
@@ -347,6 +350,10 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
|||||||
return getInstance().error;
|
return getInstance().error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getMessage() {
|
||||||
|
return getInstance().message;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicate to the user that an error has occurred. Just beep.
|
* 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) {
|
public static void showMessage(@Nullable String msg) {
|
||||||
|
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
|
getInstance().message = msg;
|
||||||
|
}
|
||||||
ProjectManager pm = ProjectManager.getInstance();
|
ProjectManager pm = ProjectManager.getInstance();
|
||||||
Project[] projects = pm.getOpenProjects();
|
Project[] projects = pm.getOpenProjects();
|
||||||
for (Project project : projects) {
|
for (Project project : projects) {
|
||||||
@@ -418,6 +428,12 @@ public class VimPlugin implements BaseComponent, PersistentStateComponent<Elemen
|
|||||||
private void turnOffPlugin() {
|
private void turnOffPlugin() {
|
||||||
KeyHandler.getInstance().fullReset(null);
|
KeyHandler.getInstance().fullReset(null);
|
||||||
|
|
||||||
|
// Unregister vim actions in command mode
|
||||||
|
RegisterActions.unregisterActions();
|
||||||
|
|
||||||
|
// Unregister ex handlers
|
||||||
|
CommandParser.getInstance().unregisterHandlers();
|
||||||
|
|
||||||
getEditor().turnOff();
|
getEditor().turnOff();
|
||||||
getSearch().turnOff();
|
getSearch().turnOff();
|
||||||
VimListenerManager.INSTANCE.turnOff();
|
VimListenerManager.INSTANCE.turnOff();
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
package com.maddyhome.idea.vim
|
||||||
|
|
||||||
import org.jdom.Element
|
import org.jdom.Element
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
package com.maddyhome.idea.vim.action
|
||||||
|
|
||||||
import javax.swing.KeyStroke
|
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
|
package com.maddyhome.idea.vim.action
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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.intellij.ui.KeyStrokeAdapter
|
||||||
import com.maddyhome.idea.vim.KeyHandler
|
import com.maddyhome.idea.vim.KeyHandler
|
||||||
import com.maddyhome.idea.vim.VimPlugin
|
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.EditorDataContext
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
import com.maddyhome.idea.vim.helper.StringHelper
|
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.helper.inNormalMode
|
||||||
import com.maddyhome.idea.vim.key.ShortcutOwner
|
import com.maddyhome.idea.vim.key.ShortcutOwner
|
||||||
import com.maddyhome.idea.vim.listener.IdeaSpecifics.aceJumpActive
|
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.InputEvent
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
@@ -90,7 +89,7 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
|||||||
if (aceJumpActive()) return false
|
if (aceJumpActive()) return false
|
||||||
val keyCode = keyStroke.keyCode
|
val keyCode = keyStroke.keyCode
|
||||||
if (LookupManager.getActiveLookup(editor) != null) {
|
if (LookupManager.getActiveLookup(editor) != null) {
|
||||||
return isEnabledForLookup(keyStroke)
|
return LookupKeys.isEnabledForLookup(keyStroke)
|
||||||
}
|
}
|
||||||
if (keyCode == KeyEvent.VK_ESCAPE) {
|
if (keyCode == KeyEvent.VK_ESCAPE) {
|
||||||
return isEnabledForEscape(editor)
|
return isEnabledForEscape(editor)
|
||||||
@@ -136,29 +135,6 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
|||||||
return fileEditorManager.allEditors.any { fileEditor -> editor == EditorUtil.getEditorEx(fileEditor) }
|
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 {
|
private fun isShortcutConflict(keyStroke: KeyStroke): Boolean {
|
||||||
return VimPlugin.getKey().getKeymapConflicts(keyStroke).isNotEmpty()
|
return VimPlugin.getKey().getKeymapConflicts(keyStroke).isNotEmpty()
|
||||||
}
|
}
|
||||||
@@ -189,6 +165,29 @@ class VimShortcutKeyAction : AnAction(), DumbAware {
|
|||||||
|
|
||||||
private fun getEditor(e: AnActionEvent): Editor? = e.getData(PlatformDataKeys.EDITOR)
|
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 {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val VIM_ONLY_EDITOR_KEYS: Set<KeyStroke> = ImmutableSet.builder<KeyStroke>().addAll(getKeyStrokes(KeyEvent.VK_ENTER, 0)).addAll(getKeyStrokes(KeyEvent.VK_ESCAPE, 0))
|
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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
if (lastCommand == null && VimRepeater.Extension.lastExtensionHandler == null) return false
|
||||||
|
|
||||||
// Save state
|
// Save state
|
||||||
val save = state.command
|
val save = state.executingCommand
|
||||||
val lastFTCmd = VimPlugin.getMotion().lastFTCmd
|
val lastFTCmd = VimPlugin.getMotion().lastFTCmd
|
||||||
val lastFTChar = VimPlugin.getMotion().lastFTChar
|
val lastFTChar = VimPlugin.getMotion().lastFTChar
|
||||||
val reg = VimPlugin.getRegister().currentRegister
|
val reg = VimPlugin.getRegister().currentRegister
|
||||||
@@ -62,7 +62,7 @@ class RepeatChangeAction : VimActionHandler.SingleExecution() {
|
|||||||
mot.count = 0
|
mot.count = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.setCommand(lastCommand)
|
state.setExecutingCommand(lastCommand)
|
||||||
|
|
||||||
KeyHandler.executeVimAction(editor, lastCommand.action, context)
|
KeyHandler.executeVimAction(editor, lastCommand.action, context)
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ class RepeatChangeAction : VimActionHandler.SingleExecution() {
|
|||||||
state.isDotRepeatInProgress = false
|
state.isDotRepeatInProgress = false
|
||||||
|
|
||||||
// Restore state
|
// Restore state
|
||||||
if (save != null) state.setCommand(save)
|
if (save != null) state.setExecutingCommand(save)
|
||||||
VimPlugin.getMotion().setLastFTCmd(lastFTCmd, lastFTChar)
|
VimPlugin.getMotion().setLastFTCmd(lastFTCmd, lastFTChar)
|
||||||
if (lastHandler != null) VimRepeater.Extension.lastExtensionHandler = lastHandler
|
if (lastHandler != null) VimRepeater.Extension.lastExtensionHandler = lastHandler
|
||||||
VimRepeater.repeatHandler = repeatHandler
|
VimRepeater.repeatHandler = repeatHandler
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.Command
|
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.handler.ChangeEditorActionHandler
|
||||||
import com.maddyhome.idea.vim.helper.EditorHelper
|
import com.maddyhome.idea.vim.helper.EditorHelper
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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.VimPlugin
|
||||||
import com.maddyhome.idea.vim.command.Argument
|
import com.maddyhome.idea.vim.command.Argument
|
||||||
import com.maddyhome.idea.vim.command.Command
|
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.handler.ChangeEditorActionHandler
|
||||||
|
|
||||||
class ChangeLastSearchReplaceAction : ChangeEditorActionHandler.SingleExecution() {
|
class ChangeLastSearchReplaceAction : ChangeEditorActionHandler.SingleExecution() {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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
|
* 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