Open ivan-pi opened 3 years ago
bash-shell completion scripts (using complete(1) and compgen(1)) would be very nice, and bash is almost ubiquitous except for some MSWindows environments. It could proceed as a separate project and not require code changes, just a stable CLI interface to describe. So it seems like a great idea.
But I was wondering what prompted the desire, as maybe there are a few other changes to fpm(1) that would help even in the DOS Programming Environment. Assuming it might be the long descriptive keywords
would short names for the command options help, so you could enter "fpm run -EL -R 'ls -l'" instead of "fpm run --example --list --runner 'ls -l'?
would something like response files, as described in the M_CLI2 documentation be useful? That was actually for possible use by fpm
as proposed by @awvwgk ; but it is not activated and might need some tweeking. As-is you can make abbreviations for your favorite commands and then enter "fpm @itest" instead of "fpm test --compiler ifort --runner time" and so on. It should be relatively platform independent as well.
I am not a big user of complete
and compgen
so I am not sure if it is remotely feasible but I am wondering if a CLI parser like M_CLI2, FLAP, kracken, getopt_long_options , ... can generate at least the beginnings of a bash command completion script. If it could, that seems like a nice idea for adding to M_CLI2.
But I was wondering what prompted the desire, as maybe there are a few other changes to fpm(1) that would help even in the DOS Programming Environment. Assuming it might be the long descriptive keywords
I don't really have a full concept for what type of completions.
My favorite would be if fpm build <tab><tab>
would list the available targets. Currently whenever I forget the name of my build targets I have to do:
fpm build --list
fpm build <my_target>
It might also be nice to have simple command completions like fpm b<tab>
to list commands starting with b.
I also like how git <tab><tab>
lists the available subcommands. I think it would be nice if fpm <tab><tab>
would do the same.
On the other hand fpm<tab><tab>
(no space) could be saved for listing plugins like fpm-search
and other future programs.
I don't think the targets can be listed by bash completion like a pathname could, but in the current release if you enter a name you know does not exist for run
you get a compact list of basenames. In a proposed PR #370
you can enter quoted glob strings like
fpm run '*'
fpm run '*demo*'
for run
and test
targets and on the --list argument and (if there is more than one target) you get a list of the basenames. Using \
Was thinking of allowing for a menu more like autocompletion but did not add it as as in the discussions it came up that something fancier that would be free (to a greater extent, anyway) to use things like ncurses or shell commands would probably be done better with a plug-in like fpm-search can be used in #364(?).
Note the only auto completion I know of is in the OS or shell, not directly in the programs; but I have not looked that hard.
I know of one command line parser (for a different language) that has bash completion built in: optparse-applicative. This is actually what I had used for the Haskell implementation, but hadn't turned on the bash completion. So there is precedent for having the bash-completion built in. I don't know all of the intricacies with how bash completion works though, so not sure how difficult it is.
Just what I was thinking from what I can tell so far; but more involved than I hoped. Looks like adding something that would just expand keywords and filenames for a regular command would be relatively straight-forward; but doing it with subcommands with M_CLI2 as it currently works totally automatically seems complicated. Maybe writing a program to take in a description of the form cmd [a|b|c]|[--help|--version] like is often in help text (at least in man-pages) would be generically useful. Some interesting possibilities. Unfortunately not trivial ones. At least, not for automating generation of the files. The original proposal seems like the better plan for the foreseeable future.
A quick and dirty bash completion demo for fpm targets based on this answer.
Cool! I would need a day to understand how or why that bash scripts works :joy:. (hopefully we can find some reviewers for PR's)
How does one ship such a bash-completion script?
How does one ship such a bash-completion script?
I imagine this is where system package managers become useful, though I know very little about distribution best-practices. The next best option may be to have the install.sh
script copy the completion scripts to the correct system location
For Unix there are two possibilities:
/etc/profile.d
eval "$(fpm bashcompletion)"
at shell startup, where fpm-bashcompletion
might be a plugin or fpm intrinsic to print the required bash functionsPerhaps slightly tangential, but the Conda installer (or conda init
command) typically add a section similar to this one to the ~/.bashrc
settings:
# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/opt/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/opt/miniconda3/etc/profile.d/conda.sh" ]; then
. "/opt/miniconda3/etc/profile.d/conda.sh"
else
export PATH="/opt/miniconda3/bin:$PATH"
fi
fi
unset __conda_setup
# <<< conda initialize <<<
(For system wide installations a symlink can be made instead like sudo ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh
):
The purpose is the following:
The contents of the file /opt/miniconda3/etc/profile.d/conda.sh
are:
Conda is a quite particular case because it tries to modify variables like PS1
to display a modified prompt and such.
For Unix there are two possibilities:
- sourcing a script at startup, this is usually placed in
/etc/profile.d
- Running
eval "$(fpm bashcompletion)"
at shell startup, wherefpm-bashcompletion
might be a plugin or fpm intrinsic to print the required bash functions
git
has a script placed in /usr/share/bash-completion/completions/
(on Ubuntu) — can we do something similar (given root permissions), or is this not recommended?
If we get with fpm ever installed in the system prefix this would be preferable, otherwise we should place the completion on install at $PREFIX/share/bash-completion/completions
, this would be possible with an extra manifest entry in the install table.
for reference /etc/bash_completion.d/ is a directory on Red Hat specifically for an admin to put completion scripts.
Along the lines mentioned, a plugin command like fpm-bash could probably customize the environment without changing user prologue files or installing files and spawn a subshell, but would therefore require repeated use instead of a "one-time" setup. Did not actually try it, but something platform-specific could be a plugin written in any language so I think it could just be a bash script.
At some point it would be nice to give
fpm
command line completion capabilities (like git or other command-line programs).An example of what the command-completion scripts look like in git can be found here: https://github.com/git/git/tree/328c10930387d301560f7cbcd3351cc485a13381/contrib/completion
A more gentle introduction can be found in various online tutorials, e.g.: https://iridakos.com/programming/2018/03/01/bash-programmable-completion-tutorial