1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-26 04:30:27 +01:00

24768: add -q option to cd, chdir, pushd, popd

use in _canonical_paths
add 4.3.6 release note with this and other stuff
This commit is contained in:
Peter Stephenson 2008-03-28 09:59:06 +00:00
parent 42ddb45fe8
commit 50d9cdeae4
5 changed files with 93 additions and 46 deletions

View file

@ -1,3 +1,10 @@
2008-03-28 Peter Stephenson <pws@csr.com>
* 24768: Completion/Unix/Type/_canonical_paths,
Doc/Zsh/builtins.yo, Etc/relnotes_4.3.6.txt, Src/builtin.c:
add -q option to cd, chdir, pushd, popd; use in _canonical_paths;
document in release note.
2008-03-27 Peter Stephenson <pws@csr.com>
* 24759: Completion/Unix/Type/_canonical_paths: unfunction

View file

@ -15,42 +15,45 @@
_canonical_paths_pwd() {
# Get the canonical directory name by changing to it.
# To be run in a subshell.
(( ${+functions[chpwd]} )) && unfunction chpwd
setopt CHASE_LINKS
cd $1 2>/dev/null && pwd
integer chaselinks
[[ -o chaselinks ]] && (( chaselinks = 1 ))
setopt localoptions nopushdignoredups chaselinks
if builtin pushd -q -- $1 2>/dev/null; then
REPLY=$PWD
(( chaselinks )) || unsetopt chaselinks
builtin popd -q
else
REPLY=$1
fi
}
_canonical_paths_get_canonical_path() {
typeset newfile dir
typeset newfile nondir
typeset -A seen
REPLY=$1
# Resolve any trailing symbolic links, guarding against loops.
while [[ -z ${seen[$REPLY]} ]]; do
seen[$REPLY]=1
newfile=()
zstat -A newfile +link $REPLY 2>/dev/null
if [[ -n $newfile[1] ]]; then
REPLY=$newfile[1]
else
break
fi
done
# Canonicalise the directory path. We may not be able to
# do this if we can't read all components.
if [[ -d $REPLY ]]; then
dir="$(_canonical_paths_pwd $REPLY)"
if [[ -n $dir ]]; then
REPLY=$dir
fi
elif [[ $REPLY = */*[^/] && $REPLY != /[^/]# ]]; then
# Don't try this if there's a trailing slash or we're in
# the root directory.
dir="$(_canonical_paths_pwd ${REPLY%/*})"
if [[ -n $dir ]]; then
REPLY=$dir/${REPLY##*/}
_canonical_paths_pwd $REPLY
else
# Resolve any trailing symbolic links, guarding against loops.
while [[ -z ${seen[$REPLY]} ]]; do
seen[$REPLY]=1
newfile=()
zstat -A newfile +link $REPLY 2>/dev/null
if [[ -n $newfile[1] ]]; then
REPLY=$newfile[1]
else
break
fi
done
if [[ $REPLY = */*[^/] && $REPLY != /[^/]# ]]; then
# Don't try this if there's a trailing slash or we're in
# the root directory.
nondir=${REPLY##*/#}
_canonical_paths_pwd ${REPLY%/#*}
REPLY+="/$nondir"
fi
fi
}

View file

@ -152,16 +152,16 @@ alias(bye)(exit)
module(cap)(zsh/cap)
findex(cd)
cindex(directories, changing)
xitem(tt(cd) [ tt(-sLP) ] [ var(arg) ])
xitem(tt(cd) [ tt(-sLP) ] var(old) var(new))
item(tt(cd) [ tt(-sLP) ] {tt(PLUS())|tt(-)}var(n))(
xitem(tt(cd) [ tt(-qsLP) ] [ var(arg) ])
xitem(tt(cd) [ tt(-qsLP) ] var(old) var(new))
item(tt(cd) [ tt(-qsLP) ] {tt(PLUS())|tt(-)}var(n))(
Change the current directory. In the first form, change the
current directory to var(arg), or to the value of tt($HOME) if
var(arg) is not specified. If var(arg) is `tt(-)', change to the
value of tt($OLDPWD), the previous directory.
Otherwise, if var(arg) begins with a slash, attempt to change to the
director given by var(arg).
directory given by var(arg).
If var(arg) does not begin with a slash, the behaviour depends on whether
the current directory `tt(.)' occurs in the list of directories contained
@ -189,11 +189,17 @@ An argument of the form `tt(-)var(n)' counts from the right.
If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())'
and `tt(-)' in this context are swapped.
If the tt(-q) (quiet) option is specified, the hook function tt(chpwd)
and the functions in the array tt(chpwd_functions) are not called.
This is useful for calls to tt(cd) that do not change the environment
seen by an interactive user.
If the tt(-s) option is specified, tt(cd) refuses to change the current
directory if the given pathname contains symlinks. If the tt(-P) option
is given or the tt(CHASE_LINKS) option is set, symbolic links are resolved
to their true values. If the tt(-L) option is given symbolic links are
followed regardless of the state of the tt(CHASE_LINKS) option.
retained in the directory (and not resolved) regardless of the state of
the tt(CHASE_LINKS) option.
)
alias(chdir)(cd)
module(clone)(zsh/clone)
@ -795,7 +801,7 @@ Same as tt(exit), except that it only works in a login shell.
)
prefix(noglob)
findex(popd)
item(tt(popd) [ {tt(PLUS())|tt(-)}var(n) ])(
item(tt(popd) [ [-q] {tt(PLUS())|tt(-)}var(n) ])(
Remove an entry from the directory stack, and perform a tt(cd) to
the new top directory. With no argument, the current top entry is
removed. An argument of the form `tt(PLUS())var(n)' identifies a stack
@ -804,6 +810,11 @@ starting with zero. An argument of the form tt(-n) counts from the right.
pindex(PUSHD_MINUS, use of)
If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())' and
`tt(-)' in this context are swapped.
If the tt(-q) (quiet) option is specified, the hook function tt(chpwd)
and the functions in the array tt($chpwd_functions) are not called,
and the new directory stack is not printed. This is useful for calls to
tt(popd) that do not change the environment seen by an interactive user.
)
findex(print)
xitem(tt(print) [ tt(-abcDilmnNoOpPrsz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ])
@ -935,9 +946,9 @@ pindex(PUSHD_TO_HOME, use of)
pindex(PUSHD_MINUS, use of)
pindex(CDABLE_VARS, use of)
pindex(PUSHD_SILENT, use of)
xitem(tt(pushd) [ tt(-sLP) ] [ var(arg) ])
xitem(tt(pushd) [ tt(-sLP) ] var(old) var(new))
item(tt(pushd) [ tt(-sLP) ] {tt(PLUS())|tt(-)}var(n))(
xitem(tt(pushd) [ tt(-qsLP) ] [ var(arg) ])
xitem(tt(pushd) [ tt(-qsLP) ] var(old) var(new))
item(tt(pushd) [ tt(-qsLP) ] {tt(PLUS())|tt(-)}var(n))(
Change the current directory, and push the old current directory
onto the directory stack. In the first form, change the
current directory to var(arg).
@ -956,8 +967,14 @@ command, starting with zero. An argument of the form `tt(-)var(n)' counts
from the right. If the tt(PUSHD_MINUS) option is set, the meanings
of `tt(PLUS())' and `tt(-)' in this context are swapped.
If the option tt(PUSHD_SILENT) is not set, the directory
stack will be printed after a tt(pushd) is performed.
If the tt(-q) (quiet) option is specified, the hook function tt(chpwd)
and the functions in the array tt($chpwd_functions) are not called,
and the new directory stack is not printed. This is useful for calls to
tt(pushd) that do not change the environment seen by an interactive user.
If the option tt(-q) is not specified and the shell option tt(PUSHD_SILENT)
is not set, the directory stack will be printed after a tt(pushd) is
performed.
The options tt(-s), tt(-L) and tt(-P) have the same meanings as for the
tt(cd) builtin.

19
Etc/relnotes_4.3.6.txt Normal file
View file

@ -0,0 +1,19 @@
Version 4.3.6 contains mostly bugfixes, but there are some small
improvements. No incompatibilities with previous versions are known.
Visible changes in the shell and its modules since 4.3.5 include the
following:
The parameter subscripting flag "e", which existed but had limited
usefulness, has been extended to allow reverse matching of strings instead
of patterns. For example, "${array[(ie)*]}" substitutes the index of the
array element that contains the exact string "*". In previous versions of
the shell a fairly hairy process was necessary to ensure pattern characters
were quoted.
The cd, chdir, pushd and popd builtins now take the option -q (quiet) which
avoids side effects when changing directories, suppressing the effect of
the chpwd function, the chpwd_functions array and printing of the directory
stack. The last was already possible with the option PUSHD_SILENT, but in
previous versions of the shell there was no easy way of suppressing the
other side effects.

View file

@ -50,8 +50,8 @@ static struct builtin builtins[] =
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "sPL", NULL),
BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "sPL", NULL),
BUILTIN("cd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
BUILTIN("chdir", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_CD, "qsPL", NULL),
BUILTIN("continue", BINF_PSPECIAL, bin_break, 0, 1, BIN_CONTINUE, NULL, NULL),
BUILTIN("declare", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klmprtuxz", NULL),
BUILTIN("dirs", 0, bin_dirs, 0, -1, 0, "clpv", NULL),
@ -98,10 +98,10 @@ static struct builtin builtins[] =
BUILTIN("patdebug", 0, bin_patdebug, 1, -1, 0, "p", NULL),
#endif
BUILTIN("popd", 0, bin_cd, 0, 1, BIN_POPD, NULL, NULL),
BUILTIN("popd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 1, BIN_POPD, "q", NULL),
BUILTIN("print", BINF_PRINTOPTS, bin_print, 0, -1, BIN_PRINT, "abcC:Df:ilmnNoOpPrRsu:z-", NULL),
BUILTIN("printf", 0, bin_print, 1, -1, BIN_PRINTF, NULL, NULL),
BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "sPL", NULL),
BUILTIN("pushd", BINF_SKIPINVALID | BINF_SKIPDASH | BINF_DASHDASHVALID, bin_cd, 0, 2, BIN_PUSHD, "qsPL", NULL),
BUILTIN("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", NULL),
@ -788,7 +788,7 @@ bin_cd(char *nam, char **argv, Options ops, int func)
unqueue_signals();
return 1;
}
cd_new_pwd(func, dir);
cd_new_pwd(func, dir, OPT_ISSET(ops, 'q'));
if (stat(unmeta(pwd), &st1) < 0) {
setjobpwd();
@ -1087,7 +1087,7 @@ cd_try_chdir(char *pfix, char *dest, int hard)
/**/
static void
cd_new_pwd(int func, LinkNode dir)
cd_new_pwd(int func, LinkNode dir, int quiet)
{
char *new_pwd, *s;
int dirstacksize;
@ -1127,7 +1127,7 @@ cd_new_pwd(int func, LinkNode dir)
if (isset(INTERACTIVE)) {
if (func != BIN_CD) {
if (unset(PUSHDSILENT))
if (unset(PUSHDSILENT) && !quiet)
printdirstack();
} else if (doprintdir) {
fprintdir(pwd, stdout);
@ -1138,7 +1138,8 @@ cd_new_pwd(int func, LinkNode dir)
/* execute the chpwd function */
fflush(stdout);
fflush(stderr);
callhookfunc("chpwd", NULL, 1);
if (!quiet)
callhookfunc("chpwd", NULL, 1);
dirstacksize = getiparam("DIRSTACKSIZE");
/* handle directory stack sizes out of range */