最近よく使っている自作ツール(1) choco

プログラミングの学習にともない作った自分用のコマンドラインツールというものがあって、折りに触れこのブログでも記録&紹介しているのだけど、それでも以前に紹介した後に手元でどんどんアップデートしつつも外には出せていないものや、新たに作ったけど自分しか知らないツールというのもあって、少しずつでもそういうのをあらためて紹介していきたいと思ったのでそうする。

リストアップしてみたら結構な数になったので、何回かに分けるかもしれない。(いま書きながらどうするか考えている。書き終える頃にはどうなるか決まっているはず)

choco

まずはこれまでも何度か紹介している以下の最新版。

github.com

mattnさんによるchoと、lestrratさんによるpecoを使って、ディレクトリをスイスイ移動したり、移動した先で選択したファイルをオープンしたりする。

choで移動しているところ

f:id:note103:20170217202617g:plain

pecoで移動して最後に選択したファイルを開いているところ

f:id:note103:20170217202639g:plain

オープンするやつはmacOSのopenコマンドを使用しているので、他の環境でどうなるかはわからない。

たぶんコンピュータを開いて作業している日のうち、これを使わない日はないと思う。
我ながらすごく便利だし、俺グッジョブという感じ。

(いやもちろん、mattnさんやlestrratさんのおかげなわけですが)

名前

以前はこのツール、 "dirmove" という名前にしていたけど、それだとファイルやディレクトリ自体を移動させる意味が含まれてしまいそうなのと、移動先のファイルを開く、という目的も大きくなってきたので名前を変えたいと思い、choとpecoを使っているので合わせて "choco" にした。

これ自体は作業のメインに使うものではなく、単にちょこちょこ動きたいだけ、というグルー(のり)的な道具なので、意味を限定しすぎず、なおかつちょっと可愛い感じで良いネーミングではないかと自分では思っている。

懸案

メインのコードはPerlで書いているが、コマンドラインから居場所をどんどん移動して、なおかつ移動先に着地しなければならない都合上、bashrcにも少なからず記述が必要になる。

詳しくはREADME.mdを参照してほしいが、現時点ではこんな感じ。

# .bashrc

function dirmove {
    local result="$1"
    local basename=""
    local dirname=""

    if [ -e "$result" ]; then
        basename=${result##*/}
        if [ -f "$result" ]; then
            dirname="${result%%$basename}"
        elif [ -d "$result" ]; then
            dirname="$result"
        fi
    fi
    cd "$dirname"
}

function choco {
    local command="${@:$#}"
    local result=$(perl ~/path/to/choco/choco.pl "$@")

    if  [ $# = 0 ] ; then
        command=echo
    elif [[ "$command" =~ - ]] ; then
        if [[ "$command" =~ p ]] || [[ "$command" =~ a ]]; then
            command=echo
        fi
    fi

    if  [ -e "$result" ]; then
        dirmove "$result"
    fi
    $command $result
}

alias s=choco
alias s.="choco -a"  # 不可視ファイルを対象に含める
alias j="choco -p open"  # pecoを使う
alias j.="choco -ap open"  # pecoを使って不可視ファイルも対象に含める

zshだとどうなるか、とかはわからない。

上では関数を二つ書いていて、chocoというメインの関数の他にdirmoveという関数を分けて作っているのだけど、これは後日紹介予定の別ツールでもそのdirmove関数を使うから。
逆に言うと、chocoしか使わないならこれらを一つの関数に合わせてしまってもよい。

いずれにせよ、けっこう行数があるので、シェルスクリプトのファイルに切り出した方が良いのではないかと思って何度か試したのだけど、前述のとおりディレクトリを移動するためにはbashrcへの記述が必須のようで*1、仕方なくbashrcにいろいろ書くことになってしまっている。

最後にエイリアスをいくつか設定しているが、ようはデフォルトだとchoを使うようになっていて、オプションとして -p を指定するとpecoを使うようになり、また -a を指定すると不可視ファイルが対象に含まれ、さらに引数の最後にopenコマンドを入れると最終的に選択したファイルがオープンされる、という感じ。

次回予告

似たようなツールを少なくとももう一つ紹介するつもりだったが、結構長くなったのでここまで。

ブログ記事1本あたりの負担を軽減してコンスタントにパブリッシュできるようにしたいところだけど、どうなるか……。

*1:たとえば「start/path/to/end」というディレクトリ構造で、「startから移動してendのディレクトリに出たい」というときに、それらの関数をbashrcではなくシェルスクリプトなどに書くと、操作中はあちこちに移動できるのだけど、操作を終えるとstartに戻ってしまう。