* [bug] escaping spaces in _canonical_paths
@ 2017-03-06 9:16 Philipp G. Haselwarter
2017-03-10 5:48 ` Bart Schaefer
0 siblings, 1 reply; 5+ messages in thread
From: Philipp G. Haselwarter @ 2017-03-06 9:16 UTC (permalink / raw)
To: zsh-workers
Hi,
when I try to umount a directory "/mnt/name with spaces" and i type
# umount /mnt/n
i press tab and the path gets completed to
# umount /mnt/name\ with\ spaces
however, if I cd into /mnt and then try to umount the relative path
# cd /mnt
# umount nam
it gets completed to
# umount name with spaces
with no escapes for the spaces.
i don't know much about zsh completion, so unfortunately I can't
investigate further by myself.
zsh --version
zsh 5.3.1 (x86_64-unknown-linux-gnu)
Best regards,
Philipp G. Haselwarter
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [bug] escaping spaces in _canonical_paths
2017-03-06 9:16 [bug] escaping spaces in _canonical_paths Philipp G. Haselwarter
@ 2017-03-10 5:48 ` Bart Schaefer
2017-03-10 5:53 ` Daniel Shahaf
0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2017-03-10 5:48 UTC (permalink / raw)
To: Philipp G. Haselwarter, zsh-workers
On Mar 6, 10:16am, Philipp G. Haselwarter wrote:
}
} however, if I cd into /mnt and then try to umount the relative path
}
} # cd /mnt
} # umount nam
}
} it gets completed to
}
} # umount name with spaces
}
} with no escapes for the spaces.
This seems to do it, although I haven't figured out why it is necessary
to do the quote manipulation in the shell code here when it is not needed
in the other (absolute-path) branch.
diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index 6eab7b6..630907b 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -41,7 +41,11 @@ _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})
+ if [[ -z $compstate[quote] ]]; then
+ matches+=(${(q)${(M)files:#$canpref*}/$canpref/$origpref})
+ else
+ matches+=(${${(M)files:#$canpref*}/$canpref/$origpref})
+ fi
fi
for subdir in $expref?*(@); do
@@ -84,7 +88,7 @@ _canonical_paths() {
files+=($@:P)
fi
- local base=$PREFIX
+ local base=${(Q)PREFIX}
typeset -i blimit
_canonical_paths_add_paths $base
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [bug] escaping spaces in _canonical_paths
2017-03-10 5:48 ` Bart Schaefer
@ 2017-03-10 5:53 ` Daniel Shahaf
2017-03-11 2:31 ` Bart Schaefer
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Shahaf @ 2017-03-10 5:53 UTC (permalink / raw)
To: zsh-workers
Bart Schaefer wrote on Thu, Mar 09, 2017 at 21:48:20 -0800:
> On Mar 6, 10:16am, Philipp G. Haselwarter wrote:
> }
> } however, if I cd into /mnt and then try to umount the relative path
> }
> } # cd /mnt
> } # umount nam
> }
> } it gets completed to
> }
> } # umount name with spaces
> }
> } with no escapes for the spaces.
>
> This seems to do it, although I haven't figured out why it is necessary
> to do the quote manipulation in the shell code here when it is not needed
> in the other (absolute-path) branch.
Perhaps the abspath branch gets confused on mountpoint names that
contain literal ' characters? Since the ${foo/bar/baz} replacement is
done on the compadd results, and compadd wasn't called with -Q.
(Can't test this right now)
> diff --git a/Completion/Unix/Type/_canonical_paths b/Completion/Unix/Type/_canonical_paths
> index 6eab7b6..630907b 100644
> --- a/Completion/Unix/Type/_canonical_paths
> +++ b/Completion/Unix/Type/_canonical_paths
> @@ -41,7 +41,11 @@ _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})
> + if [[ -z $compstate[quote] ]]; then
> + matches+=(${(q)${(M)files:#$canpref*}/$canpref/$origpref})
> + else
> + matches+=(${${(M)files:#$canpref*}/$canpref/$origpref})
> + fi
> fi
>
> for subdir in $expref?*(@); do
> @@ -84,7 +88,7 @@ _canonical_paths() {
> files+=($@:P)
> fi
>
> - local base=$PREFIX
> + local base=${(Q)PREFIX}
> typeset -i blimit
>
> _canonical_paths_add_paths $base
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [bug] escaping spaces in _canonical_paths
2017-03-10 5:53 ` Daniel Shahaf
@ 2017-03-11 2:31 ` Bart Schaefer
2017-03-11 5:20 ` Bart Schaefer
0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2017-03-11 2:31 UTC (permalink / raw)
To: Daniel Shahaf, zsh-workers
On Mar 10, 5:53am, Daniel Shahaf wrote:
}
} Perhaps the abspath branch gets confused on mountpoint names that
} contain literal ' characters? Since the ${foo/bar/baz} replacement is
} done on the compadd results, and compadd wasn't called with -Q.
Indeed, I created a mount point named "aa'cc 2" and with the patch
from 40801, _canonical_paths is not able to complete that as an
absolute path if given a prefix.
It will correctly add the absolute path to the menu of completions if
there is no path prefix.
On a quick test the absolute-path case needs $PREFIX as-is, whereas
the local-directory case needs ${(Q)PREFIX}.
There's yet a third case -- a relative sub-directory, e.g.
% cd /
% sudo umount <TAB>
will show mnt/aa\'cc\ 2 in the list of completions, but
% sudo umount mnt<TAB>
will not complete anything, whereas both
% sudo umount /mnt/a<TAB>
and
% cd mnt
% sudo umount a<TAB>
correctly show a result.
There may be 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).
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [bug] escaping spaces in _canonical_paths
2017-03-11 2:31 ` Bart Schaefer
@ 2017-03-11 5:20 ` Bart Schaefer
0 siblings, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2017-03-11 5:20 UTC (permalink / raw)
To: zsh-workers
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
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-03-11 5:20 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-06 9:16 [bug] escaping spaces in _canonical_paths Philipp G. Haselwarter
2017-03-10 5:48 ` Bart Schaefer
2017-03-10 5:53 ` Daniel Shahaf
2017-03-11 2:31 ` Bart Schaefer
2017-03-11 5:20 ` 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).