From 579eaad7d246f2de4f09b5cb823c0a266958fab6 Mon Sep 17 00:00:00 2001 From: Moviuro Date: Mon, 25 Jul 2022 23:07:29 +0200 Subject: [PATCH] zshrc: smarter smarter cd We have to account for a lot of possibilities (see zshbuiltins(1)): we stay on the safe side and only change cd target if we're sure about what we do. See examples: % zsh -d -f # reset the shell % cd % touch -- -q % cd -q # should do nothing; 43090cf version behaves weirdly here, replacing -q with . % cd /home % cd /home /etc # should go to /etc (replace home with etc in PWD) /etc % cd /home /etc # this will fail [1] cd: string not in pwd: /home % cd /home % cd -q /home /etc # should go to /etc /etc % cd -q /home /etc # this will fail [2] cd: string not in pwd: /home % cd % touch +123456 % cd +123456 # this will fail [3]; 43090cf version behaves weirdly here, replacing +123456 with . [1] I chose to make this one work. If `cd old new` fails, then try to `cd old` [2,3] I chose to fail too in that case. Handling cd arguments is not what I was planning to do when I started working on this patch ;P --- etc/zsh/zshrc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/etc/zsh/zshrc b/etc/zsh/zshrc index f887427..29a8c83 100644 --- a/etc/zsh/zshrc +++ b/etc/zsh/zshrc @@ -3470,14 +3470,27 @@ function cl () { cd $1 && ls -a } -# smart cd function, allows switching to /etc when running 'cd /etc/fstab' +# smart cd function, allows switching to /etc when running 'cd /etc/fstab', +# `cd /etc/fst` or `cd /etc/*tab` function cd () { - if (( ${#argv} == 1 )) && [[ -f ${1} ]]; then - [[ ! -e ${1:h} ]] && return 1 - print "Correcting ${1} to ${1:h}" + # zsh's builtin cd has multiple switches and behaviors, see zshbuiltins(1) + if builtin cd "$@"; then + : + # we bail out if options were passed to cd and the builtin failed + elif [[ $1 =~ '[+-].*' ]]; then + return 1 + # if cd failed and it was not given weird flags, it might actually be that + # we need to intervene + # builtin cd fails with too many arguments + elif [[ -d ${1} ]]; then + print "Correcting $@ to $1" + builtin cd ${1} + # we help correct a typo or cd-ing to not a dir by looking at the parent + elif [[ -d ${1:h} ]]; then + print "Correcting $@ to ${1:h}" >&2 builtin cd ${1:h} else - builtin cd "$@" + return 1 fi }