Atuinのシェル履歴を検索範囲から使い分ける

シェル履歴をコマンド文字列だけで検索すると、履歴が増えるほど候補の意味を判断しにくくなります。
Atuinを調べると、検索の使い勝手は「高機能な検索」だけでは決まらないことが分かりました。
検索文字列の一致方式と、履歴を探す範囲が別の設定だからです。
私が便利だと感じたのは、Ctrl-Rを起点にして、現在のプロジェクトに近い履歴と全体の履歴を切り替えられる点です。
まず標準履歴との差分を確認する
Atuinの公式READMEでは、シェル履歴へ作業ディレクトリ、終了コード、実行時間、ホスト、セッションなどの情報を付けて保存する仕組みが説明されています。
この差分を確認するため、履歴を次の3つに分けて考えることにしました。
- どの文字列に一致させるか
- どの履歴を候補へ含めるか
- 候補をどのキー操作から呼び出すか
この3つを混ぜると、「fuzzy検索に変えたのに候補が多い」という問題の原因を特定しにくいです。
AtuinはSQLiteへ履歴を保存するため、シェルの履歴ファイルを読むだけの仕組みとは保管場所も異なります。
暗号化した履歴を同期する機能もあるが、ローカルだけで使う構成も選べます。
したがって、最初に同期を有効にするのではなく、ローカル検索の挙動を確認してから保管範囲を決める方が安全です。
検索方式と検索範囲を分ける
Atuinの設定を読むと、少なくとも次の軸を分離して考えられます。
| 軸 | 例 | 確認する質問 |
|---|---|---|
| 検索方式 | prefix、fulltext、fuzzy、daemon-fuzzy |
入力文字をどのように一致させるか |
| 履歴範囲 | global、host、session、directory、workspace |
どの履歴を候補へ含めるか |
| シェル範囲 | auto、all、シェル名の配列 |
bashやzshなどを混ぜるか |
| 起点 | Ctrl-R、上矢印 |
どの操作でどの初期範囲を使うか |
たとえば、fuzzyは入力文字の一致方法です。
directoryは現在の場所に関係する履歴へ候補を絞る方法です。
前者を変えても後者は変わらないため、問題が一致率なのか候補範囲なのかを別々に確認できます。
履歴範囲を使い分ける
| 範囲 | 探すもの | 向いている場面 |
|---|---|---|
global |
端末やディレクトリをまたぐ履歴 | 実行場所を思い出せないコマンド |
directory |
現在のディレクトリに関係する履歴 | その場所で使ったテストやGit操作 |
workspace |
Gitリポジトリ全体の履歴 | モノレポのサブディレクトリをまたぐ検索 |
session |
現在のシェルセッションの履歴 | 直前の調査で試したコマンド |
host |
現在のホストの履歴 | WSLやサーバー間の環境差を避ける検索 |
globalは最も広いが、候補の意味を読み取る負担も増えます。
directoryはプロジェクトのサブディレクトリを移動すると候補が変わります。
Gitリポジトリ内を横断したい場合は、公式設定にあるworkspaceを試す価値があります。
障害対応の直後に「さっき実行したコマンド」を戻すなら、sessionの方がglobalより確認しやすいです。
WSLとサーバーで同じ履歴を同期する場合は、hostで環境を分けるとパスの違う候補を選びにくいです。
キーバインドへ範囲の役割を割り当てる
Atuinのキーバインド設定には、検索開始時のフィルターモードと上矢印用のフィルターモードを別に指定する項目があります。
最初に確認する設定は次の2つです。
filter_mode = "global"
filter_mode_shell_up_key_binding = "directory"
この組み合わせなら、Ctrl-Rは場所を問わない検索から始まり、上矢印は現在地に近い検索から始まります。
Ctrl-Rで検索UIを開いた後に同じキーを押し、フィルターモードを切り替える運用もできます。
上矢印の挙動を従来のシェル履歴へ戻したい場合は、上矢印のバインドを無効にしてCtrl-Rだけを使えばよいです。
ここで大切なのは、キーを増やすことではなく、検索範囲ごとに入口を固定することです。
検索方式はfuzzyから試す
検索方式の比較では、最初にfuzzyを使い、候補範囲が広すぎるときにフィルターを調整する順番が分かりやすいです。
pnpm test # 通常のfuzzy検索
^git # gitから始まる候補
!docker # dockerを含む候補を除外
'.env # .envを文字列として含む候補
検索構文は方式によって対応範囲が異なります。
特にdaemon-fuzzyへ変更する場合は、速度だけでなく、普段使う検索構文がその方式でも有効かを確認します。
履歴件数や応答時間に不満が出ていないなら、デーモンを先に追加する必要はありません。
複数シェルでは候補の出所を確認する
Atuinの現行設定リファレンスには、[search].shellsで現在のシェル、全シェル、指定したシェルを選ぶ設定があります。
[search]
shells = "auto"
bash、zsh、fishを併用し、構文が大きく異なる場合はautoから始める方が誤用を減らしやすいです。
すべてのシェルの履歴を横断したい場合はallを試せるが、PowerShellとWSLのようにパスやコマンド名が異なる環境では候補の確認が必要になります。
tmuxでは複数のペインが同じシェルセッションとして記録されることがあります。
長い調査の途中で履歴を戻すときはsessionから始め、見つからなければworkspaceやglobalへ広げる順番が扱いやすいです。
最小設定を作ってから広げる
設定を一度に増やすと、どの項目が検索体験を変えたのか分からなくなります。
まずは次のように、検索開始位置だけを決めます。
filter_mode = "global"
filter_mode_shell_up_key_binding = "directory"
search_mode = "fuzzy"
workspaces = true
[search]
shells = "auto"
この設定で不足したら、workspace、session、hostの順に必要な範囲を追加します。
workspacesや[search].shellsの利用可否と設定名はAtuinのバージョンで変わり得ます。
設定ファイルへ貼り付ける前に、インストール済みバージョンの公式リファレンスとatuin --helpを確認します。
履歴には秘密情報が入り得る
Atuinは履歴を便利に検索する道具であり、秘密情報を自動的に安全にする道具ではありません。
次のようなコマンドは、履歴へ残る前提で設計しない方がよいです。
- トークンをURLへ直接書いた
curl - パスワードを引数へ渡すCLI
- 一時的なクラウド認証情報を展開するコマンド
- 顧客データを含むSQLやファイルパス
すでに記録した秘密情報は、履歴の削除や除外だけで終わらせず、認証情報のローテーションも行います。
同期を有効にする場合は、履歴がどの端末へ配布されるかと、同期アカウントの管理範囲を確認します。
まとめ
Atuinを調べて分かった実用上の要点は、検索方式と履歴範囲を別の問題として扱うことです。
まずfuzzyとglobalで検索し、現在のプロジェクトを優先したいときにdirectoryまたはworkspaceへ移ります。
直前の作業を戻すときはsessionを使い、WSLやサーバーの違いがあるときはhostを確認します。
最初は同期なしで動作を確認し、必要性を説明できる機能だけを追加するのが安全な導入手順です。
