From 1b8326336454bdae138c82df12e43712bc343b19 Mon Sep 17 00:00:00 2001 From: sholderbach Date: Thu, 18 Mar 2021 16:40:13 +0100 Subject: [PATCH 1/3] Basic clear Addresses #28 Succeeds in providing a clear new screen for both the line editing and reverse search mode. Solution is conservative and prints more newlines than strictly necessary as solutions with scrolling didn't seem to work as expected. --- src/engine.rs | 24 +++++++++++++++++++++--- src/main.rs | 5 ++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 8b7bf6c3..0c0beecb 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -2,10 +2,10 @@ use std::io::{Stdout, Write}; use std::ops::Deref; use crossterm::{ - cursor::{MoveToColumn, RestorePosition, SavePosition}, + cursor::{MoveTo, MoveToColumn, RestorePosition, SavePosition}, event::{read, Event, KeyCode, KeyEvent, KeyModifiers}, style::{Color, Print, ResetColor, SetForegroundColor}, - terminal::{Clear, ClearType}, + terminal::{self, Clear, ClearType}, QueueableCommand, Result, }; @@ -60,6 +60,7 @@ pub enum Signal { Success(String), CtrlC, // Interrupt current editing CtrlD, // End terminal session + CtrlL, // FormFeed/Clear current screen } pub fn print_message(stdout: &mut Stdout, msg: &str) -> Result<()> { @@ -81,6 +82,16 @@ pub fn print_crlf(stdout: &mut Stdout) -> Result<()> { Ok(()) } +pub fn clear_screen(stdout: &mut Stdout) -> Result<()> { + let (_, num_lines) = terminal::size()?; + for _ in 0..2 * num_lines { + stdout.queue(Print("\n"))?; + } + stdout.queue(MoveTo(0, 0))?; + stdout.flush()?; + Ok(()) +} + fn queue_prompt(stdout: &mut Stdout) -> Result<()> { // print our prompt stdout @@ -436,7 +447,11 @@ impl Engine { } pub fn read_line(&mut self, stdout: &mut Stdout) -> Result { - queue_prompt(stdout)?; + if self.history_search.is_some() { + history_search_paint(stdout, &self)?; + } else { + buffer_paint(stdout, &self)?; + } stdout.flush()?; loop { @@ -477,6 +492,9 @@ impl Engine { self.run_edit_commands(&[EditCommand::Clear]); return Ok(Signal::CtrlC); } + KeyCode::Char('l') => { + return Ok(Signal::CtrlL); + } KeyCode::Char('h') => { self.run_edit_commands(&[EditCommand::Backspace]); } diff --git a/src/main.rs b/src/main.rs index 73d87bff..8a784dd5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use std::io::stdout; mod line_buffer; mod engine; -use engine::{print_crlf, print_message, Engine, Signal}; +use engine::{clear_screen, print_crlf, print_message, Engine, Signal}; mod diagnostic; use diagnostic::print_events; @@ -46,6 +46,9 @@ fn main() -> Result<()> { // We need to move one line down to start with the prompt on a new line print_crlf(&mut stdout)?; } + Signal::CtrlL => { + clear_screen(&mut stdout)?; + } } } } From c081c06b1bc30a7c8b8a8aead40d2c304b143c37 Mon Sep 17 00:00:00 2001 From: sholderbach Date: Thu, 18 Mar 2021 17:30:15 +0100 Subject: [PATCH 2/3] Command based clear --- src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.rs b/src/main.rs index 8a784dd5..f774848f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,6 +40,10 @@ fn main() -> Result<()> { if (buffer.trim() == "exit") || (buffer.trim() == "logout") { break; } + if buffer.trim() == "clear" { + clear_screen(&mut stdout)?; + continue; + } print_message(&mut stdout, &format!("Our buffer: {}", buffer))?; } Signal::CtrlC => { From 2604f7f4eb7c212a46bce679666206304070007f Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Thu, 18 Mar 2021 16:49:01 -0600 Subject: [PATCH 3/3] Redraw prompt indicator after history search The prompt indicator gets drawn over when searching the history so we need to restore it when done searching. --- src/engine.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 465b9ba4..01067daa 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -13,6 +13,8 @@ use std::io::{Stdout, Write}; use std::ops::Deref; const HISTORY_SIZE: usize = 100; +static PROMPT_INDICATOR: &str = "〉"; +const PROMPT_COLOR: Color = Color::Blue; pub enum EditCommand { MoveToStart, @@ -81,18 +83,29 @@ pub fn print_crlf(stdout: &mut Stdout) -> Result<()> { fn queue_prompt(stdout: &mut Stdout) -> Result<()> { let mut prompt = Prompt::new(); - prompt.set_prompt_indicator("〉".to_string()); + prompt.set_prompt_indicator(PROMPT_INDICATOR.to_string()); // print our prompt stdout .queue(MoveToColumn(0))? - .queue(SetForegroundColor(Color::Blue))? + .queue(SetForegroundColor(PROMPT_COLOR))? .queue(Print(prompt.print_prompt()))? .queue(ResetColor)?; Ok(()) } +fn queue_prompt_indicator(stdout: &mut Stdout) -> Result<()> { + // print our prompt + stdout + .queue(MoveToColumn(0))? + .queue(SetForegroundColor(PROMPT_COLOR))? + .queue(Print(PROMPT_INDICATOR))? + .queue(ResetColor)?; + + Ok(()) +} + fn buffer_paint(stdout: &mut Stdout, engine: &Engine, prompt_offset: u16) -> Result<()> { let new_index = engine.get_insertion_point(); @@ -577,6 +590,7 @@ impl Engine { } KeyCode::Enter => match &self.history_search { Some(search) => { + queue_prompt_indicator(stdout)?; if let Some((history_index, _)) = search.result { self.line_buffer .set_buffer(self.history[history_index].clone());