## Enhancing Command-Line Completion with Descriptions
Command-line interfaces (CLIs) are powerful tools, but remembering every flag and option can be challenging. Effective tab completion significantly improves usability, and a refined approach can make it even better by displaying helpful descriptions alongside your completions. This article explores how to achieve this, ensuring you get the details you need right at your fingertips.
### The Problem with Ambiguous Completions
Traditionally,tab completion aims to provide a concise list of possible commands or options. Though, sometimes you want more context – a fast reminder of what a particular option *does*. Simply hitting `
Standard completion systems frequently enough struggle with this. When a completion is ambiguous – meaning multiple possibilities exist – Bash and Zsh typically show both the completion *and* its associated description. But what if you want this behavior even when there’s only one possible completion?
### A Solution: Intentional Ambiguity
The key is to intentionally create ambiguity. By adding a secondary, trimmed completion alongside the primary one, you force the shell to display the description. This approach works reliably across both Bash and Zsh, providing a consistent experience.
Here’s how you can implement this strategy:
#### Bash Implementation
Utilize the `_complete_foo_bash` function to achieve this.
1. First, define the `IFS` (Internal Field Separator) to handle whitespace correctly.
2. Than, generate your completions using a helper function, `_generate_foo_completions`, passing the current word index (`$COMP_CWORD`) and the words entered so far (`${COMP_WORDS[@]}`).
3. Store the raw completions in an array called `raw`.
4. Create a new array, `trimmed`, and populate it with the raw completions.
5. If the `raw` array contains only one element, append a trimmed version of that element to the `trimmed` array. This trimmed version removes the descriptive text,creating the intentional ambiguity.
6.assign the `trimmed` array to `COMPREPLY`, which Bash uses to display the completions.
here’s the code:
“`bash
_complete_foo_bash() {
local IFS=$’n’
local raw=($(_generate_foo_completions “$COMP_CWORD” “${COMP_WORDS[@]}”))
local trimmed=()
trimmed+=( “${raw[@]}” )
if (( ${#raw[@]} == 1 )); then
trimmed+=( “${raw[0]%%:*}” )
fi
COMPREPLY=( “${trimmed[@]}” )
}
“`
This ensures that even a single completion will trigger the display of its description, while the trimmed version prevents the description from being inserted into your command.
#### Zsh Implementation
The process is similar in Zsh, using the `_complete_foo_zsh` function.
1. Declare local arrays `raw` and `trimmed`.
2. Set the `IFS` to handle whitespace.
3. Generate completions using `_generate_foo_completions`, passing the current word (`$CURRENT`) and the words entered (`${words[@]}`).
4. Iterate through the `raw` completions, adding the trimmed versions (without the description) to the `trimmed` array.
5.If there’s only one completion, append both the trimmed version and the original to both `trimmed` and `raw` arrays. This is crucial as Zsh’s `compadd` function expects parallel arrays of descriptions and tokens.
6. Use `compadd -d raw — $trimmed` to add the completions to the completion list. The `-d` flag specifies the descriptions, and the `–` separates the descriptions from the tokens.
Here’s the Zsh code:
“`bash
_complete_foo_zsh() {
local -a raw trimmed
Worth a look