From c9ad7ece977b476e80ac87634c43b907fb7f54f8 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 3 May 2012 13:48:42 +0100 Subject: [PATCH 1/2] Temporarily disable noclobber for bash bash doesn't have zsh's localoptions, so we store the old value of the clobber option in a global variable, and then explicitly restore it once the file write is complete. --- lib/core/smartcd | 14 ++++++++++++++ lib/core/smartcd_config | 6 +++++- lib/core/smartcd_edit | 6 +++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/core/smartcd b/lib/core/smartcd index 698549a..6e17aa2 100644 --- a/lib/core/smartcd +++ b/lib/core/smartcd @@ -778,6 +778,20 @@ function _smartcd_file() { echo "$this_file" } +function _smartcd_bash_local_clobber() { + _smartcd_clobber= + if [[ -n $BASH_VERSION ]]; then + for opt in `echo $SHELLOPTS | sed -e 's/:/ /g'`; do + [[ "$opt" == "noclobber" ]] && _smartcd_clobber= + done + set +o noclobber + fi +} + +function _smartcd_bash_restore_clobber() { + [[ -n "$BASH_VERSION" && -z "$_smartcd_clobber" ]] && set -o noclobber +} + # Autoload stubs function _smartcd_file_check() { _smartcd_load "smartcd_edit" && _smartcd_file_check "$@" diff --git a/lib/core/smartcd_config b/lib/core/smartcd_config index 2eec8c5..9fc2b59 100644 --- a/lib/core/smartcd_config +++ b/lib/core/smartcd_config @@ -138,7 +138,8 @@ function smartcd_config() { echo - # Temporarily disable noclobber for zsh users + # Temporarily disable noclobber for bash, zsh users + _smartcd_bash_local_clobber [[ -n $ZSH_VERSION ]] && setopt localoptions && setopt clobber if [[ -f "$HOME/.smartcd_config" ]]; then @@ -160,6 +161,9 @@ function smartcd_config() { fi fi + # Restore bash clobber option to previous value + _smartcd_bash_restore_clobber + if [[ -n $config_file_exists ]]; then echo -n "Would you like to load your config file now? [Y/n] " diff --git a/lib/core/smartcd_edit b/lib/core/smartcd_edit index be44979..94d3544 100644 --- a/lib/core/smartcd_edit +++ b/lib/core/smartcd_edit @@ -22,7 +22,8 @@ function smartcd_edit() { command mkdir -p "$smartcd_dir" fi - # Temporarily disable noclobber for zsh users + # Temporarily disable noclobber for bash, zsh users + _smartcd_bash_local_clobber [[ -n $ZSH_VERSION ]] && setopt localoptions && setopt clobber # Edit the file if interactive, otherwise write standard input to it @@ -91,6 +92,9 @@ EOF # Delete any file that is left empty command rm "$smartcd_dir/$file" fi + + # Restore bash clobber option to previous value + _smartcd_bash_restore_clobber } function smartcd_append() { From efd2494ad8d928e73ab50595cb4ca8937bfc2f5e Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 3 May 2012 14:52:14 +0100 Subject: [PATCH 2/2] Fix script mapping by always using physical paths cd /tmp mkdir foo ln -s foo foo_link cd /tmp/foo smartcd edit enter ... cd /tmp/foo_link smartcd edit enter ... Using the above sequence, the two "smartcd edit" commands should edit the same script. However, because smartcd uses the output of "pwd" to generate the path to the script directory, two different scripts are created. This patch fixes the bug by always using physical paths ("pwd -P"). It also fixes some unit test failures which occur if the directory from which the tests are run was entered via a symbolic link: cd /tmp git clone https://github.com/cxreg/smartcd.git smartcd ln -s smartcd smartcd_link cd /tmp/smartcd && ./t/harness.sh # passes cd /tmp/smartcd_link && ./t/harness.sh # smartcd.t steps 7, 10, 11 fail --- lib/core/smartcd | 6 +++--- lib/core/smartcd_edit | 6 +++--- lib/core/smartcd_helper | 4 ++-- lib/core/smartcd_template | 6 +++--- lib/core/varstash | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/core/smartcd b/lib/core/smartcd index 6e17aa2..5fde2df 100644 --- a/lib/core/smartcd +++ b/lib/core/smartcd @@ -181,7 +181,7 @@ function smartcd() { case $command in -h|help|'') echo $usage;; cd|pushd|popd) shift; _smartcd $command "$@"; return $?;; - reenter) local dir="$(pwd)" + reenter) local dir="$(pwd -P)" _smartcd cd .. _smartcd cd "$dir" ;; @@ -411,7 +411,7 @@ function _smartcd() { IFS="$_old_ifs" if (( $rv != 0 )); then return $rv; fi - local whereto="$(pwd)" + local whereto="$(pwd -P)" _smartcd_last_run_for="x$whereto" # If zsh, turn autopushd off temporarily to avoid extra pushes @@ -662,7 +662,7 @@ function _smartcd() { } function _smartcd_hook() { - local cwd="$(pwd)" + local cwd="$(pwd -P)" # Skip this if we already ran smartcd for this directory if [[ "x$cwd" != "$_smartcd_last_run_for" ]]; then diff --git a/lib/core/smartcd_edit b/lib/core/smartcd_edit index 94d3544..8442839 100644 --- a/lib/core/smartcd_edit +++ b/lib/core/smartcd_edit @@ -1,7 +1,7 @@ function smartcd_edit() { # Invoke the users editor (or vi) on the relevant file local file="$1" - local dir="${2:-$(pwd)}" + local dir="${2:-$(pwd -P)}" case $file in bash_enter|bash_leave) local type=${file#bash_};; @@ -110,13 +110,13 @@ function _smartcd_file_check() { if [[ -n $dir ]]; then # canonicalize - dir=$(builtin cd $dir 2>/dev/null && command pwd) + dir=$(builtin cd $dir 2>/dev/null && command pwd -P) if [[ -z $dir ]]; then echo "$3 is not a valid directory" return fi else - dir="$(pwd)" + dir="$(pwd -P)" fi local base=$(_smartcd_base) diff --git a/lib/core/smartcd_helper b/lib/core/smartcd_helper index 9043245..94d82d6 100644 --- a/lib/core/smartcd_helper +++ b/lib/core/smartcd_helper @@ -17,13 +17,13 @@ function smartcd_helper() { # and nothing has done the replacement yet local params i for i in "$@"; do - apush params "${i//__PATH__/${smartcd_working_dir:-$(command pwd)}}" + apush params "${i//__PATH__/${smartcd_working_dir:-$(command pwd -P)}}" done set -- "${params[@]}" fi if [[ -f "$HOME/.smartcd/helper/$type/script" ]]; then - _smartcd_exec_file "$HOME/.smartcd/helper/$type/script" "${smartcd_working_dir:-$(command pwd)}" "$@" + _smartcd_exec_file "$HOME/.smartcd/helper/$type/script" "${smartcd_working_dir:-$(command pwd -P)}" "$@" else echo "smartcd: helper $type not found" fi diff --git a/lib/core/smartcd_template b/lib/core/smartcd_template index efb9f82..a8fac16 100644 --- a/lib/core/smartcd_template +++ b/lib/core/smartcd_template @@ -68,7 +68,7 @@ EOF if [[ -f "$base/templates/$name" ]]; then echo "Template $name already exists, run \"smartcd template edit $name\" to modify it" else - smartcd_template _init "$name" "$(pwd)" + smartcd_template _init "$name" "$(pwd -P)" smartcd_template edit "$name" fi else @@ -119,7 +119,7 @@ EOF install|-i) local name="$1"; shift if [[ -n $name ]]; then if [[ -f "$base/templates/$name" ]]; then - local current_dir=$(pwd) + local current_dir=$(pwd -P) local smartcd_dir="$base/scripts$current_dir" command mkdir -p "$smartcd_dir" local mode= line= @@ -184,7 +184,7 @@ EOF esac done < "$base/templates/$name" IFS="$_old_ifs" - _smartcd_exec "$contents" "$(pwd)" + _smartcd_exec "$contents" "$(pwd -P)" else echo "Template $name not found" fi diff --git a/lib/core/varstash b/lib/core/varstash index da2a59c..aafbd3c 100644 --- a/lib/core/varstash +++ b/lib/core/varstash @@ -71,7 +71,7 @@ function stash() { fi if [[ -n $1 ]] && [[ -z $run_from_smartcd ]] && [[ -z $run_from_autostash ]]; then - local working_dir="${varstash_dir:-$(pwd)}" + local working_dir="${varstash_dir:-$(pwd -P)}" local smartcd_dir="$(_smartcd_base)/scripts$working_dir" local help_action="stashing a variable" local help_dir=$smartcd_dir @@ -209,7 +209,7 @@ function stash() { function autostash() { if [[ -n $1 ]] && [[ -z $run_from_smartcd ]]; then - local working_dir="${varstash_dir:-$(pwd)}" + local working_dir="${varstash_dir:-$(pwd -P)}" local smartcd_dir="$(_smartcd_base)/scripts$working_dir" local help_action="autostashing a variable" local help_dir=$smartcd_dir @@ -239,7 +239,7 @@ function autostash() { function unstash() { if [[ -n $1 ]] && [[ -z $run_from_smartcd ]] && [[ -z $run_from_autounstash ]]; then - local working_dir=${varstash_dir:-$(pwd)} + local working_dir=${varstash_dir:-$(pwd -P)} local smartcd_dir="$(_smartcd_base)/scripts$working_dir" local help_action="unstashing a variable" local help_dir=$smartcd_dir @@ -330,7 +330,7 @@ function autounstash() { } function _mangle_var() { - local mangle_var_where="${varstash_dir:-$(pwd)}" + local mangle_var_where="${varstash_dir:-$(pwd -P)}" mangle_var_where=${mangle_var_where//[^A-Za-z0-9]/_} echo "_tmp_${mangle_var_where}_$1" }