summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-04-04 23:49:33 +0200
committerqkzk <qu3nt1n@gmail.com>2023-04-04 23:49:33 +0200
commitd568556a4a1a211056efab10ca55a5a6631412b7 (patch)
tree2ec0dd9f84f1f08a1887e2574ed2e3f72c7d98d0 /src
parentd04825d36f294560d7a1db01680042a9ea506260 (diff)
basic shell execution with !
Diffstat (limited to 'src')
-rw-r--r--src/action_map.rs2
-rw-r--r--src/event_exec.rs11
-rw-r--r--src/keybindings.rs1
-rw-r--r--src/mode.rs3
-rw-r--r--src/opener.rs2
-rw-r--r--src/shell_menu.rs4
-rw-r--r--src/tab.rs16
7 files changed, 36 insertions, 3 deletions
diff --git a/src/action_map.rs b/src/action_map.rs
index e4fd5f4..ac0d500 100644
--- a/src/action_map.rs
+++ b/src/action_map.rs
@@ -73,6 +73,7 @@ pub enum ActionMap {
SearchNext,
SetWallpaper,
Shell,
+ ShellCommand,
ShellMenu,
Shortcut,
Sort,
@@ -170,6 +171,7 @@ impl ActionMap {
ActionMap::SearchNext => EventExec::event_search_next(current_tab),
ActionMap::SetWallpaper => EventExec::event_set_wallpaper(current_tab),
ActionMap::Shell => EventExec::event_shell(status),
+ ActionMap::ShellCommand => EventExec::event_shell_command(current_tab),
ActionMap::ShellMenu => EventExec::event_shell_menu(current_tab),
ActionMap::Shortcut => EventExec::event_shortcut(current_tab),
ActionMap::Sort => EventExec::event_sort(current_tab),
diff --git a/src/event_exec.rs b/src/event_exec.rs
index 0dafe8d..1a70e46 100644
--- a/src/event_exec.rs
+++ b/src/event_exec.rs
@@ -347,6 +347,11 @@ impl EventExec {
Ok(())
}
+ pub fn exec_shell(tab: &mut Tab) -> Result<()> {
+ tab.exec_shell()?;
+ Ok(())
+ }
+
/// Leave current mode to normal mode.
/// Reset the inputs and completion, reset the window, exit the preview.
pub fn event_reset_mode(tab: &mut Tab) -> Result<()> {
@@ -816,6 +821,11 @@ impl EventExec {
Ok(())
}
+ pub fn event_shell_command(tab: &mut Tab) -> Result<()> {
+ tab.set_mode(Mode::InputSimple(InputSimple::Shell));
+ Ok(())
+ }
+
/// Enter the shell menu mode. You can pick a TUI application to be run
pub fn event_shell_menu(tab: &mut Tab) -> Result<()> {
tab.set_mode(Mode::Navigate(Navigate::ShellMenu));
@@ -1345,6 +1355,7 @@ impl EventExec {
Mode::InputSimple(InputSimple::Chmod) => EventExec::exec_chmod(status)?,
Mode::InputSimple(InputSimple::RegexMatch) => EventExec::exec_regex(status)?,
Mode::InputSimple(InputSimple::SetNvimAddr) => EventExec::exec_set_nvim_addr(status)?,
+ Mode::InputSimple(InputSimple::Shell) => EventExec::exec_shell(status.selected())?,
Mode::InputSimple(InputSimple::Filter) => {
must_refresh = false;
EventExec::exec_filter(status, colors)?
diff --git a/src/keybindings.rs b/src/keybindings.rs
index ba33432..00916fe 100644
--- a/src/keybindings.rs
+++ b/src/keybindings.rs
@@ -46,6 +46,7 @@ impl Bindings {
(Key::Char('-'), ActionMap::Back),
(Key::Char('~'), ActionMap::Home),
(Key::Char('`'), ActionMap::GoRoot),
+ (Key::Char('!'), ActionMap::ShellCommand),
(Key::Char('@'), ActionMap::GoStart),
(Key::Char(':'), ActionMap::Command),
(Key::Char('B'), ActionMap::Bulk),
diff --git a/src/mode.rs b/src/mode.rs
index abd485a..f50243d 100644
--- a/src/mode.rs
+++ b/src/mode.rs
@@ -79,6 +79,8 @@ pub enum InputSimple {
SetNvimAddr,
/// Input a password (chars a replaced by *)
Password(PasswordKind, BlockDeviceAction, PasswordUsage),
+ /// Shell command execute as is
+ Shell,
}
/// Different modes in which we display a bunch of possible destinations.
@@ -141,6 +143,7 @@ impl fmt::Display for Mode {
Mode::InputSimple(InputSimple::Newdir) => write!(f, "Newdir: "),
Mode::InputSimple(InputSimple::RegexMatch) => write!(f, "Regex: "),
Mode::InputSimple(InputSimple::SetNvimAddr) => write!(f, "Neovim: "),
+ Mode::InputSimple(InputSimple::Shell) => write!(f, "Shell: "),
Mode::InputSimple(InputSimple::Sort) => {
write!(f, "Sort: Kind Name Modif Size Ext Rev :")
}
diff --git a/src/opener.rs b/src/opener.rs
index 46ad71d..2ba9ec0 100644
--- a/src/opener.rs
+++ b/src/opener.rs
@@ -396,7 +396,7 @@ pub fn execute_in_child(exe: &str, args: &Vec<&str>) -> Result<std::process::Chi
/// Execute a command with options in a fork.
/// Returns an handle to the child process.
/// Branch stdin, stderr and stdout to /dev/null
-pub fn execute_in_child_without_output(exe: &str, args: &Vec<&str>) -> Result<std::process::Child> {
+pub fn execute_in_child_without_output(exe: &str, args: &[&str]) -> Result<std::process::Child> {
info!("execute_in_child_without_output. executable: {exe}, arguments: {args:?}",);
Ok(Command::new(exe)
.args(args)
diff --git a/src/shell_menu.rs b/src/shell_menu.rs
index cbe32fc..4bb9932 100644
--- a/src/shell_menu.rs
+++ b/src/shell_menu.rs
@@ -52,12 +52,12 @@ impl ShellMenu {
.directory_of_selected()?
.to_str()
.context("event_shell: couldn't parse the directory")?;
- execute_in_child_without_output(&status.opener.terminal, &vec!["-d", path, "-e", command])?;
+ execute_in_child_without_output(&status.opener.terminal, &["-d", path, "-e", command])?;
Ok(())
}
fn simple(status: &Status, command: &str) -> Result<()> {
- execute_in_child_without_output(&status.opener.terminal, &vec!["-e", command])?;
+ execute_in_child_without_output(&status.opener.terminal, &["-e", command])?;
Ok(())
}
diff --git a/src/tab.rs b/src/tab.rs
index 595b3d6..778182d 100644
--- a/src/tab.rs
+++ b/src/tab.rs
@@ -11,6 +11,7 @@ use crate::fileinfo::{FileInfo, FileKind, PathContent};
use crate::filter::FilterKind;
use crate::input::Input;
use crate::mode::Mode;
+use crate::opener::execute_in_child_without_output_with_path;
use crate::preview::{Directory, Preview};
use crate::selectable_content::SelectableContent;
use crate::shortcut::Shortcut;
@@ -382,4 +383,19 @@ impl Tab {
pub fn need_second_window(&self) -> bool {
!matches!(self.mode, Mode::Normal | Mode::Tree | Mode::Preview)
}
+
+ pub fn exec_shell(&mut self) -> Result<()> {
+ let shell_command = self.input.string();
+ let args: Vec<&str> = shell_command.split_whitespace().collect();
+ if args.is_empty() {
+ return Ok(());
+ }
+ let Ok(executable) = which::which(args[0]) else { return Ok(()); };
+ let executable = executable.to_str().context("Coudln't parse the path")?;
+ let path = self.directory_of_selected()?;
+ let mut args: Vec<&str> = args.to_vec();
+ args.remove(0);
+ execute_in_child_without_output_with_path(executable, path, Some(&args))?;
+ Ok(())
+ }
}