Fix #1404, and more...
This was supposed to be just a fix for #1404 but upon visiting the source several issues became apparent and that is why the commit grew a bit more than expected. A complete list of changes bellow: * Fix #1404 No more orphaned temporary directories. Commands, options, etc. that used to be stored in there are included at build-time as here documents in the source. * Fix artifacts in =/tmp= after build Upon fixing the above I became aware that the build itself was leaving behind a heap of artifacts in =/tmp= that were not taken care of with a ~make clean~. Fixed by using temporary files and directories in the build directory. Makefile and build scripts adjusted. * Produce command aliases Regular expressions in build scripts changed to produce all command aliases except single letter ones (see below) * Do not propose single letters completions It is simply not useful and adds a lot of noise. It makes completion slower as well because you need to hit yes on the prompt: > Display all 200 possibilities? (y or n) =output-options.sh= now excludes those. * Query filters simplified Keep only the prefix of the filter with the colon in =query-filters.txt=. This change has two reasons: - Single letter completions are not useful (see above) - It allows for completion suggestions specific to each - Bonus reason: it's a completion engine, not a user manual. * Fix completion impacts on global environment The completion script was making a couple of changes to the global environment which had an impact for the rest of the shell session. ~set -o pipefail~: the change is hidden from the user and could lead to subtle errors throughout the shell session COMP_WORDBREAKS=" ": this affects subsequent completions for us and other programs too. I exclude the colon =:= from its value and use ~compopt -o filenames~ to handle escaping of special characters for us. I would like to find a solution without messing with COMP_WORDBREAKS but it is not straight forward. * Fix hiding of legit subcommands Completion was hiding all possibilities if a subcommand happens to be the prefix of another. On typing ~balance~, one should be proposed ~balancesheet~ and ~balancesheetequity~ as well. * Return early Try to complete depending on the current context and return immediately if successful. Keep completion list relevant and as short as possible. * Context aware completion - Add handlers for option parameter completion, see _hledger_compreply_optarg() - Add handlers for query filters:, see _hledger_compreply_query() - Use --file and --rules-file arguments when proposing completions for the above, see _hledger() - Propose only top level accounts at first. Again, keep it short and focused. * Custom ~compgen~ wrapper ~compgen~ is fairly complicated. There is no way to feed it a word list with literals. It will mangle your input in so many ways that we cannot trust it. To work around this several wrappers are used: _hledger_compgen() works with _hledger_quote_by_ref() to process and escape newline separated input which is then fed to ~compgen~ and finally in ~COMPREPLY~ through _hledger_compreply() and _hledger_compreply_append(). It sounds messy and I guess it is, I would like to find a more straight forward way to do it. I think it is still a way better and safer interface with ~readline~ than trying to ~grep~ our way through. * Replace ~declare~ with ~local~ Again, this script is sourced by the shell -- keep variable scopes as narrow as possible. * Use ~compopt -o nosort~ Often I resort to using it to keep different groups of completions together. Whether this is more ergonomic or not is subjective. But our input lists are already sorted at build-time so why not. Sort manually =query-filters.txt= when changing it. * Remove irrelevant comments And add some new ones :) I think that is all. Give it a spin, try to abuse it, in and outside of quotes, with some funky accounts, payees, tags, whatever, and tell me where it breaks or behaves unexpectedly.
This commit is contained in:
parent
4c9b72ea15
commit
72b737a42f
@ -10,7 +10,7 @@ generic-options.txt:
|
|||||||
hledger -h | ./output-options.sh | sort -u > $@
|
hledger -h | ./output-options.sh | sort -u > $@
|
||||||
|
|
||||||
commands.txt:
|
commands.txt:
|
||||||
hledger | ./output-commands.sh | grep -v ^hledger > $@
|
hledger | ./output-commands.sh | grep -v ^hledger | sort -u > $@
|
||||||
echo ui >> $@
|
echo ui >> $@
|
||||||
echo web >> $@
|
echo web >> $@
|
||||||
echo api >> $@
|
echo api >> $@
|
||||||
@ -23,8 +23,9 @@ commands-list.txt: commands.txt
|
|||||||
# hledger help --cat hledger | sed -n '/^QUERIES/,/^[A-Z]/p'
|
# hledger help --cat hledger | sed -n '/^QUERIES/,/^[A-Z]/p'
|
||||||
|
|
||||||
command-options: commands.txt
|
command-options: commands.txt
|
||||||
parallel -j8 'hledger {} -h | ./output-options.sh | sort -u > options-{}.txt' < commands.txt
|
parallel -j8 'hledger {} -h | ./output-options.sh {} | sort -u > options-{}.txt' < commands.txt
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f commands*.txt generic-options.txt options-*.txt
|
rm -f commands*.txt generic-options.txt options-*.txt
|
||||||
rm -f hledger-completion.bash
|
rm -f hledger-completion.bash
|
||||||
|
rm -rf _{commands,options}.tmp
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,102 +1,99 @@
|
|||||||
|
|
||||||
# Completion script for hledger.
|
# Completion script for hledger.
|
||||||
# Created using a Makefile and real 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.
|
# This script is sourced by an interactive shell, so do NOT do things like
|
||||||
set -o pipefail
|
# 'set -o pipefail' or mangle the global environment in any other way!
|
||||||
|
# That said, we *do* remove colon (:) from COMP_WORDBREAKS which impacts
|
||||||
# Note: grep "^$wordToComplete" is (functional) not safe to use if the word
|
# the rest of the session and completion for other programs.
|
||||||
# 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() {
|
_hledger_completion_function() {
|
||||||
#declare cmd=$1
|
# Current treatment for special characters:
|
||||||
declare wordToComplete=$2
|
# - exclude colon (:) from COMP_WORDBREAKS
|
||||||
declare precedingWord=$3
|
# - use comptop -o filenames to escape the rest
|
||||||
|
COMP_WORDBREAKS=${COMP_WORDBREAKS//:}
|
||||||
|
compopt -o filenames
|
||||||
|
|
||||||
declare subcommand
|
local wordToComplete=$2
|
||||||
for subcommand in "${COMP_WORDS[@]}"; do
|
local subcommand
|
||||||
if grep -Fxqe "$subcommand" "$_HLEDGER_COMPLETION_TEMPDIR/commands.txt"; then
|
local subcommandOptions
|
||||||
COMPREPLY+=( $(grep -h "^$wordToComplete" -- "$_HLEDGER_COMPLETION_TEMPDIR/options-$subcommand.txt") )
|
local i
|
||||||
break
|
|
||||||
fi
|
for (( i=1; i<${#COMP_WORDS[@]}; i++ )); do
|
||||||
|
subcommand=${COMP_WORDS[i]}
|
||||||
|
if ! grep -Fxqe "$subcommand" <<< "$_hledger_complist_commands"; then
|
||||||
subcommand=
|
subcommand=
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# There could be other commands begining with $subcommand, e.g.:
|
||||||
|
# $subcommand == reg --> register, register-match,
|
||||||
|
# $subcommand == bal --> balance, balancesheet, balancesheetequity, etc.
|
||||||
|
# Do not ignore them!
|
||||||
|
if [[ $subcommand == "$wordToComplete" ]] && ((i == COMP_CWORD)); then
|
||||||
|
local subcommandMatches
|
||||||
|
subcommandMatches=$(grep -c "^$wordToComplete" <<< "$_hledger_complist_commands")
|
||||||
|
if ((subcommandMatches > 1)); then
|
||||||
|
subcommand=
|
||||||
|
break
|
||||||
|
else
|
||||||
|
_hledger_compreply "$subcommand"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Replace dashes with underscores and use indirect expansion
|
||||||
|
subcommandOptions=_hledger_complist_options_${subcommand//-/_}
|
||||||
|
_hledger_compreply "$(_hledger_compgen "${!subcommandOptions}")"
|
||||||
|
break
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -z $subcommand ]]; then
|
if [[ -z $subcommand ]]; then
|
||||||
|
_hledger_compreply_optarg && return
|
||||||
|
|
||||||
declare completeFiles filenameSoFar
|
# Completion lists are already sorted at build-time
|
||||||
case $precedingWord in
|
# This keeps commands and options grouped separately
|
||||||
-f|--file|--rules-file)
|
compopt -o nosort
|
||||||
completeFiles=1
|
_hledger_compreply "$(_hledger_compgen "$_hledger_complist_commands")"
|
||||||
filenameSoFar=$wordToComplete
|
_hledger_compreply_append "$(_hledger_compgen "$_hledger_complist_generic_options")"
|
||||||
;;
|
|
||||||
=)
|
|
||||||
completeFiles=1
|
|
||||||
filenameSoFar=$wordToComplete
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ -n $completeFiles ]]; then
|
return 0
|
||||||
#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
|
fi
|
||||||
|
|
||||||
else
|
# Option argument completion after subcommand too
|
||||||
|
_hledger_compreply_optarg && return
|
||||||
|
|
||||||
|
# Avoid setting compopt bellow if completing an option
|
||||||
|
[[ $wordToComplete == -* ]] && return
|
||||||
|
|
||||||
# Almost all subcommands accept [QUERY]
|
# Almost all subcommands accept [QUERY]
|
||||||
# -> always add accounts to completion list
|
# -> always add accounts to completion list
|
||||||
|
# Except for those few that will complain
|
||||||
|
local noQuery=(files help test)
|
||||||
|
[[ " ${noQuery[*]} " =~ " $subcommand " ]] && return
|
||||||
|
# Add any other subcommand special treatment here, or if it becomes unwieldy
|
||||||
|
# move it out in say _hledger_compreply_subcommand() and return on success.
|
||||||
|
|
||||||
# TODO Get ledger file from -f --file arguments from COMP_WORDS and pass it to
|
# Query specific completions
|
||||||
# the 'hledger accounts' call. Note that --rules-file - if present - must also
|
_hledger_compreply_query && return
|
||||||
# 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=' '
|
|
||||||
|
|
||||||
|
# Do not sort, keep accounts and query filters grouped separately
|
||||||
|
compopt -o nosort -o nospace
|
||||||
|
_hledger_compreply_append "$(_hledger_compgen "$_hledger_complist_query_filters")"
|
||||||
|
if [[ -z $wordToComplete ]]; then
|
||||||
|
_hledger_compreply_append "$(_hledger_compgen "$(_hledger accounts --flat --depth 1)")"
|
||||||
|
else
|
||||||
|
_hledger_compreply_append "$(_hledger_compgen "$(_hledger accounts --flat)")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_hledger_extension_completion_function() {
|
_hledger_extension_completion_function() {
|
||||||
declare cmd=$1
|
local cmd=$1
|
||||||
|
shift
|
||||||
|
|
||||||
# Change parameters and arguments and call the
|
# Change parameters and arguments and call the
|
||||||
# normal hledger completion function.
|
# normal hledger completion function.
|
||||||
declare extensionName=${cmd#*-}
|
local extensionName=${cmd#*-}
|
||||||
export -a COMP_WORDS=( "hledger" "$extensionName" "${COMP_WORDS[@]:1}" )
|
COMP_WORDS=( "hledger" "$extensionName" "${COMP_WORDS[@]:1}" )
|
||||||
#echo; echo "debug: ${COMP_WORDS[@]}"
|
|
||||||
shift
|
|
||||||
_hledger_completion_function "hledger" "$@"
|
_hledger_completion_function "hledger" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,26 +104,223 @@ complete -F _hledger_completion_function hledger
|
|||||||
complete -F _hledger_extension_completion_function hledger-ui
|
complete -F _hledger_extension_completion_function hledger-ui
|
||||||
complete -F _hledger_extension_completion_function hledger-web
|
complete -F _hledger_extension_completion_function hledger-web
|
||||||
|
|
||||||
|
# Helpers
|
||||||
|
|
||||||
|
# Comment out when done
|
||||||
|
_hledger_debug() {
|
||||||
|
((HLEDGER_DEBUG)) || return 0
|
||||||
|
local var=${1:-COMP_WORDS}
|
||||||
|
printf '\ndebug: %s\n' "$(declare -p "$var")" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stolen from bash-completion
|
||||||
|
# This function quotes the argument in a way so that readline dequoting
|
||||||
|
# results in the original argument. This is necessary for at least
|
||||||
|
# `compgen' which requires its arguments quoted/escaped:
|
||||||
|
_hledger_quote_by_ref()
|
||||||
|
{
|
||||||
|
printf -v $2 %q "$1"
|
||||||
|
|
||||||
|
# If result becomes quoted like this: $'string', re-evaluate in order to
|
||||||
|
# drop the additional quoting. See also: http://www.mail-archive.com/
|
||||||
|
# bash-completion-devel@lists.alioth.debian.org/msg01942.html
|
||||||
|
[[ ${!2} == \$* ]] && eval $2=${!2}
|
||||||
|
}
|
||||||
|
|
||||||
|
_hledger_quote()
|
||||||
|
{
|
||||||
|
local quoted
|
||||||
|
_hledger_quote_by_ref "$1" quoted
|
||||||
|
printf %s "$quoted"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set the value of COMPREPLY from newline delimited completion candidates
|
||||||
|
_hledger_compreply() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
COMPREPLY=($1)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Append the value of COMPREPLY from newline delimited completion candidates
|
||||||
|
_hledger_compreply_append() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
COMPREPLY+=($1)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate input suitable for _hledger_compreply() from newline delimited
|
||||||
|
# completion candidates. It doesn't seem there is a way to feed a literal
|
||||||
|
# wordlist to compgen -- it will eat your quotes, drink your booze and...
|
||||||
|
# Completion candidates are quoted accordingly first and then we leave it to
|
||||||
|
# compgen to deal with readline.
|
||||||
|
_hledger_compgen() {
|
||||||
|
local wordlist=$1
|
||||||
|
local quoted=()
|
||||||
|
local word
|
||||||
|
local i=0
|
||||||
|
|
||||||
|
while IFS= read -r word; do
|
||||||
|
_hledger_quote_by_ref "$word" word
|
||||||
|
quoted[i++]=$word
|
||||||
|
done <<< "$wordlist"
|
||||||
|
|
||||||
|
local IFS=$'\n'
|
||||||
|
compgen -W "${quoted[*]}" -- "$wordToComplete"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try required option argument completion. Set COMPREPLY and return 0 on
|
||||||
|
# success, 1 if option doesn't require an argument or out of context
|
||||||
|
_hledger_compreply_optarg() {
|
||||||
|
local optionIndex=${1:-$((COMP_CWORD - 1))}
|
||||||
|
local recursionLevel=${2:-0}
|
||||||
|
local wordlist
|
||||||
|
local error=0
|
||||||
|
|
||||||
|
case ${COMP_WORDS[optionIndex]} in
|
||||||
|
--alias)
|
||||||
|
compopt -o nospace
|
||||||
|
_hledger_compreply "$(_hledger_compgen "$(_hledger accounts --flat)")"
|
||||||
|
;;
|
||||||
|
-f|--file|--rules-file|-o|--output-file)
|
||||||
|
_hledger_compreply "$(compgen -f -- "$wordToComplete")"
|
||||||
|
;;
|
||||||
|
--pivot)
|
||||||
|
compopt -o nosort
|
||||||
|
wordlist="code description note payee"
|
||||||
|
_hledger_compreply "$(compgen -W "$wordlist" -- "$wordToComplete")"
|
||||||
|
_hledger_compreply_append "$(_hledger_compgen "$(_hledger tags)")"
|
||||||
|
;;
|
||||||
|
--value)
|
||||||
|
wordlist="cost then end now"
|
||||||
|
_hledger_compreply "$(compgen -W "$wordlist" -- "$wordToComplete")"
|
||||||
|
;;
|
||||||
|
-X|--exchange)
|
||||||
|
_hledger_compreply "$(_hledger_compgen "$(_hledger commodities)")"
|
||||||
|
;;
|
||||||
|
--color|--colour)
|
||||||
|
compopt -o nosort
|
||||||
|
wordlist="auto always yes never no"
|
||||||
|
_hledger_compreply "$(compgen -W "$wordlist" -- "$wordToComplete")"
|
||||||
|
;;
|
||||||
|
# Argument required, but no handler (yet)
|
||||||
|
-b|--begin|-e|--end|-p|--period|--depth)
|
||||||
|
_hledger_compreply ""
|
||||||
|
;;
|
||||||
|
=)
|
||||||
|
# Recurse only once!
|
||||||
|
((recursionLevel > 1)) && return 1
|
||||||
|
if [[ ${COMP_WORDS[optionIndex - 1]} == -* ]]; then
|
||||||
|
_hledger_compreply_optarg $((optionIndex - 1)) $((recursionLevel + 1))
|
||||||
|
error=$?
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return $error
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query filter completion through introspection
|
||||||
|
_hledger_compreply_query() {
|
||||||
|
[[ $wordToComplete =~ .: ]] || return
|
||||||
|
local query=${wordToComplete%%:*}:
|
||||||
|
grep -Fxqe "$query" <<< "$_hledger_complist_query_filters" || return
|
||||||
|
|
||||||
|
local hledgerArgs=()
|
||||||
|
case $query in
|
||||||
|
acct:)
|
||||||
|
hledgerArgs=(accounts --flat)
|
||||||
|
;;
|
||||||
|
code:)
|
||||||
|
hledgerArgs=(codes)
|
||||||
|
;;
|
||||||
|
cur:)
|
||||||
|
hledgerArgs=(commodities)
|
||||||
|
;;
|
||||||
|
desc:)
|
||||||
|
hledgerArgs=(descriptions)
|
||||||
|
;;
|
||||||
|
note:)
|
||||||
|
hledgerArgs=(notes)
|
||||||
|
;;
|
||||||
|
payee:)
|
||||||
|
hledgerArgs=(payees)
|
||||||
|
;;
|
||||||
|
tag:)
|
||||||
|
hledgerArgs=(tags)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
_hledger_compreply "$(
|
||||||
|
_hledger_compgen "$(
|
||||||
|
_hledger "${hledgerArgs[@]}" | sed "s/^/$query/g"
|
||||||
|
)"
|
||||||
|
)"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get ledger file from -f --file arguments from COMP_WORDS and pass it to the
|
||||||
|
# 'hledger' call. Note that --rules-file - if present - must also be passed!
|
||||||
|
_hledger() {
|
||||||
|
local hledgerArgs=("$@")
|
||||||
|
local hledgerFile
|
||||||
|
local hledgerRulesFile
|
||||||
|
local i
|
||||||
|
|
||||||
|
# hledger balance --file ~/ledger _
|
||||||
|
# 0 1 2 3 4
|
||||||
|
for (( i=1; i < ${#COMP_WORDS[@]} - 2; i++ )); do
|
||||||
|
case ${COMP_WORDS[i]} in
|
||||||
|
-f|--file)
|
||||||
|
if [[ ${COMP_WORDS[i+1]} == '=' ]]; then
|
||||||
|
hledgerFile=${COMP_WORDS[i+2]}
|
||||||
|
else
|
||||||
|
hledgerFile=${COMP_WORDS[i+1]}
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--rules-file)
|
||||||
|
if [[ ${COMP_WORDS[i+1]} == '=' ]]; then
|
||||||
|
hledgerRulesFile=${COMP_WORDS[i+2]}
|
||||||
|
else
|
||||||
|
hledgerRulesFile=${COMP_WORDS[i+1]}
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ -f $hledgerFile ]] && hledgerArgs+=(--file "$hledgerFile")
|
||||||
|
[[ -f $hledgerRulesFile ]] && hledgerArgs+=(--rules-file "$hledgerRulesFile")
|
||||||
|
|
||||||
|
# Discard errors. Is there a way to validate files before using them?
|
||||||
|
hledger "${hledgerArgs[@]}" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# Include lists of commands and options generated by the Makefile using the
|
# Include lists of commands and options generated by the Makefile using the
|
||||||
# m4 macro processor.
|
# m4 macro processor.
|
||||||
# Included files must have exactly one newline at EOF to prevent weired errors.
|
# Included files must have exactly one newline at EOF to prevent weired errors.
|
||||||
|
|
||||||
cat <<TEXT > "$_HLEDGER_COMPLETION_TEMPDIR/commands.txt"
|
read -r -d "" _hledger_complist_commands <<TEXT
|
||||||
include(`commands.txt')dnl
|
include(`commands.txt')dnl
|
||||||
TEXT
|
TEXT
|
||||||
|
|
||||||
cat <<TEXT > "$_HLEDGER_COMPLETION_TEMPDIR/query-filters.txt"
|
read -r -d "" _hledger_complist_query_filters <<TEXT
|
||||||
include(`query-filters.txt')dnl
|
include(`query-filters.txt')dnl
|
||||||
TEXT
|
TEXT
|
||||||
|
|
||||||
cat <<TEXT > "$_HLEDGER_COMPLETION_TEMPDIR/generic-options.txt"
|
read -r -d "" _hledger_complist_generic_options <<TEXT
|
||||||
include(`generic-options.txt')dnl
|
include(`generic-options.txt')dnl
|
||||||
TEXT
|
TEXT
|
||||||
|
|
||||||
include(`foreach2.m4')
|
# Dashes are replaced by m4 with underscores to form valid identifiers
|
||||||
|
# Referenced by indirect expansion of $subcommandOptions
|
||||||
|
dnl
|
||||||
|
include(`foreach2.m4')dnl
|
||||||
foreach(`cmd', (include(`commands-list.txt')), `
|
foreach(`cmd', (include(`commands-list.txt')), `
|
||||||
cat <<TEXT > "$_HLEDGER_COMPLETION_TEMPDIR/options-cmd.txt"
|
read -r -d "" _hledger_complist_options_`'translit(cmd, -, _) <<TEXT
|
||||||
include(options-cmd.txt)dnl
|
include(options-cmd.txt)dnl
|
||||||
TEXT
|
TEXT
|
||||||
')
|
')dnl
|
||||||
|
|||||||
@ -4,20 +4,16 @@
|
|||||||
set -o errexit -o pipefail -o nounset
|
set -o errexit -o pipefail -o nounset
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
declare tmp
|
declare tmp="_commands.tmp"
|
||||||
tmp=$(mktemp)
|
|
||||||
cat > "$tmp"
|
cat > "$tmp"
|
||||||
|
|
||||||
# Do not output mistaken commands that start with a dash (e.g. -h)
|
sed -rn 's/^\s+([a-z][-a-z]+)\s+.*/\1/p' "$tmp"
|
||||||
sed -rn 's/^ ([-a-z]+).*/\1/gp' "$tmp" \
|
|
||||||
| grep -v ^-
|
|
||||||
|
|
||||||
# Output single command aliases in parenthesis:
|
# Output command aliases in parenthesis:
|
||||||
# Do not output single letter command aliases, it's not useful.
|
# Do not output single letter command aliases, it's not useful.
|
||||||
sed -rn 's/^ .*\(([a-z]+)\).*/\1/gp' "$tmp" \
|
sed -rn 's/^\s+[a-z][-a-z]+\s+\(([a-z][ ,a-z]+)\).*/\1/p' "$tmp" |
|
||||||
| grep -v ^.$
|
sed 's/\s*,\s*/\n/g' |
|
||||||
|
sed '/^.$/d'
|
||||||
# TODO missing: (reg, r) (multiple aliases)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
@ -4,10 +4,16 @@
|
|||||||
set -o errexit -o pipefail -o nounset
|
set -o errexit -o pipefail -o nounset
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
declare tmp
|
declare tmpdir="_options.tmp"
|
||||||
tmp=$(mktemp)
|
declare tmp="${tmpdir}/${1:-generic}"
|
||||||
|
|
||||||
|
mkdir -p "$tmpdir"
|
||||||
cat > "$tmp"
|
cat > "$tmp"
|
||||||
sed -rn 's/.* (-[a-zA-Z0-9]).*/\1/gp' < "$tmp"
|
|
||||||
|
# Do not propose single letter completions. It's not useful, it's noisy
|
||||||
|
# and it makes completion slower:
|
||||||
|
# Display all 200 possibilities? (y or n)
|
||||||
|
# sed -rn 's/.* (-[a-zA-Z0-9]).*/\1/gp' < "$tmp"
|
||||||
|
|
||||||
# Do not print '=' after long options with arg because it makes completion
|
# Do not print '=' after long options with arg because it makes completion
|
||||||
# for option arguments harder.
|
# for option arguments harder.
|
||||||
|
|||||||
@ -1,22 +1,15 @@
|
|||||||
not:
|
|
||||||
acct:
|
acct:
|
||||||
amt:
|
amt:
|
||||||
amt:<
|
|
||||||
amt:<=
|
|
||||||
amt:>
|
|
||||||
amt:>=
|
|
||||||
code:
|
code:
|
||||||
cur:
|
cur:
|
||||||
desc:
|
|
||||||
date:
|
date:
|
||||||
date2:
|
date2:
|
||||||
depth:
|
depth:
|
||||||
|
desc:
|
||||||
|
inacct:
|
||||||
|
not:
|
||||||
note:
|
note:
|
||||||
payee:
|
payee:
|
||||||
real:
|
real:
|
||||||
real:0
|
|
||||||
status:
|
status:
|
||||||
status:!
|
|
||||||
status:*
|
|
||||||
tag:
|
tag:
|
||||||
inacct:
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user