Windows(Powershell)でpecoを使ってみる (履歴のインクリメンタルサーチ)

TL;DR

Powershell使うくらいならWLS2を使えという話はあります。とはいえ、Windowを使うならPowershellの環境は最低限整えておきたいです。また、WSL2は外部HDDなんかを使うと非常に遅くなってしまい、かなりストレスフルになるという問題もあります。自分のPCで開発しているとやはり容量は大きな問題となり、外部HDDを使いたいこともあります。

pecoはzshとよく併用されていますが、Powershellでも使えるインクリメンタルサーチを簡易に実装できるツールです。Ctrl + rでの履歴検索は標準のままだとやっぱり使いづらいので、まず履歴をインクリメンタルサーチできるようにします。

pecoのインストール

Chocolateyを使ってインストールします。管理者権限が必要なので、管理者権限つきのpowershellを開く必要があります。

choco install peco

履歴の表示

Powershellの入力履歴は(Get-PSReadlineOption).HistorySavePathで表示されるパスにあるテキストファイルに保存されています。なので、Powershellで履歴を得るには

Get-Content (Get-PSReadlineOption).HistorySavePath | Select-Object -Unique

のようなことをすればよいです。また、コマンド履歴はユニークであってほしいので、Select-Object -Uniqueを使用しています。

pecoに流して選択結果を実行

得られた出力結果を実行するにはInvoke-Expressionを使います。

Get-Content (Get-PSReadlineOption).HistorySavePath | Select-Object -Unique | peco | Invoke-Expression

ということで、実行する関数は

function pecoHistory() {
    Get-Content (Get-PSReadlineOption).HistorySavePath | Select-Object -Unique | peco | Invoke-Expression
}

でいいですね。

profile

Powershellの.bashrcみたいなやつです。

echo $profile # pathの確認
notepad $profile # メモ帳で開く

みたいな感じでパスを確認したり、エディタで開いたりできます。

ここにさっきの関数を書き込んでおきます。これで、pecoHistoryを使えばいい感じにインクリメンタルサーチができます。

Keybindの登録

PowershellでKeybindを設定するには、Set-PSReadLineKeyHandlerを使います。組み込み関数の場合は-Function以下に書けばいいんですが、自前のスクリプトを実行する場合は-ScriptBlockを使います。ScriptBlock内では、登録したpecoHistoryコマンドを入力させて、それを実行しています。

Set-PSReadLineKeyHandler -Chord Ctrl+r -ScriptBlock {
    [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert("pecoHistory")
    [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}

以上でCtrl + rを使うことでPowershellでも履歴のインクリメンタルサーチができるようになります。

参考

この記事に関するIssueをGithubで作成する

Read Next