Implement virtual space
Implementation of virtual space as discussed here: https://github.com/microsoft/vscode/issues/13960
Examples of this feature: rec.webm rec2.webm
Most of the changes fall into one of these categories:
- updated move commands to allow moving the cursor beyond end of line
- code updated to properly handle column numbers beyond the end of line
CursorPosition.leftoverVisibleColumnsreplaced withcolumnHint, which contains the column number that we want to stay in. This makes the calculations easier, but the change needed to be propagated to a few places.
Notable changes in specific files:
replaceCommand.ts- updated to add spaces when typing beyond end of linemouseTarget.ts- updated to generate column for mouse positions beyond end of lineviewLines.ts- this change was necessary to allow virtual space also on last line of a filecursorWordOperations.ts- without this change, Ctrl + Right Arrow (next word) beyond end of line goes to the end of the line instead of the next line
Testing:
- I added a simple unit test but can implement more
@microsoft-github-policy-service agree
I have been using @x17jiri 's fork for nearly 80 hours already and haven't crossed a single problem. Please review and approve this pull request.
@alexdima
Virtual Space is an absolute must. It is extremely annoying, very frustrating trying to find the cursor. But I am impressed with what has been done with VSCode. I am a little unsure, goofy new keyboard from Logitech, but it does seem the input response is a little slow. Have not worked with VSCode for very long, a couple of days but will revert back to VS if needed.
And how do I add it? Check for updates in VSCode - nothing. Enable Experimental Features?
@r2d2Proton This is not merged in official VSCode yet. If you want to try it you can download build artifacts from my fork:
https://github.com/x17jiri/vscode/actions/runs/11200839841
Then go to "File / Preferences / Settings" and find virtual space
@alexdima What more is required for this PR to be accepted?
So this is moving forward after all, thanks @alexdima, it's very much appreciated. I still not understand the "community pr approvals", do these have to be from random people from the community or they have to be from "official" collaborators from the project? If these have to be from official collaborators, could you please ask someone to take a look?
@aiday-mar Bless us! :-)
@alexdima Thank you for review. I'll try to make the update. Is there anyone I can bother if I have questions?
@x17jiri Sure, I'm happy to help. I will keep an eye out, but if I'm not answering timely please drop me an email too.
this functionality is enabled in simple code editors like the one used for the git commit message, we need to disable it in such contexts.
Pardon me, why?
@alexdima I'm still finishing some minor details but wanted to check the basic design.
There are some differences from line wrapping which mean the information cannot stay only in the view model.
- The code converts positions from view model to model and back. Unlike with wrapping, information gets lost when we clip positions. One particular place where this can be problem is selection tracking during edits.
- edit commands need to know when to insert spaces
What I did:
- for view model,
SingleCursorStatestores positions in virtual space - for model, positions are clipped at line length and excess columns are stored in
leftoverVisualColumns - as long as we have a partial cursor state, we can recover the other part without loss of information
However, some parts of code use only Selection or Position, not SingleCursorState. For those:
- I added function
getSelectionInVirtualSpace()which returns model selection unclipped (column = column + leftoverVisualColumns) and used it instead ofgetSelection()where the information is needed - code that's not updated to use
getSelectionInVirtualSpace()will see model selections clipped at line length
I updated two low level functions in editor/common/cursor/cursor.ts so it's easy to make updates on higher levels and often it's enough to just replace getSelection() with getSelectionInVirtualSpace()
- when pushing edits, virtual space positions are handled by inserting spaces
- selection tracking algorithm should now handle virtual space positions. Although this may still need some tuning
I reverted changes in text buffer and also previous commits "fix hover" and "fix move lines", which are not necessary with this new approach.
@x17jiri you are doing a really impressive job. Thank you very much.
@m6502 Thank you. I think I've caught most bugs in this new version, but if you have some time, any help with testing will be appreciated :-)
Build artifacts can be found here: https://github.com/x17jiri/vscode/actions/runs/12200915080
@m6502 Thank you. I think I've caught most bugs in this new version, but if you have some time, any help with testing will be appreciated :-)
I have been using the latest releases for working and I'm still getting a good time with them. I'm not finding anything broken in my workflow.
@alexdima , thank you for moving this forward. I did a few tests of this updated implementation and here is what I found:
-
Adding cursors using
Alt + Shift + Up/Downclips the new cursors at the end of line. I think this is because by default, this command works with model lines -
When there is a copilot suggestion and you press
right arrow, the suggestion stays displayed and the cursor jumps after it. I think this is because the "cursor state changed" signal is not emitted when only the virtual space offset changes -
Moving lines using
Alt + Up/Downloses virtual space position -
If the buffer is updated in the background we lose position. I use format on save and when a file is saved, the cursor may or may not get clipped depending on whether the formatter made changes. This may be difficult to fix without the extra tracked ranges data and it may actually be mitigated by auto save. At the moment of auto saving, the cursors are not in virtual space
I can help either with more testing or trying to fix some of these things.
I have been using the last build artifact for Windows (# 31) for two months already. As it didn't build for Linux this weekend I started using # 30 and I'm very happy with it too.
@alexdima The remaining issues seem to be just small nuisances. Can't we move forward and integrate this on the main build? This is a feature that some of us really crave about.
Oh no, it died in January! It was so close! 😢
I still use this fork exclusively instead of the official editor. It still performs fantastically well. I'm pretty sure this PR could be accepted.
Who is responsible for accepting this PR?
As far as I know it should be @alexdima
How can we get in touch with him?
I don't know, further than citing him like @alexdima or writing to the e-mail address in his Github profile page https://github.com/alexdima
Thank you for support and testing everyone.
I rebased my changes on top of version 1.101.2. If anyone's interested, the binaries can be found here https://github.com/x17jiri/vscode/actions/runs/15948156263
Thank you for support and testing everyone.
I rebased my changes on top of version 1.101.2. If anyone's interested, the binaries can be found here https://github.com/x17jiri/vscode/actions/runs/15948156263
Thank you for the new build — I really appreciate it. However, there are issues with the extensions; most of them aren't functioning properly. The ideal long-term solution would be to integrate this implementation directly into the main VSCode repository. Which issues need to be addressed in order to make that possible?
@kosthala what extensions are not working for you?
As far as I've tested both new builds are working fine on my side, Windows 10 and Linux (CachyOS / Arch)
@kosthala what extensions are not working for you?
As far as I've tested both new builds are working fine on my side, Windows 10 and Linux (CachyOS / Arch)
Most of the extensions show a yellow warning triangle and have stopped working. The one I rely on most is the C/C++ extension. The error message says:
The C/C++ extension may only be used with Microsoft Visual Studio, Visual Studio for Mac, Visual Studio Code, Azure DevOps, Team Foundation Server, or other successor Microsoft products and services for developing and testing your applications.
Thank you for support and testing everyone.
I rebased my changes on top of version 1.101.2. If anyone's interested, the binaries can be found here https://github.com/x17jiri/vscode/actions/runs/15948156263
Hi there,
I've been using your implementation for more than a half year now, and recently had the chance to test your latest release.
There's one issue I'd consider a bug:
With virtual white space enabled, enter several lines of text into a new document tab/window. Position the text cursor somewhere in some line that is not the first one and repeat hitting the cursor-left key.
What happens: When the first position in that line is reached, the cursor remains stuck there instead of going to the end of the previous line.
I've been using Visual Studio (non-code) for more than two decades now and that ones implementation of virtual white space is somewhat ingrained into my editing habits, and therefore I'd wish vs code to be more compatible with that.
Something else, which I'd consider more of a wish, or a feature request:
When selecting a text rectangle and copying that into the clipboard, it would be very nice to have the same behaviour Visual Studio (non-code) shows upon insertion. The rectangular content gets inserted as a text rectangle, and not as new lines of text.
Say you have a document with just three lines of text:
one horse x
two battery y
three staple z
Selecting the column that begins with "horse" so that it includes the white space after "battery" and copying it to the clipboard (via Ctrl-C) and then moving the cursor in front of "one" and inserting (via Ctrl-V) it would result in
horse one horse x
battery two battery y
staple three staple z
Could it be that your implementation of virtual white space might play a role to achieve this behaviour that Visual Studio (non-code) has?
There's one issue I'd consider a bug:
With virtual white space enabled, enter several lines of text into a new document tab/window. Position the text cursor somewhere in some line that is not the first one and repeat hitting the cursor-left key.
What happens: When the first position in that line is reached, the cursor remains stuck there instead of going to the end of the previous line.
@kirnbichler It's funny how our backgrounds can influence our preferences.
I have virtual space from Turbo Pascal ingrained in my memory and that's why I added an extra if statement just to stop the cursor at the beginning of the line :smile:
@kirnbichler I have used the "real" Visual Studio for decades too and that's how it always worked for me: If virtual space is enabled the cursor stops at the start of the line if I keep pressing left. It goes to the previous line only if virtual space is disabled. Is there an option that either of us changed at some point and can't even remember? (Can't check right now).