fix: Fix tests and better logging and history 🐛

This commit is contained in:
Dheepak Krishnamurthy 2021-12-02 11:28:24 -07:00
parent b3683ae548
commit 08c30cf912
4 changed files with 137 additions and 64 deletions

3
.envrc
View file

@ -1,4 +1,5 @@
export TASKRC=`pwd`/tests/data/.taskrc
export TASKDATA=`pwd`/tests/data/.task
export XDG_STATE_HOME=`pwd`/tests/data/.config
export TASKWARRIOR_TUI_CONFIG=`pwd`/tests/data/.config
export TASKWARRIOR_TUI_DATA=`pwd`/tests/data/.data
export TASKWARRIOR_TUI_LOG_LEVEL=debug

View file

@ -2546,10 +2546,13 @@ impl TaskwarriorTui {
}
} else if input == self.keyconfig.modify {
self.mode = Mode::Tasks(Action::Modify);
self.command_history.last();
self.command_history.reset();
self.history_status = Some(format!(
" {} / {}",
self.command_history.history_index() + 1,
self.command_history
.history_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
self.update_completion_list();
@ -2598,28 +2601,37 @@ impl TaskwarriorTui {
self.mode = Mode::Tasks(Action::Subprocess);
} else if input == self.keyconfig.log {
self.mode = Mode::Tasks(Action::Log);
self.command_history.last();
self.command_history.reset();
self.history_status = Some(format!(
" {} / {}",
self.command_history.history_index() + 1,
self.command_history
.history_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(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.command_history.reset();
self.history_status = Some(format!(
" {} / {}",
self.command_history.history_index() + 1,
self.command_history
.history_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(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.command_history.reset();
self.history_status = Some(format!(
" {} / {}",
self.command_history.history_index() + 1,
self.command_history
.history_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
self.update_completion_list();
@ -2627,10 +2639,13 @@ impl TaskwarriorTui {
self.mode = Mode::Tasks(Action::HelpPopup);
} else if input == self.keyconfig.filter {
self.mode = Mode::Tasks(Action::Filter);
self.filter_history.last();
self.filter_history.reset();
self.history_status = Some(format!(
" {} / {}",
self.filter_history.history_index() + 1,
self.filter_history
.history_index()
.unwrap_or_else(|| self.filter_history.history_len().saturating_sub(1))
.saturating_add(1),
self.filter_history.history_len()
));
self.update_completion_list();
@ -2815,7 +2830,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
@ -2832,13 +2850,16 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
}
_ => {
self.command_history.last();
self.command_history.reset();
handle_movement(&mut self.modify, input);
self.update_input_for_completion();
}
@ -2932,7 +2953,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
@ -2949,13 +2973,16 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
}
_ => {
self.command_history.last();
self.command_history.reset();
handle_movement(&mut self.command, input);
self.update_input_for_completion();
}
@ -3024,7 +3051,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
@ -3041,14 +3071,17 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
}
_ => {
self.command_history.last();
self.command_history.reset();
handle_movement(&mut self.command, input);
self.update_input_for_completion();
}
@ -3142,7 +3175,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
@ -3160,13 +3196,16 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.command_history.history_len().saturating_sub(1))
.saturating_add(1),
self.command_history.history_len()
));
}
}
_ => {
self.command_history.last();
self.command_history.reset();
handle_movement(&mut self.command, input);
self.update_input_for_completion();
}
@ -3215,7 +3254,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.filter_history.history_len().saturating_sub(1))
.saturating_add(1),
self.filter_history.history_len()
));
self.dirty = true;
@ -3233,7 +3275,10 @@ impl TaskwarriorTui {
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_index()
.unwrap_or_else(|| self.filter_history.history_len().saturating_sub(1))
.saturating_add(1),
self.filter_history.history_len()
));
self.dirty = true;

View file

@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
pub struct HistoryContext {
history: History,
history_index: usize,
history_index: Option<usize>,
config_path: PathBuf,
}
@ -15,17 +15,22 @@ impl HistoryContext {
pub fn new(filename: &str) -> Self {
let history = History::new();
let config_dir_op = dirs::config_dir();
let config_path = if let Ok(s) = std::env::var("TASKWARRIOR_TUI_CONFIG") {
PathBuf::from(s)
} else {
dirs::config_dir()
.map(|d| d.join("taskwarrior-tui"))
.expect("Unable to create configuration directory for taskwarrior-tui")
};
let config_path = config_dir_op.map(|d| d.join("taskwarrior-tui")).unwrap();
std::fs::create_dir_all(&config_path).unwrap();
std::fs::create_dir_all(&config_path)
.unwrap_or_else(|_| panic!("Unable to create configuration directory in {:?}", &config_path));
let config_path = config_path.join(filename);
Self {
history,
history_index: 0,
history_index: None,
config_path,
}
}
@ -36,7 +41,7 @@ impl HistoryContext {
} else {
self.history.save(&self.config_path)?;
}
self.history_index = self.history.len();
self.history_index = None;
log::debug!("Loading history of length {}", self.history.len());
Ok(())
}
@ -50,57 +55,69 @@ impl HistoryContext {
&self.history
}
pub fn history_index(&self) -> usize {
pub fn history_index(&self) -> Option<usize> {
self.history_index
}
pub fn history_search(&mut self, buf: &str, dir: Direction) -> Option<String> {
log::debug!(
"Searching history for {:?} in direction {:?} with history index = {:?}",
"Searching history for {:?} in direction {:?} with history index = {:?} and history len = {:?}",
buf,
dir,
self.history_index()
self.history_index(),
self.history.len(),
);
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.saturating_sub(1),
Direction::Forward => self
.history_index
.saturating_add(1)
.min(self.history_len().saturating_sub(1)),
let history_index = if self.history_index().is_none() {
log::debug!("History index is none");
match dir {
Direction::Forward => return None,
Direction::Reverse => self.history_index = Some(self.history_len().saturating_sub(1)),
}
self.history_index.unwrap()
} else {
let hi = self.history_index().unwrap();
if hi == self.history.len().saturating_sub(1) && dir == Direction::Forward
|| hi == 0 && dir == Direction::Reverse
{
return None;
}
match dir {
Direction::Reverse => hi.saturating_sub(1),
Direction::Forward => hi.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) {
return 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())
self.history_index = Some(history_index);
self.history.get(history_index).cloned()
} else if buf.is_empty() {
self.history_index = history_index;
Some(self.history.get(history_index).unwrap().clone())
self.history_index = Some(history_index);
self.history.get(history_index).cloned()
} else {
log::debug!("History index = {}. Found no match.", history_index);
None
}
};
}
pub fn add(&mut self, buf: &str) {
if self.history.add(buf) {
self.history_index = self.history.len() - 1;
self.reset();
}
}
pub fn last(&mut self) {
self.history_index = self.history.len().saturating_sub(1);
pub fn reset(&mut self) {
self.history_index = None
}
pub fn history_len(&self) -> usize {

View file

@ -24,6 +24,7 @@ use std::env;
use std::error::Error;
use std::io::{self, Write};
use std::panic;
use std::path::{Path, PathBuf};
use std::time::Duration;
use anyhow::Result;
@ -62,19 +63,22 @@ pub fn destruct_terminal() {
execute!(io::stdout(), cursor::Show).unwrap();
}
fn main() {
better_panic::install();
pub fn initialize_logging() {
let data_local_dir = if let Ok(s) = std::env::var("TASKWARRIOR_TUI_DATA") {
PathBuf::from(s)
} else {
dirs::data_local_dir()
.expect("Unable to find data directory for taskwarrior-tui")
.join("taskwarrior-tui")
};
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();
.expect("Failed to build log file appender.");
let levelfilter = match std::env::var("TASKWARRIOR_TUI_LOG_LEVEL")
.unwrap_or_else(|_| "info".to_string())
@ -91,9 +95,15 @@ fn main() {
.appender(Appender::builder().build("logfile", Box::new(logfile)))
.logger(Logger::builder().build("taskwarrior_tui", levelfilter))
.build(Root::builder().appender("logfile").build(LevelFilter::Info))
.unwrap();
.expect("Failed to build logging config.");
log4rs::init_config(config).unwrap();
log4rs::init_config(config).expect("Failed to initialize logging.");
}
fn main() {
better_panic::install();
initialize_logging();
let matches = cli::generate_cli_app().get_matches();