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:
parent
42ddb45fe8
commit
50d9cdeae4
5 changed files with 93 additions and 46 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
19
Etc/relnotes_4.3.6.txt
Normal 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.
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue