Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
My funky cd replacement
- X-seq: zsh-users 21153
- From: Dominik Vogt <vogt@xxxxxxxxxxxxxxxxxx>
- To: Zsh Users <zsh-users@xxxxxxx>
- Subject: My funky cd replacement
- Date: Fri, 15 Jan 2016 15:07:33 +0100
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mail-followup-to: Zsh Users <zsh-users@xxxxxxx>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- Reply-to: vogt@xxxxxxxxxxxxxxxxxx
The attached file my own version of "cd" with all the recent
changes and fixes. On to of a plain cd it does:
When invoked with one directory argument:
* If the path is a directory, cd into it (the obvious)
* If it's not:
- If the path does not exist, strip a trailing ":" (This is
meant to simplyfy pasting a path from grep or gcc output to
the shell).
- If the path ends in one of archive the suffixes
.tar .tar.gz .tar.bz2 .tgz .TGZ .zip .ZIP .7z .7Z
strip the suffix and if the rest is a directory, cd into it.
- If the path is just a file, cd into the containing directory.
When invoked with two arguments:
* Try replacing all occurances of the first argument with the
second argument in $PWD. If any of the results is a directory,
cd into the first of them.
E.g. if you are in /aa/bb/aa/dd and there is a directory
/aa/bb/ac/dd a simple
cd a c
will switch to it. This also works with a blank first argument
like
cd "" .1
to switch from e.g. ~/foo to ~/foo.1
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt
IBM Germany
function cd ()
{
local CDOPTS
local SHELLOPTS
local SUFFIXES
local SUFFIX
local STRIPCHARS
local DIR
SHELLOPTS=(${(Oa)${${(kv)options[(I)*pushd*|cd*|*cd]/off/+o}/on/-o}})
emulate -L zsh
set $SHELLOPTS
setopt EXTENDED_GLOB
# suffixes of various archives
SUFFIXES=(.tar .tar.gz .tar.bz2 .tgz .TGZ .zip .ZIP .7z .7Z)
# characters to strip from the end of the path; this is meant for
# pasting file names from grep and gcc output without the need to edit
# them
STRIPCHARS=":"
# remove the command options
while [[ $# > 0 ]]; do
case "$1" in
-[qsLP]##)
CDOPTS=($CDOPTS[@] "$1")
shift
;;
--)
# end of options
shift
break
;;
*)
break
;;
esac
done
if [[ $# = 1 ]]; then
if [[ "$1" = "" ]]; then
# don't handle an empty argument specially
builtin cd $CDOPTS[@] -- "$1"
return
elif [[ "${1#[+-]<0->}" = "" ]]; then
# don't handle +<n> and -<n> specially
builtin cd $CDOPTS[@] -- "$1"
return
elif [[ -d "$1" ]]; then
# if it's a directory, cd into it
builtin cd $CDOPTS[@] -- "$1"
return
fi
fi
case $# in
0)
builtin cd $CDOPTS[@]
return
;;
1)
local ARG
ARG="$1"
if [[ ! -e "$ARG" ]]; then
# remove trailing garbage
ARG="${1%[${(q)STRIPCHARS}]}"
if [[ -d "$ARG" ]]; then
builtin cd $CDOPTS[@] -- "$ARG"
return
fi
fi
for SUFFIX in "$SUFFIXES[@]"; do
# if $ARG has one of the suffixes in the list, strip
# the suffix and check whether there's a dir with that
# name
DIR="${ARG%%${(q)SUFFIX}}"
if [[ "$DIR" != "$ARG" ]] && [[ -d "$DIR" ]]; then
builtin cd $CDOPTS[@] -- "$DIR"
return
fi
done
if [[ -f "$ARG" ]]; then
# cd into the containing dir
builtin cd $CDOPTS[@] -- "$(dirname "${ARG:A}")"
return
else
# just try cd
builtin cd $CDOPTS[@] -- "$ARG"
return
fi
;;
2)
# note: the pattern below fails to match the end of the string
# so it's necessary to handle this separately
if [[ "$1" = "" ]]; then
DIR="$PWD$2"
if [[ -d "$DIR" ]]; then
builtin cd $CDOPTS[@] -- "$DIR"
return
fi
fi
integer I
while DIR="${(I:${I}:)PWD/$1/$2}" && [[ "$DIR" != "$PWD" ]]; do
if [[ -d "$DIR" ]]; then
builtin cd $CDOPTS[@] -- "$DIR"
return
fi
I="$[I + 1]"
done
builtin cd $CDOPTS[@] "$@"
return
;;
*)
builtin cd $CDOPTS[@] "$@"
return
;;
esac
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author