先日、Macをフォーマットしたため、今まで構築したきた開発環境が消えました。
といっても、バックアップはとってあるので戻すことはできるのですが、せっかく綺麗に全部消えたので、もう一度作り直そうかな、と思ったわけです。
そこで、先日までシェルはZshを使っていたのですが、Fish shellに乗り換えてみました。
Zshでも、特に不便さは感じていなかったのですが、使い始めたころはプラグインを入れたり、カスタマイズしてみたり、ちょっと苦労した記憶があります。
しかし、Fish shellを使ってみて、こんなにも簡単にカスタマイズできるのか、と驚きました。
そこで今回は、Fish shellの使い方と、プラグインなしで使いやすくカスタマイズする方法を紹介したいと思います。
さて、もしもこの記事の通りに設定していただければ、プラグインを使わなくても、こんなに可愛い開発環境を作ることができます。
※フォントはインストールする必要があります。
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を使えるようになったら、今度はカスタマイズしていきましょう。
といっても、Fishはそのままでも、コマンドの色も変わり、補完機能もしっかりしています。そのままでも使えるのですが、やっぱり自分に合った設定にしていきたいですね。
Fish shellのカスタマイズは、とても斬新かつ簡単で、以下のコマンドを入力することで、ブラウザからカスタマイズすることができます。
~> fish_config
このコマンドを入力すると、ブラウザが開かれます。
そこからFishの設定を行うことができます。
promptでは、プロンプト(コマンドを入力するところを表す部分)を選ぶことができます。
また、関数は変数、履歴を確認したり、キーバインドを見たり、コマンドの省略形を設定したりすることができます。
とても簡単にカスタマイズでき便利なのですが、その分自由度は低いです。
やはり自分好みにカスタマイズしたければ、設定ファイルを自分で書き換えるしかありません。
また自分で設定ファイルを書き換えている場合、ここから変更してしまうと、その設定ファイルを消してしまうので、注意が必要です。
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から全体を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の設定ファイルではなく、ターミナルの環境設定から行う必要があります。
この設定を先にしておくことで、コマンドの文字色などを変えたりするときに、色が分かりやすくなり、便利になります。
ターミナル環境設定の方法はここでは省略しますが、暗い背景のほうが目に優しい気がするので、このような背景色と文字色、そして先ほどインストールしたフォントに変更してみました。
さて、背景色と文字色は私好みになったのですが、プロンプトの表示や、コマンドの色が、あまり好きじゃないので、次はそこを変更していきたいと思います。
ちなみに、私はPowerlineのような見た目が好きです。
lsで表示されるファイル一覧の色を変更する
ここで、lsコマンドを実行してみましょう。
~> ls
すると、このようにファイル一覧が表示されますが、とても見えにくいです。
背景色を暗くすると、デフォルトでは驚くほどに文字が見えにくいのです。
そこで、~/.config/fish/config.fishに以下のコマンドを入力します。(ない場合は作成します)
~/.config/fish/config.fish
export LSCOLORS=Gxfxcxdxbxegedabagacad
一見、複雑な文字列が並んでいます。そして、これは意味を理解しても、ややこしいです。
まず、LSCOLORSのデフォルトの値はexfxcxdxbxegedabagacadです。これは2文字でセットになっており、文字色と、背景色を表しています。
そして今回変更したいのは、フォルダ(ディレクトリ)です。
ディレクトリを表すのは先頭の2文字なので、デフォルトの値の、exの部分になります。
eは青を、xはデフォルトであることを表すので、青い文字にデフォルトの背景、という意味になります。
なので青い文字が見えにくかったのです。
そこで、一番先頭の文字をGに変えることで、ディレクトリには、太字のシアンを指定しました。
その他の部分はちょっと特別なファイルのことだったりしますので、ここでは変更しませんが、変更したい方は色々試してみてください。
Fish shellで使われる様々な文字色を変更する
lsコマンドで表示されるディレクトリの色が見えにくかったので、ここまでは目立たなかったのですが、今度はlsコマンド自体の色が見えにくいことに気付きます。
ほかのところでも、あまり自分好みの色とは言えない部分があります。
そこで、様々なところで使われる文字や背景の色を変更したいと思います。
~/.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では「$var=0」といった変数の代入はできません。かわりにsetというコマンドを使います。
例えば、以下のコマンドは、blueをローカル変数として00bcc6という値を代入する、という意味になります。
set -l blue 00bcc6
また、以下のように、わざわざ色を二回に分けて代入していて、無駄なことをしているな、と思った方もいるかもしれません。
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_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に入っています。
現在のディレクトリを表示させる
では、ユーザ名の前に現在のディレクトリを表示させてみましょう。
~/.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に入っています。
入力をミスしたときに、×マークを表示する
続いて、入力をミスしたときに、先頭に×マークを表示してみたいと思います。
~/.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よりも大きいときに、×マークを表示するようにすればいいのです。
ターミナルでコマンドを間違えると、このようになります。
プロンプトを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という関数を作成し、そこで背景と文字の色を指定しています。
背景の色は情報を分ける三角形から後ろの背景色で、文字の色は三角形の色になります。
Gitに対応させる
つづいて、Gitに対応させてみましょう。
FishはデフォルトでGitに対応しているのですが、プロンプトを初期化してしまったので、git initしても、見た目は変わりません。
やはりブランチ名とかを表示させたいわけです。
~/.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で管理しているディレクトリでは、このように表示されるようになります。
アイコンフォントで可愛くする
さて、最低限の機能ができたわけですが、まだなんだか寂しい気がします。
そこで、アイコンフォントを使って可愛くしましょう。
~/.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はとても使いやすい上に、カスタマイズしやすく、プラグインを使わなくても可愛いデザインにすることができます。
そして、Nerd Fontsを使うと、Powerlineフォント+可愛いアイコンフォントを使うことができ、自由度が増します。
自分だけの環境を作って、開発を楽しみましょう!
コメントを残す(コメントは承認後に反映されます)