-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Taskbar progress reporting via ANSI codes #14615
base: master
Are you sure you want to change the base?
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @epage (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
@rustbot author |
Hello, Ed, thank you for the review and sorry for the late feedback. It's been a lot of work lately. |
Understandable! |
// From https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC | ||
// ESC ] 9 ; 4 ; st ; pr ST | ||
// When st is 0: remove progress. | ||
// When st is 1: set progress value to pr (number, 0-100). | ||
// When st is 2: set error state in taskbar, pr is optional. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #14615 (comment)
This also raises another small issue: if user stops cargo with ctrl+c, taskbar progress is not cleared and it stays until the next invocation of a program with taskbar progress report capability. Microsoft's own winget behaves like this.
I've tried to set ctrl+c handler in cargo and clear taskbar from there. It works, but it 50-100 LOC which would be used rarely. What do you think of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am hesitant to have a ctrl+c handler but I also have had enough bad experience on Windows with colors being leaked from a program and could see myself being annoyed about progress state leaking as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's my prvious work on ctrl+c handler: de22a7f
The approach works, but then we need to set the handler depending on Progress.state. Can you please advice on this? Do you want to have a handler in src/bin/cargo/main.rs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ehuss I'd be interested in your opinion on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're now detecting a terminal regardless of the OS, a ctrl+c handler needs to be portable too, not like in my first implementation. If we still want to go this way, a few questions:
- Can we use external crate like https://crates.io/crates/ctrlc? I assume your policy is to use as few external crates as possible
- Will it iterfere with https://github.com/rust-lang/cargo/blob/master/crates/cargo-util/src/process_builder.rs#L259-L276? I don't fully understand when this code is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is used when cargo executes binaries for cargo run
or cargo <plugin>
. Not familiar with Windows but I would assume for these execvp cases we are not expected to see them returning.
5ff7484
to
584ee00
Compare
This is looking really great and making me jealous that my terminal doesn't support it! |
10e457d
to
c6d0d63
Compare
@rfcbot fcp merge In terms of stability, this adds a new config field [term]
progress.taskbar = true # whether cargo reports progress to terminal emulator Like with For rendering, this ANSI escape code is supported by at least
For emitting, this ANSI escape code is supported by at least
In the current implementation, if the user hits |
Team member @epage has proposed to merge this. The next step is review by the rest of the tagged team members: Concerns: Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
src/doc/src/reference/config.md
Outdated
#### `term.progress.taskbar` | ||
* Type: bool | ||
* Default: auto-detect | ||
* Environment: `CARGO_TERM_PROGRESS_TASKBAR` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a mild note, this environment variable doesn't work by itself (because it requires the other progress
settings).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, you might be able to fix this by adding #[serde(default)]
to the ProgressConfig::when
field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks test bad_progress_config_missing_when
Unclear why does ProgressWhen
has a Default
implementation then...
As for me it feels that any progress setting should imply when = 'auto'. Not sure should 4 years old behavior be changed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't recall any particular decisions made regarding bad_progress_config_missing_when
. I personally would not object to changing that to allow it to pass. I can't think of a reason it would be required to specify when
with width
.
src/doc/src/reference/config.md
Outdated
unicode = true # whether cargo can render output using non-ASCII unicode characters | ||
progress.when = 'auto' # whether cargo shows progress bar | ||
progress.width = 80 # width of progress bar | ||
progress.taskbar = true # whether cargo reports progress to terminal emulator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Different terminal emulators handle this differently; for instance, some of the Linux terminal emulators show this in the terminal's tab bar, instead. Rather than having a name that's specific to the rendering of a subset of terminals, could we use a name that's a little more generic?
Perhaps progress.ansi
or progress.osc
? Or, if we want something less technical, then perhaps progress.escapes
, indicating that it sends escape codes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are my points:
progress.taskbar
- I like this one for easy interchangeability withtaskbar_progress
-named fields and functionsprogress.osc
orprogress.osc9_4
- people name PRs and issues mostly with something like "OSC 9;4" so it's somewhat familiarprogress.notification
- just high-level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, my care abouts are
- Easy discover for people wanting to change this behavior
- Clear meaning when looking at a config or config docs
- Consistency with wider community
I feel like ansi
, osc
, escapes
, and osc9_4
do neither unless you are someone already in the nitty gritty implementation details. Also, our other OSC configs do not speak this way (color
, unicode
, hyperlinks
, though color
can also support wincon APIs).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
progress.taskbar - I like this one for easy interchangeability with taskbar_progress-named fields and functions
That's circular. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a clear name to explain itself. notification
sounds too far away. osc9_4
is too tied to implementation details. Maybe we'll have other reporting mechanism for some specific terminal emulator in the future (I hope not though).
Since what the feature does is reporting the progress. So, perhaps a verb progress.report
is a bit clearer?
(Hey report is also a noun 😅)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notification
can also sound like the kitty feature that slightly overlaps om the codes.
Another name I thought of was progress.system
to convey that its reporting through the system that calls into cargo.
Eventually I want to add support for multi-line progress which might need its own config and then if we ever get a watch, I would like it to look like bacon
. ui
and gui
might get confusing in those respects (well, more tui
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just looked at this again in 2025, notification sounds fine as well :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From #14615 (comment)
I've changed the feature name to progress report. This name keeps the focus on what the feature does (reporting progress) rather than how it’s rendered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Within a terminal emulator, I think that name can make sense (though that is one specific terminals name and not a common name)
Within the context of the term table
[term]
quiet = false # whether cargo output is quiet
verbose = false # whether cargo provides verbose output
color = 'auto' # whether cargo colorizes output
hyperlinks = true # whether cargo inserts links into output
unicode = true # whether cargo can render output using non-ASCII unicode characters
progress.when = 'auto' # whether cargo shows progress bar
progress.width = 80 # width of progress bar
progress.report = true # whether cargo reports progress to terminal emulator
especially if you ignore the comments, report
sounds like when
7f94679
to
cbd0508
Compare
🔔 This is now entering its final comment period, as per the review above. 🔔 |
progress_report, | ||
stderr_tty, | ||
.. | ||
} => *progress_report && *stderr_tty, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally this check is done in the supports
functions, should we make that consistent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking on the other code it seems that it's a separate thing:
supports_progress_report()
detects the supported terminal from environment variablesprogress_report_available()
(I've renamed is from thesupports_osc9_4()
for clarity) signals that terminal supports the feature and it's a tty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm following
supports_unicode
checks!stream.is_terminal() || supports_unicode::supports_unicode()
AutoStream::new(std::io::stdout(), stdout_choice)
will checkis_terminal
as well as what the terminal supports
hyperlinks is a bit odd but that is later combined with the AutoStream
check
* Default: auto-detect | ||
* Environment: `CARGO_TERM_PROGRESS_TASKBAR` | ||
|
||
Report progess to the teminal emulator for display in places like the task bar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Report progess to the teminal emulator for display in places like the task bar. | |
Report progress to the teminal emulator for display in places like the task bar. |
src/doc/src/reference/config.md
Outdated
unicode = true # whether cargo can render output using non-ASCII unicode characters | ||
progress.when = 'auto' # whether cargo shows progress bar | ||
progress.width = 80 # width of progress bar | ||
progress.taskbar = true # whether cargo reports progress to terminal emulator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a clear name to explain itself. notification
sounds too far away. osc9_4
is too tied to implementation details. Maybe we'll have other reporting mechanism for some specific terminal emulator in the future (I hope not though).
Since what the feature does is reporting the progress. So, perhaps a verb progress.report
is a bit clearer?
(Hey report is also a noun 😅)
@rfcbot reviewed Temporary concern until #14615 (comment) gets resolved, because folks may be about to go on holiday soon and I don't want this to get lost. I am not at this time attempting to actually block the FCP if this isn't changed, and I'm happy to defer to consensus; I just want to make sure that this doesn't accidentally FCP without resolving the discussion and reaching some consensus. |
Happy New Year and Merry Christmas! I had a lot of work in the last weeks of December and now I'm on New Year vacation. I'll be back in the second half of January, I'll fix the tests, decide on naming. Wishing everyone a happy new 2025! |
Just wanted to chime in here to say that WezTerm just now added support for these escapes in
wezterm/wezterm#6581 is the wezterm issue tracking this feature. |
da388a4
to
80e9682
Compare
Hi everyone! I've changed the feature name to progress report. This name keeps the focus on what the feature does (reporting progress) rather than how it’s rendered. I've also added WizTerm detection. @wez also called is like this. I can't make test to work. It passes locally on Windows and Linux but here on pipeline it behaves differently and I can't figure out why. |
// WezTerm: check if TERM_PROGRAM is "WezTerm" and the version is recent enough | ||
// https://github.com/rust-lang/cargo/pull/14615#issuecomment-2646738819 | ||
|| (std::env::var("TERM_PROGRAM").ok() == Some("WezTerm".into()) | ||
&& std::env::var("TERM_PROGRAM_VERSION") | ||
.ok() | ||
.map_or(false, |v| v.as_str() >= "20250209-182623-44866cc1")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the main reason for version checks is to deal with buggy terminal implementations. If older wezterms gracefully handle these codes, should we skip the version check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, older versions of wezterm will swallow an OSC they doesn't understand, so you could remove the version number check and just check for wezterm without it. That feels like less magic to keep track of over here.
80e9682
to
4e5077b
Compare
What does this PR try to resolve?
A few terminal emulators support progress output to Windows taskbar.
winget
uses this to show install progress.Notably, Windows Terminal recently (2020) added support for ANSI codes specified in ConEmu (another terminal emulator for Windows) documentation. Also, in "Learn Windows".
I've found the previous attempt to add this feature: #11436
As per @weihanglo's request, I've added the config option to enable/disable this feature. It's enabled on supported terminal emulators.
Fixes #11432
FCP: #14615 (comment)
How should we test and review this PR?
Run
cargo build
in Windows Terminal with configuration optionterm.progress.taskbar
set totrue
.Not sure
#[cfg(windows)]
? Probably no, because the feature is also usable in WSL.winget
is also behaves like alike. I've experimented withctrl_c handler
and it's totally fixable.Enabled
is a sensible default for WSL because it works on linux builds in Windows Terminal tooTLDR
term.progress.taskbar
option with bool type is addedVideos
Windows.PowerShell.2024-09-29.23-21-21.mp4
cmd.2024-09-29.23-36-25.mp4