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

Terminal: Support keyboard text selection & navigation #715

Closed
Tracked by #4993
MarkusAmshove opened this issue May 12, 2019 · 39 comments · Fixed by #13053
Closed
Tracked by #4993

Terminal: Support keyboard text selection & navigation #715

MarkusAmshove opened this issue May 12, 2019 · 39 comments · Fixed by #13053
Assignees
Labels
Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Priority-1 A description (P1) Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@MarkusAmshove
Copy link

Hello,

I'm using tmux on Linux machines and ConEmu on Windows machines and I really love that I can do text selection with the keyboard.

In ConEmu, there is a keybinding for "Start text selection (like text editors)", whereas in tmux there is the same thing with <prefix><b> (I think that is default), where I get a cursor that I can move with the arrow keys around the console window.
While doing this, I can select text while holding shift and (in case of ConEmu) press ENTER to copy the text into the clipboard and end the text selection.
It can also be compared with Vim's visual mode.

It would be nice if the new Windows Terminal could support this out of the box, so I can use it in e.g. PowerShell :-)

@oising oising added Area-User Interface Issues pertaining to the user interface of the Console or Terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. labels May 12, 2019
@zadjii-msft zadjii-msft added this to the Windows Terminal v1.0 milestone May 13, 2019
@zadjii-msft
Copy link
Member

@carlos-zamora this may be of interest

@ghost ghost added the Needs-Tag-Fix Doesn't match tag requirements label May 17, 2019
@miniksa miniksa added Product-Terminal The new Windows Terminal. and removed Mass-Chaos labels May 17, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label May 17, 2019
@danthe1st
Copy link

Also, if the tmux property mouse-mode does not work in the new Terminal.
It works well in conhost.

@kuesa
Copy link

kuesa commented May 22, 2019

One possible implementation would be just to do what cmd does, where if the user has selected text and presses "Enter", it will just copy the selected text to the clipboard.

@danthe1st
Copy link

Or maybe it would be possible to let the application running control what's happening when marking...
Or that the user can change between the "cmd mode" and other things

@mdtauk
Copy link

mdtauk commented May 24, 2019

If keyboard text selection is added, please don't forget about things like Shift+Home and Shift+End.

You could also have a selection go up and down a line/row with Shift+Up and Shift+Down.

Oh and with all these ligatures, copying and pasting text should probably uncombine those ligature characters - so the font choice does not affect what may get pasted in another place.

@carlos-zamora carlos-zamora added Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) and removed Area-User Interface Issues pertaining to the user interface of the Console or Terminal labels Jun 25, 2019
@carlos-zamora carlos-zamora self-assigned this Jun 25, 2019
@carlos-zamora carlos-zamora added the Help Wanted We encourage anyone to jump in on these. label Jun 25, 2019
@carlos-zamora
Copy link
Member

Added the "Help-Wanted" label. Most of this work should be able to go in TermControl (probably KeyDownHandler()). If the selection is active, edit the Terminals _endSelectionPositionAnchor by using _terminal->SetEndSelectionPosition(terminalPosition);

Terminals _ExpandWideGlyphSelectionLeft() and _ExpandWideGlyphSelectionRight() can be used to expand the selection on wide glyphs appropriately. We'd just have to make them public or have something else call them.

@RichardSlater
Copy link

Terminal is slowly driving me crazy because unlike ConEmu pressing clears the selection without copying it to the clipboard, having full-on keyboard only text selection would be a massive addition.

@pingzing
Copy link
Contributor

One fun wrinkle--PSReadLine handles buffer selection and navigation for Windows PowerShell and PSCore. So if this does get implemented, there should also be an option to disable it per-profile, so a shell can handle selection itself.

@MarkusAmshove
Copy link
Author

@pingzing I'm also using PSReadLine, but I'm unaware of the feature. Can you give me a hint? (can't find any documentation on this).

What I'm talking about in this issue is the following (beware awesome screencapturing):

4urdJqAMlL

@pingzing
Copy link
Contributor

pingzing commented Aug 11, 2019

I think it only works for the input buffer, and not previously-written text. No idea if it's documented, but it's definitely in the keybindings. For example, invoking Get-PSReadLineKeyHandler yields the following for me:

Selection functions
===================
Key                   Function            Description
---                   --------            -----------
Ctrl+a                SelectAll           Select the entire line. Moves the cursor to the end of the line
Shift+LeftArrow       SelectBackwardChar  Adjust the current selection to include the previous character
Shift+Home            SelectBackwardsLine Adjust the current selection to include from the cursor to the end of the line
Shift+Ctrl+LeftArrow  SelectBackwardWord  Adjust the current selection to include the previous word
Shift+RightArrow      SelectForwardChar   Adjust the current selection to include the next character
Shift+End             SelectLine          Adjust the current selection to include from the cursor to the start of the line
Shift+Ctrl+RightArrow SelectNextWord      Adjust the current selection to include the next word

My fear is that if Terminal implements this, it'll interfere with PSReadLine's own handling. ConEmu has similar behavior, which I have to disable if I want PSReadLine's behavior.

carlos-zamora added a commit that referenced this issue Sep 23, 2021
This introduces a spec for keyboard selection. This enables the user to create and update a selection without the use of a mouse or stylus.

## References
Contributes to #715
carlos-zamora added a commit that referenced this issue Sep 23, 2021
Implements the following keyboard selection non-configurable key bindings:
- shift+arrow --> move endpoint by character
- ctrl+shift+left/right --> move endpoint by word
- shift+home/end --> move to beginning/end of line
- ctrl+shift+home/end --> move to beginning/end of buffer

This was purposefully done in the ControlCore layer to make keyboard selection an innate part of how the terminal functions (aka a shared component across terminal consumers).

## References
#715 - Keyboard Selection
#2840 - Spec

## Detailed Description of the Pull Request / Additional comment
The most relevant section is `TerminalSelection.cpp`, where we define how each movement operates. It's basically a giant embedded switch-case statement. We leverage a lot of the work done in a11y to perform the movements.

## Validation Steps Performed
- General cases:
   - test all of the key bindings added
- Corner cases:
   - `char`: wide glyph support
   - `word`: move towards, away, and across the selection pivot
   - automatically scroll viewport
   - ESC (and other key combos) are still clearing the selection properly
@JonesMikael

This comment has been minimized.

@DHowett

This comment has been minimized.

@ofek
Copy link
Contributor

ofek commented Feb 11, 2022

Has this been implemented/released in a preview build?

@zadjii-msft zadjii-msft modified the milestones: 22H1, Terminal v1.15 Apr 12, 2022
@carlos-zamora carlos-zamora mentioned this issue May 7, 2022
10 tasks
@ghost ghost added the In-PR This issue has a related PR label May 7, 2022
@ghost ghost closed this as completed in #13053 May 20, 2022
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels May 20, 2022
ghost pushed a commit that referenced this issue May 20, 2022
## Summary of the Pull Request
Introduces a non-configurable version of mark mode to Windows Terminal. It has the following interactions defined:
- <kbd>ctrl+shift+m</kbd> --> Enter Mark Mode
- when in Mark Mode...
	- <kbd>ESC</kbd> --> Exit Mark Mode
	- arrow keys --> move "start"
	- <kbd>shift</kbd> + arrow keys --> anchor "start", move "end"
	- <kbd>ctrl+a</kbd> --> select all
- when a selection is active...

When in mark mode, the cursor does not blink.

## References
#4993 - [Epic] Keyboard Selection

## PR Checklist
* [X] Closes #715
* [X] Provides a resolution for #11985

## Detailed Description of the Pull Request / Additional comments
- `TermControl`:
	- `TermControl.cpp` just adds logic to prevent the cursor from blinking when in mark mode
- `ControlCore`
	- in the same place we handle quick edit, we add an entry point to mark mode
- `TerminalCore`
	- this leverages `UpdateSelection()` and other quick edit functions to make mark mode happen

## Validation Steps Performed
- [x] Make selection, split pane, close pane
	- NOTE: A similar scenario caused a crash at one point. Really weird. Keep an eye on it.
- [x] Cursor is off when in mark mode
- [x] general movement/selection
- [x] general movement/selection that forces the viewport to move
- [x] In mark mode, selectAll...
	- [x] arrow keys --> move start
	- [x] shift + arrow keys --> move end
- [x] (regardless of mark mode) if selection active, enter --> copy to clipboard
DHowett pushed a commit that referenced this issue Jun 20, 2022
## Summary of the Pull Request
This introduces a selection marker overlay that tells the user which endpoint is currently being moved by the keyboard. The selection markers are respect font size changes and `cursor` color.

## References
#715 - Keyboard Selection
#2840 - Keyboard Selection Spec
#5804 - Mark Mode Spec

## Detailed Description of the Pull Request / Additional comments
- `TermControl` layer:
   - Use a canvas (similar to the one used for hyperlinks) to be able to draw the selection markers.
   - If we are notified that the selection changed, update the selection markers appropriately.
   - `UpdateSelectionMarkersEventArgs` lets us distinguish between mouse and keyboard selections.  `ClearMarkers` is set to true in the following cases...
      1.  Mouse selection, via SetEndSelectionPoint
      2. `LeftClickOnTerminal`, pretty self-explanatory
      3. a selection created from searching for text
- `ControlCore` layer:
   - Responsible for notifying `TermControl` to update the selection markers when a selection has changed.
   - Transfers info (the selection endpoint positions and which endpoint we're moving) from the terminal core to the term control.
- `TerminalCore` layer:
   - Provides the viewport position of the selection endpoints.


## Validation Steps Performed
- mouse selection (w/ and w/out shift) --> no markers
- keyboard selection --> markers
- markers update appropriately when we pivot the selection
- markers scroll when you hit a boundary
- markers take the color of the cursor color setting
- markers are resized when the font size changes
@ghost
Copy link

ghost commented Jul 6, 2022

🎉This issue was addressed in #13053, which has now been successfully released as Windows Terminal Preview v1.15.186.:tada:

Handy links:

DHowett pushed a commit that referenced this issue Jul 22, 2022
## Summary of the Pull Request
This is a spec specifically dedicated to Mark Mode. It's an addition to the Keyboard Selection spec. I felt that it makes the most sense to make this a separate PR because there's a lot of ideas that are very specific to Mark Mode, and this gives us the space to modify some of that behavior and get a good look at how other terminal emulators designed this feature.

## References
#2840 - Keyboard Selection Spec (base spec/branch/PR)

## PR Checklist
* [X] Contributes to #715
@MrM40
Copy link

MrM40 commented Aug 30, 2022

If/when this is implemented I hope it will be an option! I've build in my own functionality in my application (CTRL+C, CTRL+V, CTRL+X, text-selection with SHIFT+ARROWS, SHIFT+HOME, SHIFT+END etc). I would be unhappy if my hard work gets corrupted by an native implementation....so please make it possible to disable it in settings.

It's a real pain in the Windows legacy console (in advance mode).....the text-selection is forced so pushing e.g. SHIT+HOME is captured by the console and are not parsed on to the application, please don't make same mistake.

@zadjii-msft
Copy link
Member

@MrM40 This was implemented like, 4 months ago, and has been shipped in Preview 1.15 for some time now. Feel free to check out that release and file new issues if you find any ☺️

@MrM40
Copy link

MrM40 commented Aug 31, 2022

Ohh....hard to keep up with speedy team :-)

I'm running 1.15.220719002-preview

Don't have any text-selection functionality in the default "Command Prompt" profile, it works in the profile "Windows PowerShell"
They have the same settings:
image

Should it work in the cmd prompt too?

@zadjii-msft
Copy link
Member

it works in the profile "Windows PowerShell"

PowerShell has its own text selection it maintains, as a part of the shell itself. You'll note that PowerShell's text selection works the same in 1.15 as it did in previous versions, even the same as it did in the vintage console.

The text selection added in the Terminal needs to be started first, either with a keyboard selection, or the markMode action (bound to ctrl+shift+m by default).

@MrM40
Copy link

MrM40 commented Aug 31, 2022

OK, I see. Expected it to work the same was as in legacy console in advance mode, where it just work natively (but make it impossible to make you own implementation, as e.g. SHIFT-LEFT never get parsed to your application).
I'm very happy with the way WT implemented this.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Priority-1 A description (P1) Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
Specification Tracker
  
Spec In Review ⏰
Development

Successfully merging a pull request may close this issue.