Open rkeithhill opened 5 years ago
As of #897, you can look for $Env:WT_SESSION
@dhowett-msft why not use TERM_PROGRAM also, like vs code, hyper and fluentterminal already do? Not too late to change :)
Agreed. We can't keep creating new environment variables every single time a new terminal program comes out. Linux already uses $env:TERM and if we have to check several per platform it's just terrible from a UX standpoint. Why reinvent the wheel yet again?
An application-specific variable like WT_SESSION
is really awful for anyone trying to determine what features they can use. I certainly don't want to have to check a dozen different environment variables to figure out what terminal I'm running in.
TERM_PROGRAM is slightly better, but is really just a lazy version of TERM, which is what all of these terminals should be setting.
Eventually, we're going to get a curses
library and a real terminfo database with @TIC@
and @INFOCMP@
macros, shouldn't we start behaving well now?
Hold up, I think there's been a misunderstanding here. I'm sorry about that.
We should definitely support TERM
or TERM_PROGRAM
. Unfortunately, TERM
has become somewhat like a user agent: "I work like this terminal, I promise" -- right up until it doesn't.
TERM_PROGRAM
, I've never heard of. What does it do? Who is expected to use it, and for what?
WT_SESSION
is something else. Today, it can be used to detect Windows Terminal. It is informative, not normative, as a detection mechanism. WT_SESSION
tags an individual session -- it is a GUID that the shell (or some other enlightened application) can use in coordination with the terminal to support application state resumption. This feature was inspired by both Terminal.app (the stock terminal emulator on OS X) and its featureful replacement, iTerm2. There's no new and divergent art here.
The idea there is that if WT eventually supports reloading and showing a session's history, that resumed state will use the same session GUID so the shell can do additional things like restoring the working directory or anything else it might have saved off.
informative, not normative
This is why I threw it out as an example and didn't close the feature request. I'll seek to communicate things that are rattling around in my head a bit better going forward.
It would be nice if conhost would define new TERM
values as well, so that we can know if we can use larger color palettes (of course, the fact it gets defined would imply that since it would be only in newer versions), differentiate conhost vs. Terminal, etc. In compiled code, it's easy enough to figure out via GetConsoleMode
, but in shell scripts (cmd, powershell, etc.) not so much. For examples, flavors of linux define xterm
, xterm-color
, and xterm-256color
, as well as many others. Some convention similar to that indicating color palette (level of VT support) or even Unicode support would be helpful to provide rich console experiences.
@DHowett-MSFT Maybe both? TERM_PROGRAM
for the application name, and TERM
for "feature detection"?
AFAIK the majority of (non-Windows?) terminals support TERM_PROGRAM
and TERM_PROGRAM_VERSION
, it's one of the few environment variables vscode's terminal touches (alongside TERM
, LANG
, COLORTERM
). Whether WT should support TERM
is another discussion.
xterm-256color
for best compatibility (provided the terminal supports 256 color).I just stumbled across an, obvious in retrospect, but irksome problem with using WT_SESSION as an indicator that you're running inside Windows Terminal. Since it is just a normal environment variable, it propagates as you'd expect, which means if you've launched VSCode from inside Windows Terminal, then the integrated terminal there also has WT_SESSION set, and to the parent value, which would stomp on the intended use for application state resumption.
That's behaving as expected, but certainly isn't desirable. Seems like more reason to need TERM_PROGRAM set as well.
Consider that TERM_PROGRAM
would be inherited if you spawn another terminal emulator from WT- like, for example, :terminal
in gvim. I’m not sure the heritability of environment variables makes the case for TERM_PROGRAM
stronger exactly.
True, but if the defacto protocol is that all terminal emulators set TERM_PROGRAM
(and presumably TERM_PROGRAM_VERSION
) in the child environment that's a non-issue. That would make it a bug in gvim's :terminal
support if it isn't overwriting those environment variables before spawning it's own shell process.
+1 vote for TERM_PROGRAM, it is also used on Apple and iTerm terminals.
Also, I just checked and WT_SESSION is set for CMD but not for WSL/bash. Whatever var y'all choose, it should be available from every shell for terminal detection to be reliable.
Thanks for that report; I split it out into #3948.
In my case I don't care much about what terminal program the end user is using, except that I want to know if I can send VT sequences or not. It would be nice if GetConsoleMode api returns the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag enabled when called within a Windows Terminal console or other consoles that already supports VT. If it is possible for the Windows Terminal team implement this it may also be possible to request that on Cmder/ConEmu and have a standard windows way to determine that particular console capability. Using WT_SESSION environment variable already gave me a false positive because I am used to just use start cmd
to spawn new consoles, and they inherit the env variable even when running on the regular ConHost.
The presence of Windows Terminal, or any other terminal, does not indicate that the ENABLE_VIRTUAL_TERMINAL_PROCESSING
flag is set. Because it is possible to store raw escape sequences in the text buffer with that flag turned off, it must be possible (and even, in some instances, recommended for legacy compatibility) to turn it off. Allowing the connected terminal to parse VT sequences that the console did not parse will lead to visual artifacting ala #1965 #2130 #2759 #1960.
I propose the following spec:
As well as setting the WT_TERMINAL
environmental variable, use a similar strategy to set TERM_PROGRAM
to WindowsTerminal
.
cc @DHowett-MSFT @heaths @Tyriar
Please get this out of the backlog.
Please get this out of the backlog.
I appreciate that there are folks who care about this, but I’m just not convinced of its value. TERM_PROGRAM
has been likened to a browser user agent string, which makes good sense to me if you’re going to use a user agent string to do feature detection. By and large, the past 25 years of web development have shown us that that was almost certainly the wrong thing to do.
If somebody can come up with a legitimately compelling use case apart from “I want my shell to act differently if I’m in different terminals” (which is easily achievable through other means), I’m all ears!
Also: please don’t get in the habit of calling out contributors and community members by name when you want to be heard. If everyone did this for every one of our hundreds of open workitems that someone cares about, we would be deep in emails indeed. Most of us already are: we generally get an email for every comment on every bug in this repo.
@DHowett-MSFT
A big thing is compatibility detection. Especially for the new Emoji support.
If the script knows it's running in the Windows Terminal, it uses fancy emojis. If not, it uses legacy emojis pulled from Code page 437. At this point, using !!process.env.WT_SESSION
to detect this just seems like a weird hack that isn't being used for its true purpose.
See https://github.com/sindresorhus/figures/pull/27#issuecomment-504764201
I need at least a thumbs up from a collaborator for this repository that WT_SESSION
will be sticking around for a long time and that I can confidently rely on it.
Environment variables are not a perfect solution since you can 'start cmd' and that will open an old ConHost with WT_SESSION set.
@DHowett-MSFT for basically every other nix terminal and many on Windows, you can look at TERM_PROGRAM
to see what terminal the app is being run within, but now anything that does this also needs to check WT_SESSION
as well? And what if another terminal is launched from WT, then you have both TERM_PROGRAM
and WT_SESSION
so it's impossible to tell which value was set by the "inner" terminal (WT might create a fresh env block in which case this might not apply).
This feature was inspired by both Terminal.app (the stock terminal emulator on OS X) and its featureful replacement, iTerm2. There's no new and divergent art here.
You say it's inspired but why not do exactly what they did which is extend the TERM
and TERM_PROGRAM
variables with exactly what they did; adding TERM_SESSION_ID
? imo you should replace WT_TERMINAL
with TERM_SESSION_ID
, add TERM_PROGRAM
and TERM_PROGRAM_VERSION
as there is already a standard and there is zero reason AFAICT to deviate from it.
It is invalid to consider a terminal that does not set TERM_PROGRAM
and TERM_PROGRAM_VERSION
wrong. It stands, then, that any terminal started from another terminal that has set TERM_PROGRAM
will inherit that value, and confuse all downstream shells.
There is no standard for session IDs: at my last check, Apple's Terminal.app used TERM_SESSION_ID
and iTerm2.app uses ITERM_SESSION
. Perhaps that has changed.
that any terminal started from another terminal that has set TERM_PROGRAM will inherit that value, and confuse all downstream shells.
The new terminal sets the value when it starts the process, so no confusion.
There is no standard for session IDs: at my last check, Apple's Terminal.app used TERM_SESSION_ID and iTerm2.app uses ITERM_SESSION. Perhaps that has changed.
Looks like iterm made a mistake and can't break backwards compat (iterm left, terminal.app right):
Join us
This should be set in both Windows Terminal and the windows built-in ConHost, to minimize the 'false positive' scenarios. I am pretty confident that other terminals will join too (Cmder/ConEmu,etc).
There's a problem with that one, too. conhost cannot set an environment variable in the process it's hosting, because it is actually spawned BY the process it is hosting. That's just not a capability that's afforded to Windows applications. ConEmu supports two launch modes- one where it launches the shell and the conhost and attaches to the conhost, and one where it attaches to an existing conhost. It will not be able to set environment variables in the second case.
There's a lot more issues here than may initially meet the eye.
There's a problem with that one, too. conhost cannot set an environment variable in the process it's hosting, because it is actually spawned BY the process it is hosting.
The Windows team could modify the allocate/attach code in kernelbase.dll to query the console host name and version and set those environment variables.
So as a user, to get 24bit support in apps in WSL with Windows Terminal, is this the recommended method:
[[ -n "$WT_SESSION" ]] && export COLORTERM=24bit
at least for now?
Definitely not. Client of Terminal will want to use the same means of detecting 24-bit color they were using for years before Windows Terminal came out. The traditional Windows console host has supported 24-bit color for some time now.
OK @DHowett -- what is the recommended method for a user then? I have a number of Linux utilities that assume that a 24bit terminal sets COLORTERM
(they may have other methods I don't know about). They do not currently autodetect 24-bit support in Windows Terminal, even though it does support it. When I add COLORTERM=24bit
they work OK. Is there some alternative method I should use?
So, COLORTERM
should be safe to set for all terminals on Windows as of 1803. No need to check WT_SESSION
, just set it if you're using WSL at all. :smile:
I guess that's what I mean. I have a .bashrc
which I use on Windows, Linux (incl WSL) and Mac. I want it to work everywhere. So I can either check that I'm on Windows (but then I still might be in Msys using some term emulator), or just check for WT_SESSION
.
I do think it would be nice if Windows Terminal would just set COLORTERM
like many other terminal apps (terminator, iTerm2, konsole, hyper, etc.).
Fair request.
I would, though, hope that iTerm/Terminal.app and whatever terminal emulator you use on Linux would support 24-bit color by now. Perhaps if TERM
== xterm-256color
, you can set it?
Would it make more sense, then, to just have conhost and openconsole define TERM
even if they are "xterm-256color" assuming ENABLE_VIRTUAL_TERMINAL_PROCESSING
is enabled?
WSL already does this.
Sure, that's reasonable. It's likely most terminal emulators claiming 256-color support actually support 24bit at this point. There's a list at https://gist.github.com/XVilka/8346728 if anyone's interested.
WSL does, yes, but that doesn't help my many PowerShell scripts (cross-plat, or Windows-only) where emitting vterm sequences would be easier than chaining Write-Host
with various -ForegroundColor
or -BackgroundColor
parameters.
Just chiming in that in my case, we have a program that probes COLORTERM
and checks if it it's 24-bit or 256 to determine which color mode to enable.
I'm still confused/unclear on how to go about this for Windows users?
Should we just uniformly assume a 24-bit terminal if WT_SESSION
is detected? (That doesn't seem right because 24-bit colors are supported by just launching cmd.exe directly so this test would fail for this case)
Or is it better to probe the console mode to confirm ENABLE_VIRTUAL_TERMINAL_PROCESSING is set (not ideal, extra code for this)
Is it safe to emulate by setting TERM=xterm-256color
if console mode has ENABLE_VIRTUAL_TERMINAL_PROCESSING
set?
Is it safe to emulate by setting
TERM=xterm-256color
if console mode hasENABLE_VIRTUAL_TERMINAL_PROCESSING
set?
That's certainly the TERM
that we've been aiming to emulate, yea. If you can set ENABLE_VIRTUAL_TERMINAL_PROCESSING
, then you should assume that the Console (and terminal) will be able to support 256/rgb colors. There's like, 1 build of Windows 10 (RS1, 14393 I think) where that won't work for you, but that was also just about 4 years ago, so I wouldn't worry about that too much.
Would be great if there were a built-in env var or a way to do this query without having to write a separate binary. Maybe Windows Terminal could ship with this little utility?
Just a note that I've recently discovered that the modern terminfo name for terminals that support direct, aka "true" color is TERM=xterm-direct
not TERM=xterm-256color
.
In fact a number of terminals have -direct
aliases. To compare them:
⏵ infocmp xterm-256color xterm-direct
Unfortunately, until we land #4321 we're actually +indirect
😦 (since we use the legacy syntax popularized by a misreading of the direct color spec!)
Yes, got it. Since the comment was meant as more of a goal than a current status, it shouldn't be in conflict. Simply a note that, while in most threads folks are mentioning TERM=*-256color
, those profiles have been surpassed for a number of years.
Please also make a PR to supports-hyperlinks
that is intended to detect embedded hyperlinks support. Right now it is not possible to detect that Windows Terminal has v1.4 or higher so it is not possible to properly implement the terminal&version check.
It will be handy to have COLORTERM
environment variable to detect true color support.
Excellent and useful additions, thank you so much.
@dropsonic why would detection be necessary? If vterm sequences are implemented correctly - and according to discussions for hyperlink support, Terminal is - if older Terminals don't support it hyperlinks will just show up as text (the URL, that is).
@heaths thanks for pointing it out, will try
Summary of the new feature/enhancement
Maybe this is as simple as an environment variable like VSCode uses for its terminal e.g.
TERM_PROGRAM=WindowsTerminal
/TERM_PROGRAM_VERSION=0.0.1.0
.Proposed technical implementation details (optional)
Start by creating the environment variables above so those of us using PowerShell can adapt our user experience (via PowerShell profiles) to Windows Terminal.