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

Support EnableColorSelection in Terminal #9583

Closed
Tracked by #13392
jazzdelightsme opened this issue Mar 23, 2021 · 8 comments · Fixed by #13429
Closed
Tracked by #13392

Support EnableColorSelection in Terminal #9583

jazzdelightsme opened this issue Mar 23, 2021 · 8 comments · Fixed by #13429
Labels
Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@jazzdelightsme
Copy link
Member

jazzdelightsme commented Mar 23, 2021

Support EnableColorSelection feature in Terminal

The legacy conhost has a (somewhat hidden, I think) feature called "color selection", which allows you to select text and then use some keystrokes to change the fg/bg color of the selected text (including optional search). (for a description, see here)

This feature is not on by default, and must be enabled by setting a registry value.

I LOVE this feature and use it all the time (and when people see me use it, they all want to know how to turn it on). Hence I would love to port this feature to Terminal as well.

Proposed technical implementation details

I think this would probably need to be disabled by default, and only enabled by a profile setting. Based on a recent comment by Dustin, I believe he has an aversion to things that manipulate the buffer, but I don't know why that might be considered undesirable, or what other options might be--if you want this particular selection to be green, then you have to store that information somewhere--why not in the buffer; if not in the buffer, then where?

If the team is not opposed to having optional support for this feature, I'd be interested in taking a stab at it. I would appreciate any pointers to help me get a toe-hold in the code.

@jazzdelightsme jazzdelightsme added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Mar 23, 2021
@ghost ghost added Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Mar 23, 2021
@zadjii-msft zadjii-msft changed the title Support Support EnableColorSelection in Terminal Mar 23, 2021
@zadjii-msft
Copy link
Member

For my future reference: Selection::_HandleColorSelection

I'm definitely of the same mind as Dustin in this case - I'm extremely reluctant to allow the user to modify the buffer contents like this.

  • If the region being changed is in the mutable viewport (at the "bottom" of the buffer), then we'd need to communicate these changes back to the underlying conpty as well. I'm not sure there's a VT sequence currently for "set the attributes in this region to this value". We could co-opt that as an input sequence, but it's definitely extremely hacky.
    • This of course wouldn't work if the thing on the other side wasn't a conpty. I guess in that case we wouldn't have to worry too much - if it's not a conpty, then the client app won't be reading the contents of the buffer anyways.
    • Though, if the terminal had like, a direct connection to a linux machine that was then ssh'ing to a Windows machine, then it's
      Terminal <--direct connection --> linux <-- ssh --> Windows sshd (using conpty)
      and then the Terminal is connected to a conpty, even if it doesn't know it.
  • If the region being changed is in the scrollback, then I suppose we don't have to worry too much - that won't be in the conpty buffer, so we don't need to worry about it round-tripping

It might make more sense to not handle this in the conpty buffer itself, but maybe as something else entirely - like another layer of attributes applied on top of the ones in the buffer. We had discussed in the past something like having "overlay" buffers - maybe we could do something like that to "overlay" these color regions on the Terminal buffer contents. Then we wouldn't need to worry about conpty at all.

The original UX in conhost is also incredibly undiscoverable. I'd also think that if we implement this in the Terminal, we could come up with a better UI for this, not necessarily implement it exactly the same.

@zadjii-msft zadjii-msft added Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Product-Terminal The new Windows Terminal. labels Mar 23, 2021
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Mar 23, 2021
@zadjii-msft zadjii-msft added this to the Icebox ❄ milestone Mar 23, 2021
@j4james
Copy link
Collaborator

j4james commented Mar 23, 2021

  • If the region being changed is in the mutable viewport (at the "bottom" of the buffer), then we'd need to communicate these changes back to the underlying conpty as well.

If we ever get around to reimplementing conpty so it's purely passing through the VT sequences, then it would never need to "redraw" the mutable viewport, so we wouldn't need to communicate the changes back to the conhost side. I think that's the only way a feature like this would be practical (unless of course you went with a completely different approach - like that overlay idea).

  • I'm not sure there's a VT sequence currently for "set the attributes in this region to this value". We could co-opt that as an input sequence, but it's definitely extremely hacky.

There is such a sequence (DECCARA), but I wouldn't think it appropriate to use as an input sequence.

For the record, I'm neither for or against this feature. I've used it a few times as a party-trick to amaze friends and family, but it's not something I really need.

@jazzdelightsme
Copy link
Member Author

It is a good party trick, right? :D

then we'd need to communicate these changes back to the underlying conpty as well.

For sake of discussion (and my education): what if we didn't?

I'm guessing the "bad thing" that could happen is an app asks about buffer contents at some (now-modified by the user) location, Terminal gives back the [modified] content, and the app says "what the????". Is that the problem/concern? (Or is it something else?)

My mental model of this feature is that it really is a UI feature "on top", so maybe the "overlay" idea really is the way to go. On the other hand, if we had an "export the entire buffer" feature (to file, or HTML, or whatever), I think I would want the user's modifications to be included... so it seems like actually modifying the buffer would be most straightforward for that.

Maybe most apps just don't really need to know that the user is coloring on their buffer? And if you have some apps that ARE sensitive to this, you just don't enable this feature? (or use it when using these apps)

Re: discoverability: I don't think there is anything so much worse about this feature than most. Just to figure out tabs and panes I had to read the documentation like for any other feature (and was frustrated and confused when the documentation was wrong, ha), so I don't see how EnableColorSelection is any different.

@zadjii-msft
Copy link
Member

what if we didn't?

Conpty tries it's absolute best to not repaint things that haven't actually changed, but it isn't always the best at that. If you only change the terminal buffer and not the underlying conpty one, then it's absolutely possible that conpty might decide to repaint a section that had the attributes changed, and blow away the modifications that only reside in the terminal. Hence why we might want to go with the overlay route - just leave the underlying buffer out of the question.

@j4james
Copy link
Collaborator

j4james commented Mar 24, 2021

It just occurred to me that the overlay concept doesn't really solve this problem. Imagine you've got some VT margins set, and you highlight a piece of text somewhere within the margin area, then you also scroll that area. Conpty is just going to redraw that area of the screen, but with all the content moved up one line. There's no way for the terminal to know that a scroll operation occurred, so it'll either draw the overlay in the wrong place, or maybe just erase it. Either way it's not what you want.

@DHowett DHowett removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Apr 13, 2021
@zadjii-msft
Copy link
Member

Hack project number 6:
fhl-colorSelection-000

Relevant diff:

d364eb4...dev/migrie/fhl/9583-colorSelection

I'm probably gonna leave it at this for now, and tag it up as help wanted. This is definitely the "just change the Terminal buffer contents and don't worry about conpty" version. Works.... well enough.

  • I had a mind to make SelectionColor accept either a index in the color table or a RGB color, but only got so far as a color. Hence the weird uint32_t in there
  • I didn't really validate the string parsing
  • I wanted FG/BG to be optional/nullable, but I don't think that's gonna be possible, a TextAttribute needs both. So we should validate they're both not null, or maybe just use the Default FG/BG when omitted.
  • Didn't bother with formatting the action name at all. Clearly, it's just got random garbage numbers in it.

There's also a bunch of other stuff that's in Selection::_HandleColorSelection that I didn't do yet.

If someone rounded out the corners, we'd probably take this as it is, as the experimental.colorSelection action, without having to worry about all the overlays, etc. Especially considering the scroll margins issue.

@jazzdelightsme
Copy link
Member Author

I had a mind to make SelectionColor accept either a index in the color table or a RGB color

Yes, I think this is important, because if I select some text and type alt+6, then I expect the text to become red, and not just any red, but the same red as is used by my current color theme.

I think this would be doable by sneaking a flag in the alpha channel (because we don't have access to TextColor or such things from the settings layer). And furthermore, I think it could be done in a way that basically only affects "color selection". And indexed colors would use a different syntax: so you'd say "#RRGGBB" for RGB, or "iNN" for an index.

Like so: see dev/migrie/fhl/9583-colorSelection...jazzdelightsme:user/danthom/ecs_demo_indexedColors

This allows perfect reproduction of the ctrl/alt combos from legacy conhost, with keybindings like:

    {
        "keys": "alt+1",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i07", "background": "i00" }
    },
    {
        "keys": "alt+2",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i08", "background": "i00" }
    },
    {
        "keys": "alt+3",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i09", "background": "i00" }
    },
    {
        "keys": "alt+4",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i0a", "background": "i00" }
    },
    {
        "keys": "alt+5",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i0b", "background": "i00" }
    },
    {
        "keys": "alt+6",
        "command": { "action": "experimental.colorSelection",
                     "foreground": "i0c", "background": "i00" }
    },
    // etc.
    // background
    {
        "keys": "ctrl+1",
        "command": { "action": "experimental.colorSelection",
                     "background": "i07", "foreground": "i00" }
    },
    {
        "keys": "ctrl+2",
        "command": { "action": "experimental.colorSelection",
                     "background": "i08", "foreground": "i00" }
    },
    // etc.

@zadjii-msft: any objection to this approach?

@zadjii-msft zadjii-msft added the Needs-Discussion Something that requires a team discussion before we can proceed label May 30, 2022
@zadjii-msft zadjii-msft removed the Needs-Discussion Something that requires a team discussion before we can proceed label Jun 14, 2022
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Jul 5, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…
@ghost ghost added the In-PR This issue has a related PR label Jul 5, 2022
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Jul 5, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Jul 9, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Jul 9, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Aug 1, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…
jazzdelightsme added a commit to jazzdelightsme/terminal that referenced this issue Aug 4, 2022
As described in microsoft#9583, this change implements the legacy conhost "EnableColorSelection" feature.

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to microsoft#13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
@ghost ghost closed this as completed in #13429 Aug 31, 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 Aug 31, 2022
ghost pushed a commit that referenced this issue Aug 31, 2022
## Summary of the Pull Request

As described in #9583, this change implements the legacy conhost "EnableColorSelection" feature.

## Detailed Description of the Pull Request / Additional comments

@zadjii-msft was super nice and provided the outline/plumbing (WinRT classes and such) as a hackathon-type project (thank you!)--a "SelectionColor" runtimeclass, a ColorSelection method on the ControlCore runtimeclass, associated plumbing through the layers; plus the action-and-args plumbing to allow hooking up a basic "ColorSelection" action, which allows you to put actions in your settings JSON like so:

```json
{
    "command":
    {
        "action": "experimental.colorSelection",
        "foreground": "#0f3"
    },
    "keys": "alt+4"
},
```

On top of that foundation, I added a couple of things:
* The ability to specify indexes for colors, in addition to RGB and RRGGBB colors.
  - It's a bit hacky, because there are some conversions that fight against sneaking an "I'm an index" flag in the alpha channel.
* A new "matchMode" parameter on the action, allowing you to say if you want to only color the current selection ("0") or all matches ("1").
  - I made it an int, because I'd like to enable at least one other "match mode" later, but it requires me/someone to fix up search.cpp to handle regex first.
  - Search used an old UIA "ColorSelection" method which was previously `E_NOTIMPL`, but is now wired up. Don't know what/if anything else uses this.
* An uber-toggle setting, "EnableColorSelection", which allows you to set a single `bool` in your settings JSON, to light up all the keybindings you would expect from the legacy "EnableColorSelection" feature:
    - alt+[0..9]: color foreground
    - alt+shift+[0..9]: color foreground, all matches
    - ctrl+[0..9]: color background
    - ctrl+shift+[0..9]: color background, all matches
 * A few of the actions cannot be properly invoked via their keybindings, due to #13124. `*!*` But they work if you do them from the command palette.
  * If you have "`EnableColorSelection : true`" in your settings JSON, but then specify a different action in your JSON that uses the same key binding as a color selection keybinding, your custom one wins, which I think is the right thing.
* I fixed what I think was a bug in search.cpp, which also affected the legacy EnableColorSelection feature: due to a non-inclusive coordinate comparison, you were not allowed to color a single character; but I see no reason why that should be disallowed. Now you can make all your `X`s red if you like.

"Soft" spots:
* I was a bit surprised at some of the helpers I had to provide in textBuffer.cpp. Perhaps there are existing methods that I didn't find?
* Localization? Because there are so many (40!) actions, I went to some trouble to try to provide nice command/arg descriptions. But I don't know how localization works…


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #9583
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed *(what would be the right place to add tests for this?)*
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated. *(is this needed?)*
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx

## Validation Steps Performed
Just manual testing.
@ghost
Copy link

ghost commented Sep 13, 2022

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

Handy links:

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Help Wanted We encourage anyone to jump in on these. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants