Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using zsh's compdef or compctl to complete a certain directory with _hosts for all commands

I use afuse to automount other hosts to my local file system with sshfs. Like so:

afuse -o timeout=30 -o mount_template=sshfs -C %r:/ %m -o unmount_template=fusermount -u -z %m ~/remote/

This works great, but I would like to be able to autocomplete/TAB commands using my ~/remote directory. Zsh understandably thinks ~/remote is empty, since afuse is a magical virtual FUSE file system. Once I have typed the host manually the subdirectories work fine. E.g ~/remote/host/[TAB] works fine.

Most zsh compdef tutorials focus on building a custom completer for your custom command. That is not quite what I want.

I have been trying to use compdef to override the completion of that particular directory to my hosts file (using the built-in _hosts completion function), but as far as I understand, compdef works on a per-command-basis. I want my completer to work on all commands trying to do a normal file/directory-complete on that directory.

It feels like it is so basic, that it is a one-liner, if only I knew how. How can I do this?

like image 603
Gurgeh Avatar asked Aug 31 '12 12:08

Gurgeh


People also ask

What is compdef?

Compdef is basically a function used by zsh for load the auto-completions. The completion system needs to be activated. If you're using something like oh-my-zsh then this is already taken care of, otherwise you'll need to add the following to your ~/.zshrc autoload -Uz compinit compinit.

How do you use zsh completion?

When you hit the tab key, the system will complete the path to the Documents folder. At this point, you can add a character or two to get to a unique completion, and hit the tab key again. In zsh you can also hit the tab key repeatedly to cycle through the suggested completions.

What does compinit do?

Use of compinit When run, it will define a few utility functions, arrange for all the necessary shell functions to be autoloaded, and will then re-bind all keys that do completion to use the new system.

How do I turn on autocomplete in zsh?

zsh-autocomplete adds real-time type-ahead autocompletion to Zsh. Find as you type, then press Tab to insert the top completion, Shift Tab to insert the bottom one, or ↓ / PgDn to select another completion. Enjoy using this software?


1 Answers

Add the following to your ~.zshrc file (or paste it into the command line, to try it out):

autoload -Uz compinit && compinit
bindkey '^I' complete-word
zstyle -e ':completion:*' fake-files _fake_files
_fake_files() {
  [[ $PWD/$PREFIX$SUFFIX == ~/remote/ ]] && 
      ISUFFIX=/
  reply=( 
      ~/remote:${(j: :v)${(s: :)${(ps:\t:)${${(f)~~"$(
        < /etc/hosts
      )"}%%\#*}##[:blank:]#[^[:blank:]]#}}}
  )
}

I tried this and it works. I took the long parameter expansion from _host's source code.

like image 141
Marlon Richert Avatar answered Dec 28 '22 10:12

Marlon Richert