diff --git a/src/keys.rs b/src/keys.rs index 7dcd9cf..46f64ee 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -2,6 +2,14 @@ use crate::*; use opener::open; macro_rules! press { + (Shift-$($key:tt)+) => { + Event::Key(KeyEvent { + code: KeyCode::$($key)+, + kind: KeyEventKind::Press, + modifiers: KeyModifiers::SHIFT, + state: KeyEventState::NONE + }) + }; ($($key:tt)+) => { Event::Key(KeyEvent { code: KeyCode::$($key)+, @@ -9,7 +17,7 @@ macro_rules! press { modifiers: KeyModifiers::NONE, state: KeyEventState::NONE }) - } + }; } impl Handle for Taggart { @@ -17,24 +25,26 @@ impl Handle for Taggart { let x_min = self.offset; let x_max = self.offset + self.size.h().saturating_sub(1); let event = &*input.event(); - match event { - press!(Up) => { self.cursor = self.cursor.saturating_sub(1); }, - press!(Down) => { self.cursor = self.cursor + 1; }, - press!(PageUp) => { self.cursor = self.cursor.saturating_sub(PAGE_SIZE); }, - press!(PageDown) => { self.cursor += PAGE_SIZE; }, - press!(Left) => { self.column = self.column.saturating_sub(1); }, - press!(Right) => { self.column = self.column + 1; }, - press!(Char(' ')) => { open(&self.paths[self.cursor].path)?; } - _ => match &self.editing { - Some(_value) => match event { - press!(Enter) => todo!(), - press!(Esc) => todo!(), - _ => {} - }, - None => match event { - press!(Enter) => todo!(), - _ => {} - } + match &self.editing { + Some(_value) => match event { + press!(Char(c)) => self.edit_insert(*c), + press!(Shift-Char(c)) => self.edit_insert(c.to_uppercase().next().unwrap()), + press!(Backspace) => self.edit_backspace(), + press!(Delete) => self.edit_delete(), + press!(Enter) => self.edit_cancel(), + press!(Esc) => self.edit_confirm(), + _ => {} + }, + None => match event { + press!(Up) => { self.cursor = self.cursor.saturating_sub(1); }, + press!(Down) => { self.cursor = self.cursor + 1; }, + press!(PageUp) => { self.cursor = self.cursor.saturating_sub(PAGE_SIZE); }, + press!(PageDown) => { self.cursor += PAGE_SIZE; }, + press!(Left) => { self.column = self.column.saturating_sub(1); }, + press!(Right) => { self.column = self.column + 1; }, + press!(Char(' ')) => { open(&self.paths[self.cursor].path)?; } + press!(Enter) => self.edit_begin(), + _ => {} } } if self.cursor < x_min { diff --git a/src/main.rs b/src/main.rs index 3a3ba7c..7f9f4d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,37 +41,3 @@ fn main () -> Usually<()> { let state = Arc::new(RwLock::new(Taggart::new(&path)?)); Tui::new()?.run(&state) } - -impl Taggart { - - fn new (root: &impl AsRef) -> Usually { - Ok(Self { - _root: root.as_ref().into(), - paths: Self::collect(root)?, - cursor: 0, - offset: 0, - column: 0, - size: Measure::new(), - editing: None, - columns: Columns::default(), - }) - } - - fn collect (root: &impl AsRef) -> Usually> { - let mut paths = vec![]; - for entry in WalkDir::new(&root).into_iter() - .filter_entry(|e|!e.file_name().to_str().map(|s|s.starts_with(".")).unwrap_or(false)) - { - let entry = entry?; - if entry.depth() == 0 { - continue - } - if let Some(entry) = Entry::new(root, &entry)? { - paths.push(entry); - } - } - paths.sort(); - Ok(paths) - } - -} diff --git a/src/model.rs b/src/model.rs index 38537bb..005cb69 100644 --- a/src/model.rs +++ b/src/model.rs @@ -10,7 +10,60 @@ pub struct Taggart { pub column: usize, pub columns: Columns, pub size: Measure, - pub editing: Option, + pub editing: Option<(usize, String)>, +} + +impl Taggart { + pub fn new (root: &impl AsRef) -> Usually { + Ok(Self { + _root: root.as_ref().into(), + paths: Self::collect(root)?, + cursor: 0, + offset: 0, + column: 0, + size: Measure::new(), + editing: None, + columns: Columns::default(), + }) + } + pub fn collect (root: &impl AsRef) -> Usually> { + let mut paths = vec![]; + for entry in WalkDir::new(&root).into_iter() + .filter_entry(|e|!e.file_name().to_str().map(|s|s.starts_with(".")).unwrap_or(false)) + { + let entry = entry?; + if entry.depth() == 0 { + continue + } + if let Some(entry) = Entry::new(root, &entry)? { + paths.push(entry); + } + } + paths.sort(); + Ok(paths) + } + pub fn edit_begin (&mut self) { + let value = (self.columns.0[self.column].value)(&self.paths[self.cursor]); + let value = format!("{}", value.unwrap_or_default()); + self.editing = Some((value.len(), value)); + } + pub fn edit_cancel (&mut self) { + self.editing = None; + } + pub fn edit_confirm (&mut self) { + self.editing = None; + } + pub fn edit_insert (&mut self, c: char) { + if let Some((index, value)) = &mut self.editing { + self.editing = Some((*index, format!("{value}{c}"))); + } + } + pub fn edit_backspace (&mut self) { + todo!() + } + pub fn edit_delete (&mut self) { + todo!() + } } #[derive(Ord, Eq, PartialEq, PartialOrd)] diff --git a/src/view.rs b/src/view.rs index 131df60..26aff79 100644 --- a/src/view.rs +++ b/src/view.rs @@ -3,9 +3,9 @@ use tek_tui::ratatui::{style::{Color, Style}, prelude::Stylize}; use pad::PadStr; pub struct Column { - title: Arc, - width: usize, - value: BoxOption> + Send + Sync>, + pub title: Arc, + pub width: usize, + pub value: BoxOption> + Send + Sync>, } impl Column { @@ -101,6 +101,10 @@ impl<'a> Content for TreeTable<'a> { to.fill_bg(fill, Color::Rgb(192, 128, 0)); let fill = [area.x() + x as u16, y, w, 1]; to.fill_bg(fill, Color::Rgb(224, 192, 0)); + if let Some((index, value)) = &self.0.editing { + let x = area.x() + if x > 0 { x + 1 } else { x } as u16; + to.blit(&value, x, y, None) + } } } }