Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: cd -q (was Re: _canonical_path ...)



On Thu, 27 Mar 2008 12:15:25 +0000
Peter Stephenson <pws@xxxxxxx> 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 */



Messages sorted by: Reverse Date, Date, Thread, Author