へルプオプション `--help` を受け付けるコマンドのオプション補完をある程度自動的にしてくれる `_gnu_generic` 関数の使い方です。

「 `./configure` の補完は必要な時に、危険を承知で `./configure --help` を実行して補完候補を作っている」と聞いたことがあると思います。 `_gnu_generic` というのはこれと似たような機能を提供してくれる補完システムのユーティリティ関数で、オプションの補完に `$command --help` を実行してその結果から補完候補を作ってくれます。

例えば、コマンド `emacsclient` の補完はzshには用意されておらず、オプションの補完はされません。そこで `_gnu_generic` を使います。

    ;# emacs 等もオプションの補完が無いのでここで一挙に指定してしまいます
    % compdef _gnu_generic emacs emacsclient emacs-snapshot emacsclient.emacs-snapshot
    % emacsclient -<TAB>
    --create-frame  -c       -- Create a new frame instead of trying to
    --eval          -e       -- Evaluate the FILE arguments as ELisp expressions
    --help          -H       -- Print this usage information message
    --no-wait       -n       -- Don't wait for the server to return
    --parent-id              -- Open in parent window ID, via XEmbed
    --quiet         -q       -- Don't display messages on success
    --tty           -nw  -t  -- Open a new Emacs frame on the current terminal
    --version       -V       -- Just print version info and return
    -F                       -- ALIST, --frame-parameters=ALIST
    -a                       -- EDITOR, --alternate-editor=EDITOR
    -d                       -- DISPLAY, --display=DISPLAY
    -f                       -- SERVER, --server-file=SERVER
    -s                       -- SOCKET, --socket-name=SOCKET

\*だいたい\*上手く行きました。とってもたすかります！

ここで、 `--help` の出力ではちょっとだけ上手くないみたい、とか、勝手に `$command --help` が実行されるなんて気味が悪い、はたまた、zshの補完関数を作るよりも `$command --help` のような出力をする小っちゃいプログラムを書いちゃった方が楽ちんかもしれない、なんていう場合等には、自分の都合のよいシェル関数等が実行されるようにするのもよいと思います。

例えば、 `libreoffice` コマンドでは、

    % compdef _gnu_generic libreoffice
    % libreoffice --hel<TAB>
    % libreoffice --help/-h/-?

と、ちょっとだけ悲しい感じに…そこで以下のように、指定したシェル関数が実行されるようにしてしまいます。

    % zstyle ':completion:*:libreoffice:*:options' command fake-libreoffice
    % fake-libreoffice () { libreoffice --help | sed "s#/-h/-?#,-h,-?#" }

`zstyle` の所が何だこりゃという向きにはドキュメントをあたってみるととっても詳しく記述がありますれども、ここではざっくりと。やっていることは、

「 *libreoffice* のオプション補完時に、 *fake-libreoffice* を使う」

というような設定です。(厳密に正確ではないんだけれども許して！) その下がその `fake-libreoffice` というシェル関数なんだけれども、やっているのは `libreoffice --help` の出力が都合の良くなるようにちょこっとだけ書きかえることです。

(大抵の補完関数は、あるコマンドが必要になった時に直接そのプログラムを実行するように記述されることは希で、今回のようにユーザーが指定することができるように `_call_program` 関数を経由することが多いと思います。)

すると、

    ;# ${_args_cache_*}、ここにキャッシュされるので unset します
    % unset _args_cache_libreoffice
    % libreoffice -<TAB>
    libreoffice -
    --accept             -- Specify an UNO connect-string to create an UNO accepto
    --base               -- create new database.
    --calc               -- create new spreadsheet document.
    --convert-to         -- output_file_extension(-output_filter_name) (--outdir o
    --display            -- <display>
    --draw               -- create new drawing.
    --global             -- create new global document.
    --headless           -- like invisible but no userinteraction at all.
    --help           -h  -- show this message and exit.
    --impress            -- create new presentation.
    --infilter           -- Force an input filter type if possible
    --invisible          -- no startup screen, no default document and no UI.
    --math               -- create new formula.
    --minimized          -- keep startup bitmap minimized.
    --nodefault          -- don't start with an empty document
    --nolockcheck        -- don't check for remote instances using the installatio
    --nologo             -- don't show startup screen.
    --norestore          -- suppress restart/restore after fatal errors.
    --print-to-file      -- (-printer-name printer_name) (--outdir output_dir) fil
    --printer-name       -- nasty_lowres_printer --outdir /home/user *.doc
    --pt                 -- <printer> <documents...>
    --quickstart         -- starts the quickstart service
    --show               -- <presentation>
    --unaccept           -- Close an acceptor that was created with --accept=<acce
    --version            -- display the version information.
    --view           -p  -- <documents...>
    --web                -- create new HTML document.
    --writer             -- create new text document.
    -n                   -- always open documents as new files (use as template).
    -o                   -- open documents regardless whether they are templates o

`--help` の所が意図した通りになってくれました。

`$command --help` の出力から候補を作ってもらいつつ色々したいなとなったらば、まずは `_configure` 関数を見ると、その下位の `_arguments` 関数の呼び出し方の参考にできるんじゃないかなと思いました。

さて、 なかなか `_gnu_generic` 関数だけでピッタリくるコマンドも少ないかもしれませんけれども、そういうコマンドが見つかると得したような気分になります、最近では `clamscan` コマンドがバッチリとはまってくれました(\^\^

本家のマニュアルはこちらからどうぞ。

-   [`_gnu_generic`](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-_005fgnu_005fgeneric)

-   [`_call_program`](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#index-_005fcall_005fprogram)

Qiita初投稿です、どうぞよろしくね！