diff --git a/bin/domain/imag-todo/Cargo.toml b/bin/domain/imag-todo/Cargo.toml index 3cb37b5a..210f1bce 100644 --- a/bin/domain/imag-todo/Cargo.toml +++ b/bin/domain/imag-todo/Cargo.toml @@ -30,6 +30,7 @@ filters = "0.3" kairos = "0.3" resiter = "0.4.0" handlebars = "2" +prettytable-rs = "0.8.0" libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } diff --git a/bin/domain/imag-todo/src/lib.rs b/bin/domain/imag-todo/src/lib.rs index aa163dff..ff6ba777 100644 --- a/bin/domain/imag-todo/src/lib.rs +++ b/bin/domain/imag-todo/src/lib.rs @@ -44,6 +44,7 @@ extern crate kairos; #[macro_use] extern crate failure; extern crate resiter; extern crate handlebars; +extern crate prettytable; #[cfg(feature = "import-taskwarrior")] extern crate task_hookrs; @@ -78,6 +79,9 @@ use failure::err_msg; use clap::App; use resiter::AndThen; use resiter::IterInnerOkOrElse; +use prettytable::Table; +use prettytable::Cell; +use prettytable::Row; use libimagentryedit::edit::Edit; use libimagentryview::viewer::Viewer; @@ -390,7 +394,62 @@ fn show(rt: &Runtime) -> Result<()> { let out = rt.stdout(); let mut outlock = out.lock(); - rt.ids::()? + fn show_with_table<'a, I>(rt: &Runtime, iter: I) -> Result<()> + where I: Iterator> + { + const HEADER: &'static [&'static str] = &[ + "uuid", + "status", + "sched", + "hidden", + "due", + "priority", + "text", + ]; + + let mut table = { + let mut t = Table::new(); + let header = HEADER.iter().map(|s| Cell::new(s)).collect::>(); + t.set_titles(Row::from(header)); + t + }; + + iter.map(|entry| { + use libimagentryview::error::Error as E; + + let uuid = entry.get_uuid().map_err(E::from)?.to_hyphenated().to_string(); + let status = entry.get_status().map_err(E::from)?; + let status = status.as_str().to_string(); + let sched = util::get_dt_str(entry.get_scheduled(), "Not scheduled")?.to_string(); + let hidden = util::get_dt_str(entry.get_hidden(), "Not hidden")?.to_string(); + let due = util::get_dt_str(entry.get_due(), "No due")?.to_string(); + let priority = entry.get_priority().map_err(E::from)?.map(|p| p.as_str().to_string()).unwrap_or("No prio".to_string()); + + let text = entry.get_content().to_owned(); + + let v = [ + uuid, + status, + sched, + hidden, + due, + priority, + text, + ]; + table.add_row(v.iter().map(|s| Cell::new(s)).collect()); + + Ok(entry) + }) + .and_then_ok(|e| rt.report_touched(e.get_location()).map_err(Error::from).map(|_| e)) + .collect::>>()?; + + table.print(&mut rt.stdout()) + .map(|_| ()) + .map_err(Error::from) + } + + let iter = rt + .ids::()? .ok_or_else(|| err_msg("No ids supplied"))? .into_iter() .map(Ok) @@ -398,14 +457,19 @@ fn show(rt: &Runtime) -> Result<()> { .map_inner_ok_or_else(|| err_msg("Did not find one entry")) .and_then_ok(|e| rt.report_touched(e.get_location()).map_err(Error::from).map(|_| e)) .collect::>>()? - .into_iter() - .enumerate() - .map(|(i, elem)| { - let data = util::build_data_object_for_handlebars(i, elem.deref())?; - let s = show_format.render("format", &data)?; - writeln!(outlock, "{}", s).map_err(Error::from) - }) - .collect() + .into_iter(); + + if scmd.is_present("show-no-table") { + iter.enumerate() + .map(|(i, elem)| { + let data = util::build_data_object_for_handlebars(i, elem.deref())?; + let s = show_format.render("format", &data)?; + writeln!(outlock, "{}", s).map_err(Error::from) + }) + .collect() + } else { + show_with_table(rt, iter) + } } // diff --git a/bin/domain/imag-todo/src/ui.rs b/bin/domain/imag-todo/src/ui.rs index 22ee70be..b5646273 100644 --- a/bin/domain/imag-todo/src/ui.rs +++ b/bin/domain/imag-todo/src/ui.rs @@ -146,6 +146,15 @@ pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { .help("Output format string") ) + .arg(Arg::with_name("show-no-table") + .long("no-table") + .short("T") + .takes_value(false) + .required(false) + .multiple(false) + .help("Show the entries raw, without the ascii-table") + ) + .arg(Arg::with_name("todos") .index(1) .takes_value(true)