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

PowerShell on osx - how to force to be completely monochrome #3918

Open
3 tasks done
rhubarb-geek-nz opened this issue Jan 13, 2024 · 18 comments
Open
3 tasks done

PowerShell on osx - how to force to be completely monochrome #3918

rhubarb-geek-nz opened this issue Jan 13, 2024 · 18 comments
Labels
Needs-Triage 🔍 It's a new issue that core contributor team needs to triage.

Comments

@rhubarb-geek-nz
Copy link

rhubarb-geek-nz commented Jan 13, 2024

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest released version
  • Search the existing issues, especially the pinned issues.

Exception report

See PowerShell on osx how to force to be completely monochrome

Should be able to easily use PowerShell on a monochrome terminal, ideally respecting the TERM environment variable.

Screenshot

Image 14-01-24 at 08 39

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.1
PSEdition                      Core
GitCommitId                    7.4.1
OS                             Darwin 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:34 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T8103
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Steps to reproduce

Open a terminal on macOS of type "Man Page", use pwsh

Typed text will be yellow on a yellow background

Expected behavior

Typed text should be visible no matter the type of terminal or colours used by the terminal

Actual behavior

Typed text is always yellow, hard to read on white or yellow backgrounds.

@mklement0

This comment was marked as resolved.

@rhubarb-geek-nz
Copy link
Author

PSReadLine abide by terminfo

One proposal is to have the PowerShell core's $PSStyle.OutputRendering controlled by NO_COLOR, and then PSReadLine governed by terminfo.

Given .bashrc on Debian systems uses 'xterm-256color' as the determination on whether to use colours, then PSReadLine could do similar and if terminfo says the current terminal has more than 16 colours it could use colours, if 16 or less then it should be monochrome.

We note that macOS does not support "xterm-mono" in its terminfo database. Setting TERM is global for a session so affects other programs including 'pico' and 'nano'.

% TERM=xterm-mono nano
zsh: can't find terminal definition for xterm-mono
'xterm-mono': unknown terminal type.
% TERM=xterm infocmp | grep colors 
	colors#8, cols#80, it#8, lines#24, pairs#64,

@mklement0
Copy link

@rhubarb-geek-nz, I just noticed that you can use xtermm on macOS, which is the xterm-mono equivalent and is also honored by PowerShell (but not PSReadLine yet).

Note that making PSReadline respect TERM also makes sense for supporting a value of dumb, which currently breaks the interactive experience.

Apart from that, it would be great if PSReadLine - in the absence of explicit color configuration for it (i.e. Set-PSReadLineOption -Colors ... having been called) - could automatically and dynamically - pick colors that work well with the terminal foreground and background color (at least as in effect at session startup).
I imagine that won't be trivial, though.

This would more directly give you what you want - readability - while not having to forgo color support.

@rhubarb-geek-nz
Copy link
Author

I would certainly like a monochrome option somehow. I often remove the default alias to "ls" in bash because I find it hard to read blue text on a black background, let alone yellow on white.

The great thing about monochrome is that it is (a) high contrast (b) the user's preference of colours.

@mklement0
Copy link

Understood. I think that both things are worth implementing:

  • Automatic switch to monochrome depending on the TERM value, and possibly also NO_COLOR
  • With color support enabled, intelligent choice of default colors based on the terminal's effective background and foreground color - if feasible.

@237dmitry
Copy link

I think that PSReadline should understand $PSStyle.OutputRendering = "PlainText", since unlike NO_COLOR it is cross-platform.

@mklement0
Copy link

Good point, @237dmitry.

What NO_COLOR and $PSStyle.OutputRendering = "PlainText" share (the former translates into the latter), if set directly, is that - unlike TERM, which implies specific terminal capabilities on Unix - they are pure expressions of user preference: the desire not to use color.

My only question is: Would users ever want to control this preference separately for output (already implemented in PowerShell) vs. interactive input?

@rhubarb-geek-nz
Copy link
Author

My only question is: Would users ever want to control this preference separately for output (already implemented in PowerShell) vs. interactive input?

Perhaps, they may want NO_COLOR for all rendering of output because they are copying and pasting output tables and results into a document or a report, but want the colour during editing of commands to assist with syntax highlighting and auto-completion.

@237dmitry
Copy link

NO_COLOR is the first for syntax like ENV=value command And it does not work with aliases like alias ls="ls --color"

@rhubarb-geek-nz
Copy link
Author

rhubarb-geek-nz commented Jan 15, 2024

NO_COLOR is the first for syntax like ENV=value command And it does not work with aliases like alias ls="ls --color"

I am not sure what you mean.

Environment variables like LANG and TZ have traditionally affected the output of commands. Likewise TERM affects how editors drive the terminal console.

Aliases are purely internal to shells themselves and do not affect actual programs. It is the shell interpreting an alias that appends the argument --color to an invocation of ls, not the executing of /bin/ls or /usr/bin/ls.

Debian's .bashrc has similar to

# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
    xterm-color|*-256color) color_prompt=yes;;
esac

So it determines the prompt based on the TERM environment variable. Likewise it conditionally sets up the alias of ls based on the executability of /usr/bin/dircolors

# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'

@237dmitry
Copy link

I am not sure what you mean.

I meant that this variable is not for global use so that the terminal becomes completely monochrome, but for launching individual utilities.

If I add export NO_COLOR="true" in ~/.bashrc then launched bash is still colored.

And not of all utilities understand $NO_COLOR in single-line syntax. For example, NO_COLOR="true" micro will start colored micro, and micro is not the only application.

As for pwsh, not everything is so smooth with it, because many users, unlike you, use profiles for shell configuration. And this is normal use, that's what $profile is for.

@rhubarb-geek-nz
Copy link
Author

rhubarb-geek-nz commented Jan 15, 2024

I certainly agree that NO_COLOR is not supported by every application, no-color-.org shows a list of a hundred or so programs that do (PowerShell is listed!). Likewise many applications ignore TERM. NO_COLOR is new and TERM is relayed by ssh.

One of the principles of UNIX software is mechanism, not policy.

Do we provide a mechanism to support monochrome, and if so is it a standard?

The policy is something different which we cannot enforce, who sets the variable (if that is the mechanism) in the first place and who else also abides by it.

Having the mechanism of supporting NO_COLOR does mean that I could change my .bashrc to set it depending on the TERM variable value, along with not setting the aliases for ls. That would be me implementing my policy.

In reality I don't customise machines .bashrc or profiles because life is really too short and I deal with hundreds of real and virtual machines and don't have time for customising each. However setting my TERM to be a simple "xterm" or similar does allow me to get by.

@237dmitry
Copy link

That's why we need to target pwsh so that the core and modules understand each other. To prevent PSReadline from being colorful when $PSStyle.OutputRendering is set to "PlainText". This is a single directive and works fine, even though it is primarily intended to output the results of a command to a file so that there are no esc-sequences in it.

For me, until this is implemented, I would just write a function that defines the colors in Set-PSReadlineOption

@rhubarb-geek-nz
Copy link
Author

I can't set the colours in Set-PSReadlineOption because they are not static, the macOS terminal changes automatically between dark mode and light mode depending on the time of day, and I might have one window open as "Man Page" and the other as "Homebrew".

@237dmitry
Copy link

237dmitry commented Jan 15, 2024

I can't set the colours in Set-PSReadlineOption because they are not static,

Base 16 console colors are not absolute, and they depend on terminal settings.

Just enter in different (dark and light) modes:

"`e[37m Some text `e[0m"

Screenshot 2024-01-15 235750

@rhubarb-geek-nz
Copy link
Author

rhubarb-geek-nz commented Jan 15, 2024

On MacOS Terminal in the different themes `e[37m just gave white text as per the ANSI escape sequence specification.
So when on a yellow background, it gave white text. When Terminal is in light mode it is a very pale grey, eg the background is true bright white and the text is off-white.

@237dmitry
Copy link

237dmitry commented Jan 15, 2024

So when on a yellow background, it gave white text

You have to configure terminal

Screenshot 2024-01-16 005550

function set-mono {

    $PSStyle.OutputRendering = "PlainText"

    Set-PSReadlineOption -Color @{

        Command = "`e[37m"
        Comment = "`e[37m"
        ContinuationPrompt = "`e[37m"
        Default = "`e[37m"
        Emphasis = "`e[37m"
        Error = "`e[37m"
        InlinePrediction = "`e[37m"
        Keyword = "`e[37m"
        ListPrediction = "`e[37m"
        ListPredictionSelected = "`e[7m"
        ListPredictionTooltip = "`e[37m"
        Member = "`e[37m"
        Number = "`e[37m"
        Operator = "`e[37m"
        Parameter = "`e[37m"
        Selection = "`e[7m"
        String = "`e[37m"
        Type = "`e[37m"
        Variable = "`e[37m"
    }
}

@rhubarb-geek-nz
Copy link
Author

rhubarb-geek-nz commented Jan 15, 2024

You have to configure terminal

Or just use a shell that works monochrome out of the box, eg bash or zsh, and only use PowerShell to execute scripts. The default terminal on MacOS gives you ( during the day ) black text on a white background. You should not have to reconfigure that to run PowerShell.

ProjectSynchro added a commit to ProjectSynchro/powershell-wrapper-for-wine that referenced this issue Apr 4, 2024
We can workaround bug 49780 by disabling colour outputs entirely, and removing the PSReadLine module.

See: PowerShell/PSReadLine#3918 and PowerShell/PowerShell#21160 for context.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs-Triage 🔍 It's a new issue that core contributor team needs to triage.
Projects
None yet
Development

No branches or pull requests

3 participants