* Recursive Completition @ 2012-08-18 21:09 Karoly Negyesi 2012-08-19 0:18 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Karoly Negyesi @ 2012-08-18 21:09 UTC (permalink / raw) To: zsh-users Hi, I am working with PHP and due to PSR-0 I really need recursive completition. I am switching to zsh because of this. ls **/Kernel.php[Tab] autocompletes to core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php that's really great! Even better would be if I could have ls **/Kern[tab] do that (and not just for ls, but everything else). Perfect would be just ls Kern[tab] to do that. I am aware of the performance implications -- could this be restricted to the user's home dir only so it doesnt try to read the whole OS when in the root. Oh, and maybe display the menu while I am writing a wishlist :) Thanks much Karoly Negyesi ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-18 21:09 Recursive Completition Karoly Negyesi @ 2012-08-19 0:18 ` Bart Schaefer 2012-08-19 19:44 ` Peter Stephenson 2012-08-20 9:43 ` René Neumann 0 siblings, 2 replies; 10+ messages in thread From: Bart Schaefer @ 2012-08-19 0:18 UTC (permalink / raw) To: zsh-users On Aug 18, 11:09pm, Karoly Negyesi wrote: } } ls **/Kernel.php[Tab] } } autocompletes to } } core/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Kernel.php } } that's really great! Glad you like it, but you should understand the difference between _completion_ and _expansion_ before going any further. What you've done right there is _expansion_ -- replace a glob pattern with the thing(s) it matches (expands to). This happens to be handled as part of the completion system if you've run "compinit" but it's really not quite the same thing, because it isn't applying any contextual clues to the pattern, it's just expanding it. Note that the default behavior is to try expansion first and complete only if that fails. } Even better would be if I could have } } ls **/Kern[tab] } } do that (and not just for ls, but everything else). Here the glob pattern doesn't match (because there's no file named "Kern" anywhere downstream), so it doesn't expand to anything. If you tried ls **/Kern*[tab] you'd get something (possibly many somethings). Fortunately there's a way to move this out of the realm of expansion and into that of completion; to whit, simply assert that you want completion to act as if it were using glob patterns: setopt globcomplete Now when you try ls **/Kern[tab] the completion system behaves as if you'd inserted a * just before [tab], and offers you the list of matching items as choices. It's not quite as intutive when encountering a possible branch part way down the **/ expansion -- you may be offered a set of directories as the alternatives with no obvious way to choose one of them and then go on with the same completion. This gets easier if you force menu-selection to occur. } Oh, and maybe display the menu while I am writing a wishlist :) That's all independently controlled by things like setopt automenu zstyle ':completion:*' menu 'yes=long' 'select=9' and so on. There's a bunch of stuff about this toward the end of section 6.5.2 http://zsh.sourceforge.net/Guide/zshguide06.html#l158 of the user guide. } Perfect would be just } } ls Kern[tab] } } to do that. I am aware of the performance implications -- could this } be restricted to the user's home dir only so it doesnt try to read the } whole OS when in the root. This one would require that you create a new widget or a new completion function to insert the implicit leading **/ in the right contexts. It's certainly do-able, but I'm going to leave it as an exercise for someone else, this time. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-19 0:18 ` Bart Schaefer @ 2012-08-19 19:44 ` Peter Stephenson 2012-08-19 21:07 ` Karoly Negyesi 2012-08-20 9:43 ` René Neumann 1 sibling, 1 reply; 10+ messages in thread From: Peter Stephenson @ 2012-08-19 19:44 UTC (permalink / raw) To: zsh-users On Sat, 18 Aug 2012 17:18:26 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > } Perfect would be just > } > } ls Kern[tab] > } > } to do that. I am aware of the performance implications -- could this > } be restricted to the user's home dir only so it doesnt try to read the > } whole OS when in the root. > > This one would require that you create a new widget or a new completion > function to insert the implicit leading **/ in the right contexts. It's > certainly do-able, but I'm going to leave it as an exercise for someone > else, this time. Bizarrely, I think I've got this to work as part of normal file completion, ish. No, honestly. Set the recursive-files style to true and see if this does the right thing. No documentation yet. It only works if there's no "/" in the word on the command line at the point completion is tried. I can't be sure this is the best place to put it in the file completion calling sequence, but that statement is so obvious as hardly to be worth mentioning... I wonder if there's some limit we can apply to stop this going haywire? Index: Completion/Unix/Type/_files =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_files,v retrieving revision 1.13 diff -p -u -r1.13 _files --- Completion/Unix/Type/_files 19 Mar 2010 16:38:26 -0000 1.13 +++ Completion/Unix/Type/_files 19 Aug 2012 19:40:55 -0000 @@ -1,7 +1,7 @@ #compdef -redirect-,-default-,-default- local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried -local type sdef ignvars ignvar +local type sdef ignvars ignvar prepath oprefix zparseopts -a opts \ '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+: @@ -118,7 +118,16 @@ for def in "$pats[@]"; do while _next_label "$tag" expl "$descr"; do _comp_ignore=( $_comp_ignore $ign ) if [[ -n "$end" ]]; then - _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 + if _path_files -g "$pat" "$opts[@]" "$expl[@]"; then + ret=0 + elif [[ $PREFIX$SUFFIX != */* ]] && zstyle -t ":completion:${curcontext}:" recursive-files; then + for prepath in **/*(/); do + oprefix=$PREFIX + PREFIX=$prepath/$PREFIX + _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 + PREFIX=$oprefix + done + fi else _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 fi -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-19 19:44 ` Peter Stephenson @ 2012-08-19 21:07 ` Karoly Negyesi 2012-08-20 8:57 ` Peter Stephenson 0 siblings, 1 reply; 10+ messages in thread From: Karoly Negyesi @ 2012-08-19 21:07 UTC (permalink / raw) To: Peter Stephenson; +Cc: zsh-users > I wonder if there's some limit we can apply to stop this going haywire? I only need it within a git repo -- maybe that. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-19 21:07 ` Karoly Negyesi @ 2012-08-20 8:57 ` Peter Stephenson 2012-08-20 15:33 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Peter Stephenson @ 2012-08-20 8:57 UTC (permalink / raw) To: zsh-users On Sun, 19 Aug 2012 23:07:50 +0200 Karoly Negyesi <karoly@negyesi.net> wrote: > > I wonder if there's some limit we can apply to stop this going haywire? > > I only need it within a git repo -- maybe that. One thing to do might be to change the style to be an array of patterns that are matched against the current directory and only use it in that case. So you could set it to "*/.git*". -- Peter Stephenson <pws@csr.com> Software Engineer Tel: +44 (0)1223 692070 Cambridge Silicon Radio Limited Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-20 8:57 ` Peter Stephenson @ 2012-08-20 15:33 ` Bart Schaefer 2012-08-21 18:27 ` Peter Stephenson 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 2012-08-20 15:33 UTC (permalink / raw) To: zsh-users On Aug 20, 9:57am, Peter Stephenson wrote: } } One thing to do might be to change the style to be an array of patterns } that are matched against the current directory and only use it in that } case. So you could set it to "*/.git*". That's more along the lines of what I was thinking. Match the pattern against the whole $PWD string, I presume. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-20 15:33 ` Bart Schaefer @ 2012-08-21 18:27 ` Peter Stephenson 2012-12-04 2:13 ` Karoly Negyesi 0 siblings, 1 reply; 10+ messages in thread From: Peter Stephenson @ 2012-08-21 18:27 UTC (permalink / raw) To: zsh-users Here's a second version with documentation. Index: Completion/Unix/Type/_files =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_files,v retrieving revision 1.13 diff -p -u -r1.13 _files --- Completion/Unix/Type/_files 19 Mar 2010 16:38:26 -0000 1.13 +++ Completion/Unix/Type/_files 21 Aug 2012 18:24:15 -0000 @@ -1,7 +1,7 @@ #compdef -redirect-,-default-,-default- local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried -local type sdef ignvars ignvar +local type sdef ignvars ignvar prepath oprefix rfiles rfile zparseopts -a opts \ '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+: @@ -118,7 +118,21 @@ for def in "$pats[@]"; do while _next_label "$tag" expl "$descr"; do _comp_ignore=( $_comp_ignore $ign ) if [[ -n "$end" ]]; then - _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 + if _path_files -g "$pat" "$opts[@]" "$expl[@]"; then + ret=0 + elif [[ $PREFIX$SUFFIX != */* ]] && zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles; then + for rfile in $rfiles; do + if [[ $PWD/ = ${~rfile} ]]; then + for prepath in **/*(/); do + oprefix=$PREFIX + PREFIX=$prepath/$PREFIX + _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 + PREFIX=$oprefix + done + break + fi + done + fi else _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 fi Index: Doc/Zsh/compsys.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v retrieving revision 1.247 diff -p -u -r1.247 compsys.yo --- Doc/Zsh/compsys.yo 14 Feb 2012 17:01:17 -0000 1.247 +++ Doc/Zsh/compsys.yo 21 Aug 2012 18:24:15 -0000 @@ -2355,6 +2355,28 @@ found, or var(max) words have been tried The default is to complete all words from the history at once. ) +kindex(recursive-files, completion style) +item(tt(recursive-files))( +If this style is set, its value is an array of patterns to be +tested against `tt($PWD/)': note the trailing slash, which allows +directories in the pattern to be delimited unambiguously by including +slashes on both sides. If an ordinary file completion fails +and the word on the command line does not yet have a directory part to its +name, the style is retrieved using the same tag as for the completion +just attempted, then the elements tested against tt($PWD/) in turn. +If one matches, then the shell reattempts completion by prepending the word +on the command line with each directory in the expansion of tt(**/*(/)) +in turn. Typically the elements of the style will be set to restrict +the number of directories beneath the current one to a manageable +number, for example `tt(*/.git/*)'. + +For example, + +example(zstyle ':completion:*' recursive-files '*/zsh/*') + +If the current directory is tt(/home/pws/zsh/Src), then +tt(zle_tr)em(TAB) can be completed to tt(Zle/zle_tricky.c). +) kindex(regular, completion style) item(tt(regular))( This style is used by the tt(_expand_alias) completer and bindable -- Peter Stephenson <p.w.stephenson@ntlworld.com> Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-21 18:27 ` Peter Stephenson @ 2012-12-04 2:13 ` Karoly Negyesi 0 siblings, 0 replies; 10+ messages in thread From: Karoly Negyesi @ 2012-12-04 2:13 UTC (permalink / raw) To: Peter Stephenson; +Cc: zsh-users Sorry for not getting back to you sooner on this but I wanted to say a big thanks because it works! On Tue, Aug 21, 2012 at 11:27 AM, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote: > Here's a second version with documentation. > > Index: Completion/Unix/Type/_files > =================================================================== > RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_files,v > retrieving revision 1.13 > diff -p -u -r1.13 _files > --- Completion/Unix/Type/_files 19 Mar 2010 16:38:26 -0000 1.13 > +++ Completion/Unix/Type/_files 21 Aug 2012 18:24:15 -0000 > @@ -1,7 +1,7 @@ > #compdef -redirect-,-default-,-default- > > local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried > -local type sdef ignvars ignvar > +local type sdef ignvars ignvar prepath oprefix rfiles rfile > > zparseopts -a opts \ > '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+: > @@ -118,7 +118,21 @@ for def in "$pats[@]"; do > while _next_label "$tag" expl "$descr"; do > _comp_ignore=( $_comp_ignore $ign ) > if [[ -n "$end" ]]; then > - _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 > + if _path_files -g "$pat" "$opts[@]" "$expl[@]"; then > + ret=0 > + elif [[ $PREFIX$SUFFIX != */* ]] && zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles; then > + for rfile in $rfiles; do > + if [[ $PWD/ = ${~rfile} ]]; then > + for prepath in **/*(/); do > + oprefix=$PREFIX > + PREFIX=$prepath/$PREFIX > + _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0 > + PREFIX=$oprefix > + done > + break > + fi > + done > + fi > else > _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0 > fi > Index: Doc/Zsh/compsys.yo > =================================================================== > RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compsys.yo,v > retrieving revision 1.247 > diff -p -u -r1.247 compsys.yo > --- Doc/Zsh/compsys.yo 14 Feb 2012 17:01:17 -0000 1.247 > +++ Doc/Zsh/compsys.yo 21 Aug 2012 18:24:15 -0000 > @@ -2355,6 +2355,28 @@ found, or var(max) words have been tried > > The default is to complete all words from the history at once. > ) > +kindex(recursive-files, completion style) > +item(tt(recursive-files))( > +If this style is set, its value is an array of patterns to be > +tested against `tt($PWD/)': note the trailing slash, which allows > +directories in the pattern to be delimited unambiguously by including > +slashes on both sides. If an ordinary file completion fails > +and the word on the command line does not yet have a directory part to its > +name, the style is retrieved using the same tag as for the completion > +just attempted, then the elements tested against tt($PWD/) in turn. > +If one matches, then the shell reattempts completion by prepending the word > +on the command line with each directory in the expansion of tt(**/*(/)) > +in turn. Typically the elements of the style will be set to restrict > +the number of directories beneath the current one to a manageable > +number, for example `tt(*/.git/*)'. > + > +For example, > + > +example(zstyle ':completion:*' recursive-files '*/zsh/*') > + > +If the current directory is tt(/home/pws/zsh/Src), then > +tt(zle_tr)em(TAB) can be completed to tt(Zle/zle_tricky.c). > +) > kindex(regular, completion style) > item(tt(regular))( > This style is used by the tt(_expand_alias) completer and bindable > > -- > Peter Stephenson <p.w.stephenson@ntlworld.com> > Web page now at http://homepage.ntlworld.com/p.w.stephenson/ ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-19 0:18 ` Bart Schaefer 2012-08-19 19:44 ` Peter Stephenson @ 2012-08-20 9:43 ` René Neumann 2012-08-21 4:58 ` Bart Schaefer 1 sibling, 1 reply; 10+ messages in thread From: René Neumann @ 2012-08-20 9:43 UTC (permalink / raw) To: zsh-users Am 19.08.2012 02:18, schrieb Bart Schaefer: > Fortunately there's a way to move this out of the realm of expansion > and into that of completion; to whit, simply assert that you want > completion to act as if it were using glob patterns: > > setopt globcomplete > > Now when you try > > ls **/Kern[tab] > > the completion system behaves as if you'd inserted a * just before [tab], > and offers you the list of matching items as choices. Really? I tried this, and noticed you still have to enter the * before the [tab]. The difference to noglobcomplete seems to be that now you can actually choose a file via completion, whereas before it just pushed everything onto the commandline. - René ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Recursive Completition 2012-08-20 9:43 ` René Neumann @ 2012-08-21 4:58 ` Bart Schaefer 0 siblings, 0 replies; 10+ messages in thread From: Bart Schaefer @ 2012-08-21 4:58 UTC (permalink / raw) To: zsh-users On Aug 20, 11:43am, René Neumann wrote: } Subject: Re: Recursive Completition } } Am 19.08.2012 02:18, schrieb Bart Schaefer: } > setopt globcomplete } > } > Now when you try } > } > ls **/Kern[tab] } > } > the completion system behaves as if you'd inserted a * just before [tab], } > and offers you the list of matching items as choices. } } Really? I tried this, and noticed you still have to enter the * before } the [tab]. Hmm, interesting. I didn't try it for a sufficiently deep directory hierarchy. Completion seems to treat **/ as just */ -- only expansion does the full recursive thing. Looking more closely, completion splits **/Kern into "**" and "Kern" and tries to find completions for ** first. Because the slash has been removed, ** loses its special meaning. So it really does need somethng like PWS's recent proposed patch. Or else further surgery to _path_files, which is already a bit of a Frankenstein's monster. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-12-04 2:44 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-08-18 21:09 Recursive Completition Karoly Negyesi 2012-08-19 0:18 ` Bart Schaefer 2012-08-19 19:44 ` Peter Stephenson 2012-08-19 21:07 ` Karoly Negyesi 2012-08-20 8:57 ` Peter Stephenson 2012-08-20 15:33 ` Bart Schaefer 2012-08-21 18:27 ` Peter Stephenson 2012-12-04 2:13 ` Karoly Negyesi 2012-08-20 9:43 ` René Neumann 2012-08-21 4:58 ` Bart Schaefer
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).