microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
95.64k stars 8.32k forks source link

allow dynamic switching of color theme per-tab (did we regress ColorTool?) #3687

Closed NeilMacMullen closed 3 years ago

NeilMacMullen commented 4 years ago

Description of the new feature/enhancement

Provide some mechanism to allow an open tab to switch color-theme or background without affecting other open tabs.

When you have multiple tabs/terminals open, the theme can be a valuable clue about the "context". For example I may be in the middle of one task in one tab when I receive a request to do something else. In that case I open another tab and start work there and (hopefully) return to the original task later. During the course of the day, it's not uncommon to be working on 5 or 6 different tasks simultaneously. When all the tabs use the same color scheme, I waste a lot of time examining the text on the screen to try and remind myself which "context" I was in for that tab/window. If I could use different themes for each tab/window I could use color as a visual aid.

Color is even more useful if you use separate windows rather than tabs because then it is very easy to ALT-TAB to the "red" window to return to the "database import job" or the "green" window to check in on the progress of the "file conversion job".

Proposed technical implementation details (optional)

A command to "set-theme" that only affects the current tab would be perfect. (Alternatively push/pop-theme.)

Suppose I have two tabs open, both running powershell. Both initially open using the default theme. I want to be able to type "set-theme red-theme" in tab-1 and have its color scheme immediately switch without affecting the display of tab-2.

NeilMacMullen commented 4 years ago

I notice there are some commonalities with the problem statement of https://github.com/microsoft/terminal/issues/2994 - i.e. the desire to be able to better distinguish between tabs. I think #2994 is only talking about changing the color of the tab header (which would be a great start!) whereas I'm suggesting being able to apply a complete theme.

My suggestion of using the theme has a few specific reasons behind it... 1) Themes are already supported and implemented and there are already plenty of visually-pleasing themes publicly available. 2) Themes allow both background and foreground colors to be modified (and background images IIRC) so provide good visual differentiation. 3) It seems likely that extending theme support to the per-tab level is a relatively small piece of work compared to introducing a new mechanism.

j4james commented 4 years ago

This looks similar to some of the ideas being discussed in issue #1337.

NeilMacMullen commented 4 years ago

@j4james yes - agreed although again I think my suggestion goes further in that #1337 appears to be suggesting that the color of the tab-header should be changed whereas I'm suggesting that the entire contents of the window (background and font color/style) should be selectable.

j4james commented 4 years ago

It's not like that proposal is inherently limited to tab color though. A number of the comments were suggesting changing the background color or the background image as part of the scheme. In fact the original proposal even mentioned extending the concept for other properties:

This concept could be expanded later to use other foreground and background identifiers such as images.

It's up to you, but if that issue can meet your needs with just minor enhancements (e.g. supporting additional properties, like font styles and colors) then I would have thought a comment there might be more productive.

NeilMacMullen commented 4 years ago

I didn't see it as "that vs this" - I was just pointing out that the suggestions so far seemed to be less flexible and actually involved introducing more complication whereas reusing the theme mechanism seems to be a nice consolidation of existing mechanisms. :-) Anyway, I've added a comment to that item as you suggest.

egmontkob commented 4 years ago

I can't see a way to change the profile of a tab runtime. Is this really not possible?

It would be a convenient, user-friendly approach to allow switching between profiles, as done in many terminals (e.g. gnome-terminal).

Of course not every property of a profile could be changed. Things like commandline, startingDirectory would be ignored, but colors, font etc. would be adjusted.

egmontkob commented 4 years ago

Another possibility is to add support for runtime alteration of the palette and default fg+bg colors, using the standard OSC 4, 10, 11 (and their +100 counterparts) escape sequences. This would give great flexibility to users, e.g. even picking a random background color from their shell startup files.

Technical note: In VTE + GNOME Terminal we figured out the best is if the OSC sequences have precedence over the UI / config file settings. That is, for each color slot, if its value is defined via OSC 4, 10, 11 then that one is used and the one in the settings is ignored. If a value hasn't been defined via OSC, or has been reset via OSC 104, 110, 111 then the value specified in the terminal emulator's settings is used. This way re-applying the same settings is an idempotent operation. (Previously the two sources were fighting with each other, both overwriting the value in the same slot. That way re-applying the user config (e.g. "altering" a color to the same value) would invalidate a previous OSC, which was bad.)

j4james commented 4 years ago

@egmontkob I'd encourage you to comment on #1337 to avoid splitting the discussion across multiple issues. The idea of altering settings via OSC has already been suggested there, although not in any great detail. And we do already support OSC 4, 10, and 11 - I think the +100 counterparts are in the backlog.

zadjii-msft commented 4 years ago

Correct me if I'm wrong, but isn't this almost exactly the problem colortool is trying to solve? Setting the color palette at runtime? With colortool, you can simply do colortool -x "SpaceGray Eighties" to set the color scheme to "SpaceGray Eighties".

Sure, this doesn't use the schemes that are built into the settings of the Terminal. Maybe there's a way to have colortool parse colorschemes from the Terminal to expose them as possible schemes as well.

NeilMacMullen commented 4 years ago

@zadjii-msft Hmm - that would be great it if worked but colortool -x just prints out the color table for me - it doesn't seem to affect the foreground/background colors of an subsequent text. (I tried in using both powershell and cmd tabs.)

zadjii-msft commented 4 years ago

@NeilMacMullen Yea, that's expected. You need to actually pass a color scheme parameter to set it to.

Try colortool -x cmd-legacy or colortool -x solarized_dark

NeilMacMullen commented 4 years ago

@zadjii-msft I did pass a theme name otherwise I wouldn't even have got the color-table. ;-) Just to be clear using colortool -x "c64.itermcolors" prints out the color table but doesn't change any actual colors. I also tried using the json files from the windowsterminal folder of https://github.com/mbadolato/iTerm2-Color-Schemes but colortool doesn't even recognise those. Probably I'm doing something wrong but it's not immediately obvious. Windows version is sufficiently high to that it should work according to the documentation. Note that it DOES work in a standard powershell window - just not in Terminal :-) (That's actually a significant learning for me so thanks!)

j4james commented 4 years ago

FWIW, it mostly works for me. It just doesn't set the default/black background color correctly in Windows Terminal, but I thought that was a known WT issue - possibly #293.

Jackbennett commented 4 years ago

If settings.json "profiles":{} had a sessions array or perhaps if "list": {"guid": <guid>} could also find the tabs by WT_SESSION variable GUID I was going to write powershell to add the colour directly to settings.json object for me.

If you added a sessions list of objects inside profiles that could also be a space Windows Terminal cleans up itself when you close the tab. Plus it wouldn't show up in the drop down GUI. Though closing a tab and recovering with ctrl+shift+t has a new session GUID, if you did this and didn't restore the ID you'll get new issues for saving per tab settings.

ccmattr commented 3 years ago

Some place I can edit a JSON file with the session GUIDs as a list would be perfect for me. Being able to use something simple as the basis of automation:

jq --arg s $WT_SESSION '.sessions[$s].tabColour = "Green"' settings.json

My (very simple) use case is I want to be able to dynamically change the tab colour when I access servers/DBs for a particular environment. Red for production, orange for staging etc. It makes it much clearer on how careful I need to be in each place. This is something i could do with Cygwin when I was using that daily.

zadjii-msft commented 3 years ago

@ccmattr You could much more easily add setTabColor actions to your actions, then use the command palette to pick those tab colors at runtime. Much much easier than trying to hack on top of the absolutely random WT_SESSION variable πŸ˜„

zadjii-msft commented 3 years ago

Wait also, I don't think we need to leave this open any more?

image

Looks like colortool is working in the Terminal to me. We've also added (in the nearly 2 years since this was opened!) a setColorScheme action that's usable directly from the command palette (#https://github.com/microsoft/terminal/pull/9794)

img

Which is really the final form of what I dreamed of for colortool more that 5 years ago: image

NeilMacMullen commented 3 years ago

Wowo - this is really nice! Great work :-)

ccmattr commented 3 years ago

@zadjii-msft The command palette is great, but it still requires me to remember to perform the actions when I perform the command. Is there a way to switch the colour scheme or tab colour via a script or command in the (e.g. WSL) shell?

I don't mind using a randomly generated ID if its a unique identifier to the tab session. It actually makes life significantly easier that its available already in the environment.

zadjii-msft commented 3 years ago

@ccmattr No, there's no good VT sequence for setting the tab color yet. We designed the feature expecting that at some point we might add one. #6574 is kinda tracking that work (#1868 is its twin but for the tab icon instead).

We're pretty reluctant to encouraging anyone to try building on top of WT_SESSION. WT_PROFILE_ID will get you the GUID of the profile that's running in the Terminal, though that'll be the same across different tabs, so trying to use that to edit the tabColor of the current profile would just change multiple tabs all at once.

Honestly, I think the best option for your scenario would be different profiles for different scenarios, until #6574 lands.

ccmattr commented 3 years ago

Oh, awesome I'll switch to tracking #6574.

Is there a reason you are reluctant for anyone to use WT_SESSION and WT_PROFILE_ID, besides the randomness? It seems like they're really useful pieces of metadata info that could be used for some quite complex automations with the right API.

ExfoliateYourColon commented 2 years ago

The term 'setColorScheme' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.