How can I tweak zsh's completion system to complete “fake” files in some circumstances?
More precisely, the AVFS filesystem exposes archives as directories by creating a “fake directory” next to every archive. By default, it replicates the whole directory hierarchy under its mount point ~/.avfs
. Furthermore, under ~/.avfs
, for every archive file such as /tmp/foo.zip
, besides the archive file itself ~/.avfs/tmp/foo.zip
, there is a directory called ~/.avfs/tmp/foo.zip#
which exposes the content of the archive. However this extra directory does not appear in the listing of ~/.avfs/tmp
: it only exists when explicitly requested. (This is similar to how some automounters operate.)
mountavfs
cd ~/.avfs/tmp/foo.zip\#
When I type a command like the one above, foo.zip#
doesn't appear as a completion under ~/.avfs/tmp/
, since there is no such directory. How can I tell zsh that whenever there is a file whose full path $arc
matches ~/.avfs/**/*.(tgz|zip)
¹, it should pretend that there is a directory called ${arc}#
?
(Note that I want the completion to work with every call to _files
or _dirs
, not just for the cd
command. I'd prefer not to have to duplicate the code of the _files
function, if possible.)
¹ and all the rest of the extensions
Best Answer
A fake answer appears insufficient for this fake question; the zsh builtin support for automount directories operates on directories (
fake-files dir:names
), and not on file patterns therein. This is handy to add specific named files to a directory, which may suitautomount
orsshfs
or NetApp.snapshot
type setups where the directory-to-be-mounted is a known static name,ALAS
.zshall(1)
says the "names" are strings, and experiments indicate metacharacters (e.g.#
or\#
or'*(e:"echo hi":)'
) "do not work" in various ways, so there is no way I know of to sneak a glob onto the names portion of thefake-files
statement. (Delving throughSrc/Zle/computil.c
might reveal exactly what the names can be, but that would be more work.) (Also, using recursive globs in the directory position to name archive files did not fly, but again it will take C diving to see how muchfake-files
lets you get away with.)With
compdef
, one can list the.avfs
directory completions:Except this fails, as it will only show the
#
files when it does not matter, and thus cannot complete on them. (There are productive uses for this form, though not for this case.)Using
zstyle
gets you closer, with the following.zshrc
:However, it can only complete up to the
\#/
bit (on a debian squeeze virt with a default avfs setup), but not into the virtual filesystem for an archive, so additional work will be necessary to tab complete into the archives. I'm guessing via_call_program ... ls
or something along those lines for completions at the\#
bit, unless there's a more elegant way to conzsh
into believing that directories that do not exist do.Bad news! The completion does not make it through
_path_files
for the fake directories; I suspect this is zsh globbing related. Both zsh 4.something on and zsh 5.0.8 exhibit the problem. So I suspect that a complete fix would require patches to_path_files
, or to write something different that otherwise completes on these fake dirs. A completion debugging trace can be generated by typing inls /root/.avfs/root/sometar.gz\#/
and then at the end of that typingcontrol-x
and then?
, assumingbindkey -e
and that_complete_debug
is bound to said keycombo, if someone wants to delve through why this is failing.