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 --- ChangeLog | 6 +++++- Completion/Unix/Type/_path_files | 27 ++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f34f5c5fb..cc4c0dea2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2010-05-05 Peter Stephenson + * users/15031: Completion/Unix/Type/_path_files: fix (still + incomplete) for bizarre quoting rules for files in completion + with path-completion off or accept-exact-dirs on. + * 27947: Src/exec.c, Test/C03traps.ztst: fix some cases where we should (probably) execute an EXIT trap but don't. @@ -13101,5 +13105,5 @@ ***************************************************** * This is used by the shell to define $ZSH_PATCHLEVEL -* $Revision: 1.4972 $ +* $Revision: 1.4973 $ ***************************************************** 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