Make ANSI stripping lazy in more places (#4380)

Same rationale as in #4378

Also accelerate `grid`

before:

```
Command being timed: "./eager_nu -c for i in 0..100000 { echo whatever } | grid"
        User time (seconds): 0.21
        System time (seconds): 0.05
        Percent of CPU this job got: 36%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.71
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 48112
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 10580
        Voluntary context switches: 266
        Involuntary context switches: 2595
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```

after:

```
Command being timed: "./lazy_nu -c for i in 0..100000 { echo whatever } | grid"
        User time (seconds): 0.14
        System time (seconds): 0.05
        Percent of CPU this job got: 33%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.60
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 48272
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 1
        Minor (reclaiming a frame) page faults: 10582
        Voluntary context switches: 286
        Involuntary context switches: 831
        Swaps: 0
        File system inputs: 56
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```
This commit is contained in:
Stefan Holderbach 2022-02-09 01:25:31 +01:00 committed by GitHub
parent 9c7feb2b19
commit 659da3c4a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 15 deletions

View file

@ -1,3 +1,5 @@
use std::borrow::Cow;
// use super::icons::{icon_for_file, iconify_style_ansi_to_nu}; // use super::icons::{icon_for_file, iconify_style_ansi_to_nu};
use super::icons::icon_for_file; use super::icons::icon_for_file;
use lscolors::{LsColors, Style}; use lscolors::{LsColors, Style};
@ -131,12 +133,24 @@ prints out the list properly."#
} }
} }
fn strip_ansi(astring: &str) -> String { /// Removes ANSI escape codes and some ASCII control characters
if let Ok(bytes) = strip_ansi_escapes::strip(astring) { ///
String::from_utf8_lossy(&bytes).to_string() /// Keeps `\n` removes `\r`, `\t` etc.
} else { ///
astring.to_string() /// If parsing fails silently returns the input string
fn strip_ansi(string: &str) -> Cow<str> {
// Check if any ascii control character except LF(0x0A = 10) is present,
// which will be stripped. Includes the primary start of ANSI sequences ESC
// (0x1B = decimal 27)
if string.bytes().any(|x| matches!(x, 0..=9 | 11..=31)) {
if let Ok(stripped) = strip_ansi_escapes::strip(string) {
if let Ok(new_string) = String::from_utf8(stripped) {
return Cow::Owned(new_string);
}
}
} }
// Else case includes failures to parse!
Cow::Borrowed(string)
} }
fn create_grid_output( fn create_grid_output(
@ -177,7 +191,7 @@ fn create_grid_output(
if color_param { if color_param {
if use_grid_icons { if use_grid_icons {
let no_ansi = strip_ansi(&value); let no_ansi = strip_ansi(&value);
let path = std::path::Path::new(&no_ansi); let path = std::path::Path::new(no_ansi.as_ref());
let icon = icon_for_file(path, call.head)?; let icon = icon_for_file(path, call.head)?;
let ls_colors_style = ls_colors.style_for_path(path); let ls_colors_style = ls_colors.style_for_path(path);
// eprintln!("ls_colors_style: {:?}", &ls_colors_style); // eprintln!("ls_colors_style: {:?}", &ls_colors_style);

View file

@ -91,22 +91,35 @@
//! [`fit_into_width`]: ./struct.Grid.html#method.fit_into_width //! [`fit_into_width`]: ./struct.Grid.html#method.fit_into_width
//! [`GridOptions`]: ./struct.GridOptions.html //! [`GridOptions`]: ./struct.GridOptions.html
use std::borrow::Cow;
use std::cmp::max; use std::cmp::max;
use std::fmt; use std::fmt;
use std::iter::repeat; use std::iter::repeat;
use strip_ansi_escapes::strip; use strip_ansi_escapes;
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
fn unicode_width_strip_ansi(astring: &str) -> usize { /// Removes ANSI escape codes and some ASCII control characters
let stripped_string: String = { ///
if let Ok(bytes) = strip(astring) { /// Keeps `\n` removes `\r`, `\t` etc.
String::from_utf8_lossy(&bytes).to_string() ///
} else { /// If parsing fails silently returns the input string
astring.to_string() fn strip_ansi(string: &str) -> Cow<str> {
// Check if any ascii control character except LF(0x0A = 10) is present,
// which will be stripped. Includes the primary start of ANSI sequences ESC
// (0x1B = decimal 27)
if string.bytes().any(|x| matches!(x, 0..=9 | 11..=31)) {
if let Ok(stripped) = strip_ansi_escapes::strip(string) {
if let Ok(new_string) = String::from_utf8(stripped) {
return Cow::Owned(new_string);
}
} }
}; }
// Else case includes failures to parse!
Cow::Borrowed(string)
}
UnicodeWidthStr::width(&stripped_string[..]) fn unicode_width_strip_ansi(astring: &str) -> usize {
strip_ansi(astring).width()
} }
/// Alignment indicate on which side the content should stick if some filling /// Alignment indicate on which side the content should stick if some filling