From 3f64deb152c31f2a04612d9c525537a72605d678 Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 22 Jul 2020 21:00:38 +0530 Subject: remove `d` keybind, add tab completion --- src/app/impl_self.rs | 4 +++ src/app/impl_view.rs | 8 ------ src/command.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/app/impl_self.rs b/src/app/impl_self.rs index 95f1871..7eae853 100644 --- a/src/app/impl_self.rs +++ b/src/app/impl_self.rs @@ -37,6 +37,10 @@ impl App { self.habits.push(h); } + pub fn list_habits(&self) -> Vec { + self.habits.iter().map(|x| x.name()).collect::>() + } + pub fn delete_by_name(&mut self, name: &str) { let old_len = self.habits.len(); self.habits.retain(|h| h.name() != name); diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index 892b00c..b8c4589 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -102,14 +102,6 @@ impl View for App { self.set_focus(Absolute::Down); return EventResult::Consumed(None); } - Event::Char('d') => { - if self.habits.is_empty() { - return EventResult::Consumed(None); - } - self.habits.remove(self.focus); - self.focus = self.focus.checked_sub(1).unwrap_or(0); - return EventResult::Consumed(None); - } Event::Char('w') => { // helper bind to test write to file let j = serde_json::to_string_pretty(&self.habits).unwrap(); diff --git a/src/command.rs b/src/command.rs index 29908f4..2f6b48a 100644 --- a/src/command.rs +++ b/src/command.rs @@ -1,21 +1,75 @@ use std::fmt; +use std::rc::Rc; +use cursive::event::{Event, EventResult, Key}; use cursive::theme::{BaseColor, Color, ColorStyle}; use cursive::view::Resizable; -use cursive::views::{EditView, LinearLayout, TextView}; +use cursive::views::{EditView, LinearLayout, OnEventView, TextView}; use cursive::Cursive; use crate::{app::App, CONFIGURATION}; +static COMMANDS: &'static [&'static str] = &[ + "add", + "add-auto", + "delete", + "track-up", + "track-down", + "month-prev", + "month-next", + "quit", + "help", +]; + +fn get_command_completion(prefix: &str) -> Option { + let first_match = COMMANDS.iter().filter(|&x| x.starts_with(prefix)).next(); + return first_match.map(|&x| x.into()); +} + +fn get_habit_completion(prefix: &str, habit_names: &[String]) -> Option { + let first_match = habit_names.iter().filter(|&x| x.starts_with(prefix)).next(); + eprintln!("{:?}| {:?}", prefix, first_match); + return first_match.map(|x| x.into()); +} + pub fn open_command_window(s: &mut Cursive) { - let command_window = EditView::new() - .filler(" ") - .on_submit(call_on_app) - .style(ColorStyle::new( - Color::Dark(BaseColor::Black), - Color::Dark(BaseColor::White), - )) - .fixed_width(CONFIGURATION.view_width * CONFIGURATION.grid_width); + let habit_list: Vec = s + .call_on_name("Main", |view: &mut App| { + return view.list_habits(); + }) + .unwrap(); + let style = ColorStyle::new(Color::Dark(BaseColor::Black), Color::Dark(BaseColor::White)); + let command_window = OnEventView::new( + EditView::new() + .filler(" ") + .on_submit(call_on_app) + .style(style), + ) + .on_event_inner( + Event::Key(Key::Tab), + move |view: &mut EditView, _: &Event| { + let contents = view.get_content(); + if !contents.contains(" ") { + let completion = get_command_completion(&*contents); + if let Some(c) = completion { + let cb = view.set_content(c); + return Some(EventResult::Consumed(Some(cb))); + }; + return None; + } else { + let word = contents.split(' ').last().unwrap(); + let completion = get_habit_completion(word, &habit_list); + eprintln!("{:?} | {:?}", completion, contents); + if let Some(c) = completion { + let cb = + view.set_content(format!("{}", contents) + c.strip_prefix(word).unwrap()); + return Some(EventResult::Consumed(Some(cb))); + }; + return None; + } + }, + ) + .fixed_width(CONFIGURATION.view_width * CONFIGURATION.grid_width); s.call_on_name("Frame", |view: &mut LinearLayout| { let mut commandline = LinearLayout::horizontal() .child(TextView::new(":")) -- cgit v1.2.3