7 分で読了 #tools

CLI ツールボックス

これらのツールは現在では常識になりつつありますが、実際に日常を変えるポイントは「より高速な X」ということだけでなく、非常に具体的です。ここでは私が日常的に使用している機能について一つずつ解説します。

rg(ripgrep) で grep を置き換える — 最大の差は速さではなく、⁠デフォルトの動作です。.gitignore.ignore を自動的に遵守し、隠しファイルやバイナリをスキップするため、リポジトリ内を検索しても関心のあるソースコードのみがヒットし、node_modulestarget/ で埋め尽くされることはありません。無視されたファイルも検索対象に含める場合は -uu を追加します(さらに u を一つ加えるとバイナリも検索されます)。ファイルタイプでフィルタリングするには -t rust、glob パターンでフィルタリングするには -g '*.toml' を使用し、-A/-B/-C でコンテキストを表示できます。また、rg foo -r bar で置換プレビューも可能です。高速なのは、Rust の正規表現エンジンが有限状態自動機、マルチスレッド、不要なパスのスキップを活用しているためであり、力技ではないからです。

fdfind を置き換えるfd パターン とするだけで、ファイル名に対してスマートケース(大文字小文字を区別しないが、大文字を含む場合は区別する)の正規表現マッチが実行され、find . -name '*.x' -type f のような複雑な構文を暗記する必要がありません。同様にデフォルトで gitignore を遵守します(-H で隠しファイルも対象、-I で gitignore を無視)。本当に便利なのは -x/-X によるバッチ実行です。fd -e jpg -x convert {} {.}.png とすると、各結果に対して並列でコマンドを実行し、-X を使うとすべての結果を一度にコマンドに渡します。

batcat を置き換える — 構文ハイライトは表面に過ぎず、行番号の横には git の差分(追加・削除)を示すガター(余白)が表示され、自動でページャー(less など)が起動します。重要なのはパイプラインセーフであることです。出力がターミナルでないことを検知すると、自動的にプレーンな cat として動作し、エスケープシーケンスが下游に流れ込むのを防ぎます。そのため、cat のエイリアスとして零コストで導入でき、MANPAGERbat -l man)や fzf のプレビューレンダリングバックエンドとしても機能します。

ezals を置き換えるeza -l --git --icons とすると、リスト内の各ファイルに git のステータスが直接表示され、--tree --level=2 で tree コマンドのように使用でき、かつ gitignore も遵守します。私は ls 系のコマンド(lslltree)をすべてこれに置き換えており、具体的なエイリアスは Zsh の記事をご覧ください。

zoxidez コマンドによるディレクトリジャンプ — アクセス頻度と最近のアクセス日時を掛け合わせた frecency(頻度・新着度)でソートされたディレクトリ一覧を維持します。z dow と入力すると、最も頻繁にアクセスする Downloads ディレクトリに移動し、z foo bar とすると複数のキーワードでマッチを絞り込みます。zi を使うと fzf を介して対話的に選択できます。cd の履歴から完全に自己学習するため、パスを手動で設定する必要はありません。

just をプロジェクト内の make の代わりに使う — これはビルドシステムではありません⁠。ファイルの依存関係図もタイムスタンプも確認せず、単なる「プロジェクトコマンドのエイリアス一覧」です。覚えにくい長いコマンドをレシピとして記述し、just deployjust test --release でワンライナーで実行できます。変数、.env ファイルのサポート、単一のレシピに対してシェバング(shebang)を指定して別の言語で記述することも可能です。Makefile よりも楽なのは、タブ地狱に陥らないこと、.PHONY や暗黙のルールに関する罠がないことです。

fastfetch / tldr — 前者は neofetch より高速で、システム情報をスクリーンショットに収めるのに適しています。後者はコマンドの実用的な例を提供します(tldr tar とすると最もよく使われる例が即座に表示され、man ページのフラグ一覧を読むよりもはるかに速く、オフラインキャッシュも対応しています)。

このうち、bat、eza、fzf は Zsh の補完プレビュー のバックエンドとしても機能します。

ここで数分かけて設定する価値があるのは、git の diff です。私は delta を使用しています。

[core]        pager = delta
[interactive] diffFilter = delta --color-only
[delta]       navigate = true        # n / N でファイル間を移動
              line-numbers = true
[merge]       conflictStyle = zdiff3
[diff]        colorMoved = default

このうち、2つの設定は特に効果的です。zdiff3 はマージコンフリクトの表示スタイルを「両者の対比」から「三方(3-way)」に変更し、共通祖先の情報を追加表示することで、どの変更がどこで行われたかが一目でわかり、コンフリクト解決の労力が大幅に減ります。colorMoved は、移動したコードブロックに個別の配色を適用し、コードレビュー時に「移動」を「書き換え」と誤認するのを防ぎます。delta を lazygit と組み合わせて使用すると、ブラウザで diff を見るよりもターミナル上で快適に確認できます。