cdコマンド改造記事第4回です。
前回の記事:ご注文は親ディレクトリに戻ることですか?
また、cdコマンドに手を入れていきます。
今回は、Simplistic interactive filtering toolのPecoを使っていきます。
第4羽「pecoをするお話」
何番煎じか分かりませんが、pecoという選択ツールを導入して使っていこうと思います。
fzfとかもあるので、シェル変数とか環境変数にして色んなツールを選択できるように汎用的にしていけたらいいですね。(その予定はないですけど)
pecoの導入
リポジトリ通りにいれてください。
普通に、リリースページからバイナリ落としてPATHに入れるだけです。
なにをpecoるのか?
まず、サンプルとして一番記事の多いコマンド履歴をpecoってみましょう。
仕様はテキトーな感じでいいよね。
- 新しい履歴が上に来ること
- 同じ履歴は最近のモノだけでいいこと(重複して表示しない)
peco_history()
{
local descending_order
if which sort &> /dev/null; then
descending_order='sort -r'
elif which tac &> /dev/null; then
descending_order='tac'
else
descending_order='tail -r'
fi
local trim_line_number='sed -re "s/^\s+[0-9]+\s+//"'
local trim_duplication='awk '\''!dictionaty[$0]++'\'''
local CMD=$(\history \
| eval $descending_order \
| eval $trim_line_number \
| eval $trim_duplication \
| peco --query "${READLINE_LINE}")
READLINE_LINE="${CMD}" # Input to terminal's readline
READLINE_POINT=${#CMD} # Set cursor
}
bind -x '"\C-r": peco_history'
スクリプト解説
まず、このスクリプトは処理したいことをコマンドで示し、それをローカル変数に格納するスタイルを取っています。
でないと、アホの私は土日を過ぎると「このコマンドは何を実現したいんだ……?」となってしまうからです。
-
descending_order
新しい履歴を上に持ってくる仕様を満たすために、降順に並び替える処理を担当しています。
どれもこれもbashのビルトインじゃなかったので持ってるかどうかを調べています。
とりあえず3つも調べたらどれかは持ってるでしょ(´・_・`)tacはMacではダメとかなんとか -
trim_line_number
今回は履歴の取得にhistoryコマンドをビルトイン実行しているのですが、履歴番号を付与してしまうのでそれを取り除きます。 -
trim_duplication
履歴表示は重複させない仕様を満たすため、辞書式配列を作ることで実現しています。
awkでこんなの考えた人天才ですね
これらは変数に格納されるので、所定の順番にevalコマンドで実行して最後にpecoへパイプします。
- --queryオプション
pecoのqueryオプションは初期QUERYとして文字列を渡すようです。
既に入力されている文字列を渡すことで、入力途中で実行すると最初からその文字列で絞込ませておくことができます。
最後にterminalへ反映させるために変数に結果を格納します。
-
READLINE_LINE
terminalへ入力されている文字列をpecoで選択した結果に置き換えます。
pecoで複数選択した場合のケア?知らねー -
READLINE_POINT
terminalのカーソルの位置を文字列の最後にしています。
変数に#をつけると、変数展開が行われて文字列を取得することができます。
参考:【シェル芸人への道】Bashの変数展開と真摯に向き合う
最後は、これをデフォルトでは履歴検索を担当しているショートカットキーをbindコマンドで上書きして終わりです。
最後
こんな感じで使えます。
結構便利ですね。
git logをパースするとか色々しておくと便利かもしれませんね。
もうちょっと、このpecoを使っていきたいと思います。
というか、コマンド名タイポしたときに、
その間違えたコマンドを履歴に書き込まない方法とかありませんかね?(´・_・`)ダレカー