Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [bug] escaping spaces in _canonical_paths



On Mar 10,  6:31pm, Bart Schaefer wrote:
}
} There [is] a bug with the :P modifier -- see other thread.  With that
} fixed, things are better, but still messed up when $compstate[quote] is
} a substring of the mount point name (if you see what I mean).

OK, the following is getting very close.  Ignore previous patch (40811).

Even with this, there are some oddities.  For example because "/" is
normally a mount point, if "/" is the current directory the relative
path '' (empty string) is offered as a completion.

For another, I've discovered that if you have a quote in the directory
name like my previous example:

% sudo umount mnt/aa\'<TAB>

nothing completes, because $PREFIX is actually incorrect at this point;
it has the value mnt/aa\'\' (an extra escaped quote at the end) so it
can never be correctly suffixed.  I don't know if this is a bug in
the completion internals or if _mount somehow messes it up before the
call to _canonical_paths is made.

Fascinatingly,

% sudo umount mnt/aa\<TAB>
% sudo umount mnt/aa\''cc 2'

correctly completes.

I also found one case where I managed to get a trailing space (as if
for auto-removal) to appear inside the quotes, but I can't reproduce
now.  Still, the number of cases this gets right is larger than for
the previous code, I think.  Someone will probably find a previously-
working case that this breaks.

diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index 6eab7b6..9ec7376 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -41,7 +41,16 @@ _canonical_paths_add_paths () {
     # ### Ideally, this codepath would do what the 'if' above does,
     # ### but telling compadd to pretend the "word on the command line"
     # ### is ${"the word on the command line"/$origpref/$canpref}.
-    matches+=(${${(M)files:#$canpref*}/$canpref/$origpref})
+    origpref=${(Q)origpref}
+    local canpat=${(b)${(Q)canpref}}
+    case $compstate[quote] in
+    (\')
+      matches+=(${${${(M)files:#$canpref*}/$canpat/$origpref}//\'/\'\\\'\'});;
+    (\")
+      matches+=(${${${(M)files:#$canpref*}/$canpat/$origpref}//\"/\\\"});;
+    (*)
+      matches+=(${(q-)${(M)files:#$canpref*}/$canpat/$origpref});;
+    esac
   fi
 
   for subdir in $expref?*(@); do



Messages sorted by: Reverse Date, Date, Thread, Author