1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-26 16:40:29 +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> 2008-03-27 Peter Stephenson <pws@csr.com>
* 24759: Completion/Unix/Type/_canonical_paths: unfunction * 24759: Completion/Unix/Type/_canonical_paths: unfunction

View file

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

View file

@ -152,16 +152,16 @@ alias(bye)(exit)
module(cap)(zsh/cap) module(cap)(zsh/cap)
findex(cd) findex(cd)
cindex(directories, changing) cindex(directories, changing)
xitem(tt(cd) [ tt(-sLP) ] [ var(arg) ]) xitem(tt(cd) [ tt(-qsLP) ] [ var(arg) ])
xitem(tt(cd) [ tt(-sLP) ] var(old) var(new)) xitem(tt(cd) [ tt(-qsLP) ] var(old) var(new))
item(tt(cd) [ tt(-sLP) ] {tt(PLUS())|tt(-)}var(n))( item(tt(cd) [ tt(-qsLP) ] {tt(PLUS())|tt(-)}var(n))(
Change the current directory. In the first form, change the Change the current directory. In the first form, change the
current directory to var(arg), or to the value of tt($HOME) if 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 var(arg) is not specified. If var(arg) is `tt(-)', change to the
value of tt($OLDPWD), the previous directory. value of tt($OLDPWD), the previous directory.
Otherwise, if var(arg) begins with a slash, attempt to change to the 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 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 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())' If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())'
and `tt(-)' in this context are swapped. 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 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 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 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 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) alias(chdir)(cd)
module(clone)(zsh/clone) module(clone)(zsh/clone)
@ -795,7 +801,7 @@ Same as tt(exit), except that it only works in a login shell.
) )
prefix(noglob) prefix(noglob)
findex(popd) 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 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 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 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) pindex(PUSHD_MINUS, use of)
If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())' and If the tt(PUSHD_MINUS) option is set, the meanings of `tt(PLUS())' and
`tt(-)' in this context are swapped. `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) findex(print)
xitem(tt(print) [ tt(-abcDilmnNoOpPrsz) ] [ tt(-u) var(n) ] [ tt(-f) var(format) ] [ tt(-C) var(cols) ]) 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(PUSHD_MINUS, use of)
pindex(CDABLE_VARS, use of) pindex(CDABLE_VARS, use of)
pindex(PUSHD_SILENT, use of) pindex(PUSHD_SILENT, use of)
xitem(tt(pushd) [ tt(-sLP) ] [ var(arg) ]) xitem(tt(pushd) [ tt(-qsLP) ] [ var(arg) ])
xitem(tt(pushd) [ tt(-sLP) ] var(old) var(new)) xitem(tt(pushd) [ tt(-qsLP) ] var(old) var(new))
item(tt(pushd) [ tt(-sLP) ] {tt(PLUS())|tt(-)}var(n))( item(tt(pushd) [ tt(-qsLP) ] {tt(PLUS())|tt(-)}var(n))(
Change the current directory, and push the old current directory Change the current directory, and push the old current directory
onto the directory stack. In the first form, change the onto the directory stack. In the first form, change the
current directory to var(arg). 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 from the right. If the tt(PUSHD_MINUS) option is set, the meanings
of `tt(PLUS())' and `tt(-)' in this context are swapped. of `tt(PLUS())' and `tt(-)' in this context are swapped.
If the option tt(PUSHD_SILENT) is not set, the directory If the tt(-q) (quiet) option is specified, the hook function tt(chpwd)
stack will be printed after a tt(pushd) is performed. 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 The options tt(-s), tt(-L) and tt(-P) have the same meanings as for the
tt(cd) builtin. 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("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, 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("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("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, "sPL", 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("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("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), 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), BUILTIN("patdebug", 0, bin_patdebug, 1, -1, 0, "p", NULL),
#endif #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("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("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("pushln", 0, bin_print, 0, -1, BIN_PRINT, NULL, "-nz"),
BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL), BUILTIN("pwd", 0, bin_pwd, 0, 0, 0, "rLP", NULL),
BUILTIN("r", 0, bin_fc, 0, -1, BIN_R, "nrl", 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(); unqueue_signals();
return 1; return 1;
} }
cd_new_pwd(func, dir); cd_new_pwd(func, dir, OPT_ISSET(ops, 'q'));
if (stat(unmeta(pwd), &st1) < 0) { if (stat(unmeta(pwd), &st1) < 0) {
setjobpwd(); setjobpwd();
@ -1087,7 +1087,7 @@ cd_try_chdir(char *pfix, char *dest, int hard)
/**/ /**/
static void static void
cd_new_pwd(int func, LinkNode dir) cd_new_pwd(int func, LinkNode dir, int quiet)
{ {
char *new_pwd, *s; char *new_pwd, *s;
int dirstacksize; int dirstacksize;
@ -1127,7 +1127,7 @@ cd_new_pwd(int func, LinkNode dir)
if (isset(INTERACTIVE)) { if (isset(INTERACTIVE)) {
if (func != BIN_CD) { if (func != BIN_CD) {
if (unset(PUSHDSILENT)) if (unset(PUSHDSILENT) && !quiet)
printdirstack(); printdirstack();
} else if (doprintdir) { } else if (doprintdir) {
fprintdir(pwd, stdout); fprintdir(pwd, stdout);
@ -1138,7 +1138,8 @@ cd_new_pwd(int func, LinkNode dir)
/* execute the chpwd function */ /* execute the chpwd function */
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
callhookfunc("chpwd", NULL, 1); if (!quiet)
callhookfunc("chpwd", NULL, 1);
dirstacksize = getiparam("DIRSTACKSIZE"); dirstacksize = getiparam("DIRSTACKSIZE");
/* handle directory stack sizes out of range */ /* handle directory stack sizes out of range */