From 2392951815447d2f1252fbd6ea7df23542c419cc Mon Sep 17 00:00:00 2001 From: Azad <49314270+Akmadan23@users.noreply.github.com> Date: Wed, 3 Apr 2024 20:25:51 +0200 Subject: [PATCH] feat: add support for %s and %p as first argument to subprocess commands (#515) * feat: add support for %s and %p as first argument to subprocess commands * Minor change * Simplify * Display exit status correctly --- src/commands/custom_search.rs | 4 +-- src/commands/sub_process.rs | 60 ++++++++++++++++------------------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/commands/custom_search.rs b/src/commands/custom_search.rs index 422143e21..9ca574031 100644 --- a/src/commands/custom_search.rs +++ b/src/commands/custom_search.rs @@ -1,5 +1,5 @@ use super::change_directory::change_directory; -use super::sub_process::current_filenames; +use super::sub_process::current_files; use crate::commands::cursor_move; use crate::context::AppContext; use crate::error::{AppError, AppErrorKind, AppResult}; @@ -26,7 +26,7 @@ pub fn custom_search( .command .clone(); - let current_filenames = current_filenames(context); + let current_filenames: Vec<&str> = current_files(context).iter().map(|f| f.0).collect(); let text = custom_command.replace("%s", ¤t_filenames.join(" ")); let text = text.replace( diff --git a/src/commands/sub_process.rs b/src/commands/sub_process.rs index 2e5a1c8e8..b23266baa 100644 --- a/src/commands/sub_process.rs +++ b/src/commands/sub_process.rs @@ -1,6 +1,7 @@ use crate::context::AppContext; use crate::error::AppResult; use crate::ui::AppBackend; +use std::path::Path; use std::process::{Command, Stdio}; use super::reload; @@ -12,20 +13,17 @@ pub enum SubprocessCallMode { Capture, } -pub fn current_filenames(context: &AppContext) -> Vec<&str> { +pub fn current_files(context: &AppContext) -> Vec<(&str, &Path)> { let mut result = Vec::new(); if let Some(curr_list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { let mut i = 0; - curr_list - .iter_selected() - .map(|e| e.file_name()) - .for_each(|file_name| { - result.push(file_name); - i += 1; - }); + curr_list.iter_selected().for_each(|entry| { + result.push((entry.file_name(), entry.file_path())); + i += 1; + }); if i == 0 { if let Some(entry) = curr_list.curr_entry_ref() { - result.push(entry.file_name()); + result.push((entry.file_name(), entry.file_path())); } } } @@ -38,29 +36,26 @@ fn execute_sub_process( words: &[String], mode: SubprocessCallMode, ) -> std::io::Result<()> { - let mut command = Command::new(words[0].clone()); + let current_files = current_files(context); + let command_base = if current_files.len() == 1 { + words[0] + .replace("%s", current_files[0].0) + .replace("%p", ¤t_files[0].1.to_string_lossy()) + } else { + words[0].clone() + }; + + let mut command = Command::new(command_base); for word in words.iter().skip(1) { - match (*word).as_str() { + match word.as_str() { "%s" => { - current_filenames(context).into_iter().for_each(|x| { - command.arg(x); - }); + for (file_name, _) in ¤t_files { + command.arg(file_name); + } } "%p" => { - if let Some(curr_list) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { - let mut i = 0; - curr_list - .iter_selected() - .map(|e| e.file_path()) - .for_each(|file_path| { - command.arg(file_path); - i += 1; - }); - if i == 0 { - if let Some(entry) = curr_list.curr_entry_ref() { - command.arg(entry.file_path()); - } - } + for (_, file_path) in ¤t_files { + command.arg(file_path); } } s => { @@ -78,13 +73,13 @@ fn execute_sub_process( } else { Err(std::io::Error::new( std::io::ErrorKind::Other, - format!("Command failed with {:?}", status), + format!("Command failed with {}", status), )) } } Err(err) => Err(std::io::Error::new( std::io::ErrorKind::Other, - format!("Shell execution failed: {:?}", err), + format!("Shell execution failed: {}", err), )), } } @@ -106,7 +101,7 @@ fn execute_sub_process( } else { Err(std::io::Error::new( std::io::ErrorKind::Other, - format!("Command failed with {:?}", output.status), + format!("Command failed with {}", output.status), )) } } @@ -125,9 +120,10 @@ pub fn sub_process( // Joshuto needs to release the terminal when handing it over to some interactive // shell command and restore it afterwards backend.terminal_drop(); - execute_sub_process(context, words, mode)?; + let res = execute_sub_process(context, words, mode); backend.terminal_restore()?; let _ = reload::soft_reload_curr_tab(context); + res?; context .message_queue_mut() .push_info(format!("Finished: {}", words.join(" ")));