Skip to content

Commit

Permalink
Merge pull request #4914 from Ideflop/more_implement_arguments_lines_…
Browse files Browse the repository at this point in the history
…and_number

more: implement arguments -n/--lines and --number
  • Loading branch information
sylvestre authored Jun 2, 2023
2 parents bbfa77d + f1c943e commit e8effd0
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 23 deletions.
74 changes: 51 additions & 23 deletions src/uu/more/src/more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ use std::{
time::Duration,
};

use clap::{crate_version, Arg, ArgAction, ArgMatches, Command};
use clap::{crate_version, value_parser, Arg, ArgAction, ArgMatches, Command};
use crossterm::event::KeyEventKind;
use crossterm::{
cursor::MoveTo,
cursor::{MoveTo, MoveUp},
event::{self, Event, KeyCode, KeyEvent, KeyModifiers},
execute, queue,
style::Attribute,
Expand Down Expand Up @@ -53,16 +53,28 @@ pub mod options {
const MULTI_FILE_TOP_PROMPT: &str = "::::::::::::::\n{}\n::::::::::::::\n";

struct Options {
silent: bool,
clean_print: bool,
lines: Option<u16>,
print_over: bool,
silent: bool,
squeeze: bool,
}

impl Options {
fn from(matches: &ArgMatches) -> Self {
let lines = match (
matches.get_one::<u16>(options::LINES).copied(),
matches.get_one::<u16>(options::NUMBER).copied(),
) {
// We add 1 to the number of lines to display because the last line
// is used for the banner
(Some(number), _) if number > 0 => Some(number + 1),
(None, Some(number)) if number > 0 => Some(number + 1),
(_, _) => None,
};
Self {
clean_print: matches.get_flag(options::CLEAN_PRINT),
lines,
print_over: matches.get_flag(options::PRINT_OVER),
silent: matches.get_flag(options::SILENT),
squeeze: matches.get_flag(options::SQUEEZE),
Expand Down Expand Up @@ -167,6 +179,23 @@ pub fn uu_app() -> Command {
.help("Squeeze multiple blank lines into one")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new(options::LINES)
.short('n')
.long(options::LINES)
.value_name("number")
.num_args(1)
.value_parser(value_parser!(u16).range(0..))
.help("The number of lines per screen full"),
)
.arg(
Arg::new(options::NUMBER)
.long(options::NUMBER)
.required(false)
.num_args(1)
.value_parser(value_parser!(u16).range(0..))
.help("Same as --lines"),
)
// The commented arguments below are unimplemented:
/*
.arg(
Expand All @@ -187,22 +216,6 @@ pub fn uu_app() -> Command {
.long(options::PLAIN)
.help("Suppress underlining and bold"),
)
.arg(
Arg::new(options::LINES)
.short('n')
.long(options::LINES)
.value_name("number")
.takes_value(true)
.help("The number of lines per screen full"),
)
.arg(
Arg::new(options::NUMBER)
.allow_hyphen_values(true)
.long(options::NUMBER)
.required(false)
.takes_value(true)
.help("Same as --lines"),
)
.arg(
Arg::new(options::FROM_LINE)
.short('F')
Expand Down Expand Up @@ -263,7 +276,11 @@ fn more(
next_file: Option<&str>,
options: &Options,
) -> UResult<()> {
let (cols, rows) = terminal::size().unwrap();
let (cols, mut rows) = terminal::size().unwrap();
if let Some(number) = options.lines {
rows = number;
}

let lines = break_buff(buff, usize::from(cols));

let mut pager = Pager::new(rows, lines, next_file, options);
Expand Down Expand Up @@ -327,6 +344,7 @@ fn more(
..
}) => {
pager.page_up();
paging_add_back_message(options, stdout)?;
}
Event::Key(KeyEvent {
code: KeyCode::Char('j'),
Expand All @@ -347,7 +365,7 @@ fn more(
pager.prev_line();
}
Event::Resize(col, row) => {
pager.page_resize(col, row);
pager.page_resize(col, row, options.lines);
}
Event::Key(KeyEvent {
code: KeyCode::Char(k),
Expand Down Expand Up @@ -447,8 +465,10 @@ impl<'a> Pager<'a> {
}

// TODO: Deal with column size changes.
fn page_resize(&mut self, _: u16, row: u16) {
self.content_rows = row.saturating_sub(1);
fn page_resize(&mut self, _: u16, row: u16, option_line: Option<u16>) {
if option_line.is_none() {
self.content_rows = row.saturating_sub(1);
};
}

fn draw(&mut self, stdout: &mut std::io::Stdout, wrong_key: Option<char>) {
Expand Down Expand Up @@ -536,6 +556,14 @@ impl<'a> Pager<'a> {
}
}

fn paging_add_back_message(options: &Options, stdout: &mut std::io::Stdout) -> UResult<()> {
if options.lines.is_some() {
execute!(stdout, MoveUp(1))?;
stdout.write_all("\n\r...back 1 page\n".as_bytes())?;
}
Ok(())
}

// Break the lines on the cols of the terminal
fn break_buff(buff: &str, cols: usize) -> Vec<String> {
let mut lines = Vec::with_capacity(buff.lines().count());
Expand Down
14 changes: 14 additions & 0 deletions tests/by-util/test_more.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ fn test_valid_arg() {

new_ucmd!().arg("-s").succeeds();
new_ucmd!().arg("--squeeze").succeeds();

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

#[test]
fn test_invalid_arg() {
if std::io::stdout().is_terminal() {
new_ucmd!().arg("--invalid").fails();

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

Expand Down

0 comments on commit e8effd0

Please sign in to comment.