11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PowerShellで高速cdを可能にするZLocationのすゝめ

Last updated at Posted at 2019-12-13

本記事は PowerShell Advent Calendar 2019 の 14 日目です。

ディレクトリ移動する際に便利な ZLocation という PowerShell モジュールを紹介します。

ZLocation とは

ZLocation とは cd コマンドに取って代わり、一度訪問したディレクトリを記憶して、
再度訪問する際に手早く移動するための z コマンドを提供してくれる PowerShell モジュールです。

元々、Linux 界で(そこそこ)人気の z コマンド を PowerShell に移植したものとなります。

このツールを導入することで、今まで Explorer を使って移動してしまいがちだったディレクトリへ
瞬時に移動することができるようになります。

以下、簡単な概要です。

項目 説明
開発者 Sergei Vorobev 氏(元 PowerShell のメンテナー)
登場時期 2015/05/06 (Initial release)
最新版 1.3.0 - 2019/09/051

動作環境

$PSVersionTable

#=>Name                           Value
#=>----                           -----
#=>PSVersion                      6.2.3
#=>PSEdition                      Core
#=>GitCommitId                    6.2.3
#=>OS                             Microsoft Windows 10.0.18362
#=>Platform                       Win32NT
#=>PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
#=>PSRemotingProtocolVersion      2.3
#=>SerializationVersion           1.1.0.1
#=>WSManStackVersion              3.0

インストール方法

公式ページにある通り、PowerShellGet Gallery からインストールします。
記事を書いている時の最新バージョンは 1.3.0 でした。

Install-Module ZLocation -Scope CurrentUser

(Get-InstalledModule ZLocation).Version.ToString()
#=>1.3.0

自動インポートさせる方法

次回以降 ZLocation を自動的に有効化させるために、
$profile ファイル内に Import-Module で読み込む処理を追加しておきます。
公式サイトは以下のワンラインで追加できると書いていますが、
手動で Import-Module ZLocation を追加するのでも全然丈夫です。

Add-Content -Value "`r`n`r`nImport-Module ZLocation`r`n" -Encoding utf8 -Path $profile.CurrentUserAllHosts

追記する profile ファイルですが、PowerShell コンソールや Visual Studio Code の両方から
設定を読み込みたい場合は、$profile.CurrentUserAllHosts のファイルに、
PowerShell コンソールだけでよい場合は、$profile.CurrentUserCurrentHost に書き込むようになります。

また、prompt 関数をカスタマイズしている場合は、その関数を宣言している箇所より後に記載してください。
自身でカスタマイズしていなくても、例えば、oh-my-posh などの prompt をカスタマイズしてくれる
モジュールをインポートしている場合、そのインポート箇所より後に記載する必要があります。

追記が終われば、PowerShell を再起動します。

基本的な使い方

まず、今回動作確認用に以下のディレクトリ構造を作成しました。

@(
    "z_play_ground\sample\sub",
    "z_play_ground\special\sub"
) |
% { New-Item -ItemType Directory -Path $_ }

では、cd で作成した z_play_ground ディレクトリへ移動してください。

PS ~ > cd z_play_ground
PS ~\z_play_ground >

次に z コマンドを入力します。
すると、先ほど移動した z_play_ground ディレクトリが ZLocation に記録されていることがわかります。

PS ~\z_play_ground > z
#=>
#=>Weight Path
#=>------ ----
#=>     2 C:\Users\nimzo6689
#=>     1 C:\Users\nimzo6689\z_play_ground

これで、今後 z_play_ground に移動したいときに、そのディレクトリのフルパスに含まれるキーワードを指定しただけで、
瞬時に移動できるようになりました。
試しに C:\ 直下に移動したあと、再度 ~\z_play_ground ディレクトリに移動してみます。

PS ~\z_play_ground > cd c:\
PS \ > z z_play
PS ~\z_play_ground > z
#=>
#=>Weight Path
#=>------ ----
#=>     1 C:\
#=>     2 C:\Users\nimzo6689
#=>     3 C:\Users\nimzo6689\z_play_ground

基本的な使い方はこれだけです。
最初だけ、登録されているディレクトリ数が少ないためすぐに便利さを感じられる訳ではないかもですが、
しばらく使ってさえいれば段々その便利さを体感していただけると思います。

上手く使いこなすためのコツ

ここからは使っていくのに必須という訳ではないですが、
知っておいた方がより上手く使いこなせるというナレッジをまとめていきます。

Tips 1: コマンドの実行回数に応じて Weight が上がる

ZLocation に記録される情報として、ドライブも含めたフルパスと Weight という訪問数があります。
この Weight ですが、例えば z の引数に指定したキーワードに一致するディレクトリが複数存在した場合、
最も Weight が高いディレクトリに移動するような仕様となっています。

そのため、訪問数が多いディレクトリへは比較的少ないキーワードを指定しただけで移動できるようになり、
逆に訪問数が少ないディレクトリへは他の登録済みのディレクトリ名と被らないように指定する必要があります。

PS ~\z_play_ground > cd .\sample\sub\
PS ~\z_play_ground\sample\sub > echo "一度コマンドを実行"
PS \ > cd ..\..\special\sub\
PS ~\z_play_ground\special\sub > cd ..\..

PS ~\z_play_ground > z
#=>
#=>Weight Path
#=>------ ----
#=>     1 C:\
#=>     2 C:\Users\nimzo6689
#=>     5 C:\Users\nimzo6689\z_play_ground
#=>     2 C:\Users\nimzo6689\z_play_ground\sample\sub
#=>     1 C:\Users\nimzo6689\z_play_ground\special\sub

PS ~\z_play_ground > z sub
PS ~\z_play_ground\sample\sub >

このように、~\z_play_ground\sample\sub の方が ~\z_play_ground\special\sub よりも
Weight が高いため、優先的に移動されるようになります。

※ ちなみに ZLocation に記録されるタイミングはコマンドを実行した後になるため、cd した場合、cd 後のディレクトリが ZLocation に新たに記録される対象となるようです。

Tips 2: 複数の条件を指定できる

前の Tips で説明した通り、同じキーワードに一致するディレクトリが複数存在した場合、
Weight が高いディレクトリが選択されるわけですが、
Weight が低いディレクトリへ移動することも可能です。

方法は 2 つありまして、まず1つ目は「Tab」キー、または、「Ctrl + Space」キーによる補完入力を活用することです。
ZLocation では条件に一致するディレクトリ全てを補完入力させることができます。

そのため、候補としてのディレクトリが複数あった場合でも「Tab」キー、または、
「Ctrl + Space」キーで該当のディレクトリを選択さえすれば、あとは「Enter」キーで移動できます。

方法2つ目としては、キーワードを複数指定することです。

例えば、Tips1 の続きとして、special\sub に移動したい場合、以下のようにすると補完入力に頼らなくても一発で移動可能です。

PS ~\z_play_ground > z sp sub
PS ~\z_play_ground\special\sub > z z
PS ~\z_play_ground > 

ただ、キーワードを複数指定するときは同じようなディレクトリが多く存在してしまっているときぐらいで、
ほとんどのケースは補完入力で選択した方が楽だと思います。

Tips 3: 以前いたディレクトリに戻る場合は z - で可能

よく pushd で移動すれば、以前いたディレクトリに戻りたい場合、popd で戻れるから便利ということが言われていますが、
z で移動した場合、実は内部で訪問したディレクトリの順番を保持しており、
popd のように以前いた場所に戻りたい場合は、z - で可能となります。

ただ、注意点として、z で移動したとき限定で cd で移動してしまうとその移動元のディレクトリには
z - では戻れなくなります。

PS ~\z_play_ground > z sub
PS ~\z_play_ground\sample\sub > z sp sub
PS ~\z_play_ground\special\sub > z -
PS ~\z_play_ground\sample\sub > z -
PS ~\z_play_ground >

Tips 4: 直下のサブディレクトリに移動したい場合は cd の方が便利

これは使っていて気付いたかなり細かい観点になりますが、
カレントディレクトリの配下にまだ ZLocation に登録されていないディレクトリがあり、
そこへ z で移動しようとした場合、補完入力しようとすると既に ZLocation に登録されている
他のディレクトリの候補しか出ないようになります。

文字で書くと分かりやすく書けないので、下のコマンドを実際打ってもらうのが早いです。

PS ~\z_play_ground > mkdir supercalifragilisticexpialidocious
PS ~\z_play_ground > z #ここで「Tab」や「Ctrl + Space」をしてもサブディレクトリは表示されない。。

この場合、cd で移動するか、または、.\ を最初に入力することで補完入力に出すことができます。

PS ~\z_play_ground > z .\s
# ここで「Tab」や「Ctrl + Space」を打つと候補としてサブディレクトリが表示される!
# ただ、候補として表示されるだけで `z .\s` の段階で Enter キーを押しても移動できないので注意。
PS ~\z_play_ground > cd s
# cd だと普通に補完入力に表示される。

ここら辺はクセの強い挙動になっていますね。
登録されていないディレクトリでもカレントディレクトリのサブディレクトリであれば
候補としても出してもいいのかなと思ったりもしますが、どうなんでしょう。

Tips 5: z-location.db でポータブルに使用可能

これは使う機会がどれほどあるのか分かりませんが、
ZLocation で記録されたディレクトリ情報は LiteDB の単一ファイルに保存されているので
別の PC でも記録した情報を使うことができるようです。

ファイルの場所は $env:USERPROFILE 配下にあります。

ただ、両方の PC でほぼ同じようなディレクトリ構成にしておく必要があるので、
どっちかというと、PC 買い替え時に良いのかもしれません。(未検証)

Tips 6: 登録済みのディレクトリが削除されてしまった場合

ZLocation に登録されているディレクトリが削除された場合、
z でそのディレクトリに移動を試みることで ZLocation から訪問履歴を削除することができます。

PS ~\z_play_ground > mkdir will_be_removed
PS ~\z_play_ground > cd will_be_removed
PS ~\z_play_ground > cd ..

# `-l` オプションで `will_be_removed` に一致する訪問履歴を検索する
PS ~\z_play_ground > z -l will_be_removed
#=>Weight Path
#=>------ ----
#=>     1 C:\Users\nimzo6689\will_be_removed

# ディレクトリを削除する
PS ~\z_play_ground > rm will_be_removed
# 削除されても ZLocation 内に訪問履歴は残っている
PS ~\z_play_ground > z -l will_be_removed
#=>Weight Path
#=>------ ----
#=>     1 C:\Users\nimzo6689\will_be_removed

# 削除されたディレクトリに移動を試みる
PS ~\z_play_ground > z will_be_removed
#=>WARNING: There is no path C:\Users\nimzo6689\z_play_ground\will_be_removed on the file system. Removing obsolete data from database.
#=>WARNING: Cannot find matching location

# 訪問履歴は削除されている
PS ~\z_play_ground > z -l will_be_removed

逆に言うと、z で移動しない限り削除されてしまったディレクトリは残り続けてしまうため、
万が一ディレクトリ構成が大幅に変更になった際には
LiteDB の Shell コンソールアプリなどで一括削除してしまうか、
LiteDBViewer というツールでもレコード単位で削除することができるようなので、
使ってみると便利かもしれません。

Tips 7: 本家の z コマンドとの実装差異

本家の z コマンドと比べると ZLocation は必要最小限の機能しかまだ実装できていないようです。
(もしくは、敢えて必要最小限としているか。)

メインとなる目的や挙動は一緒ですが、大きい差分としては Weight での優先順位の付け方かなと思います。

ZLocation の場合は、単純に訪問数が多ければ多いほど優先順位が上がる仕組みですが、
z コマンドの場合、何もオプションを付けづに移動するときは、
最近訪問したディレクトリと今までの訪問数を考慮して優先順位を決めているため、
ZLocation より若干使い勝手が良さそうです。

おわりに

勤務中に「探し物」をしている時間は年間 150 時間って言われているけど、
ディレクトリ移動しようとしている時間も割と洒落にならないよね。

  1. 配布先:PowerShell Gallery
    | リポジトリ | https://github.com/vors/ZLocation |
    | 実装言語 | PowerShell |
    | 対応 OS | Cross-platform (Windows, Linux or Mac) |
    | ライセンス | MIT License |
    | 公式ドキュメント | GitHub の REAME のみ |

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?