`o` Motion Cursor Position Incorrect
Opened this issue ยท 24 comments
Hi @aioutecism, hi @alisonatwork ๐ Long time no speak! Hope you are well.
I noticed a new bug in amVim in the last weeks (maybe something to do with a new version of VS Code - I'm using 1.72.2
- commit d045a5eda657f4d7b676dedbfa7aab8207f8a075
):
The o motion (moving to the next line, similar to hitting return at the end of a line or ctrl/cmd-return in the middle of a line) INTERMITTENTLY causes the cursor to move one position too far to the left on the next line (one space less indented). This leads to incorrect line position and indentation and also trailing space on the line. (for me, since I use the code formatter Prettier, it does not lead to problems with indentation or trailing space, but I imagine this would be different for those not using a formatter).
Again, to be clear, this is an intermittent problem - it does not happen every time that the o motion is used.
This does not happen when hitting the return key.
Demo:
Kapture.2022-10-31.at.17.52.52.mp4
This was also happening in 1.34.0
, before the upgrade to 1.35.0
.
This bug is not present in VSCodeVim.
My other installed extensions:
$ code --list-extensions
auiworks.amvim
bierner.comment-tagged-templates
bungcip.better-toml
Cardinal90.multi-cursor-case-preserve
codespaces-contrib.codeswing
dbaeumer.vscode-eslint
dozerg.tsimportsorter
esbenp.prettier-vscode
formulahendry.auto-close-tag
frigus02.vscode-sql-tagged-template-literals
frigus02.vscode-sql-tagged-template-literals-syntax-only
GitHub.copilot
GitHub.remotehub
JannisX11.batch-rename-extension
kumar-harsh.graphql-for-vscode
mattpocock.ts-error-translator
mechatroner.rainbow-csv
meganrogge.template-string-converter
mrmlnc.vscode-json5
ms-vscode.remote-repositories
redhat.vscode-commons
redhat.vscode-yaml
rohit-gohri.format-code-action
silvenon.mdx
styled-components.vscode-styled-components
stylelint.vscode-stylelint
sysoev.vscode-open-in-github
unifiedjs.vscode-mdx
usernamehw.errorlens
wix.glean
wmaurer.change-case
Another unusual thing when switching between insert and normal modes is that the character under the cursor can sometimes be duplicated (*only visually*) to the right of the current position (again, intermittent):
Kapture.2022-10-31.at.18.14.47.mp4
This is *only a visual duplication* - no {
character is actually added to the code here.
Not sure if this is related, but also seems like an "off-by-one" error...
@rebornix you wouldn't have any idea why these types of indentation / cursor position problems would be happening with some of the latest VS Code releases would you?
Hmm, interesting. I too have noticed some unusual off-by-one stuff happening recently, but I thought perhaps it was a long-standing quirk that I had forgotten about. I was on sabbatical for over a year so didn't really spend a lot of time behind a computer - or VS Code - and I've only been using it heavily again in the past couple months. I'll put this on my list of stuff to take a look at. I know there is quite a lot of code in the extension that tries to nudge the cursor left or right in certain situations to try make things behave more vim-y.
On a side note, @karlhorky, could you perhaps also take a look at the PR #303 ? It addresses one of the issues lots of people have tried to work around - the how to get normal hjkl keys to step over wrapped lines. It was the inspiration behind me finally getting gj
and gk
implemented, but I think we still need a solution for the case where people would prefer to bind their default hjkl to "cursorMove" behavior instead of full line up and down. The solution proposed in the PR works great, but I'm just wondering if we could make it even cleaner or more useful for people with different use cases.
I've been playing around on my local this evening (and using VS Code + amVim all day for work) and I haven't been able to reproduce either the o
error, or the duplicated character weirdness. My suspicion with the duplicated cursor thing is that it might be a graphics rendering issue, especially if it only started happening recently. Maybe there was an engine change that isn't playing nice with your graphics card? Or if it only happens on brackets it might be related to the new bracket matching? I'm not sure.
The o
error feels similar to the view mode strangeness that I've noticed in amVim. The error I notice is when you turn on v
to select, it moves you one character to the right like in vim, but then when you arrow down, it moves you another character to the right. It's always off-by-one when you are one line different than your starting line. Unless you think that might be related, I will open a new ticket for that, because that does annoy me a bit. That said, I haven't found any of those o
problems specfically on either my home computer (mostly C, WSL and Python extensions) or my work computer (WSL, Python and miscellaneous JS/TS frontend extensions). Did you try disabling the other extensions, especially stuff that listens to your typing like auto close tag, to see if it made a difference?
Just tried disabling all other extensions, still happening. Also tried on VS Code Insiders (1.73.0-insider
, commit 8fa188b2b301d36553cbc9ce1b0a146ccb93351f
), still there.
It is intermittent though - sometimes it only happens once in 20 times. Feels like a race condition - two actions being performed, and one of them (moving the cursor one to the left) happening after the other in some cases. Maybe some promise isn't being awaited or something.
I have a MacBook Pro M1 - maybe the speed contributes to this.
At first, I thought it was based on code, but I narrowed down a simple reproduction to this code (happens at the end of the lines with (
and {
on them).
export default async function uploadImage(
) {
}
@karlhorky I still haven't been able to reproduce this on any of my test machines, but I have a suspicion about what it might be. If you have a bit of time, would you be able to apply this patch on your local and see if it makes any difference?
diff --git a/src/Dispatcher.ts b/src/Dispatcher.ts
index b12e96c..c1fbcad 100644
--- a/src/Dispatcher.ts
+++ b/src/Dispatcher.ts
@@ -68,9 +68,9 @@ export class Dispatcher {
this.disposables.push(
window.onDidChangeTextEditorSelection(() => {
// Ensure this is executed after all pending commands.
- setTimeout(() => {
- ActionMode.switchByActiveSelections(this._currentMode.id);
- ActionMoveCursor.updatePreferredColumn();
+ setTimeout(async () => {
+ await ActionMode.switchByActiveSelections(this._currentMode.id);
+ await ActionMoveCursor.updatePreferredColumn();
this._currentMode.onDidChangeTextEditorSelection();
}, 0);
}),
There is another piece of code elsewhere which blocks preferred column updates from happening in a 100ms window, and it's possible that something needs to happen to change the timeout there as well, but this might be the culprit for switching modes at least.
Thanks for the suggestion!
Weirdly enough, I can't reproduce right now either. I tried to increase memory pressure and various other things, but did not get it reproduced.
I'll keep an eye on it over the next days and weeks, and if I can reproduce then I'll try making your suggestion above, cheers!
@alisonatwork Did the 1.36.0
release contain some fixes for this?
- Small improvements to mode change behavior to avoid unexpected cursor placement.
https://github.com/aioutecism/amVim-for-VSCode/releases/tag/1.36.0
I can't currently reproduce this, so maybe either 1.36.0
fixed this? Or something in VS Code changed?
In any case, I'll close this for now. ๐
Hi @karlhorky glad to hear you haven't experienced this any more. I suspect it might have been a temporary quirk of VSCode on Mac, but who knows? Either way, the investigation did lead to a bit of promise-handling optimization that arrived in 1.36.0, so amVim robustness was improved even if we didn't find the cause. Thanks for the report!
Weirdly, this started happening to me for about a week, and then it stopped again. It was mostly happening when editing PHP, and less so with Python. Just leaving this note here to give more context in case this is a bug.
Thank you for reporting this. I've had this problem recently, and it happens roughly half the time I add a newline in Go code, and I have not been able to discern a consistent rule for when it will/won't.
Strangely, for me it only began when I installed the latest version of vscode the release before last (long after you reported this issue, even though I use vscode almost every day and update immediately upon notification). And it's still happening in the current vscode release and I can't figure out how to fix it. I created this question on StackOverflow but got no responses:
How to fix newline indentation in recent version of vscode
I hope it eventually stops happening for me, like it did for you.
Ah, but I see you hypothesized that 1.36.0 might have fixed this, and I'm still on 1.34.0. For some reason vscode isn't auto-updating it beyond 1.34.0 for now. Is that expected? I'm on Linux, if that would make a difference. I guess I'll look into a manual upgrade
For some reason vscode wasn't updating the amVim extension. I removed the extension (1.34.0), restarted vscode, and reinstalled it, and that gave me 1.36.0.
Unfortunately I'm still experiencing an issue.
I used ffmpeg's x11grab to briefly record some examples. Seems to happen often with hitting o
in the middle of a line of Go code to insert a newline below. I apologize for the poor video quality and my background image occasionally bleeding through, not sure why that happened.
https://user-images.githubusercontent.com/1707476/221380521-3a20118c-57c6-460a-a317-87195315801e.mp4
Apparently that x265 video didn't embed. If anyone can point me to tips on how to make/attach a better screen recording for github from linux/gnome I'll try again. I did a little searching and didn't find a good solution yet
I use Kap, but this is macOS-only. What Sindre has recommended over there is Kooha:
Thanks for commenting, @jrefior. I have to say that I, too, am now experiencing this behavior from time to time at work in a variety of different programming languages.
The frustrating thing is that it doesn't seem to be a repeatable set of events that causes it to happen. No one language or operating system or vim command usage pattern. I do suspect it is some kind of race condition, but I can't see where it could be happening in the amVim code.
When I was originally looking into this I added logging around which column amVim considered to be the "current" one, since selecting (or remembering) the preferred column is a special behavior of amVim that it subsequently uses for up/down navigation, but it seemed like jumping to the "wrong" indent was happening at the VSCode level, while amVim still "remembered" the correct column, which I found even more confusing.
In any case, I will reopen this and try to do some more digging on what the cause might be when I find the time.
What Sindre has wulkano/Kap#994 (comment) over there is Kooha
Thanks for pointing that out. I installed Kooha, but it didn't work, and going through the troubleshooting checklist I eventually figured out why. Years ago when I installed Fedora I chose the Cinnamon spin. Apparently that meant X11 and LightDM and no Wayland, and this screen capture app works through Wayland.
I don't think it's recommended to run more than one display manager. I don't know how I would drop Cinnamon to switch to Wayland without an OS reinstall from scratch. I probably should have known my environment better and caught on to that sooner, but at least I learned something.
The .mp4 file I uploaded plays for me in VLC and demonstrates the problem, but I understand downloading mp4s is not as nice as the embedded format, and there are some occasional weird graphical glitches in my video. Maybe I'll find a better screen recording technique that works on my system. I just found OBS Studio, which looks like a better fit for my system. If I figure something out I'll try to record another issue demo
- On Fedora / GNOME 42+, it seems there is a built-in screen recorder from GNOME
- Or Kazam seems to be another alternative for X11
On Fedora / GNOME 42+
Thanks for pointing those out @karlhorky . Sorry, I should have said that the first thing I tried (before ffmpeg x11grab) was the GNOME screen recorder. It did produce videos, but the entire duration of the videos was a still snapshot of the screen, like the same screenshot displayed for tens of seconds instead of a recording of things as they changed. It also never showed a red dot in the corner, as the documentation suggested it would. I don't know why that is. It again could be because I chose the Cinnamon spin, I'm not sure.
OBS Studio was available through DNF package manager though, I installed it, and it seems to work well on my system. I recorded a new issue demo that may help with diagnosing the problem.
Thanks for your work on amVim @alisonatwork , and your attention to this issue. When I first encountered this issue while using amVim 1.34.0 it also seemed completely intermittent/random to me. After I upgraded to 1.36.0 it has seemed much more consistent in my testing so far, but that was just yesterday so it may be too early for me to say. You can see in the video that it happens quite often for me in editing Go code.
To me it looks like it may depend on both cursor position and recent cursor movement, setting up some sort of context, prior to the newline being added. But as I'm not really familiar with the source I may be off base.
At first, because it only happened to me after I upgraded vscode (I only experienced the issue in vscode 1.75.0 and 1.75.1, not before), I suspected something had changed in vscode to bring about the issue. But I don't know, and it may be that amVim updated to 1.34.0 at the same time. I don't know what earlier version of amVim I might have been running before 1.34.0.
If I can help more with testing/reproducing (or how to set up a test Go project) let me know
obs-01.mp4
Maybe the same problem as #317.
I continue to experience this intermittently. It doesn't happen all the time, but VS Code does seem to sometimes get "stuck" in a broken state where the frequency of it happening is greatly increased for that session.
@alisonatwork Does the order of actions registered to a key matter? Would the patch below make any difference?
Looking at the code, if amvim insert a new line and then goes into insert mode, the cursor bar should end up to the left of the last space on the new line, so there must be some special handling elsewhere to move the cursor bar to the end of line, which I assume won't be needed if we go into insert mode first?
diff --git a/src/Modes/Normal.ts b/src/Modes/Normal.ts
index 5bc5042..f02860e 100644
--- a/src/Modes/Normal.ts
+++ b/src/Modes/Normal.ts
@@ -77,7 +77,7 @@ export class ModeNormal extends Mode {
{
keys: 'o',
- actions: [ActionInsert.newLineAfter, ActionMode.toInsert],
+ actions: [ActionMode.toInsert, ActionInsert.newLineAfter],
},
{
keys: 'O',
Hi @qfz, thank you for your comment. I use amVim every day at work so this bug annoys me every day too, but unfortunately I have been too busy with work to test out your patch.
I am not sure if the code will allow the newLineAfter command if the mode changed, or if it does allow it, then it might result in the repeat command (.
) or count (3o
) behaving differently, so we would need to do some testing. Whenever I have some time I will try, but it's tough to find time outside of normal work hours so I would really welcome any help from you or others on this thread if you are able to test some of these ideas and see if they result in a consistent fix.
Okay, I think I have a partial fix for this in 1.37.0. It's not yet available on VS Code Marketplace or Open VSX due to token problems, but stay tuned. If anyone would like to pull the Github release and compile their own version to give it a try, that would be super helpful. It's not a 100% fix, but it does seem to reduce the incidents of problems in my initial testing. I go back to work tomorrow, so that will be the real test...
Finally, I found a stable reproducible progress(v1.3.7). Steps are:
- Select and delete some lines, by:
Shift+V
,J
orK
, thend
. - Move cursor to the end of the line,
Shift+4
. (line 26 in my example) - Append a new line,
o
.
Expected behavior
The insert mode is enabled and the cursor should be the next line with correct indentation, i.e. 4 spaces. But the cursor will be a letter left to the correct position (3 spaces). And all spaces in the left is selected. See the screenshot below.
Thanks for still looking into this! I gave your test case a try but couldn't reproduce it on my machine, in either Python or TypeScript code, but I definitely still feel like something is not quite right because I also occasionally experience this. I think it is some kind of race condition issue when multiple extensions are doing stuff at the same time and then somehow the async code doesn't reliably execute in the order we would expect, so it ends up moving the cursor to the wrong column.
This is still on my backburner to look at, it's just a matter of finding the time to do it in between my normal job ๐ Please keep adding information, anything could help us to track down and fix it, whether me or another contributor.