Skip to content

Commit

Permalink
Merge pull request #4950 from Ideflop/more_implement_arguments_plain_…
Browse files Browse the repository at this point in the history
…and_from_line

More implement arguments plain and from line
  • Loading branch information
cakebaker authored Jul 1, 2023
2 parents 0438300 + c4c3a35 commit c524ec4
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 28 deletions.
82 changes: 54 additions & 28 deletions src/uu/more/src/more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ pub mod options {
pub const FILES: &str = "files";
}

const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n";
const MULTI_FILE_TOP_PROMPT: &str = "\r::::::::::::::\n\r{}\n\r::::::::::::::\n";

struct Options {
clean_print: bool,
from_line: usize,
lines: Option<u16>,
print_over: bool,
silent: bool,
Expand All @@ -72,8 +73,13 @@ impl Options {
(None, Some(number)) if number > 0 => Some(number + 1),
(_, _) => None,
};
let from_line = match matches.get_one::<usize>(options::FROM_LINE).copied() {
Some(number) if number > 1 => number - 1,
_ => 0,
};
Self {
clean_print: matches.get_flag(options::CLEAN_PRINT),
from_line,
lines,
print_over: matches.get_flag(options::PRINT_OVER),
silent: matches.get_flag(options::SILENT),
Expand All @@ -90,7 +96,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
Err(e) => return Err(e.into()),
};

let options = Options::from(&matches);
let mut options = Options::from(&matches);

let mut buff = String::new();

Expand All @@ -115,9 +121,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
format!("cannot open {}: No such file or directory", file.quote()),
));
}
if length > 1 {
buff.push_str(&MULTI_FILE_TOP_PROMPT.replace("{}", file.to_str().unwrap()));
}
let opened_file = match File::open(file) {
Err(why) => {
terminal::disable_raw_mode().unwrap();
Expand All @@ -130,14 +133,21 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
};
let mut reader = BufReader::new(opened_file);
reader.read_to_string(&mut buff).unwrap();
more(&buff, &mut stdout, next_file.copied(), &options)?;
more(
&buff,
&mut stdout,
length > 1,
file.to_str(),
next_file.copied(),
&mut options,
)?;
buff.clear();
}
reset_term(&mut stdout);
} else if !std::io::stdin().is_terminal() {
stdin().read_to_string(&mut buff).unwrap();
let mut stdout = setup_term();
more(&buff, &mut stdout, None, &options)?;
more(&buff, &mut stdout, false, None, None, &mut options)?;
reset_term(&mut stdout);
} else {
return Err(UUsageError::new(1, "bad usage"));
Expand Down Expand Up @@ -179,6 +189,22 @@ pub fn uu_app() -> Command {
.help("Squeeze multiple blank lines into one")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::PLAIN)
.short('u')
.long(options::PLAIN)
.action(ArgAction::SetTrue)
.hide(true),
)
.arg(
Arg::new(options::FROM_LINE)
.short('F')
.long(options::FROM_LINE)
.num_args(1)
.value_name("number")
.value_parser(value_parser!(usize))
.help("Display file beginning from line number"),
)
.arg(
Arg::new(options::LINES)
.short('n')
Expand All @@ -191,7 +217,6 @@ pub fn uu_app() -> Command {
.arg(
Arg::new(options::NUMBER)
.long(options::NUMBER)
.required(false)
.num_args(1)
.value_parser(value_parser!(u16).range(0..))
.help("Same as --lines"),
Expand All @@ -210,21 +235,6 @@ pub fn uu_app() -> Command {
.long(options::NO_PAUSE)
.help("Suppress pause after form feed"),
)
.arg(
Arg::new(options::PLAIN)
.short('u')
.long(options::PLAIN)
.help("Suppress underlining and bold"),
)
.arg(
Arg::new(options::FROM_LINE)
.short('F')
.allow_hyphen_values(true)
.required(false)
.takes_value(true)
.value_name("number")
.help("Display file beginning from line number"),
)
.arg(
Arg::new(options::PATTERN)
.short('P')
Expand Down Expand Up @@ -273,8 +283,10 @@ fn reset_term(_: &mut usize) {}
fn more(
buff: &str,
stdout: &mut Stdout,
multiple_file: bool,
file: Option<&str>,
next_file: Option<&str>,
options: &Options,
options: &mut Options,
) -> UResult<()> {
let (cols, mut rows) = terminal::size().unwrap();
if let Some(number) = options.lines {
Expand All @@ -284,8 +296,23 @@ fn more(
let lines = break_buff(buff, usize::from(cols));

let mut pager = Pager::new(rows, lines, next_file, options);

if multiple_file {
execute!(stdout, terminal::Clear(terminal::ClearType::CurrentLine)).unwrap();
stdout.write_all(
MULTI_FILE_TOP_PROMPT
.replace("{}", file.unwrap_or_default())
.as_bytes(),
)?;
pager.content_rows -= 3;
}
pager.draw(stdout, None);
if pager.should_close() {
if multiple_file {
options.from_line = 0;
pager.content_rows += 3;
}

if pager.should_close() && next_file.is_none() {
return Ok(());
}

Expand Down Expand Up @@ -406,7 +433,7 @@ impl<'a> Pager<'a> {
fn new(rows: u16, lines: Vec<String>, next_file: Option<&'a str>, options: &Options) -> Self {
let line_count = lines.len();
Self {
upper_mark: 0,
upper_mark: options.from_line,
content_rows: rows.saturating_sub(1),
lines,
next_file,
Expand Down Expand Up @@ -472,10 +499,10 @@ impl<'a> Pager<'a> {
}

fn draw(&mut self, stdout: &mut std::io::Stdout, wrong_key: Option<char>) {
self.draw_lines(stdout);
let lower_mark = self
.line_count
.min(self.upper_mark.saturating_add(self.content_rows.into()));
self.draw_lines(stdout);
self.draw_prompt(stdout, lower_mark, wrong_key);
stdout.flush().unwrap();
}
Expand Down Expand Up @@ -535,7 +562,6 @@ impl<'a> Pager<'a> {
};

let status = format!("--More--({status_inner})");

let banner = match (self.silent, wrong_key) {
(true, Some(key)) => format!(
"{status} [Unknown key: '{key}'. Press 'h' for instructions. (unimplemented)]"
Expand Down
42 changes: 42 additions & 0 deletions tests/by-util/test_more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ fn test_valid_arg() {
new_ucmd!().arg("-s").succeeds();
new_ucmd!().arg("--squeeze").succeeds();

new_ucmd!().arg("-u").succeeds();
new_ucmd!().arg("--plain").succeeds();

new_ucmd!().arg("-n").arg("10").succeeds();
new_ucmd!().arg("--lines").arg("0").succeeds();
new_ucmd!().arg("--number").arg("0").succeeds();

new_ucmd!().arg("-F").arg("10").succeeds();
new_ucmd!().arg("--from-line").arg("0").succeeds();
}
}

Expand All @@ -34,6 +40,42 @@ fn test_invalid_arg() {

new_ucmd!().arg("--lines").arg("-10").fails();
new_ucmd!().arg("--number").arg("-10").fails();

new_ucmd!().arg("--from-line").arg("-10").fails();
}
}

#[test]
fn test_argument_from_file() {
if std::io::stdout().is_terminal() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;

let file = "test_file";

at.write(file, "1\n2");

// output all lines
scene
.ucmd()
.arg("-F")
.arg("0")
.arg(file)
.succeeds()
.no_stderr()
.stdout_contains("1")
.stdout_contains("2");

// output only the second line
scene
.ucmd()
.arg("-F")
.arg("2")
.arg(file)
.succeeds()
.no_stderr()
.stdout_contains("2")
.stdout_does_not_contain("1");
}
}

Expand Down

0 comments on commit c524ec4

Please sign in to comment.