From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17133 invoked by alias); 15 Apr 2014 16:07:30 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32546 Received: (qmail 24469 invoked from network); 15 Apr 2014 16:07:15 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-Biglobe-Sender: From: "Jun T." Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: ignore-parents style broken for cd Message-Id: <736C1D9E-722A-425E-9F23-C9786BCB5C72@kba.biglobe.ne.jp> Date: Wed, 16 Apr 2014 01:06:03 +0900 To: zsh-workers@zsh.org Mime-Version: 1.0 (Mac OS X Mail 7.2 \(1874\)) X-Mailer: Apple Mail (2.1874) X-Biglobe-Spnum: 63378 The ignore-parents style doesn't work for the cd command: $ zstyle ':completion:*' ignore-parents pwd parent $ mkdir junk junk/foo junk/bar $ cd junk/foo $ ls ../ # only 'bar' is offered; OK $ cd ../ # both 'foo' and 'bar' are offered This happens after the following commit: commit 012668e14ec7305c404975da8c5ba648c1586a82 Author: Barton E. Schaefer Date: Tue Sep 10 08:14:37 2013 -0700 31714: handle ".." properly when $PWD or the path prefix traverses a = symbolic link. diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 476947f..a5d328f 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -51,6 +51,18 @@ else _directory_stack && ret=3D0 fi =20 + local -a tmpWpath + if [[ $PREFIX =3D (|*/)../* ]]; then + local tmpprefix + # Use cd in a subshell to properly [not] resolve symlinks + tmpprefix=3D$(cd ${PREFIX%/*} >&/dev/null && print $PWD) (snip) But the actual problem may be not in _cd but in either _path_files or compadd (or 'compfiles -i' ?). _path_files calls compadd in a way something like the following: _comp_ignore=3D( /path/to/junk/foo ) words=3D( foo bar ) compadd -f -F _comp_ignore -W /path/to/junk/ -a words but compadd does not remove 'foo' from the words. It seems we need to set _comp_ignore=3D( foo ) instead. Is this the expected behavior of compadd? If so, then _path_files may need some fix? The patch below is my try, but I don't (and will never) understand any details of _path_files. P.S. I also didn't understand the logic at line 569: (( $#_comp_ignore && $mopts[(I)-F] )) || and modified it as below. diff --git a/Completion/Unix/Type/_path_files = b/Completion/Unix/Type/_path_files index aa58ea0..85feae5 100644 --- a/Completion/Unix/Type/_path_files +++ b/Completion/Unix/Type/_path_files @@ -564,9 +564,10 @@ for prepath in "$prepaths[@]"; do ( "$ignpar" !=3D *dir* || "$pats" =3D '*(-/)' ) && ( "$ignpar" !=3D *..* || "$tmp1[1]" =3D *../* ) ]]; then =20 - compfiles -i tmp1 _comp_ignore "$ignpar" = "$prepath$realpath$donepath" + compfiles -i tmp1 ignore "$ignpar" "$prepath$realpath$donepath" + _comp_ignore+=3D( ${(@)ignore#$prepath$realpath$donepath} ) =20 - (( $#_comp_ignore && $mopts[(I)-F] )) || + (( $#_comp_ignore && ! $mopts[(I)-F] )) && mopts=3D( "$mopts[@]" -F _comp_ignore ) fi =20