# Completion script for hledger. # Created using a Makefile and real hledger. # No set -e because this file is sourced and is not supposed to quit the current shell. set -o pipefail # TODO grep "^$wordToComplete" is (functional) not safe to use if the word # contains regex special chars. But it might be no problem because of # COMP_WORDBREAKS. # Working with bash arrays is nasty compared to editing a text file. Consider # for example grepping an array or mapping a substitution on it. # Therefore, we create temp files in RAM for completion suggestions (see below). readonly HLEDGER_COMPLETION_TEMPDIR=$(mktemp -d) hledgerCompletionFunction() { #declare cmd=$1 declare wordToComplete=$2 declare precedingWord=$3 declare subcommand for subcommand in "${COMP_WORDS[@]}"; do if grep -Fxqe "$subcommand" "$HLEDGER_COMPLETION_TEMPDIR/commands.txt"; then COMPREPLY+=( $(grep -h "^$wordToComplete" -- "$HLEDGER_COMPLETION_TEMPDIR/options-$subcommand.txt") ) break fi subcommand= done if [[ -z $subcommand ]]; then declare completeFiles filenameSoFar case $precedingWord in -f|--file|--rules-file) completeFiles=1 filenameSoFar=$wordToComplete ;; =) completeFiles=1 filenameSoFar=$wordToComplete ;; esac if [[ -n $completeFiles ]]; then #COMP_WORDBREAKS='= ' declare -a files # This does not work because assignment to 'files' in the "pipe # subshell" has no effect! #compgen -df | grep "^$filenameSoFar" | readarray -t files readarray -t files < <(compgen -df | grep "^$filenameSoFar") COMPREPLY=( "${files[@]}" ) else COMPREPLY+=( $(grep -h "^$wordToComplete" -- "$HLEDGER_COMPLETION_TEMPDIR/commands.txt" "$HLEDGER_COMPLETION_TEMPDIR/generic-options.txt") ) fi else # Almost all subcommands accept [QUERY] # -> always add accounts to completion list # TODO Get ledger file from -f --file arguments from COMP_WORDS and pass it to # the 'hledger accounts' call. Note that --rules-file - if present - must also # be passed! declare -a accounts readarray -t accounts < <(hledger accounts --flat | grep "^$wordToComplete") COMPREPLY+=( "${accounts[@]}" ) # Special characters (e.g. '-', ':') are allowed in account names. # Account names with spaces must be still be quoted (e.g. '"Expens') # for completion. Setting COMP_WORDBREAKS='' would not help here! COMP_WORDBREAKS=' ' fi } # Register completion function for hledger: complete -F hledgerCompletionFunction hledger # Include lists of commands and options generated by the Makefile using the # m4 macro processor. # Included files must have exactly one newline at EOF to prevent weired errors. cat < "$HLEDGER_COMPLETION_TEMPDIR/commands.txt" include(`commands.txt')dnl TEXT cat < "$HLEDGER_COMPLETION_TEMPDIR/generic-options.txt" include(`generic-options.txt')dnl TEXT include(`foreach2.m4') foreach(`cmd', (include(`commands-list.txt')), ` cat < "$HLEDGER_COMPLETION_TEMPDIR/options-cmd.txt" include(options-cmd.txt)dnl TEXT ')