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

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



Le Thu, 27 Mar 2008 18:45:02 +0000,
Peter Stephenson <pws@xxxxxxx> a écrit :

> 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 */
> 

Hi,

Builds and works fine on OpenBSD.
umount [TAB] works correctly.

Regards,


-- 
Pierre-Emmanuel André <pea at raveland.org>
GPG key: 0x7AE329DC



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