console-rs / console

A rust console and terminal abstraction
MIT License
961 stars 113 forks source link

Add utility function `ansi::slice_ansi_str` #206

Open remi-dupre opened 9 months ago

remi-dupre commented 9 months ago

Hi!

While working on a bug of indicatif (cf. https://github.com/console-rs/indicatif/pull/627), I needed an ANSI-aware slicing method. I think it made more sense to add it in this crate.

/// Slice a `&str` in terms of text width. This means that only the text
/// columns strictly between `start` and `stop` will be kept.
///
/// If a multi-columns character overlaps with the end of the interval it will
/// not be included. In such a case, the result will be less than `end - start`
/// columns wide.
///
/// If non-empty head and tail are specified, they are inserted between the
/// ANSI symbols from truncated bounds and the slice.
///
/// This ensures that escape codes are not screwed up in the process.
pub fn slice_str<'a>(s: &'a str, head: &str, bounds: Range<usize>, tail: &str) -> Cow<'a, str> {
    ...
}

I made this quite similar to truncate_str, which enables code reuse :blush:

I also suggested a non-allocating implementation for measure_text_width :shrug:

djc commented 9 months ago

Can you avoid let .. else in order to pass the MSRV tests?

remi-dupre commented 9 months ago

Indeed, that should be good now :+1:

remi-dupre commented 9 months ago

And format is also a recent-is feature, on it :grimacing:

I'll try to build on 1.56, it didn't work last time I tried it because it fails to resolve regex = "=1.10.3" :disappointed:

EDIT : Ok, got it

remi-dupre commented 9 months ago

Should be good, make test runs with rust 1.56 on my machine :+1: