From 144a06bf958b4e573fd3c78eab30536349d09cff Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 5 May 2010 09:54:38 +0000 Subject: users/15031: another file completion quoting fix, useful if path-completion is false or accept-exact-dirs is true --- Completion/Unix/Type/_path_files | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'Completion/Unix/Type') diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files index 9445ac77c..581835efc 100644 --- a/Completion/Unix/Type/_path_files +++ b/Completion/Unix/Type/_path_files @@ -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}" -- cgit 1.4.1