mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-24 14:36:42 +02:00
Jump to relevant task after action
This commit is contained in:
parent
d50f4f8c6c
commit
94d2c7b74b
2 changed files with 95 additions and 15 deletions
108
src/app.rs
108
src/app.rs
|
@ -180,6 +180,8 @@ pub struct TaskwarriorTuiApp {
|
|||
pub marked: HashSet<Uuid>,
|
||||
// stores index of current task that is highlighted
|
||||
pub current_selection: usize,
|
||||
pub current_selection_uuid: Option<Uuid>,
|
||||
pub current_selection_id: Option<u64>,
|
||||
pub task_report_table: TaskReportTable,
|
||||
pub calendar_year: i32,
|
||||
pub mode: AppMode,
|
||||
|
@ -236,6 +238,8 @@ impl TaskwarriorTuiApp {
|
|||
task_details: HashMap::new(),
|
||||
marked: HashSet::new(),
|
||||
current_selection: 0,
|
||||
current_selection_uuid: None,
|
||||
current_selection_id: None,
|
||||
current_context_filter: "".to_string(),
|
||||
current_context: "".to_string(),
|
||||
command: LineBuffer::with_capacity(MAX_LINE),
|
||||
|
@ -777,6 +781,12 @@ impl TaskwarriorTuiApp {
|
|||
m.cloned()
|
||||
}
|
||||
|
||||
fn task_index_by_id(&self, id: u64) -> Option<usize> {
|
||||
let tasks = &self.tasks;
|
||||
let m = tasks.iter().position(|t| t.id().unwrap() == id);
|
||||
m
|
||||
}
|
||||
|
||||
fn task_index_by_uuid(&self, uuid: Uuid) -> Option<usize> {
|
||||
let tasks = &self.tasks;
|
||||
let m = tasks.iter().position(|t| *t.uuid() == uuid);
|
||||
|
@ -995,9 +1005,30 @@ impl TaskwarriorTuiApp {
|
|||
if self.task_report_show_info {
|
||||
task::block_on(self.update_task_details())?;
|
||||
}
|
||||
self.selection_fix();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn selection_fix(&mut self) {
|
||||
if let (Some(t), Some(id)) = (self.task_current(), self.current_selection_id) {
|
||||
if t.id() != Some(id) {
|
||||
if let Some(i) = self.task_index_by_id(id) {
|
||||
self.current_selection = i;
|
||||
self.current_selection_id = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let (Some(t), Some(uuid)) = (self.task_current(), self.current_selection_uuid) {
|
||||
if t.uuid() != &uuid {
|
||||
if let Some(i) = self.task_index_by_uuid(uuid) {
|
||||
self.current_selection = i;
|
||||
self.current_selection_uuid = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_history(&mut self) -> Result<()> {
|
||||
self.filter_history_context.write()?;
|
||||
self.command_history_context.write()?;
|
||||
|
@ -1439,7 +1470,7 @@ impl TaskwarriorTuiApp {
|
|||
.join(" ")
|
||||
);
|
||||
let shell = shellexpand::tilde(&shell).into_owned();
|
||||
match shlex::split(&shell) {
|
||||
let r = match shlex::split(&shell) {
|
||||
Some(cmd) => {
|
||||
let mut command = Command::new(&cmd[0]);
|
||||
for s in cmd.iter().skip(1) {
|
||||
|
@ -1462,7 +1493,15 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
}
|
||||
None => Err(format!("Unable to run `{}`. Cannot shlex split `{}`", shell, shell)),
|
||||
};
|
||||
|
||||
if task_uuids.len() == 1 {
|
||||
if let Some(uuid) = task_uuids.get(0) {
|
||||
self.current_selection_uuid = Some(*uuid);
|
||||
}
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
pub fn task_modify(&mut self) -> Result<(), String> {
|
||||
|
@ -1484,7 +1523,7 @@ impl TaskwarriorTuiApp {
|
|||
|
||||
let shell = self.modify.as_str();
|
||||
|
||||
match shlex::split(&shell) {
|
||||
let r = match shlex::split(&shell) {
|
||||
Some(cmd) => {
|
||||
for s in cmd {
|
||||
command.arg(&s);
|
||||
|
@ -1505,7 +1544,15 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
}
|
||||
None => Err(format!("Cannot shlex split `{}`", shell,)),
|
||||
};
|
||||
|
||||
if task_uuids.len() == 1 {
|
||||
if let Some(uuid) = task_uuids.get(0) {
|
||||
self.current_selection_uuid = Some(*uuid);
|
||||
}
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
pub fn task_annotate(&mut self) -> Result<(), String> {
|
||||
|
@ -1527,7 +1574,7 @@ impl TaskwarriorTuiApp {
|
|||
|
||||
let shell = self.command.as_str();
|
||||
|
||||
match shlex::split(&shell) {
|
||||
let r = match shlex::split(&shell) {
|
||||
Some(cmd) => {
|
||||
for s in cmd {
|
||||
command.arg(&s);
|
||||
|
@ -1553,7 +1600,14 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
}
|
||||
None => Err(format!("Cannot shlex split `{}`", shell)),
|
||||
};
|
||||
|
||||
if task_uuids.len() == 1 {
|
||||
if let Some(uuid) = task_uuids.get(0) {
|
||||
self.current_selection_uuid = Some(*uuid);
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
pub fn task_add(&mut self) -> Result<(), String> {
|
||||
|
@ -1569,7 +1623,13 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
let output = command.output();
|
||||
match output {
|
||||
Ok(_) => Ok(()),
|
||||
Ok(output) => {
|
||||
let data = String::from_utf8_lossy(&output.stdout);
|
||||
let re = Regex::new(r"^Created task (?P<task_id>\d+).\n$").unwrap();
|
||||
let caps = re.captures(&data).unwrap();
|
||||
self.current_selection_id = Some(caps["task_id"].parse::<u64>().unwrap());
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(format!(
|
||||
"Cannot run `task add {}`. Check documentation for more information",
|
||||
shell
|
||||
|
@ -1611,9 +1671,6 @@ impl TaskwarriorTuiApp {
|
|||
if self.tasks.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let selected = self.current_selection;
|
||||
let task_id = self.tasks[selected].id().unwrap_or_default();
|
||||
let task_uuid = *self.tasks[selected].uuid();
|
||||
|
||||
let task_uuids = self.selected_task_uuids();
|
||||
|
||||
|
@ -1631,10 +1688,16 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
}
|
||||
|
||||
if task_uuids.len() == 1 {
|
||||
if let Some(uuid) = task_uuids.get(0) {
|
||||
self.current_selection_uuid = Some(*uuid);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn task_delete(&self) -> Result<(), String> {
|
||||
pub fn task_delete(&mut self) -> Result<(), String> {
|
||||
if self.tasks.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -1651,7 +1714,7 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
cmd.arg("delete");
|
||||
let output = cmd.output();
|
||||
match output {
|
||||
let r = match output {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(format!(
|
||||
"Cannot run `task delete` for tasks `{}`. Check documentation for more information",
|
||||
|
@ -1661,7 +1724,10 @@ impl TaskwarriorTuiApp {
|
|||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
)),
|
||||
}
|
||||
};
|
||||
self.current_selection_uuid = None;
|
||||
self.current_selection_id = None;
|
||||
r
|
||||
}
|
||||
|
||||
pub fn task_done(&mut self) -> Result<(), String> {
|
||||
|
@ -1679,7 +1745,7 @@ impl TaskwarriorTuiApp {
|
|||
}
|
||||
cmd.arg("done");
|
||||
let output = cmd.output();
|
||||
match output {
|
||||
let r = match output {
|
||||
Ok(_) => Ok(()),
|
||||
Err(_) => Err(format!(
|
||||
"Cannot run `task done` for task `{}`. Check documentation for more information",
|
||||
|
@ -1689,17 +1755,31 @@ impl TaskwarriorTuiApp {
|
|||
.collect::<Vec<String>>()
|
||||
.join(" ")
|
||||
)),
|
||||
}
|
||||
};
|
||||
self.current_selection_uuid = None;
|
||||
self.current_selection_id = None;
|
||||
r
|
||||
}
|
||||
|
||||
pub fn task_undo(&self) -> Result<(), String> {
|
||||
pub fn task_undo(&mut self) -> Result<(), String> {
|
||||
if self.tasks.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let output = Command::new("task").arg("rc.confirmation=off").arg("undo").output();
|
||||
|
||||
match output {
|
||||
Ok(_) => Ok(()),
|
||||
Ok(output) => {
|
||||
let data = String::from_utf8_lossy(&output.stdout);
|
||||
let re = Regex::new(
|
||||
r"(?P<task_uuid>[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})",
|
||||
)
|
||||
.unwrap();
|
||||
let caps = re.captures(&data).unwrap();
|
||||
if let Ok(uuid) = Uuid::parse_str(&caps["task_uuid"]) {
|
||||
self.current_selection_uuid = Some(uuid);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err("Cannot run `task undo`. Check documentation for more information".to_string()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ impl CompletionList {
|
|||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.candidates().iter().count()
|
||||
self.candidates().len()
|
||||
}
|
||||
|
||||
pub fn max_width(&self) -> Option<usize> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue