Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/uu/cat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ memchr = { workspace = true }
thiserror = { workspace = true }
uucore = { workspace = true, features = ["fast-inc", "fs", "pipes"] }
fluent = { workspace = true }
rand = { workspace = true }

[target.'cfg(unix)'.dependencies]
nix = { workspace = true }
Expand Down
43 changes: 38 additions & 5 deletions src/uu/cat/src/cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@

// spell-checker:ignore (ToDO) nonprint nonblank nonprinting ELOOP

mod colors;
mod platform;

use crate::colors::{ColorMode, ColorWriter};
use crate::platform::is_unsafe_overwrite;
use clap::{Arg, ArgAction, Command};
use memchr::memchr2;
Expand Down Expand Up @@ -133,6 +135,9 @@ struct OutputOptions {

/// use ^ and M- notation, except for LF (\\n) and TAB (\\t)
show_nonprint: bool,

/// Use colorization mode
colorization: Option<ColorMode>,
}

impl OutputOptions {
Expand All @@ -151,7 +156,8 @@ impl OutputOptions {
|| self.show_nonprint
|| self.show_ends
|| self.squeeze_blank
|| self.number != NumberingMode::None)
|| self.number != NumberingMode::None
|| self.colorization.is_some())
}
}

Expand All @@ -169,6 +175,9 @@ struct OutputState {

/// Whether we have already printed a blank line
one_blank_kept: bool,

/// The seeds of the color cycle
color_seed: [f64; 2],
}

#[cfg(unix)]
Expand Down Expand Up @@ -218,6 +227,7 @@ mod options {
pub static SHOW_TABS: &str = "show-tabs";
pub static SHOW_NONPRINTING: &str = "show-nonprinting";
pub static IGNORED_U: &str = "ignored-u";
pub static COLORIZATION: &str = "colorize";
}

#[uucore::main]
Expand Down Expand Up @@ -272,12 +282,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
None => vec![OsString::from("-")],
};

let colorization = if matches.get_flag(options::COLORIZATION) {
Some(ColorMode::new())
} else {
None
};

let options = OutputOptions {
show_ends,
number: number_mode,
show_nonprint,
show_tabs,
squeeze_blank,
colorization,
};
cat_files(&files, &options)
}
Expand Down Expand Up @@ -366,6 +383,13 @@ pub fn uu_app() -> Command {
.help(translate!("cat-help-ignored-u"))
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::COLORIZATION)
// .short("lol")
.long("lol")
.hide(true)
.action(ArgAction::SetTrue),
)
}

fn cat_handle<R: FdReadable>(
Expand Down Expand Up @@ -424,6 +448,7 @@ fn cat_files(files: &[OsString], options: &OutputOptions) -> UResult<()> {
at_line_start: true,
skipped_carriage_return: false,
one_blank_kept: false,
color_seed: [rand::random::<f64>() * 10e9; 2],
};
let mut error_messages: Vec<String> = Vec::new();

Expand Down Expand Up @@ -569,10 +594,14 @@ fn write_lines<R: FdReadable>(
state.line_number.write(&mut writer)?;
state.line_number.increment();
}

// print to end of line or end of buffer
let offset = write_end(&mut writer, &in_buf[pos..], options);

// print to end of line or end of buffer,
// dispatching according to the writer needed.
let offset = if let Some(color_mode) = options.colorization {
let mut writer = ColorWriter::new(&mut writer, color_mode, state);
write_end(&mut writer, &in_buf[pos..], options)
} else {
write_end(&mut writer, &in_buf[pos..], options)
};
// end of buffer?
if offset + pos == in_buf.len() {
state.at_line_start = false;
Expand All @@ -592,6 +621,10 @@ fn write_lines<R: FdReadable>(
}
pos += offset + 1;
}
// reset foreground at the end.
if options.colorization.is_some() {
writer.write_all(b"\x1b[39m")?;
}
// We need to flush the buffer each time around the loop in order to pass GNU tests.
// When we are reading the input from a pipe, the `handle.reader.read` call at the top
// of this loop will block (indefinitely) whist waiting for more data. The expectation
Expand Down
Loading
Loading