This is the case regardless of how the original insertion started (`A`, `gi`, etc.).
There are still several problems (which I made note of), but this is a step in the right direction.
* `parsePattern` generally leaves backslashes alone, passing them on
to the regular expression parser.
* New `parseReplace` interprets backslashes. New definitions for `\b`
(backspace), `\&` (same as `$&`), and `\0` through `\9` (same as
`$1` through `$9`).
* Rewrite these parsers in imperative style to avoid any stack overflow.
Fixes#6890
This makes VSCode handle it for us (as if we weren't capturing these keypresses at all). The most noticeable effect is that <BS> no longer closes the autocomplete popup.
Fixes#3613
- Map ([|])(m|M) to motions to the prev|next start|end of Python functions
- Map ([|])([|]) to motions to the prev|next end|start of Python classes
Fixes#6213
This reduces the jank of the surround plugin substantially, fixes a number of bugs, and uses an InputBox for specifying tags.
Fixes#1818, fixes#5211, fixes#2893, fixes#6564, fixes#3386
- `I`, `gI`, `gi`
- `w` and `go` motions
- `<C-a>` in Insert mode
- `<C-y>` and `<C-e>` in Insert mode
- `.` after content change with `<BS>`, `<Del>`, and `<CR>`
Refs #5033
Rewrite `gq` reflow to apply manual spacing (including `joinspaces`
option) just when creating whitespace from what were linebreaks.
Fixes#6569
Fix precision around `textwidth`
Fixes#3509
I finally bit the bullet, deleted all of our put logic, and re-implemented it from scratch.
This includes `p`, `P`, `gp`, `gP`, `]p`, `[`, and `:put`.
In addition to cleaner, more maintainable code, this resulted in:
- Using replace transformations, which means better performance
- Fixing VisualBlock put and block-wise put (fixes#1796)
- Fixing put when the register contains a macro (fixes#3714)
- Fixing various other corner cases, particularly with regards to cursor placement
- Beefing up our test suite
I'm sure there are still obscure corner cases that we handle wrong, but it'll be easier going forward to fix them.
- Each register now points to an array - the i'th slot contains the content for the i'th cursor
- If there are more cursors than slots, the first slot is used as a backup
- Each slot contains either a RecordedState (in the case of a macro) or a string
- Newlines in those strings should be interpreted in the context of the associated RegisterMode
- The interface was changed somewhat to be safer and more consistent
I probably broke *something*, but the tests pass and this refactor enables further improvement of the terrible put logic, so I'll fix things as they come up.
- Rename word methods to be more intuitive
- Use Position methods instead of standalone functions
- Use an object for pseudo-kwargs
- Pass WordType instead of having separate methods for "big" words
- Take `TextDocument` as a parameter
The result is a bit verbose (a more fundamental refactor might be needed
at a later date), but it's consistent, safe, and extensible.
This prepares for some changes to fix corner cases in our word handling.
Refs #5663
This fixes some edge cases as well as doing the edits in parallel
Fixes#4915, Refs #5663
Known issue: interactive `:s` does not update the document until the last replace is confirmed
- Much better edit merging, so undoing/redoing should generally only take one replace
- Correct changelist edge cases
- Improve and organize related tests
Known issue: `U` after `O` is broken, but that's a small corner case and `U` is generally much better behaved now.
As a side-effect, our linting just got substantially stricter, and this had to be a pretty wide-reaching change to comply. Sorry if this complicates any merges!
Set `vim.neovimUseConfigFile` to true to use this feature
`vim.neovimConfigFile` points to the vimrc path; will use default path on system if left blank
Fixes#5045
When `changeWordIncludesWhitespace` is `false`, 'cw' is supposed to act
like 'ce' when the current character is a non-blank. However, it is
supposed to act like a regular 'w' motion when activated on a blank
character. This fixes a small typo for correctly detecting this case.
The motivation behind this is mostly to reduce the surface area Actions can interact with.
Remappings should not be visible to them (this is fundamentally logic internal to ModeHandler/Remapper).
- Searching with `/` or `?` no longer throws "Maximum call stack size exceeded"
- Add tests for searching with '/' and '?' with multicursors
Fixes#5844
The use of nested Promises here hurt my head when trying to accommodate a breaking change in typescript 4.1, so I'm just sorting this out for myself before doing the typescript upgrade.
<Shift+Tab> key was being captured but had no normalization implemented, so only '<shift+tab>' would work.
This commit makes '<S-tab>' work as well.
Fixes#4719
This means `vimState.editor` should never be undefined - now we should start using that instead of `vscode.window.activeTextEditor` to avoid a whole bunch of pesky race conditions.
Refs #5663
[X]p did not work in visual line mode. I've split PutCommandVisual and created a separate command for putting in visual line mode. This works by using the move count to temporarily replace the register content with a repeated version of itself. This is then used in the regular PutCommandVisual and the register is restored.
Fixes#5442
Currently when you have selections with multicursors if you move in a way that those cursors would combine would then result in a situation where our 'updateView' function would think that there was a different selection even when there wasn't, because it was still thinking it should have 2 selections.
This would result in our selections to be ignored count increasing and there would never be a selection change to clear that count, so any future selection changes would be ignored until the document was closed and reopened or vscode window was reloaded or restarted.
This seems to happen a lot of times when using snippets, because now when inserting a snippet it turns the selections to visual mode multicursor and sometimes if the user moves up/down without noticing that it is in visual mode (since previously it would still be in insert mode, but this is a different issue that I'm currently working on trying to make snippets not go into visual mode) then in those case it can create the situation I mentioned above. And the user will probably not even notice it until they click somewhere and try to move.
Fixes#5212, fixes#5248, fixes#5221, fixes#5268fixes#5380
- Potential remapped keys in insert mode followed by another key that is
itself an insert mode remap would not insert the first potential key
- This was due to a old piece of code that allowed for remaps in
insert mode to have other keys preceding them. So if you had 'jk' mapped
to 'Esc' and had 'ctrl+e' mapped to something else, if you pressed 'j'
and then 'ctrl+e' it wouldn't insert 'j' because it was allowing
'j<C-e>' to be considered a valid remap
- When the user force stops a recursive remapping it shouldn't throw an
error, it should just set the 'vimState.forceStopRecursiveRemapping'
which will then make all the remaining keys be ignored until the
recursive remap finishes.
- Add test for forced stop remaps on non infinite recursive remaps.
Fixes#5419
- Fix remaps confusing '<' as potential remap to special keys like '<C-x>'
- Add test for this situation
- Prevent showing special keys like '<C-x>' with virtual key decoration
Fixes#5188
Add a new entry for running Vim in nodeless environment and load platform-specific modules based on the target.
This PR includes changes to:
- fs. In node, it's node's native fs; in nodeless, it uses vscode.workspace.fs.
- historyFile. In node, it stores the history in file system; in nodeless, it stores in memory.
- logger. In node, it uses winson; in nodeless, it uses browser console.
- lastly, it relies on Webpack to tree shake unwanted code paths (for example, remove nvim related code paths from the bundle in nodeless environment).
This is a pretty massive change; see pull request #4735 for full details
Most notably:
- Support for operator-pending mode, including remaps and a half-cursor decoration
- Correct handling of ambiguous remaps with timeout
- Correct handling of recursive special case when the RHS starts with the LHS
- Correct handling of multi-key remaps in insert mode
- Failed movements that occur partway through a remap stop & discard the rest of the remap
- Implement `unmap` and `mapclear` in .vimrc
Refs #463, refs #4908Fixes#1261, fixes#1398, fixes#1579, fixes#1821, fixes#1835Fixes#1870, fixes#1883, fixes#2041, fixes#2234, fixes#2466Fixes#2897, fixes#2955, fixes#2975, fixes#3082, fixes#3086Fixes#3171, fixes#3373, fixes#3413, fixes#3742, fixes#3768Fixes#3988, fixes#4057, fixes#4118, fixes#4236, fixes#4353Fixes#4464, fixes#4530, fixes#4532, fixes#4563, fixes#4674Fixes#4756, fixes#4883, fixes#4928, fixes#4991, fixes#5016Fixes#5057, fixes#5067, fixes#5084, fixes#5125
Enables neovim capability and fixes arg parsing for the `:p[ut]` command. Apparently the put command allows no whitespace between the command name and the register name, so commands like `:put"` are perfectly valid. I've added some subparser tests to document this.
Fixes#5052Fixes#5090
- Make easymotion default decorations have the same defaults as the Vim
plugin.
- Deprecate no longer needed configurations like
'easymotionMarkerMargin' and 'easymotionMarkerWidthPerChar'.
- Change 'easymotionMarkerFontWeight' default to 'bold'
- Add seperate color for each character of two-character markers,
default values are the same as the Vim plugin. (two different yellows)
- Add color for dimmed characters, default value is the same as the Vim
plugin. (grey)
- Add color for higlighting characters searched with search n-characters
command, default value is the same as the Vim
plugin. (green)
- Add changes to README file and update the default values.
- Change easymotion TextEditorDecorations to make them simpler to use
and understand. Remove all unnecessary parts.
- Fix the dimming zones that were including the markers as well.
- Fix the hack for two consecutive markers that wasn't checking if those
markers were on the same line.
Fixes#5092Fixes#5022Fixes#4252Fixes#1746
- Store our selections when calling 'updateView' to be later ignored.
- Create a 'ignoreIntermediateSelections' flag that is set when running
an action to ignore any selection changes triggered by any step of that
action.
- When getting a selection change event we first check if it is one of
our selections. If it is we ignore it, if it is not we still ignore it
if the 'ignoreIntermediateSelections' flag is set or if we have other
selections to ignore, because that means this selection slipped in after
the end of the action. Otherwise we handle it.
- Create new handle for selection changes with kind 'Command'. (this is
triggered by editor commands like 'smartSelect.grow' but is also
triggered when we set the 'editor.selections' on 'updateView', except
this last one will now be ignored)
Fixes#1806
When moving horizontally on visual mode the desiredColumn wasn't being kept correctly, because we were updating the desiredColumn after correcting our cursors by shifting the stop to the right so that vscode included our stop on its selection.
Fixes#5048
This PR implements filter commands, which allows filtering lines in the buffer with an external command.
The following operators are implemented here:
- !{motion}{filter}
- !!{filter}
- {Visual/Visual block/Visual line}!{filter}
Fixes#4166Fixes#4857
This PR fixes a small bug, also described in the linked issue.
Right now, when you operate on "ap" (cap, dap, vap, ...) and the paragraph is a single line, vscodevim will operate till EOF.
Fixes#5012
This PR improves the argument movement, by handling some more edge-cases and being less aggressive on the existing whitespaces in the argument (i.e. preserving indentation-level) when doing the inner argument movement.
One of the edge-cases was not checking that the cursor is actually inside the delimiters, i.e. that we actually are inside an argument list. This caused the movement to span to the neighboring separators (,) across the buffer. This PR adds a check to fail the movement right at the beginning.
Unfortunately this requires 2 scans for delimiters/separators on successful movements. I think this is okay for the current scope of argument lists, since the search range is quite limited on the second scan. In a future update one could rework the logic, so that the find-functions actually keep track of all the visited separators on the first scan.
On another note: This early failure could be relaxed in a further update, so that comma-separated lists when they are on a single line are a valid movement (there may be several cases, where this feature could be useful, e.g. from x import a, b, c in python).
This is a direct successor to #4653
- Skip over word separators (as defined by `iskeyword`)
- Do not go over line breaks (throw E348)
- Escape characters in word so you can search for characters like `{`
Fixes#4808
Instead annotate in a comment, that this edge-case will not be handled for now,
because I can not think of any case, where this would cause undesired behaviour
fixes#2338
This commit implements SelectInnerArgument and SelectAroundArgument
based on a common base class and adds a first bunch of tests.
NOTE: Not all of them pass yet.
This PR ports the :!{cmd} bang command from Vim, allowing external shell commands to be run directly from Vim's command mode.
Key features:
- :!{cmd} executes the shell command
- :{range}!{cmd} executes the shell command, pipes the line range to stdin, and replaces the line range with the output from stdout and stderr
- Embedded bangs are replaced with the previous bang command (e.g. :!dir => :!echo ! will execute echo dir)
- Cross-platform, supports Unix and Windows shells
Fixes#3154, fixes#3136, fixes#3069, fixes#4920
This makes testing different setting combinations MUCH easier.
Settings coverage is very much lacking in our test suite, which we should definitely make an effort to improve. More sane test organization and automated code coverage detection would make our gaps more obvious.
VS Code is adding support for running extensions in a nodeless environment. This PR tries to refactor the code a bit to allow later on replacing node APIs (fs, child_process) with shims.
This PR should not change any functionality for running Vim in desktop.
Once we can run Vim in a web worker, we can also think about running Vim in its own worker, which at the end will help with the performance issue: https://github.com/microsoft/vscode/issues/65876
- Shortcut aliases were using the version with space but they are supposed
to use the version without space
- Add 'a' shortcut alias to '>'
- Add tests for alias
- Add some tests for visual and visual line mode (they are not extensive
but should be enough for now)
Fixes#4965
- Recording a macro with an uppercase letter whose register doesn't
exist yet, now creates that corresponding register
- After finishing recording a macro by pressing 'q' no longer throws an
error with 'concat'
- Calling a macro that doesn't exist no longer throws error. It just
returns the same vimState.
- Add tests for these cases
Fixes#4948
The current easymotion decorations are kinda wonky, they are misaligned and little bit intrusive, also it deviates from the official easymotion. With this pr it behaves more like the official
Fixes#4610Fixes#4524Fixes#3899Fixes#2938
- The count value is already stored on RecordedState so we only need to
send the remap keys and the corresponding actions will act accordingly
- The commands weren't respecting the count, if we mapped '<' in visual
mode to the command 'editor.action.outdentLines' we couldn't use it with
count, now we can.
Fixes#2244Fixes#4903
This PR ports the :put and :put! ex commands from Vim, as described by the official documentation. The command is just a way to put text on the line above or under the cursor (always linewise).
Key things this PR adds/modifies:
- Refactors PutCommand to take in an object of boolean flags, instead of a bunch of boolean parameters
- Adds two new PutCommand flags to force linewise put and force cursor to move to the last line of pasted text
- Creates a new ex command PutExCommand with full testing suite
Fixes#4741
- Stop docker tests from sending the entire app as context to the daemon
when building the image
- Add '--rm' to the container run command to remove the container when
done with the tests
- Fix paths to extensionDevelopmentPath and testsRoot
This PR totally fixes#4308, fixes#4457 and more.
Please check newly-added tests to get part of what this PR achieves.
These tests all fails without this PR, all of them are the correct behavior of original vim.
When executing yat or dat on a line where a new tag is opened (and there are only whitespaces between the beginning of the line and the opening < of the tag and the cursor is either on one of these whitespaces or on the opening <), the current version of the extension copies or deletes the outer tag, whereas Vim operates on the inner. This PR corrects the extension's behaviour.
Fixes#4685
After the PR #4830 I found weird that none of the tests captured the issue #4827.
After looking up the tests I found that there were no macro tests that handled multiple lines on same macro (like what happens on that issue) so decided to create a new test to prevent future issues like that one.
- Fix DotCommand deleting extra character when used after a remapped <Esc> in insert mode
Fixes#4817Fixes#4814
- Fix remapped <Esc> leaving trailing character when used with multiple cursors
Fixes#4811
Co-authored-by: Jason Fields <jasonfields4@gmail.com>
Currently when pasting lines of text (i.e. text in register is linewise)
over an existing selection, the code incorrectly yanks the selected
lines of text into the register specified by the command. This is
incorrect behaviour as the selected text should always be yanked into
the unnamed register (or clipboard register if appropriate).
Fixes#2895, fixes#2939.
Fix insert mode key remaps leaving characters behind. This happened due to the new historyTracker optimizations, where we don't add the new characters one by one to history, but rather just the first one and then the rest at the end.
Fixes#4787
Incorrect behaviour when cursor is in the middle of a line.
Refactor: indentation should be get in paragraph reflow rather than
being passed in as a parameter.
When you do a search with vim-sneak, VSCodeVim doesn't save your
position and you can't go back to where you were before using .
This PR adds isJump to both sneak movements to fix that.
Fixes#4696.
* Multicursor: when iterating the cursors to execute actions for each of them, we now temporarily replace the cursorStartPosition as well and update the given cursor
* Added tests for multicursor inner motions
This PR implements two text-objects from the vim-textobj-entire plugin
This Vim plugin adds two useful text-objects:
ae which represents the entire content of a buffer
ie which represents the entire content of a buffer without the leading and trailing spaces.
You can then use gUae to transform the whole text buffer content in uppercase, whereas normally you would have to use gggUG.
This text-object has the advantage that you can use it from anywhere your cursor is currently located, you don't have to be conscious of the cursor position.
Fixes#3379