1. HOME»
  2. プログラミング・Web»
  3. ターミナル»
  4. Fish shellの使い方。プラグインなしでもここまで可愛くできる!

Fish shellの使い方。プラグインなしでもここまで可愛くできる!

先日、Macをフォーマットしたため、今まで構築したきた開発環境が消えました。
といっても、バックアップはとってあるので戻すことはできるのですが、せっかく綺麗に全部消えたので、もう一度作り直そうかな、と思ったわけです。

そこで、先日までシェルはZshを使っていたのですが、Fish shellに乗り換えてみました。
Zshでも、特に不便さは感じていなかったのですが、使い始めたころはプラグインを入れたり、カスタマイズしてみたり、ちょっと苦労した記憶があります。

しかし、Fish shellを使ってみて、こんなにも簡単にカスタマイズできるのか、と驚きました。
そこで今回は、Fish shellの使い方と、プラグインなしで使いやすくカスタマイズする方法を紹介したいと思います。

さて、もしもこの記事の通りに設定していただければ、プラグインを使わなくても、こんなに可愛い開発環境を作ることができます。
fish shell

※フォントはインストールする必要があります。

目次
  1. Fish shellのインストール
  2. デフォルトシェルをFishに変更する方法
  3. Fish shellをブラウザ上でカスタマイズするには
  4. Fish Shellの設定ファイルについて
  5. Nerd Fontsのインストール
  6. ターミナルの環境設定
  7. lsで表示されるファイル一覧の色を変更する
  8. Fish shellで使われる様々な文字色を変更する
  9. プロンプトの見た目をカスタマイズするには
  10. プロンプトにユーザ名を表示する
  11. 現在のディレクトリを表示させる
  12. 入力をミスしたときに、×マークを表示する
  13. プロンプトをPowerline風にする
  14. Gitに対応させる
  15. アイコンフォントで可愛くする
  16. まとめ

Fish shellのインストール

まず、Fish shellをインストールする方法です。
さまざまな方法があると思いますが、今回はHomebrewを使っていこうと思います。

Homebrewインストールしていない方は、こちらの記事をご覧ください。
Homebrewの使い方。よく使うコマンド一覧と詳しい解説まとめ

Fish shellのインストールには、ターミナルに以下のコマンドを入力します。

$ brew install fish
$ brew list
fish	pcre2

インストールが完了したら、Fishを起動してみましょう。

$ fish

ぶじ、Fishが起動すれば、インストールの完了です。

デフォルトシェルをFishに変更する方法

次に、デフォルトシェルをFishに変更してみましょう。
以下のコマンドをターミナルに入力します。

~> echo /usr/local/bin/fish | sudo tee -a /etc/shells
~> chsh -s /usr/local/bin/fish

ターミナルを開き直し、Fishが起動していれば成功です。

fish shell

Fish shellをブラウザ上でカスタマイズするには

さて、Fishを使えるようになったら、今度はカスタマイズしていきましょう。

といっても、Fishはそのままでも、コマンドの色も変わり、補完機能もしっかりしています。そのままでも使えるのですが、やっぱり自分に合った設定にしていきたいですね。

Fish shellのカスタマイズは、とても斬新かつ簡単で、以下のコマンドを入力することで、ブラウザからカスタマイズすることができます。

~> fish_config

このコマンドを入力すると、ブラウザが開かれます。
そこからFishの設定を行うことができます。

colorsでは、文字の色を選ぶことができます。
fish shell

promptでは、プロンプトコマンドを入力するところを表す部分)を選ぶことができます。
fish shell

また、関数は変数、履歴を確認したり、キーバインドを見たり、コマンドの省略形を設定したりすることができます。

とても簡単にカスタマイズでき便利なのですが、その分自由度は低いです。
やはり自分好みにカスタマイズしたければ、設定ファイルを自分で書き換えるしかありません。

また自分で設定ファイルを書き換えている場合、ここから変更してしまうと、その設定ファイルを消してしまうので、注意が必要です。

Fish Shellの設定ファイルについて

Fish Shellを起動すると、ホームディレクトリの.configに、fishフォルダが作成されます。
この中に、Fish shellの設定ファイルが入っています。

さきほど、fish_configコマンドブラウザが開かれ、そこで設定が可能という話をしました。
もしここでなにかを設定すると、~/.config/fish/の中に、いくつかのフォルダとファイルが作成されます。なにも設定しなければ、fish_variablesというファイルのみが作成されていると思います。

設定は、~/.config/fish/config.fishに書いていきます。もしこのファイルがない場合は作成します。
また、~/.config/fish/functions/フォルダにファイルを作成し、Fish Shellの関数をオーバーライド(機能を上書きすること)することで、カスタマイズすることもできます。

以下でその詳しい方法を見ていきましょう。

Nerd Fontsのインストール

さて、まずはカスタマイズに必要不可欠な、フォントをインストールします。
Powerlineフォントもいいのですが、今回は、アイコンフォントなどもセットになっているNerd Fontsをインストールします。

GitHub Nerd Fonts

GitHubから全体をcloneしてもいいのですが、とても時間がかかるので、今回は使いたいフォントだけをインストールすることにします。

私はこれまで、Powerlineフォントを使っており、Cousineを使っていました。なのでNerd Fontsでも、Cousineを使っていきたいと思います。

Nerd FontsのCousineをインストールするには、以下のコマンドを入力します。

cd ~/Library/Fonts && curl -fLo "Cousine Regular Nerd Font Complete.ttf" https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Cousine/Regular/complete/Cousine%20Regular%20Nerd%20Font%20Complete.ttf

ターミナルの環境設定

ターミナル自体の環境設定を行います。というのも、ターミナル全体の背景色などは、Fishの設定ファイルではなく、ターミナルの環境設定から行う必要があります。
この設定を先にしておくことで、コマンドの文字色などを変えたりするときに、色が分かりやすくなり、便利になります。

ターミナル環境設定の方法はここでは省略しますが、暗い背景のほうが目に優しい気がするので、このような背景色と文字色、そして先ほどインストールしたフォントに変更してみました。
fish shell

さて、背景色と文字色は私好みになったのですが、プロンプトの表示や、コマンドの色が、あまり好きじゃないので、次はそこを変更していきたいと思います。

ちなみに、私はPowerlineのような見た目が好きです。

lsで表示されるファイル一覧の色を変更する

ここで、lsコマンドを実行してみましょう。

~> ls

すると、このようにファイル一覧が表示されますが、とても見えにくいです。
fish shell

背景色を暗くすると、デフォルトでは驚くほどに文字が見えにくいのです。
そこで、~/.config/fish/config.fishに以下のコマンドを入力します。(ない場合は作成します)

~/.config/fish/config.fish

export LSCOLORS=Gxfxcxdxbxegedabagacad

一見、複雑な文字列が並んでいます。そして、これは意味を理解しても、ややこしいです。

まず、LSCOLORSのデフォルトの値はexfxcxdxbxegedabagacadです。これは2文字でセットになっており、文字色と、背景色を表しています。

そして今回変更したいのは、フォルダ(ディレクトリ)です。
ディレクトリを表すのは先頭の2文字なので、デフォルトの値の、exの部分になります。
eは青を、xはデフォルトであることを表すので、青い文字にデフォルトの背景、という意味になります。
なので青い文字が見えにくかったのです。

そこで、一番先頭の文字をGに変えることで、ディレクトリには、太字のシアンを指定しました。
fish shell

その他の部分はちょっと特別なファイルのことだったりしますので、ここでは変更しませんが、変更したい方は色々試してみてください。

Fish shellで使われる様々な文字色を変更する

lsコマンドで表示されるディレクトリの色が見えにくかったので、ここまでは目立たなかったのですが、今度はlsコマンド自体の色が見えにくいことに気付きます。
fish shell

ほかのところでも、あまり自分好みの色とは言えない部分があります。
fish shell

そこで、様々なところで使われる文字や背景の色を変更したいと思います。

~/.config/fish/conf.d/mytheme_colors.fishファイルを作成し、以下のソースを作成してみました。
(この後で使用するため、ここではまだ使っていない変数も作っています。)

~/.config/fish/conf.d/mytheme_colors.fish

# 使いたい色を登録しておく
set -l blue             00bcc6
set -l light_blue       8ed0ff
set -l green            00c694
set -l dark_green       287480
set -l red              ff6161
set -l pink             c600c0
set -l light_pink       f8bbf6
set -l orange           c66400
set -l yellow           fff92f

# 白と黒は誰が見ても同じなので、グローバルに登録
set -g white            ffffff
set -g black            000000

# 抽象的な名前でグローバルに登録
set -g color_dark       333333
set -g color_discreet   757575

set -g color_main       $blue
set -g color_main_light $light_blue
set -g color_warning    $red

# git color
set -g color_git_main   $green
set -g color_git_dirty  $yellow

# fish color
set -g fish_color_normal            $white                          # デフォルトの色
set -g fish_color_autosuggestion    $color_discreet                 # コマンドの提案の色
set -g fish_color_cancel            --background=$color_main        # 「^c」の色
set -g fish_color_command           $color_main_light               # コマンドの色
set -g fish_color_comment           $color_discreet                 # コメントの色
set -g fish_color_end               $color_main_light               # ; や & などの色
set -g fish_color_error             $red                            # エラーの色
set -g fish_color_escape            $color_discreet                 # \n や \x70 などのエスケープ文字の色
set -g fish_color_match             --background=$color_main_light  # 検索した文字とマッチした時の背景色
set -g fish_color_operator          $light_pink                     # パラメータ演算子の色
set -g fish_color_param             $light_pink                     # 変数
set -g fish_color_search_match      --background=$color_main        # Tab候補の選択などでの背景色
set -g fish_color_selection         --background=$dark_green        # vi、選択モードで選択された部分の背景色
set -g fish_color_quote             $light_pink                     # echo ''など

set -g fish_pager_color_progress    $color_main_light               # Tabキーで表示される補完一覧の、左下に表示される文字の色
set -g fish_pager_color_completion  $white                          # Tabキーで表示される補完一覧の文字色
set -g fish_pager_color_prefix      $color_main_light               # Tabキーで表示される補完一覧の、一致した文字の色

すると、このようになります。
fish shell

ソースについて

ここで、すこしだけ上記ソースの解説をします。
まず、Fishでは「$var=0」といった変数の代入はできません。かわりにsetというコマンドを使います。
例えば、以下のコマンドは、blueをローカル変数として00bcc6という値を代入する、という意味になります。

set -l blue 00bcc6

ローカル変数は-l、グローバル変数は-gをつけます。

また、以下のように、わざわざ色を二回に分けて代入していて、無駄なことをしているな、と思った方もいるかもしれません。

set -l blue             00bcc6
set -g color_main       $blue

私も、いろいろ試してみて、最終的にこの方法にしたのですが、もしこの変数を1つにしてしまうと、このようになります。

set -g color_main 00bcc6

さて、color_mainには何色が代入されているのでしょうか、と訊かれても私には答えられません。えっと……赤がなくて、青と緑が……ちょっと青の方が多いから……となってしまいます。
ならば、このようにすればどうでしょうか?

set -g color_main_blue 00bcc6

一見、問題はなさそうです。青だとすぐに分かります。
しかし、メインカラーはやっぱり緑に変えたい、と思ったとします。するとcolor_main_greenといったふうに変数名を変更する必要があります。
すると、color_main_blueという変数を使っていた部分すべてをcolor_main_greenに変更しなくてはなりません。

そんなわけで、変数名は、まず直感的に分かる名前の変数を作り、それを少し抽象的な名前の変数に代入する、というふうな二段階構造がいいように思います。

変数名について

また、中にはcolor_mainという変数名に違和感を覚えた方もいるかもしれません。
普通、main_colorなのでは、と思われるかもしれないです。

これは、私個人で勝手に使っている書き方なのですが、変数名を見たとき、最初にmainと書いてあると、その後の単語を見る必要があるのです。
mainと書かれていれば、メインの色かもしれないし、メインのフレーズかもしれません。メインの形かもしれません。mainの後ろにある単語を見て、そこでなんの変数なのかが分かります。

しかし、colorと変数名の先頭に書いておけば、色の変数だということがすぐに分かります。これだけで変数を探すときや、整理するときに、とても楽になります。
正しいか間違っているかは分かりませんが、参考になれば……

プロンプトの見た目をカスタマイズするには

続いて、プロンプトコマンドを入力するところを表す部分)の見た目をカスタマイズしていきます。

プロンプトをカスタマイズするには、fish_promptという関数をオーバーライドします。

では、~/.config/fish/functions/フォルダに、fish_prompt.fishファイルを作成し、以下の関数を作ります。

~/.config/fish/functions/fish_prompt.fish

function fish_prompt
end

これでプロンプトが表示されなくなります。
fish shell

このfish_prompt関数に、自分オリジナルのプロンプトを作成していけばいいのです。
以下で、表示したい情報を順番に追加していきます。

プロンプトにユーザ名を表示する

さて、プロンプトに何も表示されていない状態になったわけですが、ここに自分が欲しい情報を追加していきます。
ではまず、ユーザ名を表示してみましょう。

~/.config/fish/functions/fish_prompt.fish

function _prompt_user
    printf '%s ' (set_color $white)(whoami)
end

function fish_prompt
    _prompt_user
end

_prompt_userという関数を作成し、そこにユーザ名を表示する命令を書きました。
ユーザ名は、whoamiに入っています。

これでユーザ名を表示させることができます。
fish shell

現在のディレクトリを表示させる

では、ユーザ名の前に現在のディレクトリを表示させてみましょう。

~/.config/fish/functions/fish_prompt.fish

# ここから
function _prompt_dir
    printf ' %s ' (prompt_pwd)
end
# ここまでを追加

function _prompt_user
    printf '%s ' (set_color $white)(whoami)
end

function fish_prompt
    _prompt_dir     # 追加
    _prompt_user
end

_prompt_dirという関数を作成し、そこに現在のディレクトリを表示する命令を書きました。
現在のディレクトリは、prompt_pwdに入っています。
fish shell

入力をミスしたときに、×マークを表示する

続いて、入力をミスしたときに、先頭に×マークを表示してみたいと思います。

~/.config/fish/functions/fish_prompt.fish

set -l icon_cross \uf00d        #追加
set icon_miss     $icon_cross   #追加

function _prompt_dir
    printf ' %s ' (prompt_pwd)
end

function _prompt_user
    printf '%s ' (set_color $white)(whoami)
end

function fish_prompt

    # ここから
    set -l last_status $status
    if [ $last_status -gt 0 ]
        echo -n (set_color $white)" $icon_miss "
    end
    # ここまでを追加

    _prompt_dir
    _prompt_user
end

$statusはfish_prompt関数の中で使うことができ、普通は0が入っていますが、ミスをした場合、それに応じた数値が代入されます。
つまり、$statusの値が0よりも大きいときに、×マークを表示するようにすればいいのです。

ターミナルでコマンドを間違えると、このようになります。
fish shell

プロンプトをPowerline風にする

つづいて、プロンプトの見た目をPowerlineっぽくしてみたいと思います。

~/.config/fish/functions/fish_prompt.fish

# 区切り文字やアイコン(一目でなにか分かる名前にしておく)
set -l separator_triangle   \ue0b0              #追加
set -l icon_cross           \uf00d

# 区切り文字などを、少し抽象的な名前で登録する
set segment_separator       $separator_triangle #追加
set icon_miss               $icon_cross

set color_user                                  #追加

# 〜ここから〜
function _segment
    set_color -b $argv[1] $argv[2]
    echo -n "$segment_separator "
end
# 〜ここまで追加〜

function _prompt_dir
    printf ' %s ' (prompt_pwd)
    _segment $color_user $color_dark    #追加
end

function _prompt_user
    printf '%s ' (set_color $white)(whoami)
    _segment normal $color_user         #追加
end

function fish_prompt

    set -l last_status $status

    set_color -b $color_dark $white     #追加

    if [ $last_status -gt 0 ]
        echo -n (set_color $white)" $icon_miss "
        set color_user $color_warning   #追加
    else                                #追加
        set color_user $color_main      #追加
    end

    _prompt_dir
    _prompt_user
end

_segmentという関数を作成し、そこで背景と文字の色を指定しています。
背景の色は情報を分ける三角形から後ろの背景色で、文字の色は三角形の色になります。

Powerlineっぽくなりましたでしょうか?
fish shell

Gitに対応させる

つづいて、Gitに対応させてみましょう。
FishはデフォルトでGitに対応しているのですが、プロンプトを初期化してしまったので、git initしても、見た目は変わりません。
fish shell

やはりブランチ名とかを表示させたいわけです。

~/.config/fish/functions/fish_prompt.fish

# 区切り文字やアイコン(一目でなにか分かる名前にしておく)
set -l separator_triangle   \ue0b0
set -l icon_cross           \uf00d

# 区切り文字などを、少し抽象的な名前で登録する
set segment_separator       $separator_triangle
set icon_miss               $icon_cross

set color_user
set color_git_status_bar    #追加

function _segment
    set_color -b $argv[1] $argv[2]
    echo -n "$segment_separator "
end

function _prompt_dir
    printf ' %s ' (prompt_pwd)
    _segment $color_user $color_dark
end

function _prompt_user
    printf '%s ' (set_color $white)(whoami)

    # 〜ここから〜
    if command git rev-parse --is-inside-work-tree >/dev/null 2>&1
        _change_color_git_status_bar
        _segment $color_git_status_bar $color_user;
    else
        _segment normal $color_user
    end
    # 〜ここまでを追加〜
end

# 〜ここから〜
function _change_color_git_status_bar
    if [ (_is_git_dirty) ]; set color_git_status_bar $color_git_dirty
    else; set color_git_status_bar $color_git_main; end
end

function _is_git_dirty
    echo (command git status -s --ignore-submodules=dirty 2> /dev/null)
end

function _prompt_git
    if command git rev-parse --is-inside-work-tree >/dev/null 2>&1
        set -l git_branch (command git symbolic-ref HEAD 2> /dev/null | sed -e 's|^refs/heads/||')
        _change_color_git_status_bar
        set_color -b $color_git_status_bar
        printf '%s ' (set_color $black)$git_branch
        _segment normal $color_git_status_bar
    end
end
# 〜ここまでを追加〜

function fish_prompt

    set -l last_status $status

    set_color -b $color_dark $white

    if [ $last_status -gt 0 ]
        echo -n (set_color $white)" $icon_miss "
        set color_user $color_warning
    else
        set color_user $color_main
    end

    _prompt_dir
    _prompt_user
    _prompt_git      # 追加
end

これで、Gitで管理しているディレクトリでは、このように表示されるようになります。
fish shell

アイコンフォントで可愛くする

さて、最低限の機能ができたわけですが、まだなんだか寂しい気がします。
そこで、アイコンフォントを使って可愛くしましょう。

~/.config/fish/functions/fish_prompt.fish

# 区切り文字やアイコン(一目でなにか分かる名前にしておく)
set -l separator_triangle           \ue0b0
set -l icon_cross                   \uf00d
set -l icon_plus                    \uf067  # 追加
set -l icon_three_point_reader      \uf6d7  # 追加
set -l icon_octocat                 \uf113  # 追加

# 区切り文字などを、少し抽象的な名前で登録する
set segment_separator               $separator_triangle         # 追加
set icon_miss                       $icon_cross                 # 追加
set icon_untracked                  $icon_three_point_reader    # 追加
set icon_git_symbol                 $icon_octocat               # 追加
set icon_git_dirty                  $icon_plus                  # 追加

set icon_home                       \uf7db  # 追加
set icon_folder                     \uf07c  # 追加

set color_user
set color_git_status_bar

function _segment
    set_color -b $argv[1] $argv[2]
    echo -n "$segment_separator "
end

function _prompt_dir

    # 〜ここから〜
    if [ $HOME = $PWD ]; printf ' %s ' $icon_home
    else; printf ' %s ' $icon_folder; end
    # 〜ここまでを追加〜

    printf ' %s ' (prompt_pwd)
    _segment $color_user $color_dark
end

function _prompt_user
    printf '%s ' (set_color $white)(whoami)

    if command git rev-parse --is-inside-work-tree >/dev/null 2>&1
        _change_color_git_status_bar
        _segment $color_git_status_bar $color_user;
    else
        _segment normal $color_user
    end
end

# 〜ここから〜
function _git_prompt_untracked
    echo (command git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- :/ 2> /dev/null)
end

function _git_status_symbol
    if [ (_git_prompt_untracked) ]; echo -n "$icon_untracked "
    else if [ (_is_git_dirty) ]; echo -n "$icon_git_dirty "; end
end
# 〜ここまでを追加〜

function _change_color_git_status_bar
    if [ (_is_git_dirty) ]; set color_git_status_bar $color_git_dirty
    else; set color_git_status_bar $color_git_main; end
end

function _is_git_dirty
    echo (command git status -s --ignore-submodules=dirty 2> /dev/null)
end

function _prompt_git
    if command git rev-parse --is-inside-work-tree >/dev/null 2>&1
        set -l git_branch (command git symbolic-ref HEAD 2> /dev/null | sed -e 's|^refs/heads/||')
        set -l git_status_symbol (_git_status_symbol)                                       # 追加
        _change_color_git_status_bar
        set_color -b $color_git_status_bar
        printf '%s ' (set_color $black)"$icon_git_symbol $git_branch $git_status_symbol"    # 変更
        _segment normal $color_git_status_bar
    end
end

function fish_prompt

    set -l last_status $status

    set_color -b $color_dark $white

    if [ $last_status -gt 0 ]
        echo -n (set_color $white)" $icon_miss "
        set color_user $color_warning
    else
        set color_user $color_main
    end

    _prompt_dir
    _prompt_user
    _prompt_git
end

このようにアイコンが入って可愛くなります。
fish shell

まとめ

Fish shellはとても使いやすい上に、カスタマイズしやすく、プラグインを使わなくても可愛いデザインにすることができます。
そして、Nerd Fontsを使うと、Powerlineフォント+可愛いアイコンフォントを使うことができ、自由度が増します。
自分だけの環境を作って、開発を楽しみましょう!

コメントを残す(コメントは承認後に反映されます)

メールアドレスが公開されることはありません。 が付いている欄は必須項目です




オリジナルゲーム.com