mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-24 23:46:41 +02:00
Support custom shell command
This commit is contained in:
parent
c1fcdffb71
commit
cbb9e60ca8
3 changed files with 97 additions and 1 deletions
|
@ -56,6 +56,7 @@ Use your favorite installation method to download the [AUR package](https://aur.
|
|||
- `x`: `task delete {selected}` - Delete
|
||||
- `A`: `task {selected} annotate {string}` - Annotate current task
|
||||
- `?`: `help` - Help menu
|
||||
- `!`: `{string}` - Custom shell command
|
||||
|
||||

|
||||
|
||||
|
|
49
src/app.rs
49
src/app.rs
|
@ -116,6 +116,7 @@ pub enum AppMode {
|
|||
TaskFilter,
|
||||
TaskAdd,
|
||||
TaskAnnotate,
|
||||
TaskSubprocess,
|
||||
TaskLog,
|
||||
TaskModify,
|
||||
TaskHelpPopup,
|
||||
|
@ -195,6 +196,7 @@ impl TTApp {
|
|||
| AppMode::TaskAnnotate
|
||||
| AppMode::TaskError
|
||||
| AppMode::TaskHelpPopup
|
||||
| AppMode::TaskSubprocess
|
||||
| AppMode::TaskLog
|
||||
| AppMode::TaskModify => self.draw_task(f),
|
||||
AppMode::Calendar => self.draw_calendar(f),
|
||||
|
@ -259,6 +261,11 @@ impl TTApp {
|
|||
f.render_widget(Clear, rects[1]);
|
||||
self.draw_command(f, rects[1], &self.command[..], "Log Task");
|
||||
}
|
||||
AppMode::TaskSubprocess => {
|
||||
f.set_cursor(rects[1].x + self.cursor_location as u16 + 1, rects[1].y + 1);
|
||||
f.render_widget(Clear, rects[1]);
|
||||
self.draw_command(f, rects[1], &self.command[..], "Shell Command");
|
||||
}
|
||||
AppMode::TaskAnnotate => {
|
||||
f.set_cursor(rects[1].x + self.cursor_location as u16 + 1, rects[1].y + 1);
|
||||
f.render_widget(Clear, rects[1]);
|
||||
|
@ -282,7 +289,7 @@ impl TTApp {
|
|||
self.draw_command(f, rects[1], &self.filter[..], "Filter Tasks");
|
||||
self.draw_help_popup(f, f.size());
|
||||
}
|
||||
_ => {
|
||||
AppMode::Calendar => {
|
||||
panic!("Reached unreachable code. Something went wrong");
|
||||
}
|
||||
}
|
||||
|
@ -445,6 +452,17 @@ impl TTApp {
|
|||
Span::from("- Show this help menu"),
|
||||
]),
|
||||
Spans::from(""),
|
||||
Spans::from(vec![
|
||||
Span::from(" !"),
|
||||
Span::from(" "),
|
||||
Span::styled(
|
||||
"shell ",
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
),
|
||||
Span::from(" "),
|
||||
Span::from("- Custom shell command"),
|
||||
]),
|
||||
Spans::from(""),
|
||||
];
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(Block::default().title("Help").borders(Borders::ALL))
|
||||
|
@ -783,6 +801,35 @@ impl TTApp {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn task_subprocess(&mut self) -> Result<(), String> {
|
||||
if self.tasks.lock().unwrap().is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
match shlex::split(&self.command) {
|
||||
Some(cmd) => {
|
||||
let mut command = Command::new(&cmd[0]);
|
||||
for (i, s) in cmd.iter().enumerate() {
|
||||
if i == 0 {
|
||||
continue;
|
||||
}
|
||||
command.arg(&s);
|
||||
}
|
||||
let output = command.output();
|
||||
match output {
|
||||
Ok(_) => {
|
||||
self.command = "".to_string();
|
||||
Ok(())
|
||||
},
|
||||
Err(_) => Err(
|
||||
format!("Shell command `{}` exited with non-zero output", self.command),
|
||||
)
|
||||
}
|
||||
}
|
||||
None => Err(format!("Unable to split `{}`", &self.command)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn task_log(&mut self) -> Result<(), String> {
|
||||
if self.tasks.lock().unwrap().is_empty() {
|
||||
return Ok(());
|
||||
|
|
48
src/main.rs
48
src/main.rs
|
@ -114,8 +114,13 @@ fn tui_main(_config: &str) -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
app.cursor_location = app.modify.chars().count();
|
||||
}
|
||||
Key::Char('!') => {
|
||||
app.mode = AppMode::TaskSubprocess;
|
||||
app.cursor_location = app.command.chars().count();
|
||||
}
|
||||
Key::Char('l') => {
|
||||
app.mode = AppMode::TaskLog;
|
||||
app.cursor_location = app.command.chars().count();
|
||||
}
|
||||
Key::Char('a') => {
|
||||
app.mode = AppMode::TaskAdd;
|
||||
|
@ -183,6 +188,49 @@ fn tui_main(_config: &str) -> Result<(), Box<dyn Error>> {
|
|||
}
|
||||
_ => {}
|
||||
},
|
||||
AppMode::TaskSubprocess => match input {
|
||||
Key::Char('\n') => match app.task_subprocess() {
|
||||
Ok(_) => {
|
||||
app.mode = AppMode::TaskReport;
|
||||
app.update();
|
||||
}
|
||||
Err(e) => {
|
||||
app.mode = AppMode::TaskError;
|
||||
app.error = e;
|
||||
}
|
||||
},
|
||||
Key::Esc => {
|
||||
app.command = "".to_string();
|
||||
app.mode = AppMode::TaskReport;
|
||||
}
|
||||
Key::Right => {
|
||||
if app.cursor_location < app.command.chars().count() {
|
||||
app.cursor_location += 1;
|
||||
}
|
||||
}
|
||||
Key::Left => {
|
||||
if app.cursor_location > 0 {
|
||||
app.cursor_location -= 1;
|
||||
}
|
||||
}
|
||||
Key::Char(c) => {
|
||||
if app.cursor_location < app.command.chars().count() {
|
||||
app.command.insert_str(app.cursor_location, &c.to_string());
|
||||
} else {
|
||||
app.command.push(c);
|
||||
}
|
||||
app.cursor_location += 1;
|
||||
}
|
||||
Key::Backspace => {
|
||||
if app.cursor_location > 0 {
|
||||
app.cursor_location -= 1;
|
||||
let mut cs = app.command.chars().collect::<Vec<char>>();
|
||||
cs.remove(app.cursor_location);
|
||||
app.command = cs.into_iter().collect();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
AppMode::TaskLog => match input {
|
||||
Key::Char('\n') => match app.task_log() {
|
||||
Ok(_) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue