From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22275 invoked by alias); 29 Apr 2010 21:39:05 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 15031 Received: (qmail 16373 invoked from network); 29 Apr 2010 21:39:02 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) 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.1 Received-SPF: pass (ns1.primenet.com.au: SPF record at ntlworld.com designates 81.103.221.48 as permitted sender) Date: Thu, 29 Apr 2010 22:38:50 +0100 From: Peter Stephenson To: zsh-users@zsh.org Subject: Re: Zsh autocompletion with no access to a parent directory Message-ID: <20100429223850.14143862@pws-pc> In-Reply-To: <20100423224428.7479faa8@pws-pc> References: <3663DC29-7A8F-4A0C-8262-5FFE701C8E3A@sysctl.co.uk> <20100413174533.5a15043a@news01> <361816B9-75B6-4C88-8BE9-097B33CA2283@sysctl.co.uk> <201004140914.o3E9EPkL009936@news01.csr.com> <201004140947.o3E9llgG010201@news01.csr.com> <20100423224428.7479faa8@pws-pc> X-Mailer: Claws Mail 3.7.5 (GTK+ 2.18.9; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Cloudmark-Analysis: v=1.1 cv=1ggfb5FlKZQUfF3vzm9UBYZ2uTfLsbs/8dSljwg5+mE= c=1 sm=0 a=yCTxJr-a2pMA:10 a=DogomfpGjd0A:10 a=kj9zAlcOel0A:10 a=NLZqzBF-AAAA:8 a=rUCZ0zD2AAAA:8 a=zJzv6SGsKtvhDdDjsKcA:9 a=8irQa2q8vd2Gf-t4BBUA:7 a=0f6qs-vA3fVMuHEBwIBjsBAsQwcA:4 a=CjuIK1q_8ugA:10 a=_dQi-Dcv4p4A:10 a=lyVDlEeSCIoA:10 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 More from the world of "The Hairiest Shell Function in History, No, Really, I Mean, Like, Ever". On Fri, 23 Apr 2010 22:44:28 +0100 Peter Stephenson wrote: > On Fri, 23 Apr 2010 08:01:53 -0700 > Matt Wright wrote: > > If you have a path with a "special" character in it, where by special > > so far I've found space and tilde, then completion stops offering > > results after that letter. It's particularly frustrating on a Mac, where > > many app bundles have spaces in their names but the actual executables > > are another two layers of directories deeper after the bundle name. > > It appears to be this, though I haven't looked too closely since I've > heard it makes you blind. Where is the input supposed to be unquoted? > Er... Well, the input is supposed to be unquoted in two stages. Or something. I ran across this trying to complete the Calibre user guide, /home/pws/ebooks/John Schember/Calibre Quick Start Guide (1)/Calibre Quick Start Guide - John Schember.epub with accept-exact-dirs set. That has the added interest over setting path-completion to false that you then need a completely unquoted string to test as a directory, and the added gotcha that if that doesn't work it just blithely carries on doing normal completion so it doesn't exercise the logic to put the directory onto the path immediately. I tried this with files in directories called (1) [1] {1} 1~1 1 1 just to be sure. Matt, could you make sure this doesn't break anything? Of course, with code this trivial it's hard to make a mistake. Sob. Index: Completion/Unix/Type/_path_files =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v retrieving revision 1.51 diff -p -u -r1.51 _path_files --- Completion/Unix/Type/_path_files 23 Apr 2010 21:52:00 -0000 1.51 +++ Completion/Unix/Type/_path_files 29 Apr 2010 21:27:45 -0000 @@ -357,16 +357,26 @@ for prepath in "$prepaths[@]"; do cpre= if [[ ( -n $accept_exact_dirs || -z $path_completion ) && \ - ${(Q)pre} = (#b)(*)/([^/]#) ]]; then + ${pre} = (#b)(*)/([^/]#) ]]; then # We've been told either that we can accept an exact directory prefix # immediately, or that path expansion is inhibited. Try the longest # path prefix first: in the first case, this saves stats in the simple # case and may get around automount behaviour if early components don't # yet exist, and in the second case this is the prefix we want to keep. - tmp1=$match[1] - tpre=$match[2] + # + # Explanation of substitution: For tmp1 and tpre, which are used further + # on, we need to remove quotes from everything that's not a pattern + # character, because the code that does the file generation only + # strips qutoes from pattern characters (you know better than + # to ask why). Because we need to test for a real directory, + # however, for tmp2 we unquote everything. + tmp1=${match[1]} + tpre=${match[2]} + tmp2=${(Q)tmp1} + tmp1=${tmp1//(#b)\\([^\\\]\[\^\~\(\)\#\*\?])/$match[1]} + tpre=${tpre//(#b)\\([^\\\]\[\^\~\(\)\#\*\?])/$match[1]} while true; do - if [[ -z $path_completion || -d $prepath$realpath$donepath$tmp1 ]]; then + if [[ -z $path_completion || -d $prepath$realpath$donepath$tmp2 ]]; then donepath=$donepath$tmp1/ pre=$tpre break @@ -381,7 +391,14 @@ for prepath in "$prepaths[@]"; do tpre="$pre" tsuf="$suf" - testpath="$donepath" + # Now we strip quoting from pattern characters, too, because + # testpath is used as a literal string. I suppose we could + # alternatively use ${~testpath} later. + # + # I'm not sure if donepath itself should be entirely unquoted at + # some point but probably not here, since we need the quoted pattern + # characters in tmp1 below (I think). + testpath="${donepath//(#b)\\([\\\]\[\^\~\(\)\#\*\?])/$match[1]}" tmp2="${(M)tpre##${~skips}}" tpre="${tpre#$tmp2}" -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/