mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-24 05:26:42 +02:00
fix: Fix tests and better logging and history 🐛
This commit is contained in:
parent
b3683ae548
commit
08c30cf912
4 changed files with 137 additions and 64 deletions
3
.envrc
3
.envrc
|
@ -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
|
||||
|
|
93
src/app.rs
93
src/app.rs
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
{
|
||||
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)),
|
||||
|
||||
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 {
|
||||
|
|
26
src/main.rs
26
src/main.rs
|
@ -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();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue