mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-25 17:57:19 +02:00
feat: Add logging and fix history ✨
This commit is contained in:
parent
5c7f7fe9fd
commit
7effb72f41
6 changed files with 242 additions and 15 deletions
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
47
src/main.rs
47
src/main.rs
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue