Skip to content

Commit

Permalink
frontend: add delt <id> to manual delete a running task (#124)
Browse files Browse the repository at this point in the history
* frontend: add delmt to stop tasks by id manually
* frontend: add human writeable id to current tasks
* frontend: rework id generation for tasks to reduce short lived id reuse
  • Loading branch information
aserowy authored Nov 29, 2024
1 parent fad0692 commit 7d68bf4
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 10 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ In normal mode, all register interactions target the default register (equal to
| cp \<path> or '\<mark> | copies the selected file to the target directory. The directory must exist without a file with the same name like the source |
| d! | delete selected file/directory |
| delm \<chars> | delete current and cached marks. Every char represents one mark. ':delm AdfR', ':delm a d f R', and ':delm F' are all valid commands. Whitespaces are ignored. |
| delt \<task_id> | stop a task with the given id. The id can be found by listing tasks with `tl` |
| e! | reload current folder |
| fd \<params for fd> | uses (fd)[https://github.com/sharkdp/] to populate qfix. \<params for fd> are passed through to fd. Yeet sets the following params by default: --color never --absolute-path --base-directory current_path |
| invertcl | inverts the cl selection in current folder |
Expand Down
2 changes: 1 addition & 1 deletion yeet-frontend/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ async fn execute(
.current_tasks
.get(&Task::EnumerateDirectory(path.clone(), None).to_string())
{
cancellation.cancel();
cancellation.token.cancel();
};

if let Err(error) = emitter.unwatch(path.as_path()) {
Expand Down
11 changes: 10 additions & 1 deletion yeet-frontend/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ pub mod register;
#[derive(Default)]
pub struct Model {
pub commandline: CommandLine,
pub current_tasks: HashMap<String, CancellationToken>,
pub current_tasks: HashMap<String, CurrentTask>,
// pub current_tasks: HashMap<String, CancellationToken>,
pub files: FileWindow,
pub history: History,
pub junk: JunkYard,
pub latest_task_id: u16,
pub layout: AppLayout,
pub marks: Marks,
pub mode: Mode,
Expand All @@ -52,6 +54,13 @@ impl std::fmt::Debug for Model {
}
}

#[derive(Debug)]
pub struct CurrentTask {
pub token: CancellationToken,
pub id: u16,
pub external_id: String,
}

pub struct FileWindow {
pub current: PathBuffer,
pub parent: BufferType,
Expand Down
12 changes: 12 additions & 0 deletions yeet-frontend/src/update/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
mod file;
mod print;
mod qfix;
mod task;

#[tracing::instrument(skip(model))]
pub fn execute(cmd: &str, model: &mut Model) -> Vec<Action> {
Expand Down Expand Up @@ -47,6 +48,17 @@ pub fn execute(cmd: &str, model: &mut Model) -> Vec<Action> {
vec![action::emit_keymap(KeymapMessage::DeleteMarks(marks))],
)
}
("delt", args) if !args.is_empty() => {
let actions = match args.parse::<u16>() {
Ok(it) => task::delete(model, it),
Err(err) => {
tracing::warn!("Failed to parse id: {}", err);
return Vec::new();
}
};

add_change_mode(mode_before, mode, actions)
}
("e!", "") => add_change_mode(mode_before, mode, file::refresh(model)),
("fd", params) => add_change_mode(
mode_before,
Expand Down
13 changes: 9 additions & 4 deletions yeet-frontend/src/update/command/print.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::collections::HashMap;

use tokio_util::sync::CancellationToken;
use yeet_keymap::message::{KeymapMessage, PrintContent};

use crate::{
Expand All @@ -10,6 +9,7 @@ use crate::{
mark::Marks,
qfix::QuickFix,
register::Register,
CurrentTask,
},
update::junkyard::get_junkyard_transaction,
};
Expand All @@ -35,9 +35,14 @@ pub fn marks(marks: &Marks) -> Vec<Action> {
vec![action::emit_keymap(KeymapMessage::Print(content))]
}

pub fn tasks(tasks: &HashMap<String, CancellationToken>) -> Vec<Action> {
let mut contents = vec![":tl", "Id"];
let tasks = tasks.keys().map(|id| id.as_str());
pub fn tasks(tasks: &HashMap<String, CurrentTask>) -> Vec<Action> {
let mut contents = vec![":tl".to_string(), "Id Task".to_string()];
let mut tasks: Vec<_> = tasks
.values()
.map(|task| format!("{:<4} {}", task.id, task.external_id))
.collect();

tasks.sort();
contents.extend(tasks);

let content = contents
Expand Down
8 changes: 8 additions & 0 deletions yeet-frontend/src/update/command/task.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use crate::{action::Action, model::Model};

pub fn delete(model: &mut Model, id: u16) -> Vec<Action> {
if let Some((_, task)) = model.current_tasks.iter().find(|(_, task)| task.id == id) {
task.token.cancel();
}
Vec::new()
}
42 changes: 38 additions & 4 deletions yeet-frontend/src/update/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use yeet_keymap::message::{KeySequence, KeymapMessage, PrintContent};
use crate::{
action::Action,
event::{Envelope, Message, Preview},
model::{BufferType, Model, WindowType},
model::{BufferType, CurrentTask, Model, WindowType},
};

use self::{
Expand Down Expand Up @@ -259,13 +259,47 @@ fn add_current_task(
identifier: String,
cancellation: CancellationToken,
) -> Vec<Action> {
if let Some(cancellation) = model.current_tasks.insert(identifier, cancellation) {
cancellation.cancel();
let id = next_id(model);

if let Some(replaced_task) = model.current_tasks.insert(
identifier.clone(),
CurrentTask {
token: cancellation,
id,
external_id: identifier,
},
) {
replaced_task.token.cancel();
}
Vec::new()
}

fn next_id(model: &mut Model) -> u16 {
let mut next_id = if model.latest_task_id >= 9999 {
1
} else {
model.latest_task_id + 1
};

let mut running_ids: Vec<u16> = model.current_tasks.values().map(|task| task.id).collect();
running_ids.sort();

for id in running_ids {
if next_id == id {
next_id += 1;
} else if next_id > id {
break;
}
}

model.latest_task_id = next_id;

next_id
}

fn remove_current_task(model: &mut Model, identifier: String) -> Vec<Action> {
model.current_tasks.remove(&identifier);
if let Some(task) = model.current_tasks.remove(&identifier) {
task.token.cancel();
}
Vec::new()
}

0 comments on commit 7d68bf4

Please sign in to comment.