From 8552449510abf2cbe78b49ffe4437f619976a9e8 Mon Sep 17 00:00:00 2001 From: rhpidfyre Date: Fri, 31 Jan 2025 14:02:58 -0500 Subject: [PATCH] up arrow history indexing working, dedup history --- src/history.rs | 5 ++++- src/session.rs | 4 ++-- src/terminal.rs | 50 ++++++++++++++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/history.rs b/src/history.rs index b6f0ac1..2f3d6ad 100644 --- a/src/history.rs +++ b/src/history.rs @@ -18,7 +18,10 @@ impl History { }); file.as_ref().and_then(|file| { File::open(file).map_or_display_none(|file| { - Some(BufReader::new(file).lines().map_while(Result::ok).collect::>()) + let mut fs_history_vec = BufReader::new(file).lines().map_while(Result::ok).collect::>(); + fs_history_vec.dedup(); + fs_history_vec.reverse(); + Some(fs_history_vec) }) }).inspect(|fs_history_vec| history = fs_history_vec.clone()); diff --git a/src/session.rs b/src/session.rs index ebd572d..73afc2a 100644 --- a/src/session.rs +++ b/src/session.rs @@ -44,7 +44,7 @@ pub struct Config { #[derive(Debug, Clone)] pub struct Input { pub literal: String, - pub cursor: usize, + pub cursor: u16, } pub struct Rt { pub input: Input, @@ -66,7 +66,7 @@ impl Pse { history: History::init(), input: Input { literal: String::new(), - cursor: usize::MIN, + cursor: u16::MIN, }, }; diff --git a/src/terminal.rs b/src/terminal.rs index 3530e5f..4b1f09b 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -1,6 +1,6 @@ use crossterm::{cursor, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, terminal}; use core::fmt; -use std::{io::{self, Write}, mem}; +use std::io::{self, Write}; use thiserror::Error; use crate::{commands::Command, session::{self, Pse}}; @@ -32,7 +32,7 @@ fn debug(s: S) { } trait SpecificKeybinds { - const EXIT_1: &str; + const EXIT_ID_1: &str; const KEY_SPACE: char; fn key_literal(&mut self, keycode: KeyCode) -> InputResult<()>; fn key_ctrl(&mut self, input_key: KeyEvent, keycode: KeyCode) -> InputResult<()>; @@ -44,7 +44,7 @@ trait SpecificKeybinds { fn key_arrow_down(&mut self) -> InputResult<()>; } impl SpecificKeybinds for Pse { - const EXIT_1: &str = "exit"; + const EXIT_ID_1: &str = "exit"; const KEY_SPACE: char = ' '; fn key_literal(&mut self, keycode: KeyCode) -> InputResult<()> { @@ -58,6 +58,7 @@ impl SpecificKeybinds for Pse { match input_key.modifiers.contains(KeyModifiers::CONTROL) { true => match keycode { KeyCode::Char('c') => Err(InputHandleError::Sigint), + KeyCode::Char('r') => unimplemented!(), _ => Ok(()) }, false => self.key_literal(keycode) @@ -65,13 +66,13 @@ impl SpecificKeybinds for Pse { } fn key_enter(&mut self) -> InputResult<()> { - if self.rt.input.literal == Self::EXIT_1 { return Err(InputHandleError::UserExit) }; + if self.rt.input.literal == Self::EXIT_ID_1 { return Err(InputHandleError::UserExit) }; terminal::disable_raw_mode().map_err(InputHandleError::DisableRaw)?; println!(); self.spawn_sys_cmd(); self.rt.input.literal.clear(); - self.rt.input.cursor = usize::MIN; + self.rt.input.cursor = u16::MIN; self.term_render_ps() } @@ -102,15 +103,21 @@ impl SpecificKeybinds for Pse { } fn key_arrow_up(&mut self) -> InputResult<()> { - if self.rt.input.literal.is_empty() { - self.rt.history.index += 1; - // if self.rt.history_index == self.history.fs_history + self.rt.history.index += 1; + if self.rt.history.index != self.rt.history.history.len() as isize { + self.term_render_reset()?; + self.term_render(self.rt.history.history[self.rt.history.index as usize].clone())?; } Ok(()) } fn key_arrow_down(&mut self) -> InputResult<()> { - unimplemented!() + self.rt.history.index -= 1; + if self.rt.history.index != -1 { + self.term_render_reset()?; + self.term_render(self.rt.history.history[self.rt.history.index as usize].clone())?; + } + Ok(()) } } @@ -120,8 +127,8 @@ pub trait TermInputCursor { } impl TermInputCursor for Pse { fn term_input_cursor_move_left(&mut self) -> Option<()> { - if self.rt.input.cursor == usize::MIN { None } else { - match self.rt.input.cursor>usize::MIN { + if self.rt.input.cursor == u16::MIN { None } else { + match self.rt.input.cursor>u16::MIN { true => { self.rt.input.cursor-=1; Some(()) } false => None } @@ -129,8 +136,8 @@ impl TermInputCursor for Pse { } fn term_input_cursor_move_right(&mut self) -> Option<()> { - if self.rt.input.cursor == usize::MAX { None } else { - match self.rt.input.cursor { self.rt.input.cursor+=1; Some(()) }, false => None } @@ -141,17 +148,19 @@ impl TermInputCursor for Pse { pub trait TermProcessor { fn term_render(&mut self, def_string: String) -> InputResult<()>; fn term_render_ps(&self) -> InputResult<()>; + fn term_render_reset(&mut self) -> InputResult<()>; fn term_input_handler(&mut self, input_key: KeyEvent) -> Option<()>; fn term_input_mainthread(&mut self) -> io::Result<()>; fn term_input_processor(&mut self) -> io::Result<()>; } impl TermProcessor for Pse { fn term_render(&mut self, text: String) -> InputResult<()> { - self.rt.input.literal.insert_str(self.rt.input.cursor, &text); - self.rt.input.cursor+=1; - if self.rt.input.cursor != self.rt.input.literal.chars().count() { + self.rt.input.literal.insert_str(self.rt.input.cursor.into(), &text); + let input_literal_size = self.rt.input.literal.chars().count() as u16; + self.rt.input.cursor = input_literal_size; + if self.rt.input.cursor != input_literal_size { execute!(io::stdout(), terminal::Clear(terminal::ClearType::UntilNewLine)).map_err(InputHandleError::Flush)?; - let slice = &self.rt.input.literal[self.rt.input.cursor..]; + let slice = &self.rt.input.literal[(self.rt.input.cursor as usize)..]; write!(io::stdout(), "{text}{slice}").map_err(InputHandleError::Write)?; } else { write!(io::stdout(), "{text}").map_err(InputHandleError::Write)?; @@ -164,6 +173,13 @@ impl TermProcessor for Pse { io::stdout().flush().map_err(InputHandleError::Flush) } + fn term_render_reset(&mut self) -> InputResult<()> { + execute!(io::stdout(), cursor::MoveLeft(self.rt.input.cursor)).map_err(InputHandleError::Flush)?; + self.rt.input.cursor = u16::MIN; + self.rt.input.literal.clear(); + execute!(io::stdout(), terminal::Clear(terminal::ClearType::UntilNewLine)).map_err(InputHandleError::Flush) + } + fn term_input_handler(&mut self, input_key: KeyEvent) -> Option<()> { let input_handle = match input_key.code { KeyCode::Enter => self.key_enter(),