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

Width-filling progress bars wrap around on >1 character wide emojis #611

Open
MarijnS95 opened this issue Dec 6, 2023 · 3 comments
Open

Comments

@MarijnS95
Copy link
Contributor

afbeelding

afbeelding

Consider the example in report #144, modified to use 🖼️ emoji which takes up 2 characters in Windows terminals, and modified to use wide_bar to fill the entire screen:

use std::cmp::min;
use std::thread;
use std::time::Duration;

use indicatif::{ProgressBar, ProgressStyle};

fn main() {
    let mut downloaded = 0;
    let total_size = 231231231;

    let pb = ProgressBar::new(total_size);
    pb.set_style(
        ProgressStyle::default_bar()
            .template("{prefix} {msg:.bold} {wide_bar:.blue} ({pos}/{len}, {elapsed}, ETA {eta})")
            .unwrap()
            .progress_chars("█▇▆▅▄▃▂▁  "),
    );

    pb.set_message("🖼️ Downloading textures");
    while downloaded < total_size {
        let new = min(downloaded + 223211, total_size);
        downloaded = new;
        pb.set_position(new);
        thread::sleep(Duration::from_millis(1));
    }

    pb.set_style(
        ProgressStyle::default_bar()
            .template("{msg:>12.green.bold} downloading {total_bytes:.green} in {elapsed:.green}")
            .unwrap(),
    );
    pb.finish_with_message("Finished");
}

As can be seen in the screenshots the ) in Microsoft Terminal and the s) in VScode wrap around to the next line, spamming progress bars.

Note that in the VSCode terminal there appears to be no space between 🖼️ and Downloading, which is similar to what I observe on Linux (alacritty terminal): the emoji always takes up a single character even if it is rendered in two characters. Not having a space at all (e.g. 🖼️Downloading) gets the D rendered inside the picture frame emoji:

afbeelding

(I'm not familiar with the right ways to solve this in a platform-agnostic manner)


Looking at the organization structure here, perhaps this issue should be transferred to:

https://github.com/console-rs/console


Note that the leading space in the screenshot is simply caused by the unused {prefix} that I forgot to remove while transferring our progress bars to a minimal example.

@MarijnS95
Copy link
Contributor Author

MarijnS95 commented Dec 6, 2023

Note that in both the example and our own code ansi-parsing and unicode-width are turned on on the console crate.

EDIT: Neither is this solved by enabling improved_unicode.

@djc
Copy link
Collaborator

djc commented Dec 6, 2023

I'm open to reviewing a fix for this, but probably won't be able to do much other work on this. I suppose the style::measure() function might be implicated? Not sure which part is going wrong here, I think (particularly with those Cargo features) we should have code for handling this kind of thing.

@MarijnS95
Copy link
Contributor Author

Yeah:

#[test]
fn measure_emojis() {
    assert_eq!(measure("🖼️"), 2);
    assert_eq!(measure("🧼"), 2);
}

Fails with measure() returning 1. I'm not sure if this is also something that changes with fonts and the renderer, as shown with Windows Terminal padding the emoji to two characters while VSCode does not. I.e. printing:

println!("abcdef");
println!("🖼️  🧼"); // Only 2 spaces here

Gives in VSCode terminal:
afbeelding
But in Microsoft Terminal:
afbeelding

Even Windows Console Host adds a third space, despite not being able to render the emoji:

afbeelding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants