* Directory completion acts as if CHASE_LINKS is set @ 2013-09-05 1:23 Jan Larres 2013-09-05 2:15 ` Jan Larres 2013-09-05 15:31 ` Bart Schaefer 0 siblings, 2 replies; 13+ messages in thread From: Jan Larres @ 2013-09-05 1:23 UTC (permalink / raw) To: zsh-workers Hi, I recently noticed that completion of directories acts as if the CHASE_LINKS option is set, that is if you are in a symlinked directory and you want to complete its siblings then it will complete using the physical siblings instead of the ones from the directory that the symlink resides in. Here's an example. Note that neither CHASE_LINKS nor CHASE_DOTS is set. $ zsh --version zsh 5.0.2 (x86_64-pc-linux-gnu) $ zsh -f vanadis% tree -F . ├── bar/ └── foo/ ├── bar -> ../bar/ └── baz/ 4 directories, 0 files vanadis% cd foo/bar vanadis% cd ../[TAB] bar/ foo/ Jan ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-05 1:23 Directory completion acts as if CHASE_LINKS is set Jan Larres @ 2013-09-05 2:15 ` Jan Larres 2013-09-05 15:31 ` Bart Schaefer 1 sibling, 0 replies; 13+ messages in thread From: Jan Larres @ 2013-09-05 2:15 UTC (permalink / raw) To: zsh-workers On 05/09/13 13:23, Jan Larres wrote: > I recently noticed that completion of directories acts as if the > CHASE_LINKS option is set, that is if you are in a symlinked directory > and you want to complete its siblings then it will complete using the > physical siblings instead of the ones from the directory that the > symlink resides in. Quick clarification: this doesn't just apply to directories, any file completion that tries to complete siblings of a symlinked directory is affected. Jan ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-05 1:23 Directory completion acts as if CHASE_LINKS is set Jan Larres 2013-09-05 2:15 ` Jan Larres @ 2013-09-05 15:31 ` Bart Schaefer 2013-09-06 1:42 ` Jan Larres 2013-09-06 20:09 ` Peter Stephenson 1 sibling, 2 replies; 13+ messages in thread From: Bart Schaefer @ 2013-09-05 15:31 UTC (permalink / raw) To: zsh-workers On Sep 5, 1:23pm, Jan Larres wrote: } } I recently noticed that completion of directories acts as if the } CHASE_LINKS option is set, that is if you are in a symlinked directory } and you want to complete its siblings then it will complete using the } physical siblings instead of the ones from the directory that the } symlink resides in. "cd" itself is smart enough to interpret "../foo" as a physical path when using it as a symbolic path does not work, so the completion list in this example is incomplete rather than incorrect, which is probably why no one has ever noticed. In any case, this is a problem inherent in the way globbing interprets "../" -- filename generation does not obey the same rules as "cd" path resolution. torch% print ../*(/) ../bar ../foo torch% print $PWD:h/*(/) /tmp/cdtest/foo/baz Completion uses globbing to generate the target file names, so this has to be fixed up somehow in _cd before _path_files is called. This patch is a step in the right direction, but has the side-effect of expanding ".." into $PWD:h which is probably not desirable. There may be other nuances [particularly with completion in the middle of a word] that are not handled. So I'm not going to commit it, just presenting it for purposes of discussion. diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 476947f..9c82a2f 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -51,6 +51,14 @@ else _directory_stack && ret=0 fi + if [[ $PREFIX = (|*/)..(|/*) ]]; then + local tmpprefix + # Use cd in a subshell to properly [not] resolve symlinks + tmpprefix=$(cd $PREFIX >&/dev/null && print $PWD) || + tmpprefix=$(cd $PREFIX:h >&/dev/null && print $PWD/$PREFIX:t) + [[ -n $tmpprefix ]] && PREFIX=$tmpprefix + fi + if [[ $PREFIX != (\~|/|./|../)* ]]; then local tmpcdpath alt -- Barton E. Schaefer ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-05 15:31 ` Bart Schaefer @ 2013-09-06 1:42 ` Jan Larres 2013-09-06 6:13 ` Bart Schaefer 2013-09-06 20:09 ` Peter Stephenson 1 sibling, 1 reply; 13+ messages in thread From: Jan Larres @ 2013-09-06 1:42 UTC (permalink / raw) To: zsh-workers On 06/09/13 03:31, Bart Schaefer wrote: > In any case, this is a problem inherent in the way globbing interprets > "../" -- filename generation does not obey the same rules as "cd" path > resolution. > > torch% print ../*(/) > ../bar ../foo > torch% print $PWD:h/*(/) > /tmp/cdtest/foo/baz > > Completion uses globbing to generate the target file names, so this has > to be fixed up somehow in _cd before _path_files is called. > > This patch is a step in the right direction, but has the side-effect of > expanding ".." into $PWD:h which is probably not desirable. There may > be other nuances [particularly with completion in the middle of a word] > that are not handled. So I'm not going to commit it, just presenting it > for purposes of discussion. Thanks, that patch does solve the issue with cd to a certain degree. But as you said yourself it is not specific to cd – for example, 'ls ../[TAB]' has the same problem. So I assume that patching the individual command completions is not the best way to go about it, but I'm not familiar enough with the zsh internals to know what the right way would be. Jan ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-06 1:42 ` Jan Larres @ 2013-09-06 6:13 ` Bart Schaefer 2013-09-06 6:46 ` Jan Larres 0 siblings, 1 reply; 13+ messages in thread From: Bart Schaefer @ 2013-09-06 6:13 UTC (permalink / raw) To: zsh-workers On Sep 6, 1:42pm, Jan Larres wrote: } Subject: Re: Directory completion acts as if CHASE_LINKS is set } } On 06/09/13 03:31, Bart Schaefer wrote: } > In any case, this is a problem inherent in the way globbing interprets } > "../" -- filename generation does not obey the same rules as "cd" path } > resolution. } } Thanks, that patch does solve the issue with cd to a certain degree. But } as you said yourself it is not specific to cd - for example, 'ls ../[TAB]' } has the same problem. No, you misunderstand. It actually *is* specific to cd -- ls is an external command and will physically follow ../, so it is correct for completion for ls to do so as well. Only in shell builtins can ../ refer to $PWD:h/, and the only builtins that have this behavior are cd and pushd. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-06 6:13 ` Bart Schaefer @ 2013-09-06 6:46 ` Jan Larres 0 siblings, 0 replies; 13+ messages in thread From: Jan Larres @ 2013-09-06 6:46 UTC (permalink / raw) To: zsh-workers On 06/09/13 18:13, Bart Schaefer wrote: > On Sep 6, 1:42pm, Jan Larres wrote: > } Subject: Re: Directory completion acts as if CHASE_LINKS is set > } > } On 06/09/13 03:31, Bart Schaefer wrote: > } > In any case, this is a problem inherent in the way globbing interprets > } > "../" -- filename generation does not obey the same rules as "cd" path > } > resolution. > } > } Thanks, that patch does solve the issue with cd to a certain degree. But > } as you said yourself it is not specific to cd - for example, 'ls ../[TAB]' > } has the same problem. > > No, you misunderstand. It actually *is* specific to cd -- ls is an > external command and will physically follow ../, so it is correct for > completion for ls to do so as well. Huh, you're right. I never noticed that. That's rather counterintuitive. Then I guess cd completion really is the only thing that can be changed. Thanks for clarifying! ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-05 15:31 ` Bart Schaefer 2013-09-06 1:42 ` Jan Larres @ 2013-09-06 20:09 ` Peter Stephenson 2013-09-07 5:03 ` Bart Schaefer 1 sibling, 1 reply; 13+ messages in thread From: Peter Stephenson @ 2013-09-06 20:09 UTC (permalink / raw) To: zsh-workers On Thu, 05 Sep 2013 08:31:39 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd > index 476947f..9c82a2f 100644 > --- a/Completion/Zsh/Command/_cd > +++ b/Completion/Zsh/Command/_cd > @@ -51,6 +51,14 @@ else > _directory_stack && ret=0 > fi > > + if [[ $PREFIX = (|*/)..(|/*) ]]; then > + local tmpprefix > + # Use cd in a subshell to properly [not] resolve symlinks > + tmpprefix=$(cd $PREFIX >&/dev/null && print $PWD) || > + tmpprefix=$(cd $PREFIX:h >&/dev/null && print $PWD/$PREFIX:t) > + [[ -n $tmpprefix ]] && PREFIX=$tmpprefix > + fi > + > if [[ $PREFIX != (\~|/|./|../)* ]]; then > local tmpcdpath alt You're probably going to be better off using ${PREFIX:a} rather than cd. I also wonder if it would be better only to look at previous directory components, i.e. always take the PREFIX up to the last "/" (and require that there be one) rather than have two cases. I doubt there's much you can do better if you're completing in the middle of the word. If COMPLETEINWORD is not set, so you're sensitive to $SUFFIX, you might use $PREFIX$SUFFIX, but apart from that $PREFIX looks like the only interesting bit for path resolution. This is rather specialised. -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-06 20:09 ` Peter Stephenson @ 2013-09-07 5:03 ` Bart Schaefer 2013-09-08 17:51 ` Peter Stephenson 0 siblings, 1 reply; 13+ messages in thread From: Bart Schaefer @ 2013-09-07 5:03 UTC (permalink / raw) To: zsh-workers On Sep 6, 9:09pm, Peter Stephenson wrote: } Subject: Re: Directory completion acts as if CHASE_LINKS is set } } On Thu, 05 Sep 2013 08:31:39 -0700 } Bart Schaefer <schaefer@brasslantern.com> wrote: } > + # Use cd in a subshell to properly [not] resolve symlinks } > + tmpprefix=$(cd $PREFIX >&/dev/null && print $PWD) || } > + tmpprefix=$(cd $PREFIX:h >&/dev/null && print $PWD/$PREFIX:t) } } You're probably going to be better off using ${PREFIX:a} rather than } cd. No, sorry, that doesn't work; :a behaves like globbing and CHASE_DOTS: torch% print $PWD /tmp/cdtest/foo/bar torch% x=.. torch% print $x:a /tmp/cdtest As far as I can tell the only way to get symlinks resolved the way that "cd" does with respect to whatever CHASE options are currently set, is to actually perform the "cd". } I also wonder if it would be better only to look at previous } directory components, i.e. always take the PREFIX up to the last "/" } (and require that there be one) rather than have two cases. You'll have to actually write out what you mean here, because I can't get it to work for e.g. "cd ../" without having the first case there. } I doubt there's much you can do better if you're completing in the } middle of the word. Indeed. Also things may be a bit strange when a cdablevar is at the front of the path, with a /../ somewhere beyond it. Any suggestions for how to avoid having "../" expand into $PWD:h/ on the command line? I tried fiddling with IPREFIX the way the cdablevars branch does, but without success. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-07 5:03 ` Bart Schaefer @ 2013-09-08 17:51 ` Peter Stephenson 2013-09-08 21:26 ` Bart Schaefer 0 siblings, 1 reply; 13+ messages in thread From: Peter Stephenson @ 2013-09-08 17:51 UTC (permalink / raw) To: zsh-workers On Fri, 06 Sep 2013 22:03:00 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > On Sep 6, 9:09pm, Peter Stephenson wrote: > } Subject: Re: Directory completion acts as if CHASE_LINKS is set > } > } On Thu, 05 Sep 2013 08:31:39 -0700 > } Bart Schaefer <schaefer@brasslantern.com> wrote: > } > + # Use cd in a subshell to properly [not] resolve symlinks > } > + tmpprefix=$(cd $PREFIX >&/dev/null && print $PWD) || > } > + tmpprefix=$(cd $PREFIX:h >&/dev/null && print $PWD/$PREFIX:t) > > } I also wonder if it would be better only to look at previous > } directory components, i.e. always take the PREFIX up to the last "/" > } (and require that there be one) rather than have two cases. > > You'll have to actually write out what you mean here, because I can't > get it to work for e.g. "cd ../" without having the first case there. I'm thinking of something like ${PREFIX%/*}. pws ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-08 17:51 ` Peter Stephenson @ 2013-09-08 21:26 ` Bart Schaefer 2013-09-09 9:59 ` Peter Stephenson 2013-09-10 14:26 ` Bart Schaefer 0 siblings, 2 replies; 13+ messages in thread From: Bart Schaefer @ 2013-09-08 21:26 UTC (permalink / raw) To: zsh-workers On Sep 6, 10:03pm, Bart Schaefer wrote: > > On Sep 6, 9:09pm, Peter Stephenson wrote: > } > } You're probably going to be better off using ${PREFIX:a} rather than > } cd. > > No, sorry, that doesn't work; :a behaves like globbing and CHASE_DOTS: > > torch% print $PWD > /tmp/cdtest/foo/bar > torch% x=.. > torch% print $x:a > /tmp/cdtest Hmm, I just noticed that :a does work like "cd" IF there is a path prefix, that is, if "../" is not at the beginning of the value: torch% x=$PWD/.. torch% print $x $x:a /tmp/cdtest/foo/bar/.. /tmp/cdtest/foo So it might be possible to use :a, but it'd need a condition on the form of $PREFIX. However, the other bit that is simplified by doing a real "cd" in a subshell is that cdablevars et al. are taken care of. I suppose you could argue "that's cheating, it's important to avoid the fork" ... but I've spent enough time on this as it is, someone else can take over from here. On Sep 8, 6:51pm, Peter Stephenson wrote: } Subject: Re: Directory completion acts as if CHASE_LINKS is set } } > } I also wonder if it would be better only to look at previous } > } directory components, i.e. always take the PREFIX up to the last "/" } } I'm thinking of something like ${PREFIX%/*}. Ah, I see. Yes, that does work, and furthermore gave me the clue that I needed to get the commmand line handling right. Remaining question is whether to use ${IPREFIX}${PREFIX%/*}. I did in the assignment but not in the $(cd ...) as I can't think of a case for cd where IPREFIX would have a useful value. diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 476947f..5b581e7 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -51,6 +51,18 @@ else _directory_stack && ret=0 fi + local -a tmpWpath + if [[ $PREFIX = (|*/)../* ]]; then + local tmpprefix + # Use cd in a subshell to properly [not] resolve symlinks + tmpprefix=$(cd ${PREFIX%/*} >&/dev/null && print $PWD) + if [[ -n $tmpprefix ]]; then + tmpWpath=(-W $tmpprefix) + IPREFIX=${IPREFIX}${PREFIX%/*}/ + PREFIX=${PREFIX##*/} + fi + fi + if [[ $PREFIX != (\~|/|./|../)* ]]; then local tmpcdpath alt @@ -100,7 +112,7 @@ else return ret fi [[ CURRENT -ne 1 ]] && _wanted directories expl directory \ - _path_files -/ && ret=0 + _path_files $tmpWpath -/ && ret=0 return ret fi ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-08 21:26 ` Bart Schaefer @ 2013-09-09 9:59 ` Peter Stephenson 2013-09-10 14:26 ` Bart Schaefer 1 sibling, 0 replies; 13+ messages in thread From: Peter Stephenson @ 2013-09-09 9:59 UTC (permalink / raw) To: zsh-workers On Sun, 08 Sep 2013 14:26:28 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > Remaining question is whether to use ${IPREFIX}${PREFIX%/*}. I did in > the assignment but not in the $(cd ...) as I can't think of a case for > cd where IPREFIX would have a useful value. Doesn't seem to make a material difference that I can think of right now. pws ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-08 21:26 ` Bart Schaefer 2013-09-09 9:59 ` Peter Stephenson @ 2013-09-10 14:26 ` Bart Schaefer 2013-09-10 22:34 ` Jan Larres 1 sibling, 1 reply; 13+ messages in thread From: Bart Schaefer @ 2013-09-10 14:26 UTC (permalink / raw) To: zsh-workers On Sep 8, 2:26pm, Bart Schaefer wrote: } } Ah, I see. Yes, that does work, and furthermore gave me the clue that I } needed to get the commmand line handling right. Discovered I needed a reference to $tmpWpath in one more place. Here is the final diff ... unless we find out I messed up about IPREFIX. 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=0 fi + local -a tmpWpath + if [[ $PREFIX = (|*/)../* ]]; then + local tmpprefix + # Use cd in a subshell to properly [not] resolve symlinks + tmpprefix=$(cd ${PREFIX%/*} >&/dev/null && print $PWD) + if [[ -n $tmpprefix ]]; then + tmpWpath=(-W $tmpprefix) + IPREFIX=${IPREFIX}${PREFIX%/*}/ + PREFIX=${PREFIX##*/} + fi + fi + if [[ $PREFIX != (\~|/|./|../)* ]]; then local tmpcdpath alt @@ -88,7 +100,7 @@ else # already handled by _command_names (see _autocd) [[ CURRENT -ne 1 || ( -z "$path[(r).]" && $PREFIX != */* ) ]] && - alt=( "${cdpath+local-}directories:${cdpath+local }directory:_path_files -/" "$alt[@]" ) + alt=( "${cdpath+local-}directories:${cdpath+local }directory:_path_files $tmpWpath -/" "$alt[@]" ) if [[ CURRENT -eq argstart && noopts -eq 0 && $PREFIX = -* ]] && zstyle -t ":completion:${curcontext}:options" complete-options; then @@ -100,7 +112,7 @@ else return ret fi [[ CURRENT -ne 1 ]] && _wanted directories expl directory \ - _path_files -/ && ret=0 + _path_files $tmpWpath -/ && ret=0 return ret fi ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Directory completion acts as if CHASE_LINKS is set 2013-09-10 14:26 ` Bart Schaefer @ 2013-09-10 22:34 ` Jan Larres 0 siblings, 0 replies; 13+ messages in thread From: Jan Larres @ 2013-09-10 22:34 UTC (permalink / raw) To: zsh-workers On 11/09/13 02:26, Bart Schaefer wrote: > Discovered I needed a reference to $tmpWpath in one more place. Here is > the final diff ... unless we find out I messed up about IPREFIX. The patch seems to work fine for me, thanks! Jan ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-09-10 22:34 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2013-09-05 1:23 Directory completion acts as if CHASE_LINKS is set Jan Larres 2013-09-05 2:15 ` Jan Larres 2013-09-05 15:31 ` Bart Schaefer 2013-09-06 1:42 ` Jan Larres 2013-09-06 6:13 ` Bart Schaefer 2013-09-06 6:46 ` Jan Larres 2013-09-06 20:09 ` Peter Stephenson 2013-09-07 5:03 ` Bart Schaefer 2013-09-08 17:51 ` Peter Stephenson 2013-09-08 21:26 ` Bart Schaefer 2013-09-09 9:59 ` Peter Stephenson 2013-09-10 14:26 ` Bart Schaefer 2013-09-10 22:34 ` Jan Larres
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).