閑古鳥

オールドプログラマの日記。プログラミングとか病気(透析)の話とか。

PowerShellの履歴をpecoでインクリメンタルサーチしたい

PSReadLineをインストールする

PowerShellの履歴は再起動すると消えてしまうので、PSReadLineを入れます。 PSReadLine について - PowerShell | Microsoft Docs

Install-Module -Name PSReadLine -AllowClobber -Force

Get-Historyだと起動中のコマンドしか覚えてくれないのですが、PSReadLineを入れるとコマンド履歴がファイルに保存されて再起動しても以前の履歴が再現されるようになります。 ちなみに履歴は (Get-PSReadLineOption).HistorySavePath の先にあるテキストファイルに書き込まれます。

peco.exeをPATHの通っているフォルダに配置する

peco/peco: Simplistic interactive filtering tool peco.exeは単一バイナリで動くので環境変数PATHの通っているところに置いておけばどこからでも使えるようになります。 (今ならwingetとか使う方がいいのかな?)

Ctrl+Rの動きを上書きする

PSReadLineを入れるとCtrl+RがReverseSearchHistoryコマンドに割り当てられ、履歴の補完ができるようになるのですがちょっと使いにくい。

profile.ps1を作って:

New-Item $PROFILE
# デフォルトでは以下のファイルが作成される
# C:\Users\user\Documents\PowerShell\Microsoft.PowerShell_profile.ps1

このファイルに以下のようなコマンドを追加してCtrl+Rを上書きし、履歴をpecoに渡して検索できるようにしてみました。

Set-PSReadLineKeyHandler -Chord Ctrl+r -ScriptBlock {
    $command = Get-Content (Get-PSReadLineOption).HistorySavePath | peco --select-1 --on-cancel error
    if (-not $command) {
        return
    }
    [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
    [Microsoft.PowerShell.PSConsoleReadLine]::Insert($command)
}

ただPowerShellでpeco叩くとそれまでターミナルに表示されていた内容が消えちゃうんですよね。これなんとかできないかなぁ。

参考