mirror of
https://github.com/simonmichael/hledger.git
synced 2024-11-14 02:14:14 +03:00
133 lines
4.1 KiB
Plaintext
133 lines
4.1 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
|
|
|
|
# Note: 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.
|
|
|
|
# Note: compgen and compopt is pretty complicated. Piping to
|
|
# grep "^$wordToComplete"
|
|
# seems like a hack - I'd rather use
|
|
# compgen ... -- "$wordToComplete"
|
|
# But what options to use? I don't want to use -W because it may exceed the
|
|
# maximum command line length. -C "cat file" is not working either. It would be
|
|
# best if compgen could read from stdin but it does not.
|
|
|
|
# Note: 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)
|
|
|
|
_hledger_completion_function() {
|
|
#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
|
|
|
|
compopt -o filenames -o dirnames
|
|
readarray -t files < <(compgen -f -- "$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 < <({ cat "$_HLEDGER_COMPLETION_TEMPDIR/query-filters.txt"; hledger accounts --flat; } | grep "^$wordToComplete")
|
|
compopt -o nospace
|
|
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
|
|
|
|
}
|
|
|
|
_hledger_extension_completion_function() {
|
|
declare cmd=$1
|
|
|
|
# Change parameters and arguments and call the
|
|
# normal hledger completion function.
|
|
declare extensionName=${cmd#*-}
|
|
export -a COMP_WORDS=( "hledger" "$extensionName" "${COMP_WORDS[@]:1}" )
|
|
#echo; echo "debug: ${COMP_WORDS[@]}"
|
|
shift
|
|
_hledger_completion_function "hledger" "$@"
|
|
}
|
|
|
|
# Register completion function for hledger:
|
|
complete -F _hledger_completion_function hledger
|
|
|
|
# Register completion functions for hledger extensions:
|
|
complete -F _hledger_extension_completion_function hledger-ui
|
|
complete -F _hledger_extension_completion_function hledger-web
|
|
|
|
# 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/query-filters.txt"
|
|
include(`query-filters.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
|
|
')
|