As the GitHub Copilot is placed right in the editor component, the IdeaVim's actions are also collected. Action promoter promotes the IdeaVim's action and, since the data context has the editor, executes a Vim's actions like backspace.
Now we make sure that IdeaVim works only in the actual editor.
Since this change may affect some places where the IdeaVim used to work, but won't work now (this will be a surprise), a registry key is introduced to help the users that face this problem.
The `editorInFocus` used the weak reference in order to avoid editor leaks. However, if the user is unlucky, the GC may be called in between the console closing and switching focus to the new editor. In this case, the logic breaks and the Editor remains in the insert mode.
Now, we store only the required information about the last used editor.
This commit fixes 2 bugs at once:
1. Correctly trim surround with closing brackets motion, e.g.: `cs()`.
It should trim all surrounding white space or leave things unchanged if
there's no space.
For example cases like these:
"( ${c}foo )" // single spaces
"( ${c}foo )" // multiple spaces
"( ${c}foo)" // assymetric spaces
"(${c} )" // single space without text
"(${c} )" // multiple spaces without text
Should trim white spaces into these results accordingly:
"${c}(foo)"
"${c}(foo)"
"${c}(foo)"
"${c}()"
"${c}()"
In case of no spaces - they should be left unchanged, e.g.:
"(${c}foo)" // no spaces around the word
"(${c})" // empty parenthesis
2. Leave empty parenthesis unchanged. IdeaVim now deleted them instead.
**Context**:
In vim surround extendsion closing brackets (`}, ], )`) should remove
whitespace when using `cs` movement.
Example:
- Before: `{ example }`
- Movement: `cs{}`
- After: `{example}`
This was because were replaced with a string from `SURROUND_PAIRS` map,
which does not have any context about removing characters.
**Solution**:
Inspired from VSCode's VIM plugin[^1], I have introduced new class
`SurroundPair` that will carry this context about need to trim
characters.
**Disclaimer**:
I have never written in `Kotlin` so solution may be not use best
practices, though at least this PR seems to fix the problem and tests
are passing.
**Ticket**:
- https://youtrack.jetbrains.com/issue/VIM-1824/Vim-Surround-Does-not-remove-whitespace-with-the-closing-bracket
[^1]: 04fe42aa81/src/actions/plugins/surround.ts (L455)
1. `rawText` vs `text` is confusing and `rawText` was misused, we do not need this field in IdeaVim at all
2. `rawText` and `keys` are the same thing, just parsed. And for some reason, rawText was a nullable field
3. Register is an immutable class now
4. Working with Register class is easier and more compact now
When I added the selection clipboard, it was confusing to explain to people how this option works and why they should prepend, because the parsing was broken
I've also removed "exclude" part, because it doesn't work in IdeaVim and can confuse people
This is important for initialising options. We can't rely on FileEditorManager.selectedTextEditor, as 2024.2 changed behaviour to reset to null during creation of a new editor. This fixes tests (and option initialisation) for 242.
Also supports `mapclear!` and `unmap!`
Moves parsing of the bang modifier to the parser so we can tell the difference between `map! foo bar` and `map ! foo bar`
E.g. `map foo bar` and `vmap foo baz` would only output one map for `foo` when calling `:map`. Now it will output all maps that match the ex command's modes. This change also improves the marker characters in the first column of map output.
The window splitting was refactored to initialize the editor async. So, we have to wait till the editor will become available.
This can't be done while holding the EDT, so we start this bunch of tests from the non-EDT thread.
The problem happens in tests: after the refactorings in 242, the `EditorListenerTracker` may be called before the initialization of the IdeaVim. In this case, it'll report the VimDocumentListener as a leaked listener, however, it's incorrect.
Generally, I think that this situation with the listener tracker is a bug.
There should be no changes in IdeaVim behaviour as the multicaster does the same thing: subscribes every editor on this listener. However, the multicaster does this in the "registerEditor" stage. However, I don't think this is a problem.
The problem happens in tests: after the refactorings in 242, the `EditorListenerTracker` may be called before the initialization of the IdeaVim. In this case, it'll report the FocusChangeListener as a leaked listener, however, it's incorrect.
Generally, I think that this situation with the listener tracker is a bug.
There should be no changes in IdeaVim behaviour as the multicaster does the same thing: subscribes every editor on this listener. However, the multicaster does this in the "registerEditor" stage. However, I don't think this is a problem.
With the AI functionality, the shortcut ctrl-right got more important. However, previously it was defined as VIM_ONLY shortcut. However, taking the fact that IJ defines several actions for such shortcuts, it's not clear why we prohibit the users from using these shortcuts with the IDE actions.
Taking the fact, that we default shortcuts to VIM, I expect no changes in the behaviour.
However, just arrows are still hidden from setting the IDE handler. I think, it reduces the cognitive load for the user, especially taking the fact that arrows work almost equally in vim and IJ.
List is based on Vim's documentation, although not all digraphs are documented. Additional digraphs are added based on the output of `:digraphs`. These additional digraphs include some digraphs that produce the same character, so the code is updated to handle duplicates, with the same ordering/priority as Vim.
Extra digraphs include the Euro symbol (`=e` and `Eu`), quadruple prime (`4'`) and bullet (`oo`), amongst others.
Also removes a number of non-standard digraphs. The symbols generated don't match the descriptions. The code appears to be private use, so are not reliable. Once custom digraphs are implemented, they can be easily added back in `~/.ideavimrc`
Vim only use the `~` prefix if the encoding is "latin1". We can just treat it as though the encoding is Unicode, and match the other places we format printable characters. Note that for Vim, if `'display'` contains "uhex", then all unprintable characters are shown in hex, including control characters (`^C`, etc.). IdeaVim does not support the `'display'` option.
`OperatorArguments.mode` is the mode *before* the command was completed, rather than the current mode, which is non-obvious. E.g. for a command in Insert mode, it will still be Insert, and for a (simple) command in Normal, it will still be Normal. The only difference is that a command such as `dw` would be in Operator-pending before the command is completed. That logic is not required for this method, so it's safe to use the current mode.
This allows us to start to deprecate `OperatorArguments.mode`.
It's easier to just look at mode. We don't need the additional check on command builder, because we can't be in OP_PENDING without pushing an operator action to the command builder
Only Command has a count. The motion argument is now a sealed class hierarchy, and consists only of the motion action and optional argument. This is to reduce confusion over which count to use, and potential incorrect calculation of the count