Fuzzy Bash Completion

18 Dec 2021, Bangkok

On my little laptop, I have lots of books organized by tags. And when I’m interested in a particular topic, I’d go to that tag and browse it.

However, I also have a few favourites or currently reading books that I’d like to be able to quickly access. To make it simpler, I decided to put links to these favourites in a separate folder called ~/tags/rread.

And to make it transparent, listing all these favourites is done via a helper function rread that relies on bash completion to list all the contents of the folder, which is fine except for one small thing - bash-completion requires exact matching.

$ ls ~/tags/rread                   # Contents of ~/tags/rread
bash_pocket_reference.pdf
still-flowing-water-ajahn-chah.pdf

$ rread flow[TAB TAB]               # No matches

I’d like bash completion to match still-flowing-water-ajahn-chah.pdf in the example above.

And after digging quite a bit, here’s what I came up with that seemed to do the job.

function rread {
  # Tab completion for rread helper
  # Usage: rread [TAB Tab]
  #   ~/tags/rread contains symlinks to actual files
  xdg-open ~/tags/rread/${1} &
}

_rread_completions() {
  if [ -z ${COMP_WORDS[1]} ];
  then
    # COMP_WORDS[1] not defined
    COMPREPLY=($(compgen -W "$(ls -1 ~/tags/rread )" -- "${COMP_WORDS[1]}"))
  else
    # COMP_WORDS[1] defined
    COMPREPLY=( $(compgen -W "$(ls -1 ~/tags/rread | grep ${2} 2>/dev/null)") )
    # grep ${2} 2>/dev/null
    #   2>/dev/null - send grep usage errors to /dev/null
    #     e.g. Usage: grep [OPTION]... PATTERNS [FILE]...
    #          Try 'grep --help' for more information.
    #   ${2} - Use this instead of ${COMP_WORDS[1]}
    #          because otherwise COMPREPLY always has a value
  fi
}

complete -F _rread_completions rread

To learn more about bash completion:

Man page on bash completion
    help complete
    help compgen

GNU manual on bash completion
    https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html

Tutorial on bash completion
    https://iridakos.com/programming/2018/03/01/bash-programmable-completion-tutorial

A fuzzy bash completion tool
    https://github.com/mgalgs/fuzzy_bash_completion
Written on December 18, 2021