PowerShellのprofileを整理してpromptをいい感じにした
tl;dr
- PowerShell の profile を分割して dotfiles 管理にした
- カレントフォルダパスが長くてもいい感じに見やすいプロンプトにした
動機
Windows のシェル環境はろくにカスタマイズもせず PowerShell を使ってたんだけど、 カレントディレクトリが深くなってくるとプロンプトがどんどん長くなっていって見づらい。 コマンドの途中で折り返されたりしてツライ。
カスタマイズしようにも、profile を雑に継ぎ足してきたので、どこに手を入れたらいいか分からない。
さらに、どうせいじるなら複数環境で同じものを再現できるようにしたい。
と、以上から重い腰を上げて profile の整理に着手した。
ちなみに ConEmu + PowerShell v5 + posh-git + Chocolatey の組み合わせで使っている。
今の profile を分割管理にする
まず、今の profile はごちゃごちゃしていて見通しが悪いので、Emacs の init-loader みたいに分割管理しようと思った。
ざっと調べたところ、id:guitarrapc_tech さんのこちらの記事に全て書いてあった。
PowerShell で Profile を利用して スクリプトの自動読み込みをしてみよう
非常に詳しく説明されており大変参考になった。
Profile の場所確認
PowerShell 上で
> $profile
するとわかる。 が、これで表示されるのは CurrentUserCurrentHost のものなので、 PowerShell と PowerShell ISE 共通で読み込ませたい場合は CurrentUserAllHosts として profile.ps1 に記載する方がよい。
if (-not(Test-Path $profile.CurrentUserAllHosts)) { New-Item -Path $profile.CurrentUserAllHosts -ItemType file }
で profile.ps1 が作成される。
profile.ps1 からファイルを読み込ませる
guitarrapc_tech さんの方法を少し簡略化して、profile.ps1 を下記のようにした。
$psdir="$env:HOME\dotfiles\PowerShell" Write-Host ("Load PS Profiles from {0}\autoload" -f $psdir) -ForegroundColor DarkCyan Get-ChildItem $psdir\autoload | where Extension -eq ".ps1" | %{.$_.FullName}
これで $HOME/dotfiles/autoload 配下に置いた .ps1 が読み込まれる。
あとは、元の profile の内容を適宜分割して、autoload 配下に入れてやれば OK。
プロンプトをいい感じにする
プロンプトを改造する記事はいくつか見つかるものの、やりたいことにハマるものがないなー、と探してたら、 posh-git の README にまさにやりたいことが書いてあった。 README はちゃんと読もう。。
ちなみに、posh-git インストール直後は posh-git インストールフォルダの profile.example.ps1 を参照するようになってると思うが、 中身は
- Import-Module posh-git
- prompt のフォーマット定義
- SSH Agent 起動
なので autoload にいい感じに移動して良い。 その prompt のフォーマット部分をいじる。
カレントパス(+ Git の status)とプロンプトの間に改行を入れる
Import-Module posh-git $global:GitPromptSettings.BeforeText = '[' $global:GitPromptSettings.AfterText = '] ' function prompt { $origLastExitCode = $LASTEXITCODE Write-VcsStatus Write-Host $ExecutionContext.SessionState.Path.CurrentLocation -ForegroundColor Green $LASTEXITCODE = $origLastExitCode "$('>' * ($nestedPromptLevel + 1)) " }
Write-Host に -NoNewline をつけなければ、改行される。
$global:GitPromptSettings.BeforeText あたりは設定の微調整。README 参照。
パスに $HOME が含まれていたら ~ に置き換えてスッキリさせる
$curPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path if ($curPath.ToLower().StartsWith($Home.ToLower())) { $curPath = "~" + $curPath.SubString($Home.Length) } Write-Host $curPath -ForegroundColor Green
パスが長すぎたら省略する
$maxPathLength = 40 $curPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path if ($curPath.Length -gt $maxPathLength) { $curPath = '...' + $curPath.SubString($curPath.Length - $maxPathLength + 3) }
最終形
以上をふまえて、最終的にこんな感じになった。
function global:prompt { $origLASTEXITCODE = $LASTEXITCODE Write-VcsStatus # Replace $home by ~ if current path includes $home $curPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path if ($curPath.ToLower().StartsWith($Home.ToLower())) { $curPath = "~" + $curPath.SubString($Home.Length) } # Limit path length up to maxPathLength $maxPathLength = 40 if ($curPath.Length -gt $maxPathLength) { $curPath = '...' + $curPath.SubString($curPath.Length - $maxPathLength + 3) } Write-Host $curPath -ForegroundColor DarkGreen $global:LASTEXITCODE = $origLASTEXITCODE if ($?) { Write-Host " (*'-')" -NoNewLine -ForegroundColor "DarkGreen" } else { Write-Host " (*;-;)" -NoNewLine -ForegroundColor "Red" } return "> " }
見た目はこんな感じで、だいぶ気に入っている。
最後にかわいくした部分は Qiita の こちらの記事 を参照させてもらった。