diff --git a/src/shell/bash.rs b/src/shell/bash.rs index ce13f6c..7fcc8d3 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; +use super::{shell::Shell, trap_add_script::TRAP_ADD}; use indoc::{formatdoc, indoc}; use std::path::Path; @@ -55,34 +55,12 @@ impl Shell for Bash { fn delete_on_exit(&self, fnm_multishell: &Path) -> Option { Some(indoc::formatdoc!( r#" - # appends a command to a trap - # - # - 1st arg: code to add - # - remaining args: names of traps to modify - # - trap_add() {{ - trap_add_cmd=$1; shift || fatal "${{FUNCNAME}} usage error" - for 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 "${{trap_add_name}}")" - # print the new trap command - printf '%s\n' "${{trap_add_cmd}}" - )" "${{trap_add_name}}" \ - || fatal "unable to add to trap ${{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 trap_add + {TRAP_ADD} - trap_add 'echo hi; rm "{fnm_multishell}"' EXIT + __fnm_trap_add__ 'rm "{fnm_multishell}"' EXIT "#, - fnm_multishell = fnm_multishell.display() + fnm_multishell = fnm_multishell.display(), + TRAP_ADD = TRAP_ADD )) } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 4e27cd0..e74452f 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -7,6 +7,7 @@ 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/trap_add_script.rs b/src/shell/trap_add_script.rs new file mode 100644 index 0000000..de38262 --- /dev/null +++ b/src/shell/trap_add_script.rs @@ -0,0 +1,31 @@ +// 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 9bc13ce..91fcc6f 100644 --- a/src/shell/zsh.rs +++ b/src/shell/zsh.rs @@ -51,4 +51,15 @@ impl Shell for Zsh { autoload_hook = autoload_hook )) } + + fn delete_on_exit(&self, fnm_multishell: &Path) -> Option { + Some(indoc::formatdoc!( + r#" + {TRAP_ADD} + __fnm_trap_add__ 'rm "{fnm_multishell}"' EXIT + "#, + fnm_multishell = fnm_multishell.display(), + TRAP_ADD = super::trap_add_script::TRAP_ADD + )) + } }