From 04fe8bde15d80907b1350eda5834cebabbaf2f0f Mon Sep 17 00:00:00 2001 From: Gal Schlezinger Date: Sat, 19 Nov 2022 21:13:59 +0200 Subject: [PATCH] implement on all big shells woohoo --- src/shell/bash.rs | 24 +++++++++++++++++++++++- src/shell/fish.rs | 10 ++++++++++ src/shell/mod.rs | 1 - src/shell/powershell.rs | 10 ++++++++++ src/shell/trap_add_script.rs | 31 ------------------------------- src/shell/zsh.rs | 10 +++++++--- 6 files changed, 50 insertions(+), 36 deletions(-) delete mode 100644 src/shell/trap_add_script.rs diff --git a/src/shell/bash.rs b/src/shell/bash.rs index 7fcc8d3..35b4b20 100644 --- a/src/shell/bash.rs +++ b/src/shell/bash.rs @@ -1,6 +1,6 @@ use crate::version_file_strategy::VersionFileStrategy; -use super::{shell::Shell, trap_add_script::TRAP_ADD}; +use super::shell::Shell; use indoc::{formatdoc, indoc}; use std::path::Path; @@ -64,3 +64,25 @@ impl Shell for Bash { )) } } + +/// This code is based on Richard Hansen's answer on StackOverflow: +/// https://stackoverflow.com/a/7287873/1176984 +/// +/// Usage: +/// __fnm_trap_add__ 'echo "hello"' EXIT +pub const TRAP_ADD: &'static str = indoc::indoc!( + r#" + __fnm_trap_add__() { + __fnm_trap_add___cmd=$1; shift || fatal "${FUNCNAME} usage error" + for __fnm_trap_add___name in "$@"; do + trap -- "$( + extract_trap_cmd() { printf '%s\n' "$3"; } + eval "extract_trap_cmd $(trap -p "${__fnm_trap_add___name}")" + printf '%s\n' "${__fnm_trap_add___cmd}" + )" "${__fnm_trap_add___name}" \ + || fatal "unable to add to trap ${__fnm_trap_add___name}" + done + } + declare -f -t __fnm_trap_add__ + "# +); diff --git a/src/shell/fish.rs b/src/shell/fish.rs index 8856407..8f91c3d 100644 --- a/src/shell/fish.rs +++ b/src/shell/fish.rs @@ -46,4 +46,14 @@ impl Shell for Fish { autoload_hook = autoload_hook )) } + + fn delete_on_exit(&self, fnm_multishell: &Path) -> Option { + Some(indoc::formatdoc! {r#" + function _fnm_delete_multishell --on-event fish_exit + rm -f "{fnm_multishell}" + end + + _fnm_delete_multishell + "#, fnm_multishell = fnm_multishell.display()}) + } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index e74452f..4e27cd0 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -7,7 +7,6 @@ mod zsh; #[allow(clippy::module_inception)] mod shell; -mod trap_add_script; pub use bash::Bash; pub use fish::Fish; diff --git a/src/shell/powershell.rs b/src/shell/powershell.rs index d3c8817..949130e 100644 --- a/src/shell/powershell.rs +++ b/src/shell/powershell.rs @@ -45,6 +45,16 @@ impl Shell for PowerShell { autoload_hook = autoload_hook )) } + + fn delete_on_exit(&self, fnm_multishell: &Path) -> Option { + Some(indoc::formatdoc!( + r#" + Register-EngineEvent PowerShell.Exiting -Action {{ rm "{fnm_multishell}" > $null }} > $null + "#, + fnm_multishell = fnm_multishell.display() + )) + } + fn to_clap_shell(&self) -> clap_complete::Shell { clap_complete::Shell::PowerShell } diff --git a/src/shell/trap_add_script.rs b/src/shell/trap_add_script.rs deleted file mode 100644 index de38262..0000000 --- a/src/shell/trap_add_script.rs +++ /dev/null @@ -1,31 +0,0 @@ -// This code is based on Richard Hansen's answer on StackOverflow: -// https://stackoverflow.com/a/7287873/1176984 - -pub const TRAP_ADD: &'static str = indoc::indoc!( - r#" - # appends a command to a trap - # - # - 1st arg: code to add - # - remaining args: names of traps to modify - # - __fnm_trap_add__() { - __fnm_trap_add___cmd=$1; shift || fatal "${FUNCNAME} usage error" - for __fnm_trap_add___name in "$@"; do - trap -- "$( - # helper fn to get existing trap command from output - # of trap -p - extract_trap_cmd() { printf '%s\n' "$3"; } - # print existing trap command with newline - eval "extract_trap_cmd $(trap -p "${__fnm_trap_add___name}")" - # print the new trap command - printf '%s\n' "${__fnm_trap_add___cmd}" - )" "${__fnm_trap_add___name}" \ - || fatal "unable to add to trap ${__fnm_trap_add___name}" - done - } - # set the trace attribute for the above function. this is - # required to modify DEBUG or RETURN traps because functions don't - # inherit them unless the trace attribute is set - declare -f -t __fnm_trap_add__ - "# -); diff --git a/src/shell/zsh.rs b/src/shell/zsh.rs index 91fcc6f..ebc19dc 100644 --- a/src/shell/zsh.rs +++ b/src/shell/zsh.rs @@ -55,11 +55,15 @@ impl Shell for Zsh { fn delete_on_exit(&self, fnm_multishell: &Path) -> Option { Some(indoc::formatdoc!( r#" - {TRAP_ADD} - __fnm_trap_add__ 'rm "{fnm_multishell}"' EXIT + autoload -U add-zsh-hook + _fnm_on_exit () {{ + rm -f "{fnm_multishell}" + }} + + add-zsh-hook zshexit _fnm_on_exit \ + && _fnm_on_exit "#, fnm_multishell = fnm_multishell.display(), - TRAP_ADD = super::trap_add_script::TRAP_ADD )) } }