Add history files

This commit is contained in:
Dheepak Krishnamurthy 2021-03-31 22:45:02 -06:00
parent ba84e3fff0
commit 690ce7004f
5 changed files with 194 additions and 62 deletions

89
Cargo.lock generated
View file

@ -41,6 +41,18 @@ version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "async-attributes" name = "async-attributes"
version = "1.1.2" version = "1.1.2"
@ -218,6 +230,12 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]] [[package]]
name = "better-panic" name = "better-panic"
version = "0.2.0" version = "0.2.0"
@ -234,6 +252,17 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]] [[package]]
name = "blocking" name = "blocking"
version = "1.0.2" version = "1.0.2"
@ -357,6 +386,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.3" version = "0.8.3"
@ -464,6 +499,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "dirs"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
dependencies = [
"cfg-if 0.1.10",
"dirs-sys",
]
[[package]] [[package]]
name = "dirs-next" name = "dirs-next"
version = "2.0.0" version = "2.0.0"
@ -474,6 +519,17 @@ dependencies = [
"dirs-sys-next", "dirs-sys-next",
] ]
[[package]]
name = "dirs-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
dependencies = [
"libc",
"redox_users 0.3.5",
"winapi",
]
[[package]] [[package]]
name = "dirs-sys-next" name = "dirs-sys-next"
version = "0.1.2" version = "0.1.2"
@ -481,7 +537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [ dependencies = [
"libc", "libc",
"redox_users", "redox_users 0.4.0",
"winapi", "winapi",
] ]
@ -1074,6 +1130,17 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom 0.1.16",
"redox_syscall 0.1.57",
"rust-argon2",
]
[[package]] [[package]]
name = "redox_users" name = "redox_users"
version = "0.4.0" version = "0.4.0"
@ -1101,6 +1168,18 @@ version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
[[package]]
name = "rust-argon2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.18" version = "0.1.18"
@ -1301,6 +1380,7 @@ dependencies = [
"chrono", "chrono",
"clap", "clap",
"crossterm", "crossterm",
"dirs",
"futures", "futures",
"futures-timer", "futures-timer",
"itertools", "itertools",
@ -1316,6 +1396,7 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
"unicode-width", "unicode-width",
"uuid", "uuid",
"xdg",
] ]
[[package]] [[package]]
@ -1538,3 +1619,9 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"

View file

@ -40,6 +40,8 @@ anyhow = "1"
async-std = { version = "1", features = ["attributes", "unstable"] } async-std = { version = "1", features = ["attributes", "unstable"] }
futures = "0.3" futures = "0.3"
futures-timer = "3.0" futures-timer = "3.0"
dirs = "2.0.2"
xdg = "2"
[package.metadata.rpm] [package.metadata.rpm]
package = "taskwarrior-tui" package = "taskwarrior-tui"

View file

@ -14,6 +14,11 @@ use std::collections::{HashMap, HashSet};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use std::io::Read;
use std::io::Write;
use xdg::BaseDirectories;
use std::process::Command; use std::process::Command;
use std::time::SystemTime; use std::time::SystemTime;
@ -49,14 +54,14 @@ use tui::{
widgets::{Block, BorderType, Borders, Clear, Paragraph}, widgets::{Block, BorderType, Borders, Clear, Paragraph},
}; };
use rustyline::error::ReadlineError;
use rustyline::history::Direction as HistoryDirection; use rustyline::history::Direction as HistoryDirection;
use rustyline::history::History;
use rustyline::line_buffer::LineBuffer; use rustyline::line_buffer::LineBuffer;
use rustyline::At; use rustyline::At;
use rustyline::Editor; use rustyline::Editor;
use rustyline::Word; use rustyline::Word;
use crate::history::HistoryContext;
use std::io; use std::io;
use tui::{backend::CrosstermBackend, Terminal}; use tui::{backend::CrosstermBackend, Terminal};
@ -150,63 +155,6 @@ pub enum AppMode {
Calendar, Calendar,
} }
pub struct HistoryContext {
history: History,
history_index: usize,
}
impl HistoryContext {
pub fn new() -> Self {
let history = History::new();
Self {
history,
history_index: 0,
}
}
pub fn history(&self) -> &History {
&self.history
}
pub fn history_index(&self) -> usize {
self.history_index
}
pub fn history_search(&mut self, buf: &str, dir: HistoryDirection) -> Option<String> {
if self.history.is_empty() {
return None;
}
if self.history_index == self.history.len().saturating_sub(1) && dir == HistoryDirection::Forward
|| self.history_index == 0 && dir == HistoryDirection::Reverse
{
return Some(self.history.get(self.history_index).unwrap().clone());
}
let history_index = match dir {
HistoryDirection::Reverse => self.history_index - 1,
HistoryDirection::Forward => self.history_index + 1,
};
if let Some(history_index) = self.history.starts_with(buf, history_index, dir) {
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 {
None
}
}
pub fn add(&mut self, buf: &str) {
if self.history.add(buf) {
self.history_index = self.history.len() - 1;
}
}
pub fn last(&mut self) {
self.history_index = self.history.len().saturating_sub(1);
}
}
pub struct TaskwarriorTuiApp { pub struct TaskwarriorTuiApp {
pub should_quit: bool, pub should_quit: bool,
pub dirty: bool, pub dirty: bool,
@ -282,7 +230,9 @@ impl TaskwarriorTuiApp {
} }
app.get_context()?; app.get_context()?;
app.update(true)?; app.update(true)?;
app.filter_history_context.load("filter.history")?;
app.filter_history_context.add(app.filter.as_str()); app.filter_history_context.add(app.filter.as_str());
app.command_history_context.load("command.history")?;
Ok(app) Ok(app)
} }
@ -931,6 +881,7 @@ impl TaskwarriorTuiApp {
self.update_tags(); self.update_tags();
self.task_details.clear(); self.task_details.clear();
self.dirty = false; self.dirty = false;
self.save_history()?;
} }
self.cursor_fix(); self.cursor_fix();
self.update_task_table_state(); self.update_task_table_state();
@ -940,6 +891,12 @@ impl TaskwarriorTuiApp {
Ok(()) Ok(())
} }
pub fn save_history(&mut self) -> Result<()> {
self.filter_history_context.write("filter.history")?;
self.command_history_context.write("command.history")?;
Ok(())
}
pub fn cursor_fix(&mut self) { pub fn cursor_fix(&mut self) {
while !self.tasks.is_empty() && self.current_selection >= self.tasks.len() { while !self.tasks.is_empty() && self.current_selection >= self.tasks.len() {
self.task_report_previous(); self.task_report_previous();
@ -2351,8 +2308,6 @@ mod tests {
} }
fn setup() { fn setup() {
use std::io::Read;
use std::io::Write;
use std::process::Stdio; use std::process::Stdio;
let mut f = File::open(Path::new(env!("TASKDATA")).parent().unwrap().join("export.json")).unwrap(); let mut f = File::open(Path::new(env!("TASKDATA")).parent().unwrap().join("export.json")).unwrap();
let mut s = String::new(); let mut s = String::new();

87
src/history.rs Normal file
View file

@ -0,0 +1,87 @@
use anyhow::Result;
use rustyline::error::ReadlineError;
use rustyline::history::Direction;
use rustyline::history::History;
use std::fs::File;
use xdg::BaseDirectories;
pub struct HistoryContext {
history: History,
history_index: usize,
}
impl HistoryContext {
pub fn new() -> Self {
let history = History::new();
Self {
history,
history_index: 0,
}
}
pub fn load(&mut self, filename: &str) -> Result<()> {
let d = BaseDirectories::with_prefix("taskwarrior-tui")?;
if let Some(path) = d.find_config_file(filename) {
self.history.load(&path)?;
Ok(())
} else {
let path = d.place_config_file(filename)?;
self.history.save(&path)?;
Ok(())
}
}
pub fn write(&mut self, filename: &str) -> Result<()> {
let d = BaseDirectories::with_prefix("taskwarrior-tui")?;
if let Some(path) = d.find_config_file(filename) {
self.history.save(&path)?;
Ok(())
} else {
let path = d.place_config_file(filename)?;
self.history.save(&path)?;
Ok(())
}
}
pub fn history(&self) -> &History {
&self.history
}
pub fn history_index(&self) -> usize {
self.history_index
}
pub fn history_search(&mut self, buf: &str, dir: Direction) -> Option<String> {
if self.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
{
return Some(self.history.get(self.history_index).unwrap().clone());
}
let history_index = match dir {
Direction::Reverse => self.history_index - 1,
Direction::Forward => self.history_index + 1,
};
if let Some(history_index) = self.history.starts_with(buf, history_index, dir) {
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 {
None
}
}
pub fn add(&mut self, buf: &str) {
if self.history.add(buf) {
self.history_index = self.history.len() - 1;
}
}
pub fn last(&mut self) {
self.history_index = self.history.len().saturating_sub(1);
}
}

View file

@ -7,6 +7,7 @@ mod calendar;
mod config; mod config;
mod context; mod context;
mod help; mod help;
mod history;
mod keyconfig; mod keyconfig;
mod table; mod table;
mod task_report; mod task_report;