PowerShell+fzfでコマンド入力支援
最近はターミナルベースで作業することが多く、ターミナル環境を良くするために調整を繰り返している日々です.
正直なところ、コマンドを覚えるのが大変で 結構しんどいなと思っています.基本としてなるべくタイプ量を減らしたいのでエイリアスやスニペットツールを合わせて利用しているのですが、それらもコマンドを覚える必要があります.今、作業している環境で使っているコマンド群と、別の作業で使うコマンド群が異なっていると、切り替えがなかなか追いつきません.少し時間が空くとなおさらです.そこでチートシートやメモツールなどを参照したりもするのですが、もう少しなんとかしたいところです.
本記事では、WindowsにおいてPowerShellとfzf(fuzzy finder)を使って、ターミナル上でコマンド入力支援環境を構築する方法についてまとめておきます.ちなみに、これは正月のお休み中に構築したもので、私でもまだ検証段階中であることをご了承ください.次の環境で試しています.
Windows11 Pro 22H2
Windows Terminal 1.15.3466.0
fzf 0.33.0 (e03ac31)
また PowerShell のバージョンは次のようになっています.
> $PSVersionTable
Name Value
---- -----
PSVersion 7.3.1
PSEdition Core
GitCommitId 7.3.1
OS Microsoft Windows 10.0.22621
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PSReadLine
を使います.PowerShellのバージョンが7.3
以上であれば標準でインストールされています.また、fzf のインストールについては触れませんので各自インストールしてパスを通してください.あと、Rust製のツールを使いますので、cargo
が使える環境を前提としています.
はじめに
実はすでに先人がコマンド入力支援ツールを開発していま す.
denisidoro / navi - GitHubAn interactive cheatsheet tool for the command-line
navi
はRust製のコマンドライン入力支援ツールです.これを使いたかったのですが、Windows環境への対応はよろしくありません.実行はできますが、コマンドが bash だったりするのでそのままでは使えません.一応、カスタマイズでシェルを指定できますが、たとえばPowerShellを指定すると毎回プロファイルの読み込みが入ってレスポンスが悪いですし、そもそもカスタマイズがまだ実験的機能になっています.あとは、チートシートをダウンロードしても内部的にCドライブでしか反応しないというちょっとよくわからんことになっています.カスタマイズでパスを指定できるんですが、試した感じ上手くいきませんでした.まだまだWindowsでは使いづらいようです.公式のIssueでも進捗はない感じです.
Issues | denisidoro / navi - GitHubSupport Windows (cmd/Powershell) #40
ただ、このツールにはとてもインスパイアされました.
それなら自分で作ろう
ということで、自分で navi を作ります.ただ、Rustで作るとかそういうことはせず、PowerShell(+PSReadLine)とfzf、さらに他のツールと連携して構築します.
次のようなものを作ります.
チートシートデータ (YAML)
まず、チートシートのデータを作成します.今回はYAMLを採用しました.JSONでもいいのですが、今回のように数個のキーを持つハッシュとそれらの配列という単純な階層ではYAMLの方が見やすいかなと思いました.ただ、最終的にPowerShell上でハッシュテーブルとしてデータが持てればいいので、JSONでも構いませんし、JSONならPowerShell標準でサポートされています.
それでは、YAMLファイルを適当に作成します.場所はユーザーフォルダで、名前は navi.yaml
とします
$env:userprofile\navi.yaml
中身は次のような感じになります.
items:
# general
- name: echo_hello
description: Echo 'Hellom, World'
command: echo Hello, World!
# git
- name: git_init
description: Initialize a git repository
command: git init
- name: git_clone
description: Clone a git repository
command: git clone <branch_name> <repository> <clone_directory>
...
items
配列の中にコマンドを1つずつ定義します.コマンドはname
、description
、command