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 suit automount
or sshfs
or NetApp .snapshot
type setups where the directory-to-be-mounted is a known static name, ALAS
.
autoload -U compinit
compinit
zstyle ':completion:*' fake-files $HOME/.avfs:'ALAS POOR YORICK'
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 the fake-files
statement. (Delving through Src/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 much fake-files
lets you get away with.)
With compdef
, one can list the .avfs
directory completions:
compdef '_files -g $HOME/.avfs/\*' -p \^
function andthehash {
reply=($REPLY $REPLY\#)
}
compdef "_files -g $HOME/.avfs/'*(+andthehash)'" -p \^
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
:
autoload -U compinit
compinit
function UnderAVFS {
local pdir
[[ -z $1 ]] && return 1
pdir=$1:a
[[ ! -d $pdir ]] && pdir=$pdir:h
[[ ! -d $pdir || $pdir == . ]] && return 1
while [[ $pdir != / ]]; do
[[ $pdir == $HOME/.avfs ]] && return 0
pdir=$pdir:h
done
return 1
}
function AVFSExtras {
if UnderAVFS $REPLY; then
reply=($REPLY)
# TODO embiggen list of archive suffixes
[[ $REPLY == *.(bz2|tbz2) ]] && reply+=($REPLY\#)
fi
}
# Try to match avfs, otherwise the default pattern. Probably could greatly
# benefit from caching, to avoid hits on UnderAVFS function.
zstyle ':completion:*' file-patterns '*(+AVFSExtras):avfs-files' '%p:all-files'
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 con zsh
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 in ls /root/.avfs/root/sometar.gz\#/
and then at the end of that typing control-x
and then ?
, assuming bindkey -e
and that _complete_debug
is bound to said keycombo, if someone wants to delve through why this is failing.
Best Answer
Short & sweet answer
Try my
zsh-autocomplete
plugin. It configures Zsh's completion system to do what you're asking for out of the box, plus lots of other useful features.Longer, DIY answer
To get fuzzy completion in Zsh, add this to your
.zshrc
:What this does is tell the completion system to allow any number of characters added anywhere to the string you've typed.
Next, to get the thing you want with directories, add this:
accept-exact-dirs
makes it so that when you have two dirsnm
andnode_modules
and you typenm
, it will never try to complete it to the latter.list-suffixes
tells it to try to complete every partial directory name in the path you've entered and not just the first one.To get the
accept-exact-dirs
-style behavior also for all other completions, add this:More info can be found here: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Standard-Styles