From 5956435f6b38efc2ff01435aacc87330f8dd3c1e Mon Sep 17 00:00:00 2001 From: Dheepak Krishnamurthy Date: Sat, 27 Nov 2021 12:26:20 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20Add=20history=20status=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.rs | 228 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 152 insertions(+), 76 deletions(-) diff --git a/src/app.rs b/src/app.rs index ab22450..1ed2e28 100644 --- a/src/app.rs +++ b/src/app.rs @@ -546,7 +546,10 @@ impl TaskwarriorTui { f, rects[1], "Press any key to continue.", - Span::styled("Error", Style::default().add_modifier(Modifier::BOLD)), + ( + Span::styled("Error", Style::default().add_modifier(Modifier::BOLD)), + None, + ), 0, false, self.error.clone(), @@ -579,10 +582,9 @@ impl TaskwarriorTui { f, rects[1], self.filter.as_str(), - format!( - "{}{}", - "Filter Tasks", - self.history_status.clone().unwrap_or_else(|| "".to_string()) + ( + Span::raw("Filter Tasks"), + Some(Span::raw(self.history_status.clone().unwrap_or_else(|| "".to_string()))), ), Self::get_position(&self.filter), false, @@ -595,7 +597,10 @@ impl TaskwarriorTui { f, rects[1], self.command.as_str(), - Span::styled("Jump to Task", Style::default().add_modifier(Modifier::BOLD)), + ( + Span::styled("Jump to Task", Style::default().add_modifier(Modifier::BOLD)), + None, + ), position, true, self.error.clone(), @@ -610,13 +615,15 @@ impl TaskwarriorTui { f, rects[1], self.filter.as_str(), - Span::styled( - format!( - "{}{}", - "Filter Tasks", - self.history_status.clone().unwrap_or_else(|| "".to_string()) + ( + Span::styled( + format!("{}", "Filter Tasks",), + Style::default().add_modifier(Modifier::BOLD), ), - Style::default().add_modifier(Modifier::BOLD), + Some(Span::styled( + format!("{}", self.history_status.clone().unwrap_or_else(|| "".to_string())), + Style::default().add_modifier(Modifier::BOLD), + )), ), position, true, @@ -632,13 +639,15 @@ impl TaskwarriorTui { f, rects[1], self.command.as_str(), - Span::styled( - format!( - "{}{}", - "Log Task", - self.history_status.clone().unwrap_or_else(|| "".to_string()) + ( + Span::styled( + format!("{}", "Log Task",), + Style::default().add_modifier(Modifier::BOLD), ), - Style::default().add_modifier(Modifier::BOLD), + Some(Span::styled( + format!("{}", self.history_status.clone().unwrap_or_else(|| "".to_string())), + Style::default().add_modifier(Modifier::BOLD), + )), ), position, true, @@ -651,7 +660,10 @@ impl TaskwarriorTui { f, rects[1], self.command.as_str(), - Span::styled("Shell Command", Style::default().add_modifier(Modifier::BOLD)), + ( + Span::styled("Shell Command", Style::default().add_modifier(Modifier::BOLD)), + None, + ), position, true, self.error.clone(), @@ -671,13 +683,12 @@ impl TaskwarriorTui { f, rects[1], self.modify.as_str(), - Span::styled( - format!( - "{}{}", - label, - self.history_status.clone().unwrap_or_else(|| "".to_string()) - ), - Style::default().add_modifier(Modifier::BOLD), + ( + Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + Some(Span::styled( + format!("{}", self.history_status.clone().unwrap_or_else(|| "".to_string())), + Style::default().add_modifier(Modifier::BOLD), + )), ), position, true, @@ -698,13 +709,12 @@ impl TaskwarriorTui { f, rects[1], self.command.as_str(), - Span::styled( - format!( - "{}{}", - label, - self.history_status.clone().unwrap_or_else(|| "".to_string()) - ), - Style::default().add_modifier(Modifier::BOLD), + ( + Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + Some(Span::styled( + format!("{}", self.history_status.clone().unwrap_or_else(|| "".to_string())), + Style::default().add_modifier(Modifier::BOLD), + )), ), position, true, @@ -720,13 +730,12 @@ impl TaskwarriorTui { f, rects[1], self.command.as_str(), - Span::styled( - format!( - "{}{}", - "Add Task", - self.history_status.clone().unwrap_or_else(|| "".to_string()) - ), - Style::default().add_modifier(Modifier::BOLD), + ( + Span::styled("Add Task", Style::default().add_modifier(Modifier::BOLD)), + Some(Span::styled( + self.history_status.clone().unwrap_or_else(|| "".to_string()), + Style::default().add_modifier(Modifier::BOLD), + )), ), position, true, @@ -738,7 +747,7 @@ impl TaskwarriorTui { f, rects[1], self.filter.as_str(), - "Filter Tasks", + ("Filter Tasks".into(), None), Self::get_position(&self.filter), false, self.error.clone(), @@ -750,7 +759,7 @@ impl TaskwarriorTui { f, rects[1], self.filter.as_str(), - "Filter Tasks", + ("Filter Tasks".into(), None), Self::get_position(&self.filter), false, self.error.clone(), @@ -775,7 +784,7 @@ impl TaskwarriorTui { f, rects[1], &format!("Press <{}> to confirm or <{}> to abort.", x, q), - Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + (Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), None), 0, false, self.error.clone(), @@ -799,7 +808,7 @@ impl TaskwarriorTui { f, rects[1], &format!("Press <{}> to confirm or <{}> to abort.", x, q), - Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + (Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), None), 0, false, self.error.clone(), @@ -959,17 +968,15 @@ impl TaskwarriorTui { f.render_stateful_widget(items, rect, &mut self.completion_list.state); } - fn draw_command<'a, T>( + fn draw_command( f: &mut Frame, rect: Rect, text: &str, - title: T, + title: (Span, Option), position: usize, cursor: bool, error: Option, - ) where - T: Into>, - { + ) { f.render_widget(Clear, rect); if cursor { f.set_cursor( @@ -982,13 +989,22 @@ impl TaskwarriorTui { } else { Style::default() }; + + let title = if let Some(subtitle) = title.1 { + let w = (title.0.width() + subtitle.width()).try_into().unwrap(); + let w = rect.width.saturating_sub(w).saturating_sub(2); + Spans::from(vec![title.0, Span::from("─".repeat(w.into())), subtitle]) + } else { + Spans::from(vec![title.0]) + }; + let p = Paragraph::new(Text::from(text)) .block( Block::default() .borders(Borders::ALL) .border_type(BorderType::Rounded) .border_style(border_style) - .title(title.into()), + .title(title), ) .scroll((0, ((position + 3) as u16).saturating_sub(rect.width))); f.render_widget(p, rect); @@ -2537,7 +2553,11 @@ impl TaskwarriorTui { } else if input == self.keyconfig.modify { self.mode = Mode::Tasks(Action::Modify); self.command_history.last(); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); self.update_completion_list(); match self.task_table_state.mode() { TableMode::SingleSelection => match self.task_current() { @@ -2585,24 +2605,40 @@ impl TaskwarriorTui { } else if input == self.keyconfig.log { self.mode = Mode::Tasks(Action::Log); self.command_history.last(); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); self.update_completion_list(); } else if input == self.keyconfig.add { self.mode = Mode::Tasks(Action::Add); self.command_history.last(); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); self.update_completion_list(); } else if input == self.keyconfig.annotate { self.mode = Mode::Tasks(Action::Annotate); self.command_history.last(); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); self.update_completion_list(); } else if input == self.keyconfig.help { self.mode = Mode::Tasks(Action::HelpPopup); } else if input == self.keyconfig.filter { self.mode = Mode::Tasks(Action::Filter); self.filter_history.last(); - // self.history_status = Some(format!(" {} / {}", self.filter_history.history_index() + 1, self.filter_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.filter_history.history_index() + 1, + self.filter_history.history_len() + )); self.update_completion_list(); } else if input == Key::Char(':') { self.mode = Mode::Tasks(Action::Jump); @@ -2783,7 +2819,11 @@ impl TaskwarriorTui { let p = self.modify.pos(); self.modify.update("", 0); self.modify.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } Key::Down => { @@ -2796,7 +2836,11 @@ impl TaskwarriorTui { let p = self.modify.pos(); self.modify.update("", 0); self.modify.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } _ => { @@ -2836,7 +2880,7 @@ impl TaskwarriorTui { self.completion_list.unselect(); } else { self.command.update("", 0); - // self.history_status = None; + self.history_status = None; self.mode = Mode::Tasks(Action::Report); } } @@ -2858,7 +2902,7 @@ impl TaskwarriorTui { self.mode = Mode::Tasks(Action::Report); self.command_history.add(self.command.as_str()); self.command.update("", 0); - // self.history_status = None; + self.history_status = None; self.update(true)?; } Err(e) => { @@ -2892,7 +2936,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } Key::Down => { @@ -2905,7 +2953,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } _ => { @@ -2922,7 +2974,7 @@ impl TaskwarriorTui { } else { self.command.update("", 0); self.mode = Mode::Tasks(Action::Report); - // self.history_status = None; + self.history_status = None; } } Key::Char('\n') => { @@ -2943,7 +2995,7 @@ impl TaskwarriorTui { self.mode = Mode::Tasks(Action::Report); self.command_history.add(self.command.as_str()); self.command.update("", 0); - // self.history_status = None; + self.history_status = None; self.update(true)?; } Err(e) => { @@ -2976,7 +3028,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } Key::Down => { @@ -2989,7 +3045,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } @@ -3031,7 +3091,7 @@ impl TaskwarriorTui { self.completion_list.unselect(); } else { self.command.update("", 0); - // self.history_status = None; + self.history_status = None; self.mode = Mode::Tasks(Action::Report); } } @@ -3053,7 +3113,7 @@ impl TaskwarriorTui { self.mode = Mode::Tasks(Action::Report); self.command_history.add(self.command.as_str()); self.command.update("", 0); - // self.history_status = None; + self.history_status = None; self.update(true)?; } Err(e) => { @@ -3086,7 +3146,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } @@ -3100,7 +3164,11 @@ impl TaskwarriorTui { let p = self.command.pos(); self.command.update("", 0); self.command.update(&s, std::cmp::min(s.len(), p)); - // self.history_status = Some(format!(" {} / {}", self.command_history.history_index() + 1, self.command_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.command_history.history_index() + 1, + self.command_history.history_len() + )); } } _ => { @@ -3117,7 +3185,7 @@ impl TaskwarriorTui { } else { self.mode = Mode::Tasks(Action::Report); self.filter_history.add(self.filter.as_str()); - // self.history_status = None; + self.history_status = None; self.update(true)?; } } @@ -3137,7 +3205,7 @@ impl TaskwarriorTui { } else { self.mode = Mode::Tasks(Action::Report); self.filter_history.add(self.filter.as_str()); - // self.history_status = None; + self.history_status = None; self.update(true)?; } } @@ -3151,7 +3219,11 @@ impl TaskwarriorTui { let p = self.filter.pos(); self.filter.update("", 0); self.filter.update(&s, std::cmp::min(p, s.len())); - // self.history_status = Some(format!(" {} / {}", self.filter_history.history_index() + 1, self.filter_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.filter_history.history_index() + 1, + self.filter_history.history_len() + )); self.dirty = true; } } @@ -3165,7 +3237,11 @@ impl TaskwarriorTui { let p = self.filter.pos(); self.filter.update("", 0); self.filter.update(&s, std::cmp::min(p, s.len())); - // self.history_status = Some(format!(" {} / {}", self.filter_history.history_index() + 1, self.filter_history.history_len())); + self.history_status = Some(format!( + " {} / {}", + self.filter_history.history_index() + 1, + self.filter_history.history_len() + )); self.dirty = true; } } @@ -3188,7 +3264,7 @@ impl TaskwarriorTui { for c in self.config.filter.chars() { self.filter.insert(c, 1); } - // self.history_status = None; + self.history_status = None; self.update_input_for_completion(); self.dirty = true; } @@ -4051,7 +4127,7 @@ mod tests { f, rects[1], app.modify.as_str(), - Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + (Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), None), position, true, app.error.clone(), @@ -4108,7 +4184,7 @@ mod tests { f, rects[1], app.modify.as_str(), - Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), + (Span::styled(label, Style::default().add_modifier(Modifier::BOLD)), None), position, true, app.error.clone(),