Search code examples
bashbash-completion

bash completion for teamocil


I'm trying to define bash auto-completion for teamocil so that when I type teamocil <tab> it should complete with the file names in the folder ~/.teamocil/ without the file extensions. There's an example for zsh in the website:

compctl -g '~/.teamocil/*(:t:r)' teamocil

how can I use this in bash?

Edit: Influenced by michael_n 's answer I have come up with a one-liner:

complete -W "$(teamocil --list)" teamocil

Solution

  • Here's a generalized version of another completion script I have that does something similar. It assumes a generic hypothetical command "flist", using some directory of files defined by FLIST_DIR to complete the command (omitting options).

    Modify the following for your program (teamocil), change the default dir from $HOME/flist to $HOME/.teamocil), define your own filters/transformations, etc; and then just source it (e.g., . ~/bin/completion/bash_completion_flist), optionally adding it to your existing list of bash completions.

    # bash_completion_flist: 
    #  for some hypothetical command called "flist",
    #  generate completions using a directory of files
    
    FLIST_DIR=${FLIST_DIR=:-"$HOME/flist"}
    
    _flist_list_files() {
       ls $FLIST_DIR | sed 's/\..*//'
    }
    
    _flist() {
       local cur="${COMP_WORDS[COMP_CWORD]}"       
       COMPREPLY=()
       [[ ${cur} != -* ]] \
          && COMPREPLY=($(compgen -W "$(_flist_list_files)" -- ${cur}))
    }
    
    complete -o bashdefault -o default -o nospace -F _flist flist 2>/dev/null \
        || complete -o default -o nospace -F _flist flist
    

    Notes:

    • it could be shorter, but this is more or less a template for longer, more complicated completions. (Functions are Good.)
    • the actual completion command (complete -o ...) is a bit of a hack to work across different versions of bash.
    • the suffix stripping is over-simplfied if there are "." in the filename, and is left as an exercise for the reader :-) There are multiple ways to do this (sed, awk, etc); the best is via bash-isms (base=${filename%.*}), but the easiest is arguably the simple sed with some assumptions about the filename format.