|
@@ -2,86 +2,15 @@ use std::collections::HashSet;
|
|
|
|
|
|
use crate::prelude::*;
|
|
|
|
|
|
-use crate::{show, data::{AccountName, Hoard}};
|
|
|
-
|
|
|
-fn prompt_account(data: &Hoard) -> anyhow::Result<Option<AccountName>> {
|
|
|
- println!("Enter new account:");
|
|
|
-
|
|
|
- let mut acc = String::default();
|
|
|
-
|
|
|
- let stdout = console::Term::stdout();
|
|
|
-
|
|
|
- println!();
|
|
|
-
|
|
|
- stdout.move_cursor_up(1)?;
|
|
|
-
|
|
|
- loop {
|
|
|
- stdout.clear_line()?;
|
|
|
- stdout.write_line(format!("{}", console::style(&acc).yellow()).as_str())?;
|
|
|
- stdout.move_cursor_up(1)?;
|
|
|
- stdout.move_cursor_right(acc.len())?;
|
|
|
-
|
|
|
- match console::Term::stdout().read_key()? {
|
|
|
- console::Key::Backspace => {
|
|
|
- acc.pop();
|
|
|
- },
|
|
|
- console::Key::Enter => {
|
|
|
- if let Some(r) = data.account_names().find(|an| **an == *acc) {
|
|
|
- return Ok(Some(r))
|
|
|
- }
|
|
|
- },
|
|
|
- console::Key::Char(c) => {
|
|
|
- if !c.is_control() {
|
|
|
- acc.push(c);
|
|
|
- }
|
|
|
- },
|
|
|
- console::Key::Tab => {
|
|
|
- if acc.is_empty() { continue }
|
|
|
-
|
|
|
- let possibles = data.account_names().filter(|an| an.starts_with(acc.as_str())).collect::<Vec<_>>();
|
|
|
-
|
|
|
- if possibles.is_empty() { continue }
|
|
|
-
|
|
|
- let longest = possibles.iter().map(|s| s.len()).min().unwrap();
|
|
|
-
|
|
|
- let mut longest_prefix = 0;
|
|
|
- for plen in 1..=longest {
|
|
|
- if possibles.iter().all(|p| p.starts_with(&possibles[0][0..plen])) {
|
|
|
- longest_prefix = plen;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- acc.clear();
|
|
|
- acc.push_str(&possibles[0][0..longest_prefix]);
|
|
|
-
|
|
|
- stdout.clear_to_end_of_screen()?;
|
|
|
-
|
|
|
- if possibles.len() == 1 {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- stdout.move_cursor_down(1)?;
|
|
|
- stdout.clear_line()?;
|
|
|
-
|
|
|
- let mut line = String::new();
|
|
|
- let len = possibles.len();
|
|
|
- for possible in possibles.iter().take(5) {
|
|
|
- line.push_str(format!("{} ", console::style(possible).white().dim()).as_str());
|
|
|
- }
|
|
|
- if len > 5 {
|
|
|
- line.push_str("...");
|
|
|
- }
|
|
|
-
|
|
|
- stdout.write_line(line.as_str())?;
|
|
|
- stdout.move_cursor_up(2)?;
|
|
|
-
|
|
|
- },
|
|
|
- console::Key::Escape => {
|
|
|
- return Ok(None)
|
|
|
- },
|
|
|
- _key => (),
|
|
|
- }
|
|
|
- }
|
|
|
+use crate::data::{AccountName, Hoard};
|
|
|
+
|
|
|
+#[derive(PartialEq, Clone, Copy, Debug, cliask::ActionEnum)]
|
|
|
+enum Action {
|
|
|
+ Ignore,
|
|
|
+ Skip,
|
|
|
+ Edit,
|
|
|
+ Finish,
|
|
|
+ Abort
|
|
|
}
|
|
|
|
|
|
pub fn do_comb(data: &Hoard, account: AccountName) -> anyhow::Result<bool> {
|
|
@@ -108,33 +37,30 @@ pub fn do_comb(data: &Hoard, account: AccountName) -> anyhow::Result<bool> {
|
|
|
println!();
|
|
|
show::show_transaction(Some(&data), &txn);
|
|
|
|
|
|
- println!();
|
|
|
- println!("(I)gnore (S)kip all (E)dit (F)inish (A)bort: ");
|
|
|
- let action = loop {
|
|
|
- match console::Term::stdout().read_char().unwrap().to_lowercase().next() {
|
|
|
- Some('s') => break 's',
|
|
|
- Some('e') => break 'e',
|
|
|
- Some('i') => break 'i',
|
|
|
- Some('f') => break 'f',
|
|
|
- Some('a') => break 'a',
|
|
|
- _ => (),
|
|
|
- }
|
|
|
- };
|
|
|
+ let action = cliask::ActionPrompt::new().with_default(Action::Ignore).run()?;
|
|
|
|
|
|
- if action == 'i' { () }
|
|
|
- else if action == 's' {
|
|
|
- ignore.insert(txn.title.clone());
|
|
|
- } else if action == 'a' {
|
|
|
- aborted = true;
|
|
|
- break
|
|
|
- } else if action == 'e' {
|
|
|
- let Some(new_account) = prompt_account(data)? else { continue };
|
|
|
- drop(txn);
|
|
|
- let mut txn = txn_ref.borrow_mut();
|
|
|
- txn.changes.iter_mut().find(|e| *e.account == account).iter_mut().for_each(|ch| *ch.account = new_account);
|
|
|
- changed = true;
|
|
|
- } else if action == 'f' {
|
|
|
- break
|
|
|
+ match action {
|
|
|
+ Action::Ignore => (),
|
|
|
+ Action::Skip => {
|
|
|
+ ignore.insert(txn.title.clone());
|
|
|
+ },
|
|
|
+ Action::Edit => {
|
|
|
+ let Some(new_account) = cliask::SelectPrompt::new("Select account:")
|
|
|
+ .with_items(data.account_names())
|
|
|
+ .run_cancellable()? else { continue };
|
|
|
+
|
|
|
+ drop(txn);
|
|
|
+ let mut txn = txn_ref.borrow_mut();
|
|
|
+ txn.changes.iter_mut().find(|e| *e.account == account).iter_mut().for_each(|ch| *ch.account = new_account);
|
|
|
+ changed = true;
|
|
|
+ },
|
|
|
+ Action::Finish => {
|
|
|
+ break
|
|
|
+ },
|
|
|
+ Action::Abort => {
|
|
|
+ aborted = true;
|
|
|
+ break
|
|
|
+ },
|
|
|
}
|
|
|
}
|
|
|
|