From b335e7f2aeb6125e068d614affeed96fa2f11e6c Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 17:57:35 +0800 Subject: [PATCH 1/6] Now stops at the last line first. Press down again to go to next file or quit Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 206cebbc2..d83961d2c 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -239,7 +239,11 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo code: KeyCode::Char(' '), modifiers: KeyModifiers::NONE, }) => { - pager.page_down(); + if pager.should_close() { + return; + } else { + pager.page_down(); + } } Event::Key(KeyEvent { code: KeyCode::Up, @@ -253,9 +257,6 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo } pager.draw(stdout, wrong_key); - if pager.should_close() { - return; - } } } } @@ -268,7 +269,6 @@ struct Pager<'a> { lines: Vec, next_file: Option<&'a str>, line_count: usize, - close_on_down: bool, silent: bool, } @@ -277,33 +277,25 @@ impl<'a> Pager<'a> { let line_count = lines.len(); Self { upper_mark: 0, - content_rows: rows - 1, + content_rows: rows.saturating_sub(1), lines, next_file, line_count, - close_on_down: false, silent, } } fn should_close(&mut self) -> bool { - if self.upper_mark + self.content_rows >= self.line_count { - if self.close_on_down { - return true; - } - if self.next_file.is_none() { - return true; - } else { - self.close_on_down = true; - } - } else { - self.close_on_down = false; - } - false + self.upper_mark + .saturating_add(self.content_rows) + .eq(&self.line_count) } fn page_down(&mut self) { - self.upper_mark += self.content_rows; + self.upper_mark = self + .upper_mark + .saturating_add(self.content_rows) + .min(self.line_count.saturating_sub(self.content_rows)); } fn page_up(&mut self) { @@ -364,7 +356,7 @@ impl<'a> Pager<'a> { // Break the lines on the cols of the terminal fn break_buff(buff: &str, cols: usize) -> Vec { - let mut lines = Vec::new(); + let mut lines = Vec::with_capacity(buff.lines().count()); for l in buff.lines() { lines.append(&mut break_line(l, cols)); From 63ee42826b017ac4d0075dbdfc373535e731d3af Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 18:02:31 +0800 Subject: [PATCH 2/6] Fixed numeric type 1. Its better to bump u16 to usize than the other way round. 2. Highly unlikely to have a terminal with usize rows...makes making sense of the code easier. Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index d83961d2c..90ef07e99 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -210,7 +210,7 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo let (cols, rows) = terminal::size().unwrap(); let lines = break_buff(buff, usize::from(cols)); - let mut pager = Pager::new(rows as usize, lines, next_file, silent); + let mut pager = Pager::new(rows, lines, next_file, silent); pager.draw(stdout, false); if pager.should_close() { return; @@ -265,7 +265,7 @@ struct Pager<'a> { // The current line at the top of the screen upper_mark: usize, // The number of rows that fit on the screen - content_rows: usize, + content_rows: u16, lines: Vec, next_file: Option<&'a str>, line_count: usize, @@ -273,7 +273,7 @@ struct Pager<'a> { } impl<'a> Pager<'a> { - fn new(rows: usize, lines: Vec, next_file: Option<&'a str>, silent: bool) -> Self { + fn new(rows: u16, lines: Vec, next_file: Option<&'a str>, silent: bool) -> Self { let line_count = lines.len(); Self { upper_mark: 0, @@ -287,23 +287,25 @@ impl<'a> Pager<'a> { fn should_close(&mut self) -> bool { self.upper_mark - .saturating_add(self.content_rows) + .saturating_add(self.content_rows.into()) .eq(&self.line_count) } fn page_down(&mut self) { self.upper_mark = self .upper_mark - .saturating_add(self.content_rows) - .min(self.line_count.saturating_sub(self.content_rows)); + .saturating_add(self.content_rows.into()) + .min(self.line_count.saturating_sub(self.content_rows.into())); } fn page_up(&mut self) { - self.upper_mark = self.upper_mark.saturating_sub(self.content_rows); + self.upper_mark = self.upper_mark.saturating_sub(self.content_rows.into()); } fn draw(&self, stdout: &mut std::io::Stdout, wrong_key: bool) { - let lower_mark = self.line_count.min(self.upper_mark + self.content_rows); + 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(); @@ -315,7 +317,7 @@ impl<'a> Pager<'a> { .lines .iter() .skip(self.upper_mark) - .take(self.content_rows); + .take(self.content_rows.into()); for line in displayed_lines { stdout From ee6419f11c85056682f4ba190cd9f6329f04043c Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 18:10:38 +0800 Subject: [PATCH 3/6] Fixing display when resizing terminal Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 90ef07e99..dac48cea7 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -251,6 +251,10 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo }) => { pager.page_up(); } + Event::Resize(col, row) => { + pager.page_resize(col, row); + } + // FIXME: Need to fix, there are more than just unknown keys. _ => { wrong_key = true; } @@ -302,6 +306,11 @@ impl<'a> Pager<'a> { self.upper_mark = self.upper_mark.saturating_sub(self.content_rows.into()); } + // TODO: Deal with column size changes. + fn page_resize(&mut self, _: u16, row: u16) { + self.content_rows = row.saturating_sub(1); + } + fn draw(&self, stdout: &mut std::io::Stdout, wrong_key: bool) { let lower_mark = self .line_count From 28c6fad6e3855176ea77b5899be225d9f2eff5ee Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 18:25:14 +0800 Subject: [PATCH 4/6] Now displays the unknown key entered Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index dac48cea7..3724cd801 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -211,13 +211,13 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo let lines = break_buff(buff, usize::from(cols)); let mut pager = Pager::new(rows, lines, next_file, silent); - pager.draw(stdout, false); + pager.draw(stdout, None); if pager.should_close() { return; } loop { - let mut wrong_key = false; + let mut wrong_key = None; if event::poll(Duration::from_millis(10)).unwrap() { match event::read().unwrap() { Event::Key(KeyEvent { @@ -254,10 +254,11 @@ fn more(buff: &str, mut stdout: &mut Stdout, next_file: Option<&str>, silent: bo Event::Resize(col, row) => { pager.page_resize(col, row); } - // FIXME: Need to fix, there are more than just unknown keys. - _ => { - wrong_key = true; - } + Event::Key(KeyEvent { + code: KeyCode::Char(k), + .. + }) => wrong_key = Some(k), + _ => continue, } pager.draw(stdout, wrong_key); @@ -311,7 +312,7 @@ impl<'a> Pager<'a> { self.content_rows = row.saturating_sub(1); } - fn draw(&self, stdout: &mut std::io::Stdout, wrong_key: bool) { + fn draw(&self, stdout: &mut std::io::Stdout, wrong_key: Option) { let lower_mark = self .line_count .min(self.upper_mark.saturating_add(self.content_rows.into())); @@ -335,7 +336,7 @@ impl<'a> Pager<'a> { } } - fn draw_prompt(&self, stdout: &mut Stdout, lower_mark: usize, wrong_key: bool) { + fn draw_prompt(&self, stdout: &mut Stdout, lower_mark: usize, wrong_key: Option) { let status_inner = if lower_mark == self.line_count { format!("Next file: {}", self.next_file.unwrap_or_default()) } else { @@ -348,10 +349,15 @@ impl<'a> Pager<'a> { let status = format!("--More--({})", status_inner); let banner = match (self.silent, wrong_key) { - (true, true) => "[Press 'h' for instructions. (unimplemented)]".to_string(), - (true, false) => format!("{}[Press space to continue, 'q' to quit.]", status), - (false, true) => format!("{}{}", status, BELL), - (false, false) => status, + (true, Some(key)) => { + format!( + "{} [Unknown key: '{}'. Press 'h' for instructions. (unimplemented)]", + status, key + ) + } + (true, None) => format!("{}[Press space to continue, 'q' to quit.]", status), + (false, Some(_)) => format!("{}{}", status, BELL), + (false, None) => status, }; write!( From 9ed5091be6bf4f0f9c13ec85a1b1ea9f72c4eccb Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 20:30:15 +0800 Subject: [PATCH 5/6] Fixed hanging with smaller content Using 'seq 10 | cargo run -- more' should no longer hangs. Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 3724cd801..93a2f0edf 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -293,7 +293,7 @@ impl<'a> Pager<'a> { fn should_close(&mut self) -> bool { self.upper_mark .saturating_add(self.content_rows.into()) - .eq(&self.line_count) + .ge(&self.line_count) } fn page_down(&mut self) { From 083e74597613d2edd1d17fce1bca282a8db0f315 Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sat, 12 Jun 2021 20:34:21 +0800 Subject: [PATCH 6/6] Simplified page down implementation Signed-off-by: Hanif Bin Ariffin --- src/uu/more/src/more.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index 93a2f0edf..d7fba5080 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -297,10 +297,7 @@ impl<'a> Pager<'a> { } fn page_down(&mut self) { - self.upper_mark = self - .upper_mark - .saturating_add(self.content_rows.into()) - .min(self.line_count.saturating_sub(self.content_rows.into())); + self.upper_mark = self.upper_mark.saturating_add(self.content_rows.into()); } fn page_up(&mut self) {