hledger/shell-completion/hledger-completion.bash.m4
Jakob Schöttl e491f34ddf Bugfix and remove unused code
Bug was: Account names with spaces were broken into single completion
suggestions, not line by line.
2019-01-23 16:46:17 -08:00

102 lines
3.0 KiB
Plaintext

# 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 <<TEXT > "$HLEDGER_COMPLETION_TEMPDIR/commands.txt"
include(`commands.txt')dnl
TEXT
cat <<TEXT > "$HLEDGER_COMPLETION_TEMPDIR/generic-options.txt"
include(`generic-options.txt')dnl
TEXT
include(`foreach2.m4')
foreach(`cmd', (include(`commands-list.txt')), `
cat <<TEXT > "$HLEDGER_COMPLETION_TEMPDIR/options-cmd.txt"
include(options-cmd.txt)dnl
TEXT
')