diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/app/impl_self.rs | 8 | ||||
| -rw-r--r-- | src/app/impl_view.rs | 19 | ||||
| -rw-r--r-- | src/command.rs | 74 |
3 files changed, 71 insertions, 30 deletions
diff --git a/src/app/impl_self.rs b/src/app/impl_self.rs index 8a84cb2..1dfe268 100644 --- a/src/app/impl_self.rs +++ b/src/app/impl_self.rs | |||
| @@ -54,6 +54,10 @@ impl App { | |||
| 54 | } | 54 | } |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | pub fn list_habits(&self) -> Vec<String> { | ||
| 58 | self.habits.iter().map(|x| x.name()).collect::<Vec<_>>() | ||
| 59 | } | ||
| 60 | |||
| 57 | pub fn delete_by_name(&mut self, name: &str) { | 61 | pub fn delete_by_name(&mut self, name: &str) { |
| 58 | let old_len = self.habits.len(); | 62 | let old_len = self.habits.len(); |
| 59 | self.habits.retain(|h| h.name() != name); | 63 | self.habits.retain(|h| h.name() != name); |
| @@ -141,7 +145,7 @@ impl App { | |||
| 141 | let completed = total - remaining; | 145 | let completed = total - remaining; |
| 142 | 146 | ||
| 143 | let timestamp = if self.view_month_offset == 0 { | 147 | let timestamp = if self.view_month_offset == 0 { |
| 144 | format!("{}", Local::now().date().format("%d/%b/%y"),) | 148 | format!("{}", Local::now().naive_local().date().format("%d/%b/%y"),) |
| 145 | } else { | 149 | } else { |
| 146 | let months = self.view_month_offset; | 150 | let months = self.view_month_offset; |
| 147 | format!("{}", format!("{} months ago", months),) | 151 | format!("{}", format!("{} months ago", months),) |
| @@ -270,7 +274,7 @@ impl App { | |||
| 270 | self.message.set_message("help <command>|commands|keys") | 274 | self.message.set_message("help <command>|commands|keys") |
| 271 | } | 275 | } |
| 272 | } | 276 | } |
| 273 | Command::Quit => self.save_state(), | 277 | Command::Quit | Command::Write => self.save_state(), |
| 274 | Command::MonthNext => self.sift_forward(), | 278 | Command::MonthNext => self.sift_forward(), |
| 275 | Command::MonthPrev => self.sift_backward(), | 279 | Command::MonthPrev => self.sift_backward(), |
| 276 | Command::Blank => {} | 280 | Command::Blank => {} |
diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index 892b00c..0dfd20b 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs | |||
| @@ -102,25 +102,6 @@ impl View for App { | |||
| 102 | self.set_focus(Absolute::Down); | 102 | self.set_focus(Absolute::Down); |
| 103 | return EventResult::Consumed(None); | 103 | return EventResult::Consumed(None); |
| 104 | } | 104 | } |
| 105 | Event::Char('d') => { | ||
| 106 | if self.habits.is_empty() { | ||
| 107 | return EventResult::Consumed(None); | ||
| 108 | } | ||
| 109 | self.habits.remove(self.focus); | ||
| 110 | self.focus = self.focus.checked_sub(1).unwrap_or(0); | ||
| 111 | return EventResult::Consumed(None); | ||
| 112 | } | ||
| 113 | Event::Char('w') => { | ||
| 114 | // helper bind to test write to file | ||
| 115 | let j = serde_json::to_string_pretty(&self.habits).unwrap(); | ||
| 116 | let mut file = File::create("foo.txt").unwrap(); | ||
| 117 | file.write_all(j.as_bytes()).unwrap(); | ||
| 118 | return EventResult::Consumed(None); | ||
| 119 | } | ||
| 120 | Event::Char('q') => { | ||
| 121 | self.save_state(); | ||
| 122 | return EventResult::with_cb(|s| s.quit()); | ||
| 123 | } | ||
| 124 | Event::Char('v') => { | 105 | Event::Char('v') => { |
| 125 | if self.habits.is_empty() { | 106 | if self.habits.is_empty() { |
| 126 | return EventResult::Consumed(None); | 107 | return EventResult::Consumed(None); |
diff --git a/src/command.rs b/src/command.rs index 29908f4..38d48e9 100644 --- a/src/command.rs +++ b/src/command.rs | |||
| @@ -1,21 +1,75 @@ | |||
| 1 | use std::fmt; | 1 | use std::fmt; |
| 2 | 2 | ||
| 3 | use cursive::event::{Event, EventResult, Key}; | ||
| 3 | use cursive::theme::{BaseColor, Color, ColorStyle}; | 4 | use cursive::theme::{BaseColor, Color, ColorStyle}; |
| 4 | use cursive::view::Resizable; | 5 | use cursive::view::Resizable; |
| 5 | use cursive::views::{EditView, LinearLayout, TextView}; | 6 | use cursive::views::{EditView, LinearLayout, OnEventView, TextView}; |
| 6 | use cursive::Cursive; | 7 | use cursive::Cursive; |
| 7 | 8 | ||
| 8 | use crate::{app::App, CONFIGURATION}; | 9 | use crate::{app::App, CONFIGURATION}; |
| 9 | 10 | ||
| 11 | static COMMANDS: &'static [&'static str] = &[ | ||
| 12 | "add", | ||
| 13 | "add-auto", | ||
| 14 | "delete", | ||
| 15 | "track-up", | ||
| 16 | "track-down", | ||
| 17 | "month-prev", | ||
| 18 | "month-next", | ||
| 19 | "quit", | ||
| 20 | "write", | ||
| 21 | "help", | ||
| 22 | ]; | ||
| 23 | |||
| 24 | fn get_command_completion(prefix: &str) -> Option<String> { | ||
| 25 | let first_match = COMMANDS.iter().filter(|&x| x.starts_with(prefix)).next(); | ||
| 26 | return first_match.map(|&x| x.into()); | ||
| 27 | } | ||
| 28 | |||
| 29 | fn get_habit_completion(prefix: &str, habit_names: &[String]) -> Option<String> { | ||
| 30 | let first_match = habit_names.iter().filter(|&x| x.starts_with(prefix)).next(); | ||
| 31 | eprintln!("{:?}| {:?}", prefix, first_match); | ||
| 32 | return first_match.map(|x| x.into()); | ||
| 33 | } | ||
| 34 | |||
| 10 | pub fn open_command_window(s: &mut Cursive) { | 35 | pub fn open_command_window(s: &mut Cursive) { |
| 11 | let command_window = EditView::new() | 36 | let habit_list: Vec<String> = s |
| 12 | .filler(" ") | 37 | .call_on_name("Main", |view: &mut App| { |
| 13 | .on_submit(call_on_app) | 38 | return view.list_habits(); |
| 14 | .style(ColorStyle::new( | 39 | }) |
| 15 | Color::Dark(BaseColor::Black), | 40 | .unwrap(); |
| 16 | Color::Dark(BaseColor::White), | 41 | let style = ColorStyle::new(Color::Dark(BaseColor::Black), Color::Dark(BaseColor::White)); |
| 17 | )) | 42 | let command_window = OnEventView::new( |
| 18 | .fixed_width(CONFIGURATION.view_width * CONFIGURATION.grid_width); | 43 | EditView::new() |
| 44 | .filler(" ") | ||
| 45 | .on_submit(call_on_app) | ||
| 46 | .style(style), | ||
| 47 | ) | ||
| 48 | .on_event_inner( | ||
| 49 | Event::Key(Key::Tab), | ||
| 50 | move |view: &mut EditView, _: &Event| { | ||
| 51 | let contents = view.get_content(); | ||
| 52 | if !contents.contains(" ") { | ||
| 53 | let completion = get_command_completion(&*contents); | ||
| 54 | if let Some(c) = completion { | ||
| 55 | let cb = view.set_content(c); | ||
| 56 | return Some(EventResult::Consumed(Some(cb))); | ||
| 57 | }; | ||
| 58 | return None; | ||
| 59 | } else { | ||
| 60 | let word = contents.split(' ').last().unwrap(); | ||
| 61 | let completion = get_habit_completion(word, &habit_list); | ||
| 62 | eprintln!("{:?} | {:?}", completion, contents); | ||
| 63 | if let Some(c) = completion { | ||
| 64 | let cb = | ||
| 65 | view.set_content(format!("{}", contents) + c.strip_prefix(word).unwrap()); | ||
| 66 | return Some(EventResult::Consumed(Some(cb))); | ||
| 67 | }; | ||
| 68 | return None; | ||
| 69 | } | ||
| 70 | }, | ||
| 71 | ) | ||
| 72 | .fixed_width(CONFIGURATION.view_width * CONFIGURATION.grid_width); | ||
| 19 | s.call_on_name("Frame", |view: &mut LinearLayout| { | 73 | s.call_on_name("Frame", |view: &mut LinearLayout| { |
| 20 | let mut commandline = LinearLayout::horizontal() | 74 | let mut commandline = LinearLayout::horizontal() |
| 21 | .child(TextView::new(":")) | 75 | .child(TextView::new(":")) |
| @@ -60,6 +114,7 @@ pub enum Command { | |||
| 60 | TrackUp(String), | 114 | TrackUp(String), |
| 61 | TrackDown(String), | 115 | TrackDown(String), |
| 62 | Help(Option<String>), | 116 | Help(Option<String>), |
| 117 | Write, | ||
| 63 | Quit, | 118 | Quit, |
| 64 | Blank, | 119 | Blank, |
| 65 | } | 120 | } |
| @@ -144,6 +199,7 @@ impl Command { | |||
| 144 | "mprev" | "month-prev" => return Ok(Command::MonthPrev), | 199 | "mprev" | "month-prev" => return Ok(Command::MonthPrev), |
| 145 | "mnext" | "month-next" => return Ok(Command::MonthNext), | 200 | "mnext" | "month-next" => return Ok(Command::MonthNext), |
| 146 | "q" | "quit" => return Ok(Command::Quit), | 201 | "q" | "quit" => return Ok(Command::Quit), |
| 202 | "w" | "write" => return Ok(Command::Write), | ||
| 147 | "" => return Ok(Command::Blank), | 203 | "" => return Ok(Command::Blank), |
| 148 | s => return Err(CommandLineError::InvalidCommand(s.into())), | 204 | s => return Err(CommandLineError::InvalidCommand(s.into())), |
| 149 | } | 205 | } |
