feat: Add logging and fix history

This commit is contained in:
Dheepak Krishnamurthy 2021-11-27 11:29:01 -07:00
parent 5c7f7fe9fd
commit 7effb72f41
6 changed files with 242 additions and 15 deletions

View file

@ -80,6 +80,8 @@ use task_hookrs::project::Project;
use versions::Versioning;
use log::{debug, error, info, log_enabled, trace, warn, Level, LevelFilter};
const MAX_LINE: usize = 4096;
lazy_static! {
@ -1283,6 +1285,7 @@ impl TaskwarriorTui {
}
pub fn update(&mut self, force: bool) -> Result<()> {
trace!("self.update({:?});", force);
if force || self.dirty || self.tasks_changed_since(self.last_export).unwrap_or(true) {
let task_uuids = self.selected_task_uuids();
if self.current_selection_uuid.is_none() && self.current_selection_id.is_none() && task_uuids.len() == 1 {
@ -1410,6 +1413,7 @@ impl TaskwarriorTui {
}
pub fn update_task_table_state(&mut self) {
trace!("self.update_task_table_state()");
self.task_table_state.select(Some(self.current_selection));
for uuid in self.marked.clone() {

View file

@ -15,13 +15,6 @@ impl HistoryContext {
pub fn new(filename: &str) -> Self {
let history = History::new();
#[cfg(target_family = "unix")]
let config_dir_op = std::env::var_os("XDG_STATE_HOME")
.map(PathBuf::from)
.filter(|p| p.is_absolute())
.or_else(|| dirs::home_dir().map(|d| d.join(".config")));
#[cfg(not(target_family = "unix"))]
let config_dir_op = dirs::config_dir();
let config_path = config_dir_op.map(|d| d.join("taskwarrior-tui")).unwrap();
@ -44,6 +37,7 @@ impl HistoryContext {
self.history.save(&self.config_path)?;
}
self.history_index = self.history.len();
log::debug!("Loading history of length {}", self.history.len());
Ok(())
}
@ -61,25 +55,40 @@ impl HistoryContext {
}
pub fn history_search(&mut self, buf: &str, dir: Direction) -> Option<String> {
log::debug!(
"Searching history for {:?} in direction {:?} with history index = {:?}",
buf,
dir,
self.history_index()
);
if self.history.is_empty() {
log::debug!("History is empty");
return None;
}
if self.history_index == self.history.len().saturating_sub(1) && dir == Direction::Forward
|| self.history_index == 0 && dir == Direction::Reverse
{
log::debug!("No more history left to search");
return None;
}
let history_index = match dir {
Direction::Reverse => self.history_index,
Direction::Forward => self.history_index,
Direction::Reverse => self.history_index.saturating_sub(1),
Direction::Forward => self
.history_index
.saturating_add(1)
.min(self.history_len().saturating_sub(1)),
};
log::debug!("Using history index = {} for searching", history_index);
if let Some(history_index) = self.history.starts_with(buf, history_index, dir) {
log::debug!("Found index {:?}", history_index);
log::debug!("Previous index {:?}", self.history_index);
self.history_index = history_index;
Some(self.history.get(history_index).unwrap().clone())
} else if buf.is_empty() {
self.history_index = history_index;
Some(self.history.get(history_index).unwrap().clone())
} else {
log::debug!("History index = {}. Found no match.", history_index);
None
}
}

View file

@ -16,6 +16,10 @@ mod pane;
mod table;
mod task_report;
use log::{debug, error, info, log_enabled, trace, warn, Level, LevelFilter};
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Logger, Root};
use log4rs::encode::pattern::PatternEncoder;
use std::env;
use std::error::Error;
use std::io::{self, Write};
@ -41,8 +45,8 @@ use crate::action::Action;
use crate::event::{Event, EventConfig, Events, Key};
use crate::keyconfig::KeyConfig;
/// # Panics
/// Will panic if could not obtain terminal
const LOG_PATTERN: &str = "{d(%Y-%m-%d %H:%M:%S)} | {l} | {f}:{L} | {m}{n}";
pub fn setup_terminal() -> Terminal<CrosstermBackend<io::Stdout>> {
enable_raw_mode().expect("Running not in terminal");
let mut stdout = io::stdout();
@ -51,8 +55,7 @@ pub fn setup_terminal() -> Terminal<CrosstermBackend<io::Stdout>> {
let backend = CrosstermBackend::new(stdout);
Terminal::new(backend).unwrap()
}
/// # Panics
/// Will panic if could not `disable_raw_mode`
pub fn destruct_terminal() {
disable_raw_mode().unwrap();
execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap();
@ -61,10 +64,44 @@ pub fn destruct_terminal() {
fn main() {
better_panic::install();
let data_local_dir = dirs::data_local_dir()
.expect("Unable to open data local directory.")
.join("taskwarrior-tui");
std::fs::create_dir_all(&data_local_dir).unwrap_or_else(|_| panic!("Unable to create {:?}", data_local_dir));
let logfile = FileAppender::builder()
.encoder(Box::new(PatternEncoder::new(LOG_PATTERN)))
.append(false)
.build(data_local_dir.join("taskwarrior-tui.log"))
.unwrap();
let levelfilter = match std::env::var("TASKWARRIOR_TUI_LOG_LEVEL")
.unwrap_or_else(|_| "info".to_string())
.as_str()
{
"off" => LevelFilter::Off,
"warn" => LevelFilter::Warn,
"info" => LevelFilter::Info,
"debug" => LevelFilter::Debug,
"trace" => LevelFilter::Trace,
_ => LevelFilter::Info,
};
let config = Config::builder()
.appender(Appender::builder().build("logfile", Box::new(logfile)))
.logger(Logger::builder().build("taskwarrior_tui", levelfilter))
.build(Root::builder().appender("logfile").build(LevelFilter::Info))
.unwrap();
log4rs::init_config(config).unwrap();
let matches = cli::generate_cli_app().get_matches();
debug!("getting matches from clap...");
let config = matches.value_of("config").unwrap_or("~/.taskrc");
let report = matches.value_of("report").unwrap_or("next");
debug!("report = {:?}", &report);
debug!("config = {:?}", &config);
let r = task::block_on(tui_main(config, report));
if let Err(err) = r {
eprintln!("\x1b[0;31m[taskwarrior-tui error]\x1b[0m: {}\n\nIf you need additional help, please report as a github issue on https://github.com/kdheepak/taskwarrior-tui", err);
@ -99,6 +136,7 @@ async fn tui_main(_config: &str, report: &str) -> Result<()> {
// Handle input
match events.next().await? {
Event::Input(input) => {
debug!("Received input = {:?}", input);
if (input == app.keyconfig.edit
|| input == app.keyconfig.shortcut1
|| input == app.keyconfig.shortcut2
@ -136,6 +174,7 @@ async fn tui_main(_config: &str, report: &str) -> Result<()> {
}
}
Event::Tick => {
trace!("Tick event");
let r = app.update(false);
if r.is_err() {
destruct_terminal();