mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-24 14:36:42 +02:00
feat: Use all tasks for completion ✨
This commit is contained in:
parent
c9691a62aa
commit
15eccfc785
2 changed files with 74 additions and 10 deletions
74
src/app.rs
74
src/app.rs
|
@ -167,6 +167,7 @@ pub struct TaskwarriorTui {
|
||||||
pub filter: LineBuffer,
|
pub filter: LineBuffer,
|
||||||
pub modify: LineBuffer,
|
pub modify: LineBuffer,
|
||||||
pub tasks: Vec<Task>,
|
pub tasks: Vec<Task>,
|
||||||
|
pub all_tasks: Vec<Task>,
|
||||||
pub task_details: HashMap<Uuid, String>,
|
pub task_details: HashMap<Uuid, String>,
|
||||||
pub marked: HashSet<Uuid>,
|
pub marked: HashSet<Uuid>,
|
||||||
// stores index of current task that is highlighted
|
// stores index of current task that is highlighted
|
||||||
|
@ -240,6 +241,7 @@ impl TaskwarriorTui {
|
||||||
dirty: true,
|
dirty: true,
|
||||||
task_table_state: TableState::default(),
|
task_table_state: TableState::default(),
|
||||||
tasks: vec![],
|
tasks: vec![],
|
||||||
|
all_tasks: vec![],
|
||||||
task_details: HashMap::new(),
|
task_details: HashMap::new(),
|
||||||
marked: HashSet::new(),
|
marked: HashSet::new(),
|
||||||
current_selection: 0,
|
current_selection: 0,
|
||||||
|
@ -1286,6 +1288,9 @@ impl TaskwarriorTui {
|
||||||
self.last_export = Some(std::time::SystemTime::now());
|
self.last_export = Some(std::time::SystemTime::now());
|
||||||
self.task_report_table.export_headers(None, &self.report)?;
|
self.task_report_table.export_headers(None, &self.report)?;
|
||||||
self.export_tasks()?;
|
self.export_tasks()?;
|
||||||
|
if self.config.uda_task_report_use_all_tasks_for_completion {
|
||||||
|
self.export_all_tasks()?;
|
||||||
|
}
|
||||||
self.contexts.update_data()?;
|
self.contexts.update_data()?;
|
||||||
self.projects.update_data()?;
|
self.projects.update_data()?;
|
||||||
self.update_tags();
|
self.update_tags();
|
||||||
|
@ -1607,6 +1612,49 @@ impl TaskwarriorTui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn export_all_tasks(&mut self) -> Result<()> {
|
||||||
|
let mut task = Command::new("task");
|
||||||
|
|
||||||
|
task.arg("rc.json.array=on")
|
||||||
|
.arg("rc.confirmation=off")
|
||||||
|
.arg("rc.json.depends.array=on")
|
||||||
|
.arg("rc.color=off")
|
||||||
|
.arg("rc._forcecolor=off");
|
||||||
|
// .arg("rc.verbose:override=false");
|
||||||
|
|
||||||
|
task.arg("export");
|
||||||
|
|
||||||
|
task.arg("all");
|
||||||
|
|
||||||
|
info!("Running `{:?}`", task);
|
||||||
|
let output = task.output()?;
|
||||||
|
let data = String::from_utf8_lossy(&output.stdout);
|
||||||
|
let error = String::from_utf8_lossy(&output.stderr);
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
if let Ok(imported) = import(data.as_bytes()) {
|
||||||
|
self.all_tasks = imported;
|
||||||
|
info!("Imported {} tasks", self.tasks.len());
|
||||||
|
self.error = None;
|
||||||
|
if self.mode == Mode::Tasks(Action::Error) {
|
||||||
|
self.mode = self.previous_mode.clone().unwrap_or(Mode::Tasks(Action::Report));
|
||||||
|
self.previous_mode = None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.error = Some(format!("Unable to parse output of `{:?}`:\n`{:?}`", task, data));
|
||||||
|
self.mode = Mode::Tasks(Action::Error);
|
||||||
|
debug!("Unable to parse output: {:?}", data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.error = Some(format!(
|
||||||
|
"Cannot run `{:?}` - ({}) error:\n{}",
|
||||||
|
&task, output.status, error
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn export_tasks(&mut self) -> Result<()> {
|
pub fn export_tasks(&mut self) -> Result<()> {
|
||||||
let mut task = Command::new("task");
|
let mut task = Command::new("task");
|
||||||
|
|
||||||
|
@ -3392,6 +3440,12 @@ impl TaskwarriorTui {
|
||||||
pub fn update_completion_list(&mut self) {
|
pub fn update_completion_list(&mut self) {
|
||||||
self.completion_list.clear();
|
self.completion_list.clear();
|
||||||
|
|
||||||
|
let tasks = if self.config.uda_task_report_use_all_tasks_for_completion {
|
||||||
|
&self.all_tasks
|
||||||
|
} else {
|
||||||
|
&self.tasks
|
||||||
|
};
|
||||||
|
|
||||||
if let Mode::Tasks(Action::Modify | Action::Filter | Action::Annotate | Action::Add | Action::Log) = self.mode {
|
if let Mode::Tasks(Action::Modify | Action::Filter | Action::Annotate | Action::Add | Action::Log) = self.mode {
|
||||||
for s in vec![
|
for s in vec![
|
||||||
"project:".to_string(),
|
"project:".to_string(),
|
||||||
|
@ -3440,7 +3494,7 @@ impl TaskwarriorTui {
|
||||||
self.completion_list.insert(("priority".to_string(), p));
|
self.completion_list.insert(("priority".to_string(), p));
|
||||||
}
|
}
|
||||||
let virtual_tags = self.task_report_table.virtual_tags.clone();
|
let virtual_tags = self.task_report_table.virtual_tags.clone();
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(tags) = task.tags() {
|
if let Some(tags) = task.tags() {
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
if !virtual_tags.contains(tag) {
|
if !virtual_tags.contains(tag) {
|
||||||
|
@ -3450,7 +3504,7 @@ impl TaskwarriorTui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(tags) = task.tags() {
|
if let Some(tags) = task.tags() {
|
||||||
for tag in tags {
|
for tag in tags {
|
||||||
if !virtual_tags.contains(tag) {
|
if !virtual_tags.contains(tag) {
|
||||||
|
@ -3459,7 +3513,7 @@ impl TaskwarriorTui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(project) = task.project() {
|
if let Some(project) = task.project() {
|
||||||
let p = if project.contains(' ') {
|
let p = if project.contains(' ') {
|
||||||
format!(r#""{}""#, &project)
|
format!(r#""{}""#, &project)
|
||||||
|
@ -3469,7 +3523,7 @@ impl TaskwarriorTui {
|
||||||
self.completion_list.insert(("project".to_string(), p));
|
self.completion_list.insert(("project".to_string(), p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(date) = task.due() {
|
if let Some(date) = task.due() {
|
||||||
let now = Local::now();
|
let now = Local::now();
|
||||||
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
||||||
|
@ -3485,7 +3539,7 @@ impl TaskwarriorTui {
|
||||||
self.completion_list.insert(("due".to_string(), s));
|
self.completion_list.insert(("due".to_string(), s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(date) = task.wait() {
|
if let Some(date) = task.wait() {
|
||||||
let now = Local::now();
|
let now = Local::now();
|
||||||
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
||||||
|
@ -3501,7 +3555,7 @@ impl TaskwarriorTui {
|
||||||
self.completion_list.insert(("wait".to_string(), s));
|
self.completion_list.insert(("wait".to_string(), s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(date) = task.scheduled() {
|
if let Some(date) = task.scheduled() {
|
||||||
let now = Local::now();
|
let now = Local::now();
|
||||||
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
||||||
|
@ -3517,7 +3571,7 @@ impl TaskwarriorTui {
|
||||||
self.completion_list.insert(("scheduled".to_string(), s));
|
self.completion_list.insert(("scheduled".to_string(), s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for task in &self.tasks {
|
for task in tasks {
|
||||||
if let Some(date) = task.end() {
|
if let Some(date) = task.end() {
|
||||||
let now = Local::now();
|
let now = Local::now();
|
||||||
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
let date = TimeZone::from_utc_datetime(now.offset(), date);
|
||||||
|
@ -3548,17 +3602,17 @@ impl TaskwarriorTui {
|
||||||
Mode::Tasks(Action::Add | Action::Annotate | Action::Log) => {
|
Mode::Tasks(Action::Add | Action::Annotate | Action::Log) => {
|
||||||
let i = get_start_word_under_cursor(self.command.as_str(), self.command.pos());
|
let i = get_start_word_under_cursor(self.command.as_str(), self.command.pos());
|
||||||
let input = self.command.as_str()[i..self.command.pos()].to_string();
|
let input = self.command.as_str()[i..self.command.pos()].to_string();
|
||||||
self.completion_list.input(input, self.command.as_str().to_string());
|
self.completion_list.input(input, "".to_string());
|
||||||
}
|
}
|
||||||
Mode::Tasks(Action::Modify) => {
|
Mode::Tasks(Action::Modify) => {
|
||||||
let i = get_start_word_under_cursor(self.modify.as_str(), self.modify.pos());
|
let i = get_start_word_under_cursor(self.modify.as_str(), self.modify.pos());
|
||||||
let input = self.modify.as_str()[i..self.modify.pos()].to_string();
|
let input = self.modify.as_str()[i..self.modify.pos()].to_string();
|
||||||
self.completion_list.input(input, self.modify.as_str().to_string());
|
self.completion_list.input(input, "".to_string());
|
||||||
}
|
}
|
||||||
Mode::Tasks(Action::Filter) => {
|
Mode::Tasks(Action::Filter) => {
|
||||||
let i = get_start_word_under_cursor(self.filter.as_str(), self.filter.pos());
|
let i = get_start_word_under_cursor(self.filter.as_str(), self.filter.pos());
|
||||||
let input = self.filter.as_str()[i..self.filter.pos()].to_string();
|
let input = self.filter.as_str()[i..self.filter.pos()].to_string();
|
||||||
self.completion_list.input(input, self.filter.as_str().to_string());
|
self.completion_list.input(input, "".to_string());
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ pub struct Config {
|
||||||
pub uda_prefill_task_metadata: bool,
|
pub uda_prefill_task_metadata: bool,
|
||||||
pub uda_reset_filter_on_esc: bool,
|
pub uda_reset_filter_on_esc: bool,
|
||||||
pub uda_task_detail_prefetch: usize,
|
pub uda_task_detail_prefetch: usize,
|
||||||
|
pub uda_task_report_use_all_tasks_for_completion: bool,
|
||||||
pub uda_task_report_show_info: bool,
|
pub uda_task_report_show_info: bool,
|
||||||
pub uda_task_report_looping: bool,
|
pub uda_task_report_looping: bool,
|
||||||
pub uda_task_report_jump_to_task_on_add: bool,
|
pub uda_task_report_jump_to_task_on_add: bool,
|
||||||
|
@ -109,6 +110,7 @@ impl Config {
|
||||||
let uda_prefill_task_metadata = Self::get_uda_prefill_task_metadata(data);
|
let uda_prefill_task_metadata = Self::get_uda_prefill_task_metadata(data);
|
||||||
let uda_reset_filter_on_esc = Self::get_uda_reset_filter_on_esc(data);
|
let uda_reset_filter_on_esc = Self::get_uda_reset_filter_on_esc(data);
|
||||||
let uda_task_detail_prefetch = Self::get_uda_task_detail_prefetch(data);
|
let uda_task_detail_prefetch = Self::get_uda_task_detail_prefetch(data);
|
||||||
|
let uda_task_report_use_all_tasks_for_completion = Self::get_uda_task_report_use_all_tasks_for_completion(data);
|
||||||
let uda_task_report_show_info = Self::get_uda_task_report_show_info(data);
|
let uda_task_report_show_info = Self::get_uda_task_report_show_info(data);
|
||||||
let uda_task_report_looping = Self::get_uda_task_report_looping(data);
|
let uda_task_report_looping = Self::get_uda_task_report_looping(data);
|
||||||
let uda_task_report_jump_to_task_on_add = Self::get_uda_task_report_jump_to_task_on_add(data);
|
let uda_task_report_jump_to_task_on_add = Self::get_uda_task_report_jump_to_task_on_add(data);
|
||||||
|
@ -165,6 +167,7 @@ impl Config {
|
||||||
uda_prefill_task_metadata,
|
uda_prefill_task_metadata,
|
||||||
uda_reset_filter_on_esc,
|
uda_reset_filter_on_esc,
|
||||||
uda_task_detail_prefetch,
|
uda_task_detail_prefetch,
|
||||||
|
uda_task_report_use_all_tasks_for_completion,
|
||||||
uda_task_report_show_info,
|
uda_task_report_show_info,
|
||||||
uda_task_report_looping,
|
uda_task_report_looping,
|
||||||
uda_task_report_jump_to_task_on_add,
|
uda_task_report_jump_to_task_on_add,
|
||||||
|
@ -510,6 +513,13 @@ impl Config {
|
||||||
.unwrap_or(10)
|
.unwrap_or(10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_uda_task_report_use_all_tasks_for_completion(data: &str) -> bool {
|
||||||
|
Self::get_config("uda.taskwarrior-tui.task-report.use-all-tasks-for-completion", data)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.get_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_uda_task_report_show_info(data: &str) -> bool {
|
fn get_uda_task_report_show_info(data: &str) -> bool {
|
||||||
Self::get_config("uda.taskwarrior-tui.task-report.show-info", data)
|
Self::get_config("uda.taskwarrior-tui.task-report.show-info", data)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue