Terminal: Consider adding a WT_PROFILE env var pointing to settings file

Created on 13 Feb 2020  路  15Comments  路  Source: microsoft/terminal

If the settings UI is not planned until after 1.0, then I strongly recommend adding an environment variable with the path to the json settings file, so it can be edited with the editor of choice (vi, notepad, nano, emacs, whatever) from within the shell of choice without burning brain calories trying to find it buried in AppData. Also: Relying on the GUI menu is, well, unreliable, due to there being no guarantee of a valid file association for json files.

We've already got WT_SESSION env var -- something like WT_PROFILE would be useful.

Then from within cmd or powershell, I can easily edit settings with my preferred editor, or interactively using $settings = gc $env:WT_PROFILE | convertto-json and flipping settings on the object model directly before saving it back out.

Area-Settings Help Wanted Issue-Feature Product-Terminal

All 15 comments

@oising Are you able to access settings _at all_? I no longer find a profiles.json file, and Ctrl-, no longer even pulls one up.

@akulbe I think now there is only a defaults.json and you may create your own profiles.json file as a differential to this (things in your file will override the defaults).

There's a readonly defaults.json alongside the executable, and a user-editable one for overrides in your local app data folder.

Run the following one-liner in powershell to open the defaults.json file:

notepad (join-path ((dir (gcm wt.exe).source).target | split-path) defaults.json)

The profiles.json file is in %LOCALAPPDATA%\packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\

Conflicts with https://github.com/microsoft/terminal/issues/3589 request, maybe have the variable be WT_CONFIGFILE?

Currently the location is pretty stable and discoverable, this change would only be relevant if you could also customize the path.

Does anyone actually have a use for WT_Session? Is it just so you can distinguish different terminal connections to the same (e.g. ssh) session? To me, the WT_Profile in #3589 would be really useful. This one, pointing to the config file (confusingly named profile.json), would also be useful but it feels less useful -- isn't there only one location (plus one for dev builds)?

Conflicts with #3589 request, maybe have the variable be WT_CONFIGFILE?

Currently the location is pretty stable and discoverable, this change would only be relevant if you could also customize the path.

Well there are actually two config files, in different locations - I propose:

env var WT_PROFILES (user editable) for:

%LOCALAPPDATA%\packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\profiles.json

env var WT_DEFAULTS (read only, for reference) for:

%PROGRAMFILES%\WindowsApps\Microsoft.WindowsTerminal_0.9.433.0_x64__8wekyb3d8bbwe\defaults.json

While they are "discoverable" - for certain definitions of discoverability - I think they are unwieldy enough to benefit from an environment variable.

@Jaykul I really like your idea for the active profile ID. What do you suggest for a name? I think WT_PROFILE is too close to WT_PROFILES (which matches the name of the json file, likewise for WT_DEFAULTS)

On February 20, 2020, @oising said:

env var WT_DEFAULTS (read only, for reference)

Can you expand on what you mean by a read-only environment variable? Windows, doesn't have anything like read-only environment variables AFAIK. A process is free to modify its own environment or to start children with custom environments.

My expectation of a variable like WT_PROFILE would be that I could use it to change where Windows Terminal reads user settings from. I would use it to move this to my "dotfiles" repository where I keep various application settings so I can version and sync them across machines.

Based on how other, similar software works, I think it would make sense if Windows Terminal only read this environment variable at process start up and then monitored the path for changes. It would also be reasonable for Windows Terminal to detect changes to the environment "template" by handling WM_SETTINGCHANGE notifications. (Though, there are some subtle details to consider about when changes are applied. Lots of thoughts in #1125, "Feature Request: Terminal should listen for the WM_SETTINGCHANGE for environment variable updates".)

@chwarr The WT_DEFAULTS environment variable will point to the readonly file defaults.json. It's not a readonly env var.

As for your thoughts on WT_PROFILE, well, sure, that makes sense but I'm not sure that would make it into my PR. I'd imagine that may be something that gets haggled about for post v1.0.

Ah, @oising was talking about the mutability of the file, not the variable.

There's a related issue in this space, "Add support for roaming settings.json or storing it elsewhere".

I've added WT_DEFAULTS and WT_PROFILES which reflect defaults.json and profiles.json respectively. They also will translate correctly under WSL.

So, here's the thing. I adore the work you did in #4852, and I'd like to land some of it as it improves environment handling in Terminal across the board.

What I'm most worried about here is introducing what amounts to a public API this close to v1.

As I reviewed it, I found myself asking some questions:

  1. Does this expose anything that can't otherwise be determined?

    • sorta, it's annoying to detect it but the location _is_ broadly stable. if we ever solve profile includes, the location gets more complex.

  2. Are we agreeing to ship this _forever_, or somehow communicate that we're making a breaking change later?
  3. If we _produce_ a WT_SETTINGS environment variable today, why don't we _consume_ one?

    • If we plan to consume one, we need to matrix-in to our support flow that people might have globally overridden their settings locations

    • If we plan to consume it, we're somewhat unique among applications of this type

    • Spawning WT from WT logically "rolls-forward" the settings used by the parent. Cool! But...

    • Which config file wins when you run wt split-pane and we finally land the ability to split a pane in the _existing_ terminal? The one in WT_SETTINGS or the one in the destination terminal instance? Both? Neither? Do we get an error?

I'm wary of doing this _for 1.0_ because we don't have time to answer those questions. That doesn't mean we're not interested in the change overall. :smile:

To turn the discussion around a bit, though... copying a comment from @Jaykul on the pull request:

And since the VT color _queries_ were also never finished, there's no way to discover what crazy colors someone's using in their terminal

Why would someone want this? Honest question. I realize it's the conjunction of PROFILE_ID _and_ SETTINGS, so I don't have a good place to discuss it, but:

If an application has specific color requirements, it shouldn't need to _parse our settings files--both of them--then layer them with the exact same logic we do_ to figure out what colors the user's going to see. It should just set the palette it wants and be done with it, or use the 24-bit color escapes.

We've been burned so many times, in so many ways, when we've offered public APIs or "detectables" to determine console/terminal state. People take dependencies on reserved flag values not being used (oops), and that consoles have an HWND (thanks SSH), and that the high 8 bits in a cell are unused when you're using the ANSI versions of the APIs (thanks Pascal).


I think it's worth getting in #4852 without the _path_ versions and only including the WT_PROFILE_ID var (closing #3589 in the process.) What do you think?

(Also, thank you for bearing with us as we release-engineer our first v1 of something: this is painful in part because I'm not communicating very well about it. I'm sorry.)

I think it's worth getting in #4852 without the path versions and only including the WT_PROFILE_ID var (closing #3589 in the process.) What do you think?

@DHowett-MSFT If I'm reading this correctly, then you may ship this in v1.0 if I can drop the WT_DEFAULTS and WT_SETTINGS env vars? I can do that, of course.

Update: It's done. Just remove two lines, and edited one.

(Also, thank you for bearing with us as we release-engineer our first v1 of something: this is painful in part because I'm not communicating very well about it. I'm sorry.)

It's quite alright, Dustin. Thank you for your very thoughtful commentary.

Just to complicate things a little bit.

What about WT_SettingsPath which could give back the path of the same file which gets opened by hitting ctrl+, ?

The path in the name would really limit the scope, and make most of the questions irrelevant. I realize that this is not the end solution but sounds like a great MVP.

If you only give back the currently used, and editable path, it will be up to the users to decide what do they want to do with it. This approach sounds supportable in the future, because if you change the path - to support roaming or whatever - or the file name, etc., WT must always know where the active settings are, because it had to read the content.


I'm editing the content of the settings.json in PSWinTerminal but figuring out if the running terminal is the GA version or it Preview isn't pretty. I'd to look for the parent process' path and look for the word preview in the folder name. With PowerShell this is easy, but with Windows PowerShell I had to use Get-CimInstance.

It would be really nice if I can simply just use WT_SettingsPath to get the path of the settings file.


What do you think?

_From @arqtiq in #7773_

Numerous times I tried to automate some settings / profiles edits on the Terminal settings themselves, and I usually lack informations about the current tab environment :

  • What is the current loaded profile / scheme ?

  • Is the host the preview package ?

I'm sure there are also more info we could export to env vars based on people needs.
This would be veery useful to manage the terminal settings / themes / profiles directly from the command line !

When opening a new tab, set:

  • $WT_CURRENT_PROFILE (_Microsoft PowerShell, CMD, ..._)

  • $WT_CURRENT_SCHEME

  • $WT_IS_PREVIEW (1 / 0, if the current terminal running package is the preview one)

Was this page helpful?
0 / 5 - 0 ratings