Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions src/actions/shell.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
pub fn run(cmd: &str) -> anyhow::Result<()> {
pub fn run(cmd: &str, keep_open: bool) -> anyhow::Result<()> {
let mut command = {
let mut c = std::process::Command::new("cmd");
c.arg("/C").arg(cmd);
c.arg(if keep_open { "/K" } else { "/C" }).arg(cmd);
c
};
command.spawn().map(|_| ()).map_err(|e| e.into())
}

pub fn add(name: &str, args: &str) -> anyhow::Result<()> {
crate::plugins::shell::append_shell_cmd(
crate::plugins::shell::SHELL_CMDS_FILE,
name,
args,
)?;
crate::plugins::shell::append_shell_cmd(crate::plugins::shell::SHELL_CMDS_FILE, name, args)?;
Ok(())
}

pub fn remove(name: &str) -> anyhow::Result<()> {
crate::plugins::shell::remove_shell_cmd(
crate::plugins::shell::SHELL_CMDS_FILE,
name,
)?;
crate::plugins::shell::remove_shell_cmd(crate::plugins::shell::SHELL_CMDS_FILE, name)?;
Ok(())
}
1 change: 1 addition & 0 deletions src/gui/shell_cmd_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ impl ShellCmdDialog {
name: self.name.clone(),
args: self.args.clone(),
autocomplete: true,
keep_open: false,
});
} else if let Some(e) = self.entries.get_mut(idx) {
e.name = self.name.clone();
Expand Down
23 changes: 19 additions & 4 deletions src/launcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,10 @@ pub(crate) fn system_command(action: &str) -> Option<std::process::Command> {

#[derive(Debug, Clone, PartialEq)]
enum ActionKind<'a> {
Shell(&'a str),
Shell {
cmd: &'a str,
keep_open: bool,
},
ShellAdd {
name: &'a str,
args: &'a str,
Expand All @@ -267,7 +270,10 @@ enum ActionKind<'a> {
ClipboardClear,
ClipboardCopy(usize),
ClipboardText(&'a str),
Calc { result: &'a str, expr: Option<&'a str> },
Calc {
result: &'a str,
expr: Option<&'a str>,
},
CalcHistory(usize),
BookmarkAdd(&'a str),
BookmarkRemove(&'a str),
Expand Down Expand Up @@ -375,8 +381,17 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> {
if let Some(name) = s.strip_prefix("shell:remove:") {
return ActionKind::ShellRemove(name);
}
if let Some(cmd) = s.strip_prefix("shell_keep:") {
return ActionKind::Shell {
cmd,
keep_open: true,
};
}
if let Some(cmd) = s.strip_prefix("shell:") {
return ActionKind::Shell(cmd);
return ActionKind::Shell {
cmd,
keep_open: false,
};
}
if let Some(rest) = s.strip_prefix("clipboard:") {
if rest == "clear" {
Expand Down Expand Up @@ -703,7 +718,7 @@ fn parse_action_kind(action: &Action) -> ActionKind<'_> {
pub fn launch_action(action: &Action) -> anyhow::Result<()> {
use crate::actions::*;
match parse_action_kind(action) {
ActionKind::Shell(cmd) => shell::run(cmd),
ActionKind::Shell { cmd, keep_open } => shell::run(cmd, keep_open),
ActionKind::ShellAdd { name, args } => shell::add(name, args),
ActionKind::ShellRemove(name) => shell::remove(name),
ActionKind::ClipboardClear => clipboard::clear_history(),
Expand Down
63 changes: 47 additions & 16 deletions src/plugins/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct ShellCmdEntry {
/// When false this command will not be suggested when typing `sh <query>`.
#[serde(default = "default_autocomplete")]
pub autocomplete: bool,
#[serde(default)]
pub keep_open: bool,
}

fn default_autocomplete() -> bool {
Expand Down Expand Up @@ -44,6 +46,7 @@ pub fn append_shell_cmd(path: &str, name: &str, args: &str) -> anyhow::Result<()
name: name.to_string(),
args: args.to_string(),
autocomplete: true,
keep_open: false,
});
save_shell_cmds(path, &list)?;
}
Expand All @@ -67,12 +70,12 @@ impl Plugin for ShellPlugin {
let trimmed = query.trim();
if let Some(rest) = crate::common::strip_prefix_ci(trimmed, "sh") {
if rest.is_empty() {
return vec![Action {
label: "sh: edit saved commands".into(),
desc: "Shell".into(),
action: "shell:dialog".into(),
args: None,
}];
return vec![Action {
label: "sh: edit saved commands".into(),
desc: "Shell".into(),
action: "shell:dialog".into(),
args: None,
}];
}
}

Expand Down Expand Up @@ -124,11 +127,14 @@ impl Plugin for ShellPlugin {
matcher.fuzzy_match(&c.name, filter).is_some()
|| matcher.fuzzy_match(&c.args, filter).is_some()
})
.map(|c| Action {
label: c.name,
desc: "Shell".into(),
action: format!("shell:{}", c.args),
args: None,
.map(|c| {
let prefix = if c.keep_open { "shell_keep:" } else { "shell:" };
Action {
label: c.name,
desc: "Shell".into(),
action: format!("{}{}", prefix, c.args),
args: None,
}
})
.collect();
}
Expand All @@ -151,10 +157,15 @@ impl Plugin for ShellPlugin {
}
}
if let Some((entry, _)) = best {
let prefix = if entry.keep_open {
"shell_keep:"
} else {
"shell:"
};
return vec![Action {
label: format!("Run {}", entry.name),
desc: "Shell".into(),
action: format!("shell:{}", entry.args),
action: format!("{}{}", prefix, entry.args),
args: None,
}];
}
Expand Down Expand Up @@ -183,10 +194,30 @@ impl Plugin for ShellPlugin {

fn commands(&self) -> Vec<Action> {
vec![
Action { label: "sh".into(), desc: "Shell".into(), action: "query:sh".into(), args: None },
Action { label: "sh add".into(), desc: "Shell".into(), action: "query:sh add ".into(), args: None },
Action { label: "sh rm".into(), desc: "Shell".into(), action: "query:sh rm ".into(), args: None },
Action { label: "sh list".into(), desc: "Shell".into(), action: "query:sh list".into(), args: None },
Action {
label: "sh".into(),
desc: "Shell".into(),
action: "query:sh".into(),
args: None,
},
Action {
label: "sh add".into(),
desc: "Shell".into(),
action: "query:sh add ".into(),
args: None,
},
Action {
label: "sh rm".into(),
desc: "Shell".into(),
action: "query:sh rm ".into(),
args: None,
},
Action {
label: "sh list".into(),
desc: "Shell".into(),
action: "query:sh list".into(),
args: None,
},
]
}
}
27 changes: 27 additions & 0 deletions tests/shell_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ fn load_shell_cmds_roundtrip() {
name: "test".into(),
args: "echo hi".into(),
autocomplete: true,
keep_open: false,
}];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();
let loaded = load_shell_cmds(SHELL_CMDS_FILE).unwrap();
assert_eq!(loaded.len(), 1);
assert_eq!(loaded[0].name, "test");
assert_eq!(loaded[0].args, "echo hi");
assert!(loaded[0].autocomplete);
assert!(!loaded[0].keep_open);
}

#[test]
Expand All @@ -38,6 +40,7 @@ fn search_named_command_returns_action() {
name: "demo".into(),
args: "dir".into(),
autocomplete: true,
keep_open: false,
}];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();

Expand All @@ -57,6 +60,7 @@ fn search_respects_autocomplete_flag() {
name: "demo".into(),
args: "dir".into(),
autocomplete: false,
keep_open: false,
}];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();

Expand All @@ -66,6 +70,26 @@ fn search_respects_autocomplete_flag() {
assert_eq!(results[0].action, "shell:demo");
}

#[test]
fn search_keep_open_uses_shell_keep_prefix() {
let _lock = TEST_MUTEX.lock().unwrap();
let dir = tempdir().unwrap();
std::env::set_current_dir(dir.path()).unwrap();

let entries = vec![ShellCmdEntry {
name: "demo".into(),
args: "dir".into(),
autocomplete: true,
keep_open: true,
}];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();

let plugin = ShellPlugin;
let results = plugin.search("sh demo");
assert_eq!(results.len(), 1);
assert_eq!(results[0].action, "shell_keep:dir");
}

#[test]
fn search_plain_sh_opens_dialog() {
let _lock = TEST_MUTEX.lock().unwrap();
Expand Down Expand Up @@ -98,11 +122,13 @@ fn rm_lists_matching_commands() {
name: "a".into(),
args: "cmd_a".into(),
autocomplete: true,
keep_open: false,
},
ShellCmdEntry {
name: "b".into(),
args: "cmd_b".into(),
autocomplete: true,
keep_open: false,
},
];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();
Expand All @@ -123,6 +149,7 @@ fn list_returns_saved_commands() {
name: "x".into(),
args: "dir".into(),
autocomplete: true,
keep_open: false,
}];
save_shell_cmds(SHELL_CMDS_FILE, &entries).unwrap();

Expand Down
Loading