⚒️

Windows: pecoを使ってWindowsのhistoryを使いこなす

2022/06/09に公開

TL;DR

PowerShell のヒストリーを、peco をつかって一覧から選択できるようにします。
さらに Ctrl+p キーに上記の機能を割り当てて、ヒストリーを簡単に使えるようにします。

はじめに

Windows Terminal と PowerShell のおかげで、Windows のコマンドライン環境がかなり使いやすくなりました。
ヒストリー機能も、Ctrl+r キーでインクリメントサーチができるなどの機能向上があります。
ここでは、peco を使った PowerShell スクリプトでヒストリーを便利にします。

スクリプトの作成

ヒストリーの表示

PowerShell の history コマンドでは、セッションごとのヒストリーしか表示されません。
(Get-PSReadlineOption).HistorySavePathにヒストリーのログが保存されているので、tail を使って必要なヒストリーを表示します。


(tail -20 (Get-PSReadLineOption).HistorySavePath)

コマンドの実行

表示されたヒストリーを peco で選択すれば、実行するコマンドラインが取得できます。実行するだけならInvoke-Expressionコマンドレットで実行するだけです。
しかし、ここではコマンドの引数などを編集することもあります。SendKeysの機能を使い、選択したコマンドをキー入力します。

[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
[System.Windows.Forms.SendKeys]::SendWait(<選択したコマンド>)

関数の作成

そのほか、peco で ESC でキャンセルしたときの処理などをいれた関数は、つぎのようになります。

SelectandExecHistory.ps1
<#
  .SYNOPSIS
    select command from history and execute

  .DESCRIPTION
    select history wuth peco and set command line to execute this.

  .EXAMPLE
    Set-PSReadLineKeyHandler -chord Ctrl+p -scriptBlock { SelectandExecHistory }
    using above that hit ctrl+p to use this.

#>
function global:SelectandExecHistory()
{
   $selectCmd = (tail -20 (Get-PSReadLineOption).HistorySavePath)|peco --select-1 --on-cancel error
   if ($?) {
      [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
      [System.Windows.Forms.SendKeys]::SendWait($selectCmd)
   } else {
      [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
   }
}

一応、gist にもあげています。
gist

キーへのバインディング

作成した関数は、このままでは使えません。コマンドは入力されますが、実行されないで次のプロンプトが表示されてしまいます。
次のようにして、適当なキーで作成した関数を呼び出します (今回は、Ctrl+p キーで呼び出しています)。

Set-PSReadLineKeyHandler -chord Ctrl+p -scriptBlock { SelectandExecHistory }

作成した関数、および上記のキーコンフィグを PowerShell の初期設定スクリプトに記入します。以後、Ctrl+p キーでヒストリーを簡単に扱えるようになります。

参考資料

GitHubで編集を提案

Discussion