diff options
author | qkzk <qu3nt1n@gmail.com> | 2023-04-04 23:49:33 +0200 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2023-04-04 23:49:33 +0200 |
commit | d568556a4a1a211056efab10ca55a5a6631412b7 (patch) | |
tree | 2ec0dd9f84f1f08a1887e2574ed2e3f72c7d98d0 /src | |
parent | d04825d36f294560d7a1db01680042a9ea506260 (diff) |
basic shell execution with !
Diffstat (limited to 'src')
-rw-r--r-- | src/action_map.rs | 2 | ||||
-rw-r--r-- | src/event_exec.rs | 11 | ||||
-rw-r--r-- | src/keybindings.rs | 1 | ||||
-rw-r--r-- | src/mode.rs | 3 | ||||
-rw-r--r-- | src/opener.rs | 2 | ||||
-rw-r--r-- | src/shell_menu.rs | 4 | ||||
-rw-r--r-- | src/tab.rs | 16 |
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(()) } @@ -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(()) + } } |