microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
162.15k stars 28.53k forks source link

[feature request] extending mouse handling to "remember" the column clicked when clicking past the end of line #205470

Closed RandomDummy closed 1 week ago

RandomDummy commented 6 months ago

Context

When moving vertically, cursors keeps track of their initial column. For instance in the following setup:

_____________s____
____i
____w________c__

A cursor starting on s moving down twice The expected behavior is to i, then c. Without this "column memory", it would end up at the position w.

Feature request

The goal of this feature request is to reuse this "column memory" in the context of a mouse click. For instance with the following setup:

____s        X
____c________f____

With a mouse click on X, the cursor would visibly be set on s. Moving down currently lead to c, the request is to go to f instead.

This makes keyboard adjustment after missing selecting long lines shorter.
Improving the usability of selection tools with low accuracy/precision (e.g. eye tracking).

Internally, the "column memory" works through the property leftoverVisibleColumns. The formula seems to be initialColumn = cursor.column + cursor.leftoverVisibleColumns?
A distinction is made between 2 kind of cursor's position: "model" (actual text position) and "visual" (within the editor (seems to account for line wrapping, and injected text)).
From my limited testing, setting the visual position's leftoverVisibleColumns to mouseColumn - visualColumn is sufficient to handle the behavior.

Edge case: click under the textarea

There is an edge case when clicking under the last line:
The cursor gets move to the end of the text and mouseColumn - visualColumn ends up negative. Negative values seems to snap the cursor back a few characters on the next vertical motion.
(input: click on 'X', then move up once):

____f__c_
_______s

    X

(X: position of the click, s: visual position of the cursor, f: cursor after moving up with negative leftoverVisibleColumns, c: current behavior)

It's a strange behavior but somehow not too far from the keyboard's:

___s______e___
___1______2

Starting at s:

Not sure if bug or feature, and even less if expending it to the mouse would make sens.


As for drilling the relevant values down to where there would need to be used, the relevant part of the stack trace seems to be:

  1. ViewController#dispatchMouse
  2. ViewController#moveTo
  3. BaseMoveToCommand#runCoreEditorCommand (inherited from CoreEditorCommand<MoveCommandOptions>)
  4. CursorMoveCommands#moveTo

The 1) is the last function having access to the mouseColumn, the 4) is the function setting the leftoverVisibleColumns to an hardcoded 0.
Also, ViewController has access to a IComputedEditorOption making it the ideal place for a feature switch.

If mouseColumn was to be drilled through the above call stack, there are 2 points that seems delicate to me:

adding mouseColumn to ViewController#moveTo

This is a public function of an exported class (could be used by 3rd party). I see 2 way the drilling could go:

Adding the parameter to the existing function would allow 3rd party's code with access to a ViewController to set arbitrary cursor offset.

adding a property to MoveCommandOptions to carry column info

The commands using MoveCommandOptions (or derivated) are:

If the change was extended to commands other than _moveTo, it would probably be _moveToSelect, createCursor, _lastCursorMoveToSelect.


So, to recap the main points left to address:

  1. How should a click below the code behave ? (negative leftoverVisibleColumns ? clamp to a positive/zero value ?)
  2. Are there other interactions affected by the change that the feature breaks ?
  3. If the relevant argument have to be drilled down through the stack, does it happens through new private interface of by evolving existing one ?
  4. Are there other actions that could benefit from this capability ?
VSCodeTriageBot commented 2 months ago

This feature request is now a candidate for our backlog. The community has 60 days to upvote the issue. If it receives 20 upvotes we will move it to our backlog. If not, we will close it. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

vs-code-engineering[bot] commented 2 weeks ago

This feature request has not yet received the 20 community upvotes it takes to make to our backlog. 10 days to go. To learn more about how we handle feature requests, please see our documentation.

Happy Coding!

vs-code-engineering[bot] commented 1 week ago

:slightly_frowning_face: In the last 60 days, this feature request has received less than 20 community upvotes and we closed it. Still a big Thank You to you for taking the time to create this issue! To learn more about how we handle feature requests, please see our documentation.

Happy Coding!