From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29817 invoked from network); 27 Mar 2008 18:45:47 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00 autolearn=ham version=3.2.4 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 27 Mar 2008 18:45:47 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 97089 invoked from network); 27 Mar 2008 18:45:44 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 27 Mar 2008 18:45:44 -0000 Received: (qmail 3052 invoked by alias); 27 Mar 2008 18:45:41 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 24768 Received: (qmail 3038 invoked from network); 27 Mar 2008 18:45:41 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 27 Mar 2008 18:45:41 -0000 Received: from cluster-g.mailcontrol.com (cluster-g.mailcontrol.com [85.115.41.190]) by bifrost.dotsrc.org (Postfix) with ESMTP id D797682CD267 for ; Thu, 27 Mar 2008 19:45:33 +0100 (CET) Received: from cameurexb01.EUROPE.ROOT.PRI ([62.189.241.200]) by rly01g.srv.mailcontrol.com (MailControl) with ESMTP id m2RIjHRt013682 for ; Thu, 27 Mar 2008 18:45:26 GMT Received: from news01 ([10.103.143.38]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Thu, 27 Mar 2008 18:45:03 +0000 Date: Thu, 27 Mar 2008 18:45:02 +0000 From: Peter Stephenson To: zsh-workers@sunsite.dk Subject: Re: PATCH: cd -q (was Re: _canonical_path ...) Message-ID: <20080327184502.09b2a535@news01> In-Reply-To: <20080327121525.5b4059f9@news01> References: <20080326114413.80713vrmznwpnyuc@bapt.selfip.org> <080326083638.ZM16858@torch.brasslantern.com> <200803261540.m2QFeJmm017381@news01.csr.com> <200803261604.m2QG41Ke017772@news01.csr.com> <200803261621.m2QGLptV017966@news01.csr.com> <20080326173824.0a55c00d@coredump.raveland.priv> <20080326164615.1d5893ed@news01> <20080327102325.55808716@news01> <20080327120807.415095ee@raveland.org> <20080327112506.7298e9ef@news01> <20080327121525.5b4059f9@news01> Organization: CSR X-Mailer: Claws Mail 3.3.1 (GTK+ 2.12.5; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 27 Mar 2008 18:45:03.0054 (UTC) FILETIME=[AAF1DEE0:01C8903A] X-Scanned-By: MailControl A-08-00-04 (www.mailcontrol.com) on 10.71.0.111 X-Virus-Scanned: ClamAV 0.91.2/6430/Thu Mar 27 18:39:43 2008 on bifrost X-Virus-Status: Clean On Thu, 27 Mar 2008 12:15:25 +0000 Peter Stephenson wrote: > Any comments about the following proposal, which adds the -q option > to all relevant functions? If it looks OK, I'll change the function > above to unsetopt PUSHD_NO_DUPS and use pushd -q/popd -q to sanitize > the directory with REPLY=$PWD and remove the fork. Here is what I'm likely to commit. It includes various related suggestions. It doesn't include a new style for the canonical stuff. Index: Completion/Unix/Type/_canonical_paths =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_canonical_paths,v retrieving revision 1.4 diff -u -r1.4 _canonical_paths --- Completion/Unix/Type/_canonical_paths 27 Mar 2008 11:29:20 -0000 1.4 +++ Completion/Unix/Type/_canonical_paths 27 Mar 2008 18:42:17 -0000 @@ -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 } Index: Doc/Zsh/builtins.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v retrieving revision 1.103 diff -u -r1.103 builtins.yo --- Doc/Zsh/builtins.yo 1 Feb 2008 19:59:45 -0000 1.103 +++ Doc/Zsh/builtins.yo 27 Mar 2008 18:42:17 -0000 @@ -152,16 +152,16 @@ 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 @@ 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 @@ ) 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 @@ 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_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 @@ 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. Index: Src/builtin.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.188 diff -u -r1.188 builtin.c --- Src/builtin.c 2 Mar 2008 21:21:53 -0000 1.188 +++ Src/builtin.c 27 Mar 2008 18:42:18 -0000 @@ -50,8 +50,8 @@ 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 @@ 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 @@ 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 @@ /**/ 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 @@ 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 @@ /* 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 */