The core of generate
is ./scripts/generate.sh
.
generate.sh
can directly generate completion scripts for most commands.
However, the help of some commands is not standardized, or some options or positional parameters in the command require dynamic data, you may need to add scripts to assist generate.sh
to complete the job.
You may check out the src for examples.
generate.sh
internally generates the completion script according to the following processing flow.
parse-tab.awk parse-script.awk
help-text(_patch_help) ---------------> table(_patch_table) ------------------> script
Let's take aichat
as an example.
- help-text:
aichat --help
Use ChatGPT, LocalAI and other LLMs in the terminal.
Usage: aichat [OPTIONS] [TEXT]...
Arguments:
[TEXT]... Input text
Options:
-m, --model <MODEL> Choose a LLM model
-r, --role <ROLE> Choose a role
-s, --session [<SESSION>] Create or reuse a session
-H, --no-highlight Disable syntax highlighting
-S, --no-stream No stream output
--dry-run Run in dry run mode
--info Print related information
--list-models List all available models
--list-roles List all available roles
--list-sessions List all available sessions
-h, --help Print help
-V, --version Print version
- table:
aichat --help | gawk -f scripts/parse-table.awk
option # -m, --model <MODEL> # Choose a LLM model
option # -r, --role <ROLE> # Choose a role
option # -s, --session [<SESSION>] # Create or reuse a session
option # -H, --no-highlight # Disable syntax highlighting
option # -S, --no-stream # No stream output
option # --dry-run # Run in dry run mode
option # --info # Print related information
option # --list-models # List all available models
option # --list-roles # List all available roles
option # --list-sessions # List all available sessions
option # -h, --help # Print help
option # -V, --version # Print version
argument # [TEXT]... # Input text #
- script:
aichat --help | gawk -f scripts/parse-table.awk | gawk -f scripts/parse-script.awk
# @option -m --model Choose a LLM model
# @option -r --role Choose a role
# @option -s --session Create or reuse a session
# @flag -H --no-highlight Disable syntax highlighting
# @flag -S --no-stream No stream output
# @flag --dry-run Run in dry run mode
# @flag --info Print related information
# @flag --list-models List all available models
# @flag --list-roles List all available roles
# @flag --list-sessions List all available sessions
# @flag -h --help Print help
# @flag -V --version Print version
# @arg text* Input text
When generate.sh <cmd>
is executed, it will look for a <cmd>.sh
file in the src/
directory and run the _patch_*
functions in it.
_patch_help
is a hook to provide/patch help text. If omitted, generate.sh
runs <cmd> [subcmd]... --help
to generate help text.
Here are some use cases for _patch_help
:
- curl: execute
curl --help all
to get help text. - npm: manually provide help text as the help text generated by npm is too non-standard.
- ssh: use man-page other than help text.
_patch_table
is a hook to patch the generated table,usually used to bind option/positional parameter to _choice*
functions.
Let's also take aichat
as an example.
_patch_table() {
_patch_table_edit_options \
'--model;[`_choice_model`]' \
'--role;[`_choice_role`]' \
'--session;[`_choice_session`]' \
}
With _patch_table
, _choice_*
is appended to fourth column.
- option # -r, --role <ROLE> # Choose a role
+ option # -r, --role <ROLE> # Choose a role # [`_choice_role`]
This affects the final generated argc script.
- # @option -r --role Choose a role
+ # @option -r --role[`_choice_role`] Choose a role
_choice_fn
will generate dynamic completion candidates.
Let's also take aichat
as an example.
Suppose you are typing aichat --role <tab>
, when <tab>
is pressed, _choice_role
bound to --role
will run and provide completion data.
In _choice_*
function, you can use argc_*
variables to easily access option/positional value. see argc-variables for more details.
We also privode some utility functions to make it easier to write _choice_*
function.
_choice_fn() {
echo abc # value only,
echo -e "def\0" # value only, no space
echo -e "ijk\tDesc" # value with description
echo -e "nop\0\tDesc" # value with description, no space
}
Argcfile.sh
provide a number of commands that can help with the development of the completion script.
- print: Print help/table/script, used for debugging
_patch_help
and_patch_table
- generate: Generate the completion script.
- choice-fn: Run a choice fn directly
argc print aichat -k help # Run: _patch_help
argc print aichat -k table # Run: _patch_help | awk -f ./scripts/parse-table.awk | _patch_table
argc print aichat -k script # Run: _patch_help | awk -f ./scripts/parse-table.awk | _patch_table | awk -f ./scripts/parse-script.awk
argc generate aichat # Run: ./scripts/generate.sh -o completions/aichat.sh aichat
argc format aichat # Run: ./scripts/format.sh src/aichat.sh
argc choice-fn src/aichat.sh _choice_model # Run _choice_model in src/aichat.sh
argc choice-fn completions/aichat.sh _choice_model # Run _choice_model in completions/aichat.sh