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

Enable color output whenever stdout is TTY #34347

Merged
merged 15 commits into from
Mar 27, 2020

Conversation

karan0299
Copy link
Contributor

Fixes #34317 . Made a check if STDOUT is a TTY and color is not set explicitly by the user , then set global variable have_color to true.
In my opinion , there should be separate have_color variable for STDOUT and STDERR, since we can have separate TTY for STDOUT and STDERR

base/client.jl Outdated Show resolved Hide resolved
@ararslan ararslan added needs news A NEWS entry is required for this change display and printing Aesthetics and correctness of printed representations of objects. labels Jan 12, 2020
@ararslan ararslan requested a review from JeffBezanson January 12, 2020 16:33
@JeffBezanson
Copy link
Member

Welcome, and thanks for working on this!

In my opinion , there should be separate have_color variable for STDOUT and STDERR

That's a good point. For now, the easy thing would be to only enable color if stdout and stderr are both TTYs.

Looking at the code in more detail, we should really reduce use of the have_color global and instead keep a value per TTY object. Within julia the right way to check for color is get(iostream, :color, false), but for TTYs that is implemented using the global variable. Instead, it should be a field of the object that is set automatically and overridden for stdout/stderr by the --color command line option. What do you think?

@karan0299
Copy link
Contributor Author

@JeffBezanson
Yeah , This is quite a better approach . There is a mutable struct TTY in base/stream.jl . I think if we add field color in that struct this initially set true and can be overridden by --color as you have already mentioned. This would solve our problem I think. Will try to get a PR on this.

@vtjnash
Copy link
Member

vtjnash commented Jan 14, 2020

Looking at the code in more detail, we should really reduce use of the have_color global and instead keep a value per TTY object

We have both because stdout could be assigned to any object. So there's a have_color global that reflects mostly just reflects the --color flag and applies to any IO object type. And then TTY also is supposed to have some auto-detection capabilities.

@JeffBezanson
Copy link
Member

JeffBezanson commented Jan 14, 2020

It looks to me like printstyled uses get(io, :color, false), and only TTYs implement :color (by returning the global have_color). I guess --color can continue to determine the default color setting for all TTYs, but ideally when --color is not specified each TTY should set its :color flag by autodetection (by running tput redirected to that object?)

@karan0299
Copy link
Contributor Author

@JeffBezanson For now i have implemented code to enable color when stdout and stderr are both TTY's . What should be the next step ?

@karan0299
Copy link
Contributor Author

@JeffBezanson Any updates on this one?

@JeffBezanson
Copy link
Member

This seems OK for now. @ararslan requested a NEWS entry, so just add a line to NEWS.md saying that color now defaults to on when stdout and stderr are TTYs.

@karan0299
Copy link
Contributor Author

I have made an entry in News.md with the purpose of this pr

@ararslan ararslan removed the needs news A NEWS entry is required for this change label Jan 28, 2020
NEWS.md Outdated
@@ -32,6 +32,8 @@ Language changes
(in addition to the one that enters the help mode) to see the full
docstring. ([#25930])

* Color nows defaults to on when stdout and stderr are TTYs ([#34347])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Color nows defaults to on when stdout and stderr are TTYs ([#34347])
* Color now defaults to on when stdout and stderr are TTYs ([#34347])

@JeffBezanson JeffBezanson added the triage This should be discussed on a triage call label Jan 29, 2020
@JeffBezanson
Copy link
Member

Thinking about it some more, this probably needs more discussion. In interactive mode, we try to check whether the terminal supports color. If checking is important, then it doesn't make much sense to skip the check in non-interactive mode. Before, we probably wanted to avoid the check to save startup time. I think there are 3 options:

  1. Keep things as they are, default to color=no so we don't need any checks.
  2. Add the hascolor check from stdlib/REPL/src/Terminals.jl to this PR; don't worry about the startup time cost.
  3. Use this PR as-is, and remove the hascolor check from the REPL. Just assume color is available.

@StefanKarpinski
Copy link
Member

Idea from discussion on triage: delay checking of the output stream (by calling tput, etc.) until we actually do something that would be different based on if there's color or not. So, for example, println("Hello, world") doesn't care if there's color or not, whereas logging does care, so the color check would happen the first time a log message is printed and then get cached after that.

@JeffBezanson
Copy link
Member

Could be done this way:

  1. Make the global have_color 3-state: true / false / nothing (nothing means not yet set)
  2. The first time the TTY code queries the global, if it's nothing then call the detection function, which will have to be refactored a bit so you don't need a TTYTerminal object.

@karan0299
Copy link
Contributor Author

@JeffBezanson I have understood your point but while implementing , I am not sure how I can do this without TTYTerminal object.
Thanks.

@tkf
Copy link
Member

tkf commented Feb 8, 2020

  1. Make the global have_color 3-state

Do you mean for a "quick fix"? It would be really nice if this is a per-instance property. I have multiple packages opening non-stdio TTYs and relying on a global state is rather ugly for such usages.

@karan0299
Copy link
Contributor Author

karan0299 commented Feb 12, 2020

I have the implementation to remove Dependency of TTYTerminal object from hascolor function

function hascolor()
        term_type = get(ENV, "TERM", @static Sys.iswindows() ? "" : "dumb")
        startswith(term_type, "xterm") && return true
        try 
          @static if Sys.KERNEL === :FreeBSD  
                return success('tput AF 0')     
            else
                return success('tput setaf 0')  
            end
        catch
            return false
    end
end

@JeffBezanson please verify.

@karan0299 karan0299 closed this Feb 12, 2020
@karan0299 karan0299 reopened this Feb 12, 2020
@JeffBezanson JeffBezanson removed the triage This should be discussed on a triage call label Feb 13, 2020
@JeffBezanson
Copy link
Member

Yes looks OK to me.

@mkitti
Copy link
Contributor

mkitti commented Mar 26, 2020

I think the commits 95c8ea3 59586de in #35240 may be useful to get this over the line.

@karan0299
Copy link
Contributor Author

@mkitti yeah I think this is a concrete approach to settle the problem

Comment on lines 26 to 30
<<<<<<< HEAD


=======
>>>>>>> 59586ded0da55b383c01b5d6e3538cd9680d79a3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove lines 26 - 30

Suggested change
<<<<<<< HEAD
=======
>>>>>>> 59586ded0da55b383c01b5d6e3538cd9680d79a3
<<<<<<< HEAD
=======
>>>>>>> 59586ded0da55b383c01b5d6e3538cd9680d79a3

@mkitti
Copy link
Contributor

mkitti commented Mar 26, 2020

@karan0299 You still have some merge conflict marks at the end of base/ttyhascolor.jl. Take those out.

@@ -241,6 +241,7 @@ include("filesystem.jl")
using .Filesystem
include("cmd.jl")
include("process.jl")
include("ttyhascolor.jl")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be its own file? Otherwise it seems like it makes sense to keep it with the implementation of TTY.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ,we can shift this to stdlib/REPL/src/Terminal.jl

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JeffBezanson The code in ttyhascolor.jl needs to come after process.jl due to the use of success. stream.jl is included before process.jl, and we were getting compilation errors because of this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I figured it was something like that.

base/loading.jl Outdated
io = open(pipeline(`$(julia_cmd()) -O0
--output-ji $output --output-incremental=yes
--startup-file=no --history-file=no --warn-overwrite=yes
--color=$(have_color ? "yes" : "no")
--color=$(have_color === true ? "yes" : "no")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
--color=$(have_color === true ? "yes" : "no")
--color=$(have_color === nothing ? "auto" : have_color ? "yes" : "no")

@mkitti
Copy link
Contributor

mkitti commented Mar 27, 2020

I'm not sure why the one test failed for building on Mac. Looks like some kind of stochastic error. Could someone restart that test to see?

@karan0299
Copy link
Contributor Author

All CI tests passed

@JeffBezanson JeffBezanson merged commit 8a39bc7 into JuliaLang:master Mar 27, 2020
@JeffBezanson
Copy link
Member

Thanks for your persistence on this one. Ended up being more complicated than I would have thought! Glad to have this finally merged :)

maleadt added a commit that referenced this pull request Mar 29, 2020
maleadt added a commit that referenced this pull request Mar 30, 2020
Revert "Enable color output whenever stdout is TTY (#34347)"
KristofferC added a commit that referenced this pull request Apr 8, 2020
Unrevert #34347 and bump Pkg to a version that is compatible with it
oxinabox pushed a commit to oxinabox/julia that referenced this pull request Apr 8, 2020
oxinabox pushed a commit to oxinabox/julia that referenced this pull request Apr 8, 2020
ravibitsgoa pushed a commit to ravibitsgoa/julia that referenced this pull request Apr 9, 2020
ravibitsgoa pushed a commit to ravibitsgoa/julia that referenced this pull request Apr 9, 2020
KristofferC pushed a commit that referenced this pull request Apr 11, 2020
KristofferC pushed a commit that referenced this pull request Apr 11, 2020
staticfloat pushed a commit that referenced this pull request Apr 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display and printing Aesthetics and correctness of printed representations of objects.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

enable color output whenever stdout is a TTY
8 participants