Last active
February 22, 2023 15:06
-
Star
(111)
You must be signed in to star a gist -
Fork
(2)
You must be signed in to fork a gist
-
-
Save rummelonp/4954559 to your computer and use it in GitHub Desktop.
Revisions
-
rummelonp revised this gist
Feb 15, 2013 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -217,15 +217,15 @@ __nyan_modes() {  オプションと補完候補に同時に出すために `_arguments` 関数を使う オプションの指定は `optname[desc]` と指定する 同じ意味のオプションがある場合は `{optname1,optiname2}` とカンマ区切りで書く 引数の指定は `n:message:action` と指定する `n` は何番目の引数に対して動作するかを表す 何回でも同じ引数を補完出来て良いので `*` と指定しておく `message` はその補完候補の説明を表す 今回は引数を省略する(理由は後述) @@ -234,7 +234,7 @@ __nyan_modes() { `*: :__nyan_modes` と書くことで、全ての補完候補で `__nyan_modes` 関数が使われる `__nyan_modes` 関数内の `_values` 関数で `mode` というグループ名(説明)指定しているため `message` を省略してる 説明を出すため/見通しをよくするためモードの補完候補を別関数に分けたが、説明を伴わない場合は `'*:mode:(neko usagi kuma github)'` のように書くことも出来る 出来れば `--help` が入力された時はそこで補完を終了させたい 最後にそのための改良をする -
rummelonp revised this gist
Feb 14, 2013 . 1 changed file with 1 addition and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -48,9 +48,7 @@ _nyan() { compdef _nyan nyan ``` ## nyan コマンドを作る まずは猫を表示してくれる可愛い `nyan` コマンドを作る -
rummelonp revised this gist
Feb 14, 2013 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -167,7 +167,6 @@ _nyan() { 'kuma' \ 'github' } ```  @@ -190,7 +189,6 @@ _nyan() { 'kuma[kawaii kuma-neko]' \ 'github[kawaii octcat]' } ```  -
rummelonp created this gist
Feb 14, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,303 @@ # zsh の補完関数の自作導入編 あまり深く理解してないので識者のツッコミ大歓迎 ## 補完を有効にする 取り敢えず最低限だけ ```zsh # 補完を有効にする autoload -U compinit compinit -u # 補完メッセージを読みやすくする zstyle ':completion:*' verbose yes zstyle ':completion:*' format '%B%d%b' zstyle ':completion:*:warnings' format 'No matches for: %d' zstyle ':completion:*' group-name '' ``` ## 補完関数のルール $fpath の通ったディレクトリに補完関数を置く `nyan` コマンドの補完関数なら `_nyan` という名前で保存する 補完関数の先頭には `#compdef nyan` と補完対象のコマンド名を書く ファイル名と同じ名前の関数を作りその中に補完関数を書く `~/zsh/functions/_nyan` ```zsh #compdef nyan _nyan() { # 補完関数 } ``` あるいは下記のように書いたファイルを `source ~/zsh/lib/_nyan.zsh` と読み込むことで補完関数を有効にすることも出来る `compdef _nyan nyan` は `_nyan` 関数を `nyan` コマンドの補完関数として使うという意味になる `~/zsh/lib/_nyan.zsh` ```zsh _nyan() { # 補完関数 } compdef _nyan nyan ``` ## 実際に作ってみる ### nyan コマンドを作る まずは猫を表示してくれる可愛い `nyan` コマンドを作る `~/bin/nyan` ```zsh #!/usr/bin/env zsh function nyan() { typeset -a modes help() { echo 'Usage: nyan <mode>' echo echo 'Modes:' echo ' neko, usagi, kuma, github' } neko() { echo ' ∧_∧' echo "ฅ'ω'ฅ < ニャーン" } usagi() { echo ' /) /)' echo '_( _ ๑❛ᴗ❛)_ < ニャーン' } kuma() { echo '(´(ェ)`) < ニャーン' } github() { echo '=͟͟͞͞=͟͟͞͞=͟͟͞͞ (\ (\' echo '=͟͟͞͞=͟͟͞͞=͟͟͞͞(,, 0 ω 0) < ニャーン' echo '=͟͟͞͞=͟͟͞͞=͟͟͞͞(/ (/ \) \)' } while [ $1 ]; do case $1 in -h|--help) help return ;; *) modes=($modes[*] $1) ;; esac shift done if (( $#modes == 0 )); then neko return fi for mode in $modes; do if type $mode > /dev/null 2>&1; then $mode else echo "No such mode \"$mode\"" fi done } nyan $@ ``` 動かしてみる ```zsh $ nyan ∧_∧ ฅ'ω'ฅ < ニャーン $ nyan wan No such mode "wan" $ nyan --help Usage: nyan <mode> Modes: neko, usagi, kuma, github $ nyan usagi /) /) _( _ ๑❛ᴗ❛)_ < ニャーン $ nyan kuma github (´(ェ)`) < ニャーン =͟͟͞͞=͟͟͞͞=͟͟͞͞ (\ (\ =͟͟͞͞=͟͟͞͞=͟͟͞͞(,, 0 ω 0) < ニャーン =͟͟͞͞=͟͟͞͞=͟͟͞͞(/ (/ \) \) ``` neko, usagi, kuma, github の4つのモードと --help の1つのオプションがある モードは複数指定することが出来る ## nyan 補完関数を作る まずは4つの全てのモードを補完候補に出してみる `~/zsh/functions/_nyan` ```zsh #compdef nyan _nyan() { _values \ 'mode' \ 'neko' \ 'usagi' \ 'kuma' \ 'github' } ```  `_values` 関数を使うとひとつ目の引数が補完候補のグループ名、その後の引数が補完候補となる `_values` で指定した補完候補は複数かつ同じものを何度でも補完出来る もしひとつの候補を一度しか入力させたくない場合は `_values` 関数に `-w` オプションを渡せば良い ついでに説明文も表示してみる ```zsh #compdef nyan _nyan() { _values \ 'mode' \ 'neko[kawaii normal neko]' \ 'usagi[kawaii usa-neko]' \ 'kuma[kawaii kuma-neko]' \ 'github[kawaii octcat]' } ```  `[]` 内に説明を書くことで、補完候補の横に説明が表示される 次は `--help` オプションを補完候補に出してみる ```zsh #compdef nyan _nyan() { _arguments \ {-h,--help}'[show help]' \ '*: :__nyan_modes' } __nyan_modes() { _values \ 'mode' \ 'neko[kawaii normal neko]' \ 'usagi[kawaii usa-neko]' \ 'kuma[kawaii kuma-neko]' \ 'github[kawaii octcat]' } ```  オプションと補完候補に同時に出すために今回は `_arguments` 関数を使う オプションの指定は `optname[desc]` と指定する 同じ意味のオプションがある場合は `{optname1,optiname2}` とカンマ区切りで書く 引数の指定は `n:message:action` と指定する `n` は何番目の引数に対して動作するかを表す 今回は何回でも同じ引数を補完出来て良いので `*` と指定しておく `message` はその補完候補の説明を表す 今回は引数を省略する(理由は後述) `action` はどういう動作をするかを表す `*: :__nyan_modes` と書くことで、全ての補完候補で `__nyan_modes` 関数が使われる `__nyan_modes` 関数内の `_values` 関数で `mode` というグループ名(説明)指定しているため `message` を省略してる 今回は説明を出すため/見通しをよくするためモードの補完候補を別関数に分けたが、説明を伴わない場合は `'*:mode:(neko usagi kuma github)'` のように書くことも出来る 出来れば `--help` が入力された時はそこで補完を終了させたい 最後にそのための改良をする ```zsh #compdef nyan _nyan() { _arguments \ '(- *)'{-h,--help}'[show help]' \ '*: :->modes' case $state in modes) _values \ 'mode' \ 'neko[kawaii normal neko]' \ 'usagi[kawaii usa-neko]' \ 'kuma[kawaii kuma-neko]' \ 'github[kawaii octcat]' ;; esac } ```  `nyan` コマンドの補完関数完全版である `'(- *)'` で排他指定をしている `-` の部分で `--help`(`-h`)が補完された時に `-h`(`--help`)を補完候補から除く `*` の部分で `--help`(`-h`)が補完された時にそれ以降の補完を終了している ## その他の便利な補完関数 `_arguments` は他にもオプションや指定がたくさんあったり `_files` でマッチしたファイルのみ候補に出したり `_alternative` と `_describe` を使って複数のグループの補完候補を表示したり `_store_cache` を使って補完候補をキャッシュしたり 他にもたくさんあるけどイマイチ理解が浅いので気が向いた時に続編を書くかも書かないかも ## その他 補完関数は先人たちが書いたものがたくさんある `git` の補完関数はでかいが参考になる 自分が普段よく使うコマンドの補完関数を読んでみると良い 後、これを入れておくと便利 [zsh-users/zsh-completions](https://github.com/zsh-users/zsh-completions) Mac で homebrew なら `brew install zsh-completions` で入る ## 参考文献 [zsh: 20. Completion System](http://zsh.sourceforge.net/Doc/Release/Completion-System.html)(英語) 多分これに全て書かれてるけど要所しか読んでない [zsh補完関数の書き方(訳)](http://www.ayu.ics.keio.ac.jp/~mukai/translate/write_zsh_functions.html) 大体の雰囲気が分かる [zsh補完関数を自作すると便利 - はこべブログ♨](http://hakobe932.hatenablog.com/entry/2012/02/13/214934) ひとつの補完関数を書く過程を書かれてて分かりやすい