1
0
mirror of https://github.com/chylex/IntelliJ-IdeaVim.git synced 2025-08-17 16:31:45 +02:00

Compare commits

...

21 Commits

Author SHA1 Message Date
Alex Plate
c9fd0782ae Use a different method for compatibility 2021-02-08 12:41:30 +03:00
Alex Plate
c5779935d3 Extract escape key code 2021-02-08 12:28:34 +03:00
Alex Plate
70154d4526 Add log line about NERDTree 2021-02-08 12:16:37 +03:00
Alex Plate
070dfae93d Fix nerdtree for multiple opened projects 2021-02-08 12:11:54 +03:00
Alex Plate
4e5fc734e2 Fix quick search in NERDTree 2021-02-08 11:22:53 +03:00
Alex Plate
9004749754 Update compatibility with ActionPromoter 2021-02-08 10:19:06 +03:00
Alex Plate
e42e7b81ef Fix tests 2021-02-02 19:14:02 +03:00
Alex Plate
e788221099 [VIM-2220] Do not try to get a command state for null editor 2021-02-02 11:37:39 +03:00
Alex Plate
e96b383339 Update email 2021-02-02 11:16:57 +03:00
Alex Plate
e63044e72f [VIM-2217] Fix AppCode specific code 2021-02-01 11:14:30 +03:00
Alex Plate
0ac530eb86 Add 大牙(Henry Zhu) to the contributors list 2021-02-01 10:32:53 +03:00
大牙(Henry Zhu)
c1fd63ab25 fix invalid url of docs 2021-02-01 10:28:48 +03:00
Alex Plate
fd0d010908 Update the link to ideajoin examples 2021-02-01 10:27:30 +03:00
Alex Plate
de159d6e3a Add IdeaVim actions promoter to promote vim actions 2021-02-01 10:17:33 +03:00
Alex Plate
27293c3d36 Deprecate EditorDataContext construction instead of making it private 2021-01-29 12:15:16 +03:00
Alex Plate
ffe55f05ba Update plugin verifier versions 2021-01-29 11:46:56 +03:00
Alex Plate
d3b9a5af37 Update todo list of the NERDTree plugin 2021-01-29 11:38:41 +03:00
Alex Plate
d7772bec48 Add empty test to avoid warning 2021-01-29 11:33:06 +03:00
Alex Plate
c2e32d8989 Add docs as submodule 2021-01-28 18:25:57 +03:00
Alex Plate
cdbff1ef64 Remove doc folder from the project 2021-01-28 18:25:00 +03:00
Alex Plate
7d20053401 Disable random mappings property test 2021-01-26 11:19:58 +03:00
24 changed files with 202 additions and 411 deletions

View File

@@ -73,6 +73,7 @@
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$3</ID>
<ID>MagicNumber:VimHighlightedYank.kt$VimHighlightedYank.HighlightHandler$4</ID>
<ID>MatchingDeclarationName:CommandDefinition.kt$CommandName</ID>
<ID>MaxLineLength:EditorDataContext.kt$EditorDataContext$class</ID>
<ID>MaxLineLength:ExBeanClass.kt$ExBeanClass$logger&lt;ExBeanClass&gt;().error("IdeaVim doesn't accept contributions to `vimActions` extension points. Please create a plugin using `VimExtension`. Plugin to blame: ${this.pluginDescriptor.pluginId}")</ID>
<ID>MaxLineLength:NotificationService.kt$NotificationService$notification.addAction(AppendToIdeaVimRcAction(notification, "set clipboard+=ideaput", "ideaput") { OptionsManager.clipboard.append(ClipboardOptionsData.ideaput) })</ID>
<ID>MaxLineLength:NotificationService.kt$NotificationService.AppendToIdeaVimRcAction$private inner</ID>

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "doc"]
path = doc
url = https://github.com/JetBrains/ideavim.wiki.git

View File

@@ -343,6 +343,10 @@ Contributors:
[![icon][github]](https://github.com/DeveloperHacker)
&nbsp;
Sergei Vorobyov
* [![icon][mail]](mailto:daya0576@gmail.com)
[![icon][github]](https://github.com/daya0576)
&nbsp;
大牙(Henry Zhu)
If you are a contributor and your name is not listed here, feel free to
contact the maintainers.

View File

@@ -33,6 +33,12 @@ usual beta standards.
* [VIM-1799](https://youtrack.jetbrains.com/issue/VIM-1799)
[VIM-1794](https://youtrack.jetbrains.com/issue/VIM-179a)
Special characters are not interpreted on yanking
* [VIM-2218](https://youtrack.jetbrains.com/issue/VIM-2218) Fix some shortcuts for 2021.+
* [VIM-2217](https://youtrack.jetbrains.com/issue/VIM-2217) Fix adding new line at the end of the file for the AppCode
* [VIM-2220](https://youtrack.jetbrains.com/issue/VIM-2220) Do not try to get a commandState for null editor
### Merged PRs:
* [269](https://github.com/JetBrains/ideavim/pull/269) by [大牙(Henry Zhu)](https://github.com/daya0576): fix invalid link of submodule docs
## 0.64, 2020-12-23

View File

@@ -81,12 +81,12 @@ Here are some examples of supported vim features and commands:
* Motion / deletion / change / window / etc. commands
* Key mappings
* Marks / Macros / Digraphs / Registers
* Some [set commands](doc/set-commands.md)
* Some [set commands](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands)
* Full Vim regexps for search and search/replace
* Vim web help
* `~/.ideavimrc` configuration file
[Emulated Vim plugins](doc/emulated-plugins.md):
[Emulated Vim plugins](https://github.com/JetBrains/ideavim/wiki/Emulated-plugins):
* vim-easymotion
* vim-surround
@@ -198,7 +198,7 @@ Put your settings to `$XDG_CONFIG_HOME/ideavim/ideavimrc` file.
Emulated Vim Plugins
--------------------
See [doc/emulated-plugins.md](doc/emulated-plugins.md)
See [doc/emulated-plugins.md](https://github.com/JetBrains/ideavim/wiki/Emulated-plugins)
Executing IDE Actions
---------------------
@@ -257,15 +257,15 @@ IdeaVim tips and tricks
- `set ideajoin` to enable join via the IDE. See the [examples](https://jb.gg/f9zji9).
- Make sure `ideaput` is enabled for `clipboard` to enable native IJ insertion in Vim.
- Sync IJ bookmarks and Vim marks: `set ideamarks`
- Check out more [ex commands](doc/set-commands.md).
- Check out more [ex commands](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
- Use your vim settings with IdeaVim. Put `source ~/.vimrc` in `~/.ideavimrc`.
> :warning: Please note that IdeaVim currently parses `~/.ideavimrc` & `~/.vimrc` files via simple pattern-matching.
See [VIM-669](https://youtrack.jetbrains.com/issue/VIM-669) for proper parsing
of VimL files.
- Control the status bar icon via the [`ideastatusicon` option](doc/set-commands.md).
- Not familiar with the default behaviour during a refactoring? See the [`idearefactormode` option](doc/set-commands.md).
- Control the status bar icon via the [`ideastatusicon` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
- Not familiar with the default behaviour during a refactoring? See the [`idearefactormode` option](https://github.com/JetBrains/ideavim/wiki/%22set%22-commands).
Some facts about Vim
-------

View File

@@ -59,7 +59,7 @@ runIdeForUiTests {
}
runPluginVerifier {
ideVersions = ["IC-2020.2.3", "IC-2020.3"]
ideVersions = ["IC-2020.2.3", "IC-2020.3.2"]
downloadDirectory = "${project.buildDir}/pluginVerifier/ides"
teamCityOutputFormat = true
}

1
doc Submodule

Submodule doc added at 44ef1a858b

View File

@@ -1,186 +0,0 @@
Emulated Vim Plugins
--------------------
IdeaVim extensions emulate plugins of the original Vim. In order to use
IdeaVim extensions, you have to enable them via this command in your `~/.ideavimrc`:
```
set <extension-name>
```
If you reuse your existing `.vimrc` file using `source ~/.vimrc`, IdeaVim can parse and enable plugins that are defined
using [vim-plug](https://github.com/junegunn/vim-plug) or [vundle](https://github.com/VundleVim/Vundle.vim).
No additional set commands in `~/.ideavimrc` are required.
If you'd like to disable some plugin that's enabled in `.vimrc`, you can use `set no<extension-name>`
in `~/.ideavimrc`.
Available extensions:
## easymotion
* Setup:
* Install [IdeaVim-EasyMotion](https://plugins.jetbrains.com/plugin/13360-ideavim-easymotion/)
and [AceJump](https://plugins.jetbrains.com/plugin/7086-acejump/) plugins.
* `set easymotion`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/easymotion/vim-easymotion'</code>
<br/>
<code>Plug 'easymotion/vim-easymotion'</code>
<br/>
<code>Plug 'vim-easymotion'</code>
</details>
* Emulates [vim-easymotion](https://github.com/easymotion/vim-easymotion)
* Commands: All commands with the mappings are supported. See the [full list of supported commands](https://github.com/AlexPl292/IdeaVim-EasyMotion#supported-commands).
## surround
* Setup: `set surround`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/tpope/vim-surround'</code>
<br/>
<code>Plug 'tpope/vim-surround'</code>
<br/>
<code>Plug 'vim-surround'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1697'</code>
</details>
* Emulates [vim-surround](https://github.com/tpope/vim-surround)
* Commands: `ys`, `cs`, `ds`, `S`
## multiple-cursors
* Setup: `set multiple-cursors`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/terryma/vim-multiple-cursors'</code>
<br/>
<code>Plug 'terryma/vim-multiple-cursors'</code>
<br/>
<code>Plug 'vim-multiple-cursors'</code>
</details>
* Emulates [vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors)
* Commands: `<A-n>`, `<A-x>`, `<A-p>`, `g<A-n>`
## commentary
* Setup: `set commentary`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/tpope/vim-commentary'</code>
<br/>
<code>Plug 'tpope/vim-commentary'</code>
<br/>
<code>Plug 'vim-commentary'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=3695'</code>
<br/>
<code>Plug 'tomtom/tcomment_vim'</code>
<br/>
<code>Plug 'tcomment_vim'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=1173'</code>
</details>
* Emulates [commentary.vim](https://github.com/tpope/vim-commentary)
* Commands: `gcc`, `gc + motion`, `v_gc`
* By [Daniel Leong](https://github.com/dhleong)
## ReplaceWithRegister
* Setup: `set ReplaceWithRegister`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/vim-scripts/ReplaceWithRegister'</code>
<br/>
<code>Plug 'vim-scripts/ReplaceWithRegister'</code>
<br/>
<code>Plug 'ReplaceWithRegister'</code>
<br/>
<code>Plug 'https://github.com/inkarkat/vim-ReplaceWithRegister'</code>
<br/>
<code>Plug 'inkarkat/vim-ReplaceWithRegister'</code>
<br/>
<code>Plug 'vim-ReplaceWithRegister'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2703'</code>
</details>
* Emulates [ReplaceWithRegister](https://github.com/vim-scripts/ReplaceWithRegister)
* Commands: `gr`, `grr`
* By [igrekster](https://github.com/igrekster)
## argtextobj
* Setup:
* `set argtextobj`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/vim-scripts/argtextobj.vim'</code>
<br/>
<code>Plug 'vim-scripts/argtextobj.vim'</code>
<br/>
<code>Plug 'argtextobj.vim'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2699'</code>
</details>
* By default, only the arguments inside parenthesis are considered. To extend the functionality
to other types of brackets, set `g:argtextobj_pairs` variable to a comma-separated
list of colon-separated pairs (same as VIM's `matchpairs` option), like
`let g:argtextobj_pairs="(:),{:},<:>"`. The order of pairs matters when
handling symbols that can also be operators: `func(x << 5, 20) >> 17`. To handle
this syntax parenthesis, must come before angle brackets in the list.
* Emulates [argtextobj.vim](https://www.vim.org/scripts/script.php?script_id=2699)
* Additional text objects: `aa`, `ia`
## exchange
* Setup: `set exchange`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/tommcdo/vim-exchange'</code>
<br/>
<code>Plug 'tommcdo/vim-exchange'</code>
<br/>
<code>Plug 'vim-exchange'</code>
</details>
* Emulates [vim-exchange](https://github.com/tommcdo/vim-exchange)
* Commands: `cx`, `cxx`, `X`, `cxc`
* By [fan-tom](https://github.com/fan-tom)
## textobj-entire
* Setup: `set textobj-entire`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/kana/vim-textobj-entire'</code>
<br/>
<code>Plug 'kana/vim-textobj-entire'</code>
<br/>
<code>Plug 'vim-textobj-entire'</code>
<br/>
<code>Plug 'https://www.vim.org/scripts/script.php?script_id=2610'</code>
</details>
* Emulates [vim-textobj-entire](https://github.com/kana/vim-textobj-entire)
* Additional text objects: `ae`, `ie`
* By [Alexandre Grison](https://github.com/agrison)
## highlightedyank
* Setup:
* `set highlightedyank`
* <details>
<summary>Alternative vim-plug / vundle syntax</summary>
<code>Plug 'https://github.com/machakann/vim-highlightedyank'</code>
<br/>
<code>Plug 'machakann/vim-highlightedyank'</code>
<br/>
<code>Plug 'vim-highlightedyank'</code>
</details>
* if you want to optimize highlight duration, assign a time in milliseconds:
`let g:highlightedyank_highlight_duration = "1000"`
A negative number makes the highlight persistent.
`let g:highlightedyank_highlight_duration = "-1"`
* if you want to change background color of highlight you can provide the rgba of the color you want e.g.
`let g:highlightedyank_highlight_color = "rgba(160, 160, 160, 155)"`
* Emulates [vim-highlightedyank](https://github.com/machakann/vim-highlightedyank)
* By [KostkaBrukowa](https://github.com/KostkaBrukowa)

View File

@@ -1,51 +0,0 @@
Some examples of join command with `ideajoin` option enabled.
Put `set ideajoin` to your `~/.ideavimrc` to enable this functionality.
1) Automatic join concatenated lines:
```
"Hello" + -> "Hello world"
" world!"
```
2) Nested if's:
```
if (a) { -> if (a && b) {
if (b) { ...
... }
}
}
```
3) Remove braces from one line for / if / while:
```
if (fail) { -> if (fail) return;
return;
}
```
4) Kotlin one line method:
```
fun myNumber(): Int { -> fun myNumber(): Int = 42
return 42
}
```
5) Join declaration and initialization:
```
int a; -> int a = 5;
a = 5;
```
6) Chain call:
```
sb.append("a"); -> sb.append("a").append("b");
sb.append("b");
```
And other functions provided by the plugins.

View File

@@ -1,137 +0,0 @@
List of Supported Set Commands
==============================
The following `:set` commands can appear in `~/.ideavimrc` or be set manually in the command mode:
'clipboard' 'cb' clipboard options
Standard clipboard options plus
`ideaput` (default on) - IdeaVim ONLY
enable native idea paste action for put operations
'digraph' 'dg' enable the entering of digraphs in Insert mode
'gdefault' 'gd' the ":substitute" flag 'g' is by default
'history' 'hi' number of command-lines that are remembered
'hlsearch' 'hls' highlight matches with the last search pattern
'ignorecase' 'ic' ignore case in search patterns
'iskeyword' 'isk' defines keywords for commands like 'w', '*', etc.
'incsearch' 'is' show where search pattern typed so far matches
`keymodel` `km` String (default "continueselect,stopselect")
List of comma separated words, which enable special things that keys
can do. These values can be used:
startsel Using a shifted special[1] key starts selection (either
Select mode or Visual mode, depending on "key" being
present in 'selectmode').
stopsel Using a NOT-shifted special[1] key stops selection.
Automatically enables `stopselect` and `stopvisual`
stopselect Using a NOT-shifted special[1] key stops - IdeaVim ONLY
select mode and removes selection.
stopvisual Using a NOT-shifted special[1] key stops - IdeaVim ONLY
visual mode and removes selection.
continueselect Using a shifted arrow key doesn't - IdeaVim ONLY
start selection, but in select mode
acts like startsel is enabled
continuevisual Using a shifted arrow key doesn't - IdeaVim ONLY
start selection, but in visual mode
acts like startsel is enabled
'matchpairs' 'mps' pairs of characters that "%" can match
'maxmapdepth' 'mmd' Maximum depth of mappings
'more' 'more' When on, listings pause when the whole screen is filled.
'nrformats' 'nf' number formats recognized for CTRL-A command
'number' 'nu' print the line number in front of each line
'relativenumber' 'rnu' show the line number relative to the line with
the cursor
'scroll' 'scr' lines to scroll with CTRL-U and CTRL-D
'scrolljump' 'sj' minimum number of lines to scroll
'scrolloff' 'so' minimum number of lines above and below the cursor
'selection' 'sel' what type of selection to use
`selectmode` `slm` String (default "")
This is a comma-separated list of words, which specify when to start
Select mode instead of Visual mode, when a selection is started.
Possible values:
mouse when using the mouse
key when using shifted special[1] keys
cmd when using "v", "V", or <C-V>
ideaselection when IDE sets a selection - IdeaVim ONLY
(examples: extend selection, wrap with while, etc.)
'showmode' 'smd' message on the status line to show current mode
'showcmd' 'sc' show (partial) command in the status bar
'sidescroll' 'ss' minimum number of columns to scroll horizontally
'sidescrolloff' 'siso' min. number of columns to left and right of cursor
'smartcase' 'scs' no ignore case when pattern is uppercase
'timeout' 'to' use timeout for mapped key sequences
'timeoutlen' 'tm' timeout duration for a mapped key sequence
'undolevels' 'ul' maximum number of changes that can be undone
'viminfo' 'vi' information to remember after restart
'visualbell' 'vb' use visual bell instead of beeping
'wrapscan' 'ws' searches wrap around the end of file
IdeaVim only commands:
`ideamarks` `ideamarks` Boolean (default true)
If true, creation of global mark will trigger creation of IDE's bookmark
and vice versa.
`idearefactormode` `idearefactormode` String(default "select")
Define the mode that would be enabled during
the refactoring (renaming, live template, introduce variable, etc)
Use one of the following values:
- keep - keep the mode that was enabled before starting a refactoring
- select - start refactoring in select mode
- visual - start refactoring in visual mode
This option has effect if you are in normal, insert or replace mode before refactoring start.
Visual or select mode are not changed.
`ideajoin` `ideajoin` Boolean (default false)
If true, join command will be performed via IDE
See wiki/`ideajoin` examples
`ideastatusicon` `ideastatusicon` String(default "enabled")
Define the behavior of IdeaVim icon in the status bar.
Use one of the following values:
- enabled - icon is shown in the status bar
- gray - use the gray version of the icon
- disabled - hide the icon
`ideawrite` `ideawrite` String (default "all")
"file" or "all". Defines the behaviour of ":w" command.
Value "all" enables execution of ":wa" (save all) command on ":w" (save).
This feature exists because some IJ options like "Prettier on save" or "ESlint on save"
work only with "save all" action. If this option is set to "all", these actions work
also with ":w" command.
`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>"
`ideavimsupport` `ideavimsupport` List of strings (default "dialog")
Define the list of additional buffers where IdeaVim is enabled.
- dialog - enable IdeaVim in dialogs
- singleline - enable IdeaVim in single line editors (not suggested)
----------
[1] - cursor keys, <End>, <Home>, <PageUp> and <PageDown>

View File

@@ -91,4 +91,17 @@
</aliases>
</vimExtension>
</extensions>
<!-- IdeaVim extensions-->
<extensions defaultExtensionNs="com.intellij">
<projectService serviceImplementation="com.maddyhome.idea.vim.extension.nerdtree.NerdTree$NerdDispatcher"/>
</extensions>
<projectListeners>
<listener class="com.maddyhome.idea.vim.extension.nerdtree.NerdTree$ProjectViewListener"
topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"/>
</projectListeners>
<applicationListeners>
<listener class="com.maddyhome.idea.vim.extension.nerdtree.NerdTree$NerdProjectListener"
topic="com.intellij.openapi.project.ProjectManagerListener"/>
</applicationListeners>
</idea-plugin>

View File

@@ -79,6 +79,8 @@
<postStartupActivity implementation="com.maddyhome.idea.vim.PluginStartup" order="first"/>
<editorFloatingToolbarProvider implementation="com.maddyhome.idea.vim.ui.ReloadFloatingToolbar"/>
<actionPromoter implementation="com.maddyhome.idea.vim.key.VimActionsPromoter" order="last"/>
</extensions>
<xi:include href="/META-INF/includes/ApplicationServices.xml" xpointer="xpointer(/idea-plugin/*)"/>

View File

@@ -821,7 +821,7 @@ public class KeyHandler {
*
* @param editor The editor to reset.
*/
public void partialReset(@Nullable Editor editor) {
public void partialReset(@NotNull Editor editor) {
CommandState editorState = CommandState.getInstance(editor);
editorState.getMappingState().resetMappingSequence();
editorState.getCommandBuilder().resetInProgressCommandPart(getKeyRoot(editorState.getMappingState().getMappingMode()));
@@ -832,7 +832,7 @@ public class KeyHandler {
*
* @param editor The editor to reset.
*/
public void reset(@Nullable Editor editor) {
public void reset(@NotNull Editor editor) {
partialReset(editor);
CommandState editorState = CommandState.getInstance(editor);
editorState.getCommandBuilder().resetAll(getKeyRoot(editorState.getMappingState().getMappingMode()));
@@ -848,7 +848,7 @@ public class KeyHandler {
*
* @param editor The editor to reset.
*/
public void fullReset(@Nullable Editor editor) {
public void fullReset(@NotNull Editor editor) {
VimPlugin.clearError();
CommandState.getInstance(editor).reset();
reset(editor);
@@ -856,10 +856,8 @@ public class KeyHandler {
if (registerGroup != null) {
registerGroup.resetRegister();
}
if (editor != null) {
VisualGroupKt.updateCaretState(editor);
editor.getSelectionModel().removeSelection();
}
VisualGroupKt.updateCaretState(editor);
editor.getSelectionModel().removeSelection();
}
// This method is copied from com.intellij.openapi.editor.actionSystem.EditorAction.getProjectAwareDataContext

View File

@@ -374,8 +374,6 @@ public class VimPlugin implements PersistentStateComponent<Element>, Disposable
}
private void turnOffPlugin() {
KeyHandler.getInstance().fullReset(null);
SearchGroup searchGroup = getSearchIfCreated();
if (searchGroup != null) {
searchGroup.turnOff();

View File

@@ -330,10 +330,7 @@ class CommandState private constructor() {
private val defaultModeState = ModeState(Mode.COMMAND, SubMode.NONE)
@JvmStatic
@Contract("null -> new")
fun getInstance(editor: Editor?): CommandState {
if (editor == null) return CommandState()
fun getInstance(editor: Editor): CommandState {
var res = editor.vimCommandState
if (res == null) {
res = CommandState()

View File

@@ -25,15 +25,20 @@ import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ProjectManagerListener
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowId
import com.intellij.openapi.wm.ex.ToolWindowManagerEx
import com.intellij.openapi.wm.ex.ToolWindowManagerListener
import com.intellij.ui.KeyStrokeAdapter
import com.intellij.ui.TreeExpandCollapse
import com.intellij.ui.speedSearch.SpeedSearchSupply
import com.intellij.util.ui.tree.TreeUtil
import com.maddyhome.idea.vim.KeyHandler
import com.maddyhome.idea.vim.VimPlugin
@@ -46,6 +51,7 @@ import com.maddyhome.idea.vim.helper.MessageHelper
import com.maddyhome.idea.vim.helper.runAfterGotFocus
import com.maddyhome.idea.vim.key.CommandNode
import com.maddyhome.idea.vim.key.CommandPartNode
import com.maddyhome.idea.vim.key.MappingOwner
import com.maddyhome.idea.vim.key.Node
import com.maddyhome.idea.vim.key.RequiredShortcut
import com.maddyhome.idea.vim.key.RootNode
@@ -54,6 +60,15 @@ import java.awt.event.KeyEvent
import javax.swing.KeyStroke
import javax.swing.SwingConstants
/**
* Features and issues:
* - Files are opened with "open with a single click"
* - Enable mappings in project view for regilar commands "j", "k", etc.
* - Support more regular commands (gg, G, etc.)
* - Support ex commands in project view (https://youtrack.jetbrains.com/issue/VIM-1042#focus=Comments-27-4654338.0-0)
* - Add label after pressing `/`
* - Write UI tests
*/
/**
* Key Description help-tag~
@@ -105,9 +120,11 @@ import javax.swing.SwingConstants
* ?........Toggle the display of the quick help.......................|NERDTree-?|
*/
class NerdTree : VimExtension {
override fun getName(): String = "NERDTree"
override fun getName(): String = pluginName
override fun init() {
LOG.info("IdeaVim: Initializing NERDTree extension. Disable this extension if you observe a strange behaviour of the project tree. E.g. moving down on 'j'")
registerCommands()
addCommand("NERDTreeFocus", IjCommandHandler("ActivateProjectToolWindow"))
@@ -117,7 +134,10 @@ class NerdTree : VimExtension {
addCommand("NERDTreeFind", IjCommandHandler("SelectInProjectView"))
addCommand("NERDTreeRefreshRoot", IjCommandHandler("Synchronize"))
ProjectManager.getInstance().openProjects.forEach { project -> installDispatcher(project) }
synchronized(monitor) {
commandsRegistered = true
ProjectManager.getInstance().openProjects.forEach { project -> installDispatcher(project) }
}
}
class IjCommandHandler(private val actionId: String) : CommandAliasHandler {
@@ -148,16 +168,38 @@ class NerdTree : VimExtension {
}
}
private fun installDispatcher(project: Project) {
val action = NerdDispatcher.instance
val shortcuts = collectShortcuts(actionsRoot).map { RequiredShortcut(it, owner) }
action.registerCustomShortcutSet(
KeyGroup.toShortcutSet(shortcuts),
(ProjectView.getInstance(project) as ProjectViewImpl).component
)
class ProjectViewListener(private val project: Project) : ToolWindowManagerListener {
// [VERSION UPDATE] 2020.1+
override fun toolWindowShown(id: String, toolWindow: ToolWindow) {
if (ToolWindowId.PROJECT_VIEW != toolWindow.id) return
val dispatcher = NerdDispatcher.getInstance(project)
if (dispatcher.speedSearchListenerInstalled) return
val tree = ProjectView.getInstance(project).currentProjectViewPane.tree ?: return
val supply = SpeedSearchSupply.getSupply(tree, true) ?: return
// NB: Here might be some issues with concurrency, but it's not really bad, I think
dispatcher.speedSearchListenerInstalled = true
supply.addChangeListener {
dispatcher.waitForSearch = false
}
}
}
class NerdProjectListener : ProjectManagerListener {
override fun projectOpened(project: Project) {
synchronized(monitor) {
if (!commandsRegistered) return
installDispatcher(project)
}
}
}
class NerdDispatcher : DumbAwareAction() {
internal var waitForSearch = false
internal var speedSearchListenerInstalled = false
override fun actionPerformed(e: AnActionEvent) {
var keyStroke = getKeyStroke(e) ?: return
val keyChar = keyStroke.keyChar
@@ -182,8 +224,33 @@ class NerdTree : VimExtension {
}
}
override fun update(e: AnActionEvent) {
val project = e.project ?: return
// Special processing of esc.
if ((e.inputEvent as? KeyEvent)?.keyCode == ESCAPE_KEY_CODE) {
e.presentation.isEnabled = waitForSearch
return
}
if (waitForSearch) {
e.presentation.isEnabled = false
return
}
e.presentation.isEnabled = !speedSearchIsHere(project)
}
private fun speedSearchIsHere(project: Project): Boolean {
val component = ProjectView.getInstance(project).currentProjectViewPane.tree ?: return false
return SpeedSearchSupply.getSupply(component) != null
}
companion object {
val instance = NerdDispatcher()
fun getInstance(project: Project): NerdDispatcher {
return project.getService(NerdDispatcher::class.java)
}
private const val ESCAPE_KEY_CODE = 27
}
/**
@@ -351,9 +418,27 @@ class NerdTree : VimExtension {
registerCommand("g:NERDTreeMapMenu", "m", NerdAction.ToIj("ShowPopupMenu"))
registerCommand("g:NERDTreeMapQuit", "q", NerdAction.ToIj("HideActiveWindow"))
registerCommand("g:NERDTreeMapToggleZoom", "A", NerdAction.ToIj("MaximizeToolWindow"))
registerCommand("/", NerdAction.Code { project, _, _ ->
NerdDispatcher.getInstance(project).waitForSearch = true
})
registerCommand("<ESC>", NerdAction.Code { project, _, _ ->
val instance = NerdDispatcher.getInstance(project)
if (instance.waitForSearch) {
instance.waitForSearch = false
}
})
}
companion object {
const val pluginName = "NERDTree"
internal val monitor = Any()
internal var commandsRegistered = false
private val LOG = logger<NerdTree>()
fun callAction(name: String, context: DataContext) {
val action = ActionManager.getInstance().getAction(name) ?: run {
VimPlugin.showMessage(MessageHelper.message("action.not.found.0", name))
@@ -390,5 +475,14 @@ class NerdTree : VimExtension {
res
} else emptySet()
}
private fun installDispatcher(project: Project) {
val dispatcher = NerdDispatcher.getInstance(project)
val shortcuts = collectShortcuts(actionsRoot).map { RequiredShortcut(it, MappingOwner.Plugin.get(pluginName)) }
dispatcher.registerCustomShortcutSet(
KeyGroup.toShortcutSet(shortcuts),
(ProjectView.getInstance(project) as ProjectViewImpl).component
)
}
}
}

View File

@@ -242,7 +242,7 @@ class NotificationService(private val project: Project?) {
val IDEAVIM_STICKY_GROUP = NotificationGroup("ideavim-sticky", NotificationDisplayType.STICKY_BALLOON, false)
const val IDEAVIM_NOTIFICATION_ID = "ideavim"
const val IDEAVIM_NOTIFICATION_TITLE = "IdeaVim"
const val ideajoinExamplesUrl = "https://github.com/JetBrains/ideavim/wiki/%60ideajoin%60-examples"
const val ideajoinExamplesUrl = "https://jb.gg/f9zji9"
private fun createIdeaVimRcManually(message: String, project: Project?) {
val notification = Notification(IDEAVIM_NOTIFICATION_ID, IDEAVIM_NOTIFICATION_TITLE, message, NotificationType.WARNING)

View File

@@ -102,5 +102,5 @@ val Editor.inSingleCommandMode
get() = this.subMode == CommandState.SubMode.SINGLE_COMMAND && this.inNormalMode
@get:JvmName("commandState")
val Editor?.commandState
val Editor.commandState
get() = CommandState.getInstance(this)

View File

@@ -21,7 +21,7 @@ import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.editor.Editor
class EditorDataContext private constructor(private val editor: Editor, private val contextDelegate: DataContext? = null) : DataContext {
class EditorDataContext @Deprecated("Please use `init` method") constructor(private val editor: Editor, private val contextDelegate: DataContext? = null) : DataContext {
/**
* Returns the object corresponding to the specified data identifier. Some of the supported data identifiers are
* defined in the [PlatformDataKeys] class.

View File

@@ -0,0 +1,33 @@
/*
* IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
* Copyright (C) 2003-2021 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.key
import com.intellij.openapi.actionSystem.ActionPromoter
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.EmptyAction
import com.maddyhome.idea.vim.action.VimShortcutKeyAction
class VimActionsPromoter : ActionPromoter {
override fun promote(actions: MutableList<out AnAction>, context: DataContext): List<AnAction> {
return actions.filter {
it is EmptyAction.MyDelegatingAction && it.delegate is VimShortcutKeyAction
}
}
}

View File

@@ -113,7 +113,7 @@ object IdeaSpecifics {
//region Enter insert mode after surround with if
if (surrounderAction == action.javaClass.name && surrounderItems.any { action.templatePresentation.text.endsWith(it) }) {
editor?.let {
val commandState = editor.commandState
val commandState = it.commandState
while (commandState.mode != CommandState.Mode.COMMAND) {
commandState.popModes()
}
@@ -228,6 +228,7 @@ object IdeaSpecifics {
caret.putUserData(facedAppCodeTemplate, offset..templateEnd)
}
if (offsetLeftEnd >= 0
&& offset + 1 <= editor.fileSize
&& editor.document.charsSequence.subSequence(offsetLeftEnd, offset + 1).toString() == TEMPLATE_END) {
caret.shake()

View File

@@ -49,9 +49,13 @@ public abstract class JavaVimTestCase extends JavaCodeInsightFixtureTestCase {
protected void setUp() throws Exception {
super.setUp();
KeyHandler.getInstance().fullReset(myFixture.getEditor());
Editor editor = myFixture.getEditor();
if (editor != null) {
KeyHandler.getInstance().fullReset(editor);
}
OptionsManager.INSTANCE.resetAllOptions();
VimPlugin.getKey().resetKeyMappings();
VimPlugin.clearError();
}
@Override

View File

@@ -88,7 +88,10 @@ abstract class VimTestCase : UsefulTestCase() {
myFixture.setUp()
myFixture.testDataPath = testDataPath
// Note that myFixture.editor is usually null here. It's only set once configureByText has been called
KeyHandler.getInstance().fullReset(myFixture.editor)
val editor = myFixture.editor
if (editor != null) {
KeyHandler.getInstance().fullReset(editor)
}
resetAllOptions()
VimPlugin.getKey().resetKeyMappings()
VimPlugin.getSearch().resetState()
@@ -100,6 +103,8 @@ abstract class VimTestCase : UsefulTestCase() {
ExEntryPanel.getInstance().entry.setBounds(0, 0, 100, 25)
NeovimTesting.setUp(this)
VimPlugin.clearError()
}
private val testDataPath: String

View File

@@ -25,7 +25,8 @@ import org.jetbrains.jetCheck.PropertyChecker
// TODO: 25.01.2021 Add neovim test integration
class MapPropertyTest : VimPropertyTest() {
fun testRandomMappings() {
// Disabled, it works too long
fun /*test*/RandomMappings() {
PropertyChecker.checkScenarios {
ImperativeCommand { env ->
val editor = configureByText(simpleText)
@@ -61,6 +62,10 @@ class MapPropertyTest : VimPropertyTest() {
}
}
}
fun testEmpty() {
// Just an empty test
}
}
// I think, it would be enough to test normal mode only. Not sure if it's true