Oh My Poshを利用してPowerShellプロンプトをいい感じにする

## 注意事項（2022年5月1日追記）

**`Oh My Posh`のバージョンが7.75.0から、本記事で紹介しているPowerShellギャラリーからインストールするPowerShellモジュール版のサポートは終了するようです。**

※PowerShellモジュール版のoh-my-posh v 7.75.0をインストールすると下記のメッセージが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/f271e2b9-90c8-8089-2eb9-dd26380bc644.png)

**現在は提供方式がバイナリをインストールする方式に変更されており。
インストール手順も変更となっています。**

[PowerShell module](https://ohmyposh.dev/docs/migrating)

**このため本手順で紹介しているインストール方法は過去の手法となり。
本手順でインストールされるモジュール版は古い手順となるためご注意下さい**

**なおすでにインストールしているPowerShellモジュール版のOh My Poshをバイナリ版に移行する記事を下記に投稿しています。**

[Oh My PoshをPowerShellモジュール版からバイナリインストール版に移行してみる](https://qiita.com/SAITO_Keita/items/622f32bbdd2602917e26)

**また一からバイナリ提供版をインストールする場合は下記参照。**

[Oh My Poshを利用してPowerShellプロンプトをいい感じにする（バイナリインストール・Windows Terminal）](https://qiita.com/SAITO_Keita/items/14cd9d7349bc2256b4da)

**以上追記終了、以下本文**

[Git For Windowsをさわってみる from PowerShell＋【oh-my-poshとposh-gitも】](https://qiita.com/SAITO_Keita/items/ae84c52e42eac009cf96)　の記事で、`PowerShell`で`git`を利用する過程で`Oh My Posh`と`posh-git`利用について書きましたが、`Oh My Posh`についてはざっくりと流したので本記事では`Oh My Posh`の利用を主題において記載します。

## Oh My Poshとは

`Oh My Posh`は`PowerShell`のコンソールをいい感じにカスタマイズ表示してくれるPowerShellモジュールとなっており。
`zsh`の`oh-my-zash`に影響されて始まったプロジェクトのようです。

このモジュールが作られた動機については下記ブログに記載があります。

[Shell shock](https://blog.itdepends.be/shell-shock/)

いいかんじに設定するとは書きましたが、どんな感じになるかは下記サイトに標準テーマの見栄えがまとまっているため。
こちらをみて気になった方は`Oh My Posh`の導入を検討するのがいいでしょう。

[Oh My Posh Docs - themes](https://ohmyposh.dev/docs/themes)

## 各種Webサイト

- [JanDeDobbeleer/oh-my-posh](https://github.com/jandedobbeleer/oh-my-posh)
- [oh-my-posh document](https://ohmyposh.dev/)
- [MSDocs WindowsTerminal - PowerLine](https://docs.microsoft.com/en-us/windows/terminal/tutorials/powerline-setup)
- [PowerShell Gallery oh-my-posh](https://www.powershellgallery.com/packages/oh-my-posh/)

## v2とv3

[Oh My Posh 3 vs Oh My Posh 2](https://ohmyposh.dev/docs/#oh-my-posh-3-vs-oh-my-posh-2)

上記ドキュメントにはv2とv3についての記載がありますが今現在は普通にインストールすると`v5.8.0`がインストールされるため特に気にする必要はないかと思います。

ちなみにv2からv3にかけて実装を作り直して、色々とコマンドレット名に変更があったりしました。

## 端末環境

- Windows 10
- PowerShell 7.2.0-preview.10
- Windows Terminal Preview 1.11.2731.0
- oh-my-posh v5.8.0
- posh-git v1.0.0

普段、`WindowsTerminal`上で`PowerShell`を利用しているため、本記事でもフォント設定部分は`WindowsTerminal`を設定する事で対応しています。

## oh-my-poshをインストールする

```PowerShell:oh-my-poshをインストール
Install-Module -Name oh-my-posh 
```

上記の例だとマシンスコープにモジュールをインストールしていますが、ユーザスコープにインストールする場合は`-Scope CurrentUser`をつけてインストールして下さい。

## フォントをインストールする

[Oh My Posh Docs - Font](https://ohmyposh.dev/docs/fonts)

`Oh My Posh`は[Nerdフォント](https://www.nerdfonts.com/)と呼ばれる、多数のアイコンを含む開発者向けのフォント利用を前提として構築されています。

このため、まずは`Nerdフォント`をインストールする必要があります。
ちなみに上記ドキュメントでは、`Meslo LGM NF`フォントを推奨しています。

フォントをインストールしたあとは、コンソールでインストールしたフォントを利用するよう設定して下さい。

下記は`WindowsTerminal`に[HackGenNerd Consoleフォント](https://github.com/yuru7/HackGen)を設定した図。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/33609f29-760f-1795-4499-95e62f1d517d.png)

## Oh my Poshで用意されている標準テーマを確認してみる。

まずは本モジュールで利用できるコマンドレットを確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/21e01201-ba28-e4c6-fca9-5e9b71784e7a.png)

v5.8.0では上記のコマンドがインストールされています。
v2からv3にかけて変更された古いコマンドがAliasとして登録されており、実行するとドキュメントへのリンクを表示する`Get-PoshInfoForV2Users`が実行されます。

ここでは`Get-PoshThemes`コマンドレットを実行して`Oh My Posh`が提供しているテーマ一覧がを表示してみます。

実行すると、各種テーマが表示されるので自分が気に入るテーマ名を控えておいて下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/64e42c6c-acbe-c3b0-77d5-735add756f81.png)

## PoshThemesを適用する

先程控えておいたテーマを適用するには`Set-PoshPrompt -Theme テーマ名`で適用できます。

`rudolfs-dark`テーマを適用してみた例。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/f1bae597-9219-e52f-de70-f77a02ab3b69.png)

さてこの`Set-PoshPormpt`でテーマが適用された状態でもう一度、モジュールで利用できるコマンドを確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/7e06f1ed-c21d-3044-bfdc-55fabd68dedf.png)

現在、読み込んでいるテーマファイルの場所を表示する`Get-PoshContext`。テーマのイメージファイルを保存する`Export-PoshImage`などのコマンドが増えています。

なお`Set-PoshPormpt`で適用したテーマの有効期間ついては現在開いているセッション中有効となり。

別セッションでPowerShellプロンプト起動時は再度読み込む必要があります。

毎回コマンドを実行するのは手間なので起動時に自動実行される起動プロファイル`$Profile`に設定を書き込みます。

## 起動時にPoshTemesを読み込むよう$profileに設定を書き込む

Powershellのプロファイルは環境変数`$Profile`に場所が格納されているため`notepad`で編集する場合は下記のように実行して下さい。

```PowerShell
notepad $Profile
````

下記は起動時に`rudolfs-dark`を読み込む設定

```profile
Import-Module oh-my-posh
Set-PoshPrompt -Theme rudolfs-dark
```

標準テーマをそのまま利用する場合はテーマ名指定で問題ありません。

`Set-PoshPrompt -Theme rudolfs-dark`を読み込んだあとに、`Get-PoshContext`を実行すればわかりますが。
テーマ設定が格納されているのは`...\Modules\oh-my-posh\5.8.0\bin`となっていることからわかる通り。
`Oh My Posh`のインストールバージョン毎のディレクトリに含まれているテーマを読み込んでいます。

このため、テーマ名の指定だとモジュールをバージョアップした際に、該当のテーマがなくなっていたら起動時にエラーになるかと思います。（そんなケースがあるかどうかですが）

## Set-PoshPromptでテーマ名ではなくテーマ設定ファイルのパスを指定してテーマを読み込む

[Oh My Posh Docs - Override the theme settings](https://ohmyposh.dev/docs/pwsh#override-the-theme-settings)

`Oh My Posh`のテーマを改造する場合はドキュメントにある通り。

コマンドを実行して読み込んでいるテーマの設定を`~/.mytheme.omp.json`として保存できるため、保存したファイルを更新するのがいいかと思います。

いきなり１から設定ファイルの記述を始めるのは中々ハードルが高い。

```PowerShell
Set-PoshPrompt -Theme rudolfs-dark
Export-PoshTheme -FilePath ~/.mytheme.omp.json -Format json
```

設定方法は後述しますが、`~/.mytheme.omp.json`を自分好みのカスタマイズが完了したら。

起動プロファイル`$Profile`に`Set-PoshPrompt -Theme ~/.mytheme.omp.json`とテーマ名ではなく設定ファイルパスで指定します。

こうする事によりモジュールのバージョンを上げるたびに、設定ファイルを最新バージョンのモジュール配下に設置しなくてよくなります。
テーマ名だと動作しているバージョンのフォルダを探しにいく。

## 実際にテーマを改造してみる

先程エクスポートテーマを改造するために必要な情報は下記のドキュメントを参照すれば得られます。

[Configuration|Oh MyPosh](https://ohmyposh.dev/docs/configure)

`Oh My Posh`では様々な機能がセグメントとして用意されており、それに対してプロパティを設定する事でプロンプトをカスタマイズできます。

下記は筆者が現時点で設定しているテーマをサンプルとして載せておきます。

`paradox`テーマを改造して、下記の設定をしています。

- ユーザ名とホスト名を非表示。
- Pathセグメントの表示スタイルをAgnosterを指定して、カレントディレクトリとホームの表示を設定
- AWSセグメントの表示設定
- posh-gitセグメントの表示設定

`posh-git`セグメントを利用するには、前提として`posh-git`モジュールががインストールされていて、環境変数`$env:POSH_GIT_ENABLED = $true`となっている必要があったり。

`oh-my-posh`では標準でgitセグメントが用意されていて、どちらか使えば問題ないのですがここで掲載している設定ではなんとなく両方表示させているのでだいぶ冗長な感はあります。

こちらを適用すると下記のような感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/a44891a1-a7fa-7168-6e36-a6219536fcea.png)


```json:paradoxを改造した一例
{
  "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "root",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#100e23",
          "background": "#ffe9aa"
        },
        {
          "type": "session",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#100e23",
          "background": "#ffffff",
          "properties": {
            "display_user": false,
            "display_host": false
          }
        },
        {
          "type": "path",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#100e23",
          "background": "#91ddff",
          "properties": {
            "folder_icon": "\uF115",
            "folder_separator_icon": " \uE0B1 ",
            "style": "agnoster"
          }
        },
        {
          "type": "git",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#193549",
          "background": "#95ffa4",
          "properties": {
            "display_status": true,
            "display_stash_count": true,
            "display_upstream_icon": true
          }
        },
        {
          "type": "poshgit",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#000000",
          "background": "#000000"
        },
        {
          "type": "aws",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#ffffff",
          "background": "#FFA400",
          "properties": {
            "prefix": " \uE7AD ",
            "template": "{{.Profile}}{{if .Region}}@{{.Region}}{{end}}"
          }
        },
        {
          "type": "python",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#100e23",
          "background": "#906cff",
          "properties": {
            "prefix": " \uE235 "
          }
        },
        {
          "type": "exit",
          "style": "powerline",
          "powerline_symbol": "\uE0B0",
          "foreground": "#ffffff",
          "background": "#ff8080",
          "properties": {
            "prefix": " \uE20F"
          }
        }
      ]
    },
    {
      "type": "newline"
    },
    {
      "type": "prompt",
      "alignment": "left",
      "segments": [
        {
          "type": "text",
          "style": "plain",
          "foreground": "#007ACC",
          "properties": {
            "prefix": "",
            "text": "\u276F"
          }
        }
      ]
    }
  ],
  "final_space": false
}
```

## 総評

プロンプトのカスタマイズについては見栄えという観点以外には。

AWSセグメントは環境変数に設定されているプロファイル情報を表示してくれるため`.aws/config`に設定しているコンフィグ情報を環境変数`AWS_PROFILE`に書き込んでくれる[posh-awsp](https://github.com/jonscheiding/posh-awsp)モジュールと組み合わせ利用すると、視覚的に今どのプロファイルを利用しているのかわかり便利です。

今回は利用していませんが、Azureセグメントも用意されているためAzureを利用する場合にも便利なのかもしれません。