An extensive overhaul by @zhelezov of the bash programmable
completions in shell-completions/.
"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. Oops, they are actually synonymous when used in a function but
local declares our intentions explicitly.
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
editing 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."
price directives after the last transaction/posting date if using
--value=end.
Also enlarges the reportspan to encompass full intervals for budget
goals.
* `help` command's output is no longer listing help topics, so
those completions are removed.
* `check` command supersedes `check-dates`, `check-dupes`, etc.
Most of the included files are meant to be output literally, without any
macro processing. Using `undivert` in place of `include` achieves that.
This is a safety net against unsanitized input generated during the
build. Also, developers editing the shell code stub shouldn't be
constantly alert about triggering accidental macro expansion.
In order that `undivert` mimics GNU behaviour on BSDs, the `-g` flag is
used for the m4 invocation.
Install the symlinks unconditionally. This way the user don't need
to reinstall completion after adding an extension. Of course fine-
grained control is possible with: `make install EXTENSIONS=web` e.g.
It is not a substitute for proper error checking, it can easily cause
more trouble than good and it would be a burden for contributors and a
source for potential misbehavior. See this take on the topic for
example: http://mywiki.wooledge.org/BashFAQ/105
A `make clean` before commit removes hledger-completion.bash and
it is supposed to be in the repository. `make clean` removes build
artifacts while keeping the latter. Do a `make clean-all` to purge
everything.
It is just a pipe of sed regex filters and all can be viewed/edited
in one place. Add a couple of debug targets to see easily the
effects of regex changes.
This way we can easily edit m4 in m4-mode and the shell script stub
in sh-mode and prevent subtle errors coming from accidental quoting
issues or macros (mis)interpreted by m4.