Home

Awesome

sh-manpage-completions

Automatically generate bash and zsh completions from man pages.

Uses fish-shell's create_manpage_completions.py to parse the pages, then converts the resulting fish completions.

Example

./run.sh /usr/share/man/man1/tar.1.gz

You can then take the files from completions/$shell/ and use them according to your configuration:

Requirements

./dependencies.sh is run to check for any missing executables.

Testing

If you introduce any source changes, validate them with ./test.sh, which generates completions for an example man page, and fails if any differences are found:

--- ./test/out/zsh/_foo 2023-10-19 07:57:51.901604671 +0100
+++ ./completions/zsh/_foo      2023-10-19 08:09:41.024276201 +0100
@@ -6,4 +6,4 @@
                {-y,--yellow}'[Option 2]' \
                '--bar[Option 3]' \
                '-b[Option 4]' \
-               '--orange[Option 5]'
+               '--orange[Option 5]' \
Test FAILED: 'zsh' completion mismatched expected output.

Limitations

Bash doesn't support descriptions in completions. There has been some discussion about workarounds. Two different strategies were implemented:

  1. Separate descriptions

Consists on printing the completions with descriptions, before bash displays the completions again. It results in redundancy but doesn't break tab behaviour. Descriptions can be omitted like so:

BASH_NO_DESCRIPTIONS=1 ./run.sh /usr/share/man/man1/tar.1.gz
  1. Filter through a selector

You can use a fuzzy selector to extract the right option, containing both the completion and its description. No redundancy, but relies on an external application. Can be used like so:

BASH_USE_SELECTOR=1 ./run.sh /usr/share/man/man1/tar.1.gz

Uses fzf by default. You can pass another one, optionally with an argument that takes the current input as a query, filtering down the results:

BASH_USE_SELECTOR=1 SELECTOR=fzy SELECTOR_QUERY='-q' ./run.sh /usr/share/man/man1/tar.1.gz

Related Work

License

Files in fish-tools were taken from fish-shell's source code, which is released under the GNU General Public License, version 2 (see LICENSE.GPL2).

The remaining source code is released under the MIT License (see LICENSE.MIT).