Skip to content

Progress bar visibility does not respect TERM=dumb or NO_COLOR=1 #763

@shaanmajid

Description

@shaanmajid

indicatif outputs cursor movement escape sequences even when TERM=dumb and/or NO_COLOR=1 is set, displaying raw ANSI sequences in environments that use pseudo-TTYs but cannot interpret ANSI sequences.

When deciding whether to render progress bars, indicatif checks terminal.is_terminal(), which downstream only checks if stdout/stderr is a TTY (isatty()).

This recently came up in j178/prek#1551 where a user of fugitive.vim -- which sets both TERM=dumb and/or NO_COLOR=1 -- saw raw ANSI sequences from our indicatif spinner.

MRE

cargo.toml:

[dependencies]
indicatif = "0.18.3"

src/main.rs:

use indicatif::ProgressBar;

fn main() {
    let pb = ProgressBar::new_spinner();
    pb.tick();
    pb.finish_with_message("done");
}

Build:

cargo build --release

Run (note, script syntax below is for macOS; Linux syntax varies slightly):

script -q /dev/null creates a pseudo-TTY so isatty() returns true. 1b 5b is hex for ESC[ — the ANSI escape sequence prefix.

# Normal TTY - escape sequences expected
script -q /dev/null ./target/release/mre 2>&1 | xxd | grep '1b 5b'
# Output: 00000050: ... 0d1b 5b32 4b ...  (ESC[2K present)

# With TERM=dumb - escape sequences should be suppressed
TERM=dumb script -q /dev/null ./target/release/mre 2>&1 | xxd | grep '1b 5b'
# Output: (same - ESC[2K still present)

# With NO_COLOR=1 - escape sequences should be suppressed
NO_COLOR=1 script -q /dev/null ./target/release/mre 2>&1 | xxd | grep '1b 5b'
# Output: (same - ESC[2K still present)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions