Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new commands to allow finer-grain line navigation #9220

Closed
wants to merge 1 commit into from

Conversation

TanukiSharp
Copy link

This PR propose a change to allow more behaviors for the line navigation feature, through new keyboard shortcut commands.

The problem

Now pressing Home and End keys makes the cursor move to the first/last non white space character first, then to the real beginning/end of line, and so forth. This makes VSCode behave like WebStorm for example, however I would like to be able to make it behave like Visual Studio.

  • WebStorn:
    • Home goes to the first non white space character, then goes to the very beginning of the line
    • End goes to the last non white space character, then goes to the very end of the line
  • Visual Studio:
    • Home goes to the first non white space character, then goes to the very beginning of the line (same as WebStorm)
    • End just go to the the very end of the line

Until then, I could not find the way to setup VSCode and make it behave like Visual Studio, that's why I propose a change.

The proposal

First, I believe a bit a terminology is required in order to be sure that we are all on the same page.
If the vocabulary I use is not correct, please let me know.

Terminology

What I call the visual boundaries of a line, is the line not including the white space characters, so simply said, the visual boundaries of a line go from the first 'visible' character to the last 'visible' character.

The logical boundaries of a line is the whole line, including all the characters from the beginning to the first line separator character, including white spaces.

Example:

"        alice and bob alice and bob       "
 |       |                         |      |
 ^-------|-- logical boundaries ---|------^
         |                         |
         ^--- visual boundaries ---^

New cursor commands

To be able to change the line navigation behavior, and still let other people configure it the way they want, I added new cursor commands. Existing ones are CursorHome and CursorEnd (along with their *Select related command).

For the ones interested, they can be found through the menu File / Preferences / Keyboard Shortcuts, then this way:

{ "key": "end",                   "command": "cursorEnd",
                                     "when": "editorTextFocus" },
{ "key": "home",                  "command": "cursorHome",
                                     "when": "editorTextFocus" },

I added the following new commands:

Cursor*VisualThenLogical
Cursor*LogicalThenVisual
Cursor*VisualOnly
Cursor*LogicalOnly

where '*' is Home and End, and of course their *Select related commands, making a total of 16 new commands.

Note that CursorHomeVisualThenLogical is simply an alias to existing CursorHome, and the same goes for CursorEndVisualThenLogical aliasing CursorEnd, since this is the default behavior of VSCode.

The new commands appear in the list at the bottom of the keyboard shortcuts configuration file as other available commands.

Unit tests

I added new unit tests (all passing) for each combination of commands and contexts.
Those are in the file cursor.test.ts.

Linting

When I ran the tslint command, some reports appeared, but none concerning the change I made, so should be fine.

Combination of cases

I've tested the change, and it works in all line navigation modes, including all combination or selection, wrapped lines and multi cursor contexts.

monaco editor

I had to modify monaco.d.ts in order to add new handlers, however I'm not sure if I'm supposed to do that, neither if I'm supposed to do it that way. I tried to find the code I needed to change in the monacor-editor related GitHub repositories, but I could not find what I was looking for.

Visual Studio like setup

{ "key": "end",           "command": "cursorEndLogicalOnly",
                             "when": "editorTextFocus" },
{ "key": "shift+end",     "command": "cursorEndLogicalOnlySelect",
                             "when": "editorTextFocus" },
{ "key": "home",          "command": "cursorHomeVisualThenLogical",
                             "when": "editorTextFocus" },
{ "key": "shift+home",    "command": "cursorHomeVisualThenLogicalSelect",
                             "when": "editorTextFocus" }

Do not forget to set the *Select version, or you may experience asymmetries.

@msftclas
Copy link

Hi @TanukiSharp, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@TanukiSharp, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

@sandy081
Copy link
Member

Hi @TanukiSharp, firstly I am impressed with the description provided by you here. Steps are very organized and descriptive and explains what is being done clearly. It is a good idea to have commands for navigating cursor to logical screen positions of the line. These are very much needed for various use cases.

As part of our July Iteration Plan, we are enhancing our editor by providing commands to the extension developers, through which they can perform some screen motions on the editor which cannot be done through API. This is mainly driven for VIM editor extension. Please refer to this Evaluate API gaps for better VIM support for more information.

Coincidentally, work we are doing for this feature is overlapping with this pull request. I am implementing a single command cursorMove that can take logical line / screen positions like lineStart, lineFirstNonWhitespaceCharacter... as arguments. Refer to feature #9143. You can also take a look at the implementation here #9292. Our idea is to move all cursor specific commands into single command with arguments. We also have plans to enhance key bindings to allow arguments, so that, user can provide key bindings to argument based commands.

So, please go through our plan, design and implementation and let us know if they suit your requirements and we can discuss on how to move forward.

Thanks a lot for bringing good ideas.

@rebornix rebornix mentioned this pull request Jul 20, 2016
4 tasks
@TanukiSharp
Copy link
Author

Hello @sandy081

Sorry for late reply, and thank you for your review and information.

I've checked the content of July iteration plan and other pull requests / issues, looks great.
I'll update my pull request (close or keep open with changes) based on next update.

Thank you.

@alexdima alexdima added this to the Backlog milestone Aug 16, 2016
@alexdima
Copy link
Member

@TanukiSharp Please don't do any more work on this PR for now. We plan to add args support to the keybindings.json and then we can evaluate if the functionality suggested through this PR is covered. We can also cherry pick the very nice tests 👍

@TanukiSharp
Copy link
Author

I see, thank you very much for your update, because I was kind of wondering what to do next.
Despite the unit tests I wrote are passing, github stills tells the CI is failing, I'll try to see if I can update that, at least.

@alexdima
Copy link
Member

The CI fails due to https://travis-ci.org/Microsoft/vscode/jobs/144503630#L2089

[02:41:53] Error: monaco.d.ts is no longer up to date. Please run gulp watch and commit the new file.
    at formatError (/home/travis/.nvm/versions/node/v5.10.1/lib/node_modules/gulp/bin/gulp.js:169:10)
    at Gulp.<anonymous> (/home/travis/.nvm/versions/node/v5.10.1/lib/node_modules/gulp/bin/gulp.js:195:15)
    at emitOne (events.js:90:13)
    at Gulp.emit (events.js:182:7)
    at Gulp.Orchestrator._emitTaskDone (/home/travis/build/Microsoft/vscode/node_modules/orchestrator/index.js:264:8)
    at /home/travis/build/Microsoft/vscode/node_modules/orchestrator/index.js:275:23
    at finish (/home/travis/build/Microsoft/vscode/node_modules/orchestrator/lib/runTask.js:21:8)
    at Stream.<anonymous> (/home/travis/build/Microsoft/vscode/node_modules/orchestrator/lib/runTask.js:52:4)
    at Stream.f (/home/travis/build/Microsoft/vscode/node_modules/once/once.js:17:25)
    at emitOne (events.js:95:20)

Most likely your changes resulted in a new monaco editor API shape (contained in monaco.d.ts and you did not stage that file).

@alexdima
Copy link
Member

I believe the initial reason for adding these commands has been mitigated by our various tweaks for home and end, where e.g. end stops first at the wrapped line end, and then at the model line end.

@alexdima alexdima closed this Sep 27, 2017
@github-actions github-actions bot locked and limited conversation to collaborators Mar 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants