cargoコマンドをTABで補完できるようにする

# やりたいこと

bash上でcargo コマンドの後に打ち込む文字列を、自動的にTABで補完してほしい。

```bash
[kmtr@localhost ~]$ cargo　[TAB]
bench      check      doc        install    publish    search     uninstall
build      clean      init       new        run        test       update
[kmtr@localhost ~]$ cargo c[TAB]
check  clean
[kmtr@localhost ~]$ cargo c

```

---
# 参考文献
ここらへんを見れば、多分自作できるとは思います。


- Cyboze Inside Out  [Bashタブ補完自作入門](https://blog.cybozu.io/entry/2016/09/26/080000)
- [Bash用の補完スクリプトの作り方](https://qiita.com/nil2/items/8a1544e206928c753a2e)
- [bash-completionを活用して、manやhelpを見ずに、バシバシ長いコマンドを打つ](https://qiita.com/yamada-hakase/items/bf163f0924e4d925fefb)


---
# 必要な外部プログラム

bash-completion-extrasをインストールしておく。

```bash
# yum install  bash-completion-extras -y
```

---
# .bashの設定ファイルを書く

各個人の.bash_completionにコマンドを書くと、自動補完のためのalias的に動いてくれる。

```plaintext:.bash_completion
# cargo completion                                          -*- shell-script -*-

_cargo()
{
    local cur
    local command_list
    _init_completion || return

    command_list=`cargo | grep "^    " | grep -v "-" | cut -d " " -f 1-5  | grep -v "cargo"`

    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
        return 0
    fi
    if [ "${cword}" -eq 1 ]; then
        COMPREPLY=( $( compgen -W "${command_list}" -- "$cur" ) )
    fi
} &&
complete -F _cargo cargo

# ex: ts=4 sw=4 et filetype=sh

```

----

## 簡単な解説

現在文字列 `$cur`"が、`-*` だった場合、_parse_help $1を実行した文字列を、候補に追加する。

```bash
    if [[ "$cur" == -* ]]; then
        COMPREPLY=( $( compgen -W '$( _parse_help "$1" )' -- "$cur" ) )
        return 0
    fi
```

----

### _parse_help

cargoコマンドを実行すると、以下の文字列が得られる。

```plaintext
[kmtr@localhost ~]$ cargo
Rust's package manager

USAGE:
    cargo [OPTIONS] [SUBCOMMAND]

OPTIONS:
    -V, --version           Print version info and exit
        --list              List installed commands
        --explain <CODE>    Run `rustc --explain CODE`
    -v, --verbose           Use verbose output (-vv very verbose/build.rs output)
    -q, --quiet             No output printed to stdout
        --color <WHEN>      Coloring: auto, always, never
        --frozen            Require Cargo.lock and cache are up to date
        --locked            Require Cargo.lock is up to date
        --offline           Run without accessing the network
    -Z <FLAG>...            Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details
    -h, --help              Prints help information
:

```

_parse_help cargoと実行すると、引き通にとれる文字列を抽出してくれる。

```plaintext
[kmtr@localhost ~]$ _parse_help cargo
--version
--list
--explain
--verbose
--quiet
--color
--frozen
--locked
--offline
-Z
--help
```


### 引数を自動的に作る

cargoコマンドを実行すると、以下の文字列が得られる。

```plaintext
Some common cargo commands are (see all commands with --list):
    build       Compile the current package
    check       Analyze the current package and report errors, but don't build object files
    clean       Remove the target directory
    doc         Build this package's and its dependencies' documentation
    new         Create a new cargo package
    init        Create a new cargo package in an existing directory
    run         Run a binary or example of the local package
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock
    search      Search registry for crates
    publish     Package and upload this package to the registry
    install     Install a Rust binary. Default location is $HOME/.cargo/bin
    uninstall   Uninstall a Rust binary
```

----

ここから欲しい文字列だけを抜き出す

```plaintext

    command_list=`cargo | grep "^    " | grep -v "-" | cut -d " " -f 1-5  | grep -v "cargo"`

    if [ "${cword}" -eq 1 ]; then
        COMPREPLY=( $( compgen -W "${command_list}" -- "$cur" ) )
    fi

````


以上になります。