Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

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

share|improve this question
    
Does ~/.avfs contain a "copy" of the whole file-system? –  richard Jun 16 '14 at 14:13
    
@richard Yes, every /path/to/foo is visible as ~/.avfs/path/to/foo. –  Gilles Jun 16 '14 at 15:46
    
This might be easier fixed in avfs. If it presented the default # directory entry for any files that matched the strings it supports, or even magic tested the files in a directory for what needed to have a # entry, then the completion would just work. I guess there would be a performance hit for something like find as it would now trawl through compressed files. –  Matt Jul 21 '14 at 14:56

1 Answer 1

In zsh you can use compctl -K to register your own function to generation completion options. For example:

compctl -f -c -u -r -K myAVFScompletion "*" -tn

Then you need to define your own function:

myAVFScompletion () {
    read -c COMMAND ARGS

    # Decide what paths you want to suggest completion for
    # by looking inside the ~/.avfs folder.

    # Place your suggestions into an array:
    reply=( a_path b_path ... )
}

Obviously the above needs some more work, but it's something to start with.

A similar (but different) custom completion function can be registered for bash.

Here is an example with implementations for bash and zsh. (It offers completion of command-line options by grabbing the options out of the command's man page.)

And here are some quick guesses at things that might work inside your completion function:

if [[ -d "$ARGS#" ]]
then reply=( "$ARGS#" )
else reply=
fi

Or perhaps this:

reply=( $(find ~/.avfs -type f -name "*.tgz" -or -name "*.zip" | sed 's+$+#+') )

Good luck!

share|improve this answer
    
I know how to write a completion function, thank you very much. The problem is how to modify the existing completion mechanism for files. Note that I use the “new” completion mechanism, not compctl, i.e. I want to change what _files does. Your answer is not helpful at all. –  Gilles Jun 5 at 12:52
    
@Gilles Not to start a flame war, and at the risk of coming off wrong, at least he tried... This has been sitting in the unanswered "attic" 2 years plus... +1 t reset to 0 for the effort. –  eyoung100 Jul 24 at 21:59
    
@eyoung100 Please do not give +1 for effort (not that effort is apparent here). Upvoting unhelpful answers is detrimental to the site. –  Gilles Jul 24 at 22:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.