Fishermanは名前を変更しFisherとなったため、それにともない内容を修正しました。
Yaourtはすでに開発が終了しているため、Yayを使うよう修正しました。
Fisherのインストール方法やコマンド体系の情報が古くなっています。プラグイン紹介以下もすべて修正する必要があるため、修正していません。FisherのREADMEを参考にしてください。
「fishいいよ」みたいな話は何度かちらっと聞いていたんですけど、ちょっと調べてみたところPOSIX非互換ということで、あまり興味を持てずにいました。
しかし最近Twitterで勧められて試しに使ってみたところ、すごく良かったので導入方法とかおすすめプラグインとか紹介してみたいと思います。
僕も入門したところなので、あんまり詳しくはないですけど。
似たような内容ですが、目的を絞った記事も書いたので興味があれば読んでみてください。
こっちの方がわかりやすいかもです。
上の記事は内容が古いままです。
awesome-fishに情報がまとめられているので、見てみるといいと思います。
fishとは
Friendly interactive shellの略称だそうです。
ユーザーフレンドリさと対話的利用、わかりやすさを重要視しているようですね。
今までのシェルと同じように直感的に使えて、かつ古い悪習(case
の終了がesac
とか)を捨て去っているという感じです。
なのでPOSIX非互換となっています。
POSIXというのは、シェルスクリプトの標準仕様のようなものです。
shはPOSIX互換のシェルですね。
Bourne Shellを単にshと呼んだりするそうですが、UnixやLinuxにある/bin/sh
はsh
そのものであったり、bash --posix
へのリンクであったりするそうです。
bash --posix
はBashの機能で、POSIX互換の機能のみ使用してスクリプトを動かすモードです。
自分の環境のshが本当にshなのか別のシェルなのか気になる方はls -l $(which sh)
を実行すると見ることができるらしいです。
ls
の-l
オプションはリンクが張られているかを表示するために付けてます。
閑話休題。
BashとかZshとかは、POSIX互換ではなくPOSIX準拠となっています。
というのも、POSIXの仕様で決められたものは全て動かせますけど、それ以外の拡張機能もあるのです。
互換ならどちらで書いてもどちらでも動きますけど、準拠は違います。
shで書いたものはBashで動きますけど、Bashで書いたものはshで動かないかもしれません。
Bashの拡張機能を使っているとshでは動きませんからね。
ちなみに非互換は完全に別物という意味です。
fishはこのPOSIX非互換が問題になるかもと思っていたんですけど、
コピペしてきたスクリプトとか動かすときだけshなりBashなり使えばいいですし、プラグイン紹介に書いてますけどBash互換のスクリプトを動かせるようなプラグインもあります。
そこまで困ることもないかもしれませんね。
以上、半分以上POSIXの話になっていた気もしますけど、fishについてでした。
fishのここが良かった
- デフォルトで色々いい感じなので、ほぼ設定いらず
-
シンタックスハイライトの機能がすごい
- 入力中のコマンドにもシンタックスハイライトが効く
- コマンドやオプションが合っているかがひと目でわかる
- コマンド履歴からの補完
- コマンド入力中にインタラクティブに補完が見える
スクリーンショットはちょっと見た目をいじったあとのものです。
あと公式サイトにもアピールポイントが書いてありますね。
- 履歴から自動で補完候補を表示
- カラフルでわかりやすい
- シンタックスがシンプルでわかりやすい
- ブラウザでグラフィカルに設定をいじれる
- わざわざ補完のためのコードを書かなくてもmanページから補完できる
- 他のシェルでも使えるTabでの補完やシンタックスハイライトを強化しているだけなので、特別に新しいことを覚える必要がない
かなり雑な意訳ですがこんな感じでしょうか。
設定
基本的には~/.config/fish/config.fish
に書いていきます。
でも設定ファイルを直接書くのって不安ですよね。
そこで、fishにはブラウザでグラフィカルに設定をいじる方法が用意されています。
fishでfish_config
を実行してみてください。
上のスクリーンショットのようにURLが表示されているので、アクセスしてみましょう。
これなら簡単に設定をいじれそうですね。
あとブラウザで変更した設定は~/.config/fish/config.fish
ではなく~/.config/fish/fishd.<hostname>
に保存されています。
<hostname>
はLinuxに設定されたホストネームですね。
コンピュータの名前とも呼ばれます。
たぶんLinuxのインストールのときに、コンピュータの名前を設定してユーザを作ってユーザ名を設定して、みたいなことをしていますよね。きっと。
この~/.config/fish/fishd.<hostname>
ですけど、自動生成されるものなので中身は書き換えないように注意してください。
Fisher
Fisherはfishのプラグインの管理ツールです。
似たようなツールとしてOh My Fishがありますけど、Fisherの方が後発なのと、FisherはOh My Fishのプラグインもインストールできるためこちらを使いたいと思います。
インストール
インストール方法はFisherのGithubのページにありますけど、ワンライナーです。
まず、それぞれのパッケージマネージャとかを使ってfishを入れてください。
yay -S fish
そしてfish
を起動後、以下のインストール用のワンライナーを実行してください。
curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
おまけ
Fisherはfishスクリプトで書かれています。
fishには関数(コマンド)が呼び出されたとき、その関数と同名のファイルを~/.config/fish/functions/
以下から探し、その中の同名の関数を実行するという仕様があります。
fisher
コマンドはこの仕様を利用して実装されているんですね。
つまり、上記のインストールスクリプトでは単にhttps://git.io/fisher
というfishスクリプトを~/.config/fish/functions/fisher.fish
に持ってきているだけです。
なのでブラウザでhttps://git.io/fisher
にアクセスするとFisherのコードを見ることができますね。
fishをログインシェルにする
ログインシェル、またはデフォルトシェルとも呼ばれますね。
いきなりですけどArch Linuxではfishをデフォルトシェルにしないことが推奨されています。
詳しくはArchWikiのfish読んでください。
そんな事情もあり、他のLinuxディストリビューションでもfishをログインシェルにするかどうかは各自の判断に任せたいと思います。
ログインシェルにしたい人は以下のスクリプトを実行してください。
chsh -s $(which fish)
chsh -s (which fish)
ちなみにですけど、chsh
はchange shell
で$()
はコマンドの実行結果を取得するものです。
fishでは()
ですね。
Fisherの使い方
fisher -h
(fisher --help
)でサブコマンドの一覧を見ることができます。
ちなみにですけど、fish
起動してないとfisher
コマンドは使えません。
インストールのおまけで書いた通りの理由ですね。
基本的にはfisher add user/foo
でGitHubで公開されているプラグインをインストールすることができます。
削除するときはfisher rm foo
です。
インストール済みのプラグインの一覧はfisher ls
で見られます。
詳しいことはプラグイン紹介で書きますけど、僕が入れてるのはこんな感じですね。
プラグイン紹介
awesome-fishに色々あるので、一度ながめてみてください。
そんなに数は多くないですし。
個人的なおすすめプラグインです。
まだfishを使い始めたところなので、それくらいの意識で読んでいただけるとちょうど良いかと思います。
oh-my-fish/theme-bobthefish
fisher add oh-my-fish/theme-bobthefish
VimにPowerlineというプラグインがあるんですけど、それのfish版です。
Gitのブランチとかステータスをわかりやすく表示してくれるツールですね。
Powerline Fontsを使っていますので、文字化けする人はインストールしてください。
yay -S powerline-fonts
また上記のリンクにもインストール方法が書かれています。
それでも文字化けするという人は、Cicaというフォントを入れてみて、それぞれのターミナルで設定してみてください。
yay -S ttf-cica
Cicaは様々なアイコンフォントがデフォルトで使えるプログラミング用フォントです。
もちろん日本語にも対応しています。
元はRictyというフォントで、そこにNerd FontsやNoto Emojiなどを合成したものになりますね。
Noto Emojiはそのまま絵文字、Nerd FontsはPowerlineを含む様々なアイコンフォントをまとめたフォントです。
ちなみにですけど、グリフ(文字)をまとめたものをフォントと呼んで、さらにフォント同士を合成することをパッチを当てる、と言ったりします。
RictyにNerd Fontsのパッチを当てる、みたいな感じです。
あとこれは蛇足なので聞き流してほしいんですけど、グリフってあんまり聞き慣れない言葉ですよね。
でもファンタジーが好きな人や中学生くらいで病にかかった人なら神聖文字(ヒエログリフ)とか聞いたことあるかもしれません。
閑話休題。
bobthefishの良さを知ってもらうため、少しデモを行いたいと思います。
まずGitのリポジトリのディレクトリに行きます。
カレントディレクトリの横に、gitでよく見かけるアイコンが見えますね。
ブランチのアイコンです。
次に、ファイルを変更してみます。
ここではREADME.mdを削除してみます。
表示が赤色に変わりましたね。
変更されたファイルがあるよ、という警告みたいです。
では、先ほどの変更をgit add
でステージングしてみます。
今度は黄色になりました。
コミットしていないステージングがあるよ、というのがひと目でわかりますね。
次はコミットを行ってみます。
コミットを行うと、緑色の表示に戻りましたけど、何やら**+
記号**が付いていますね。
これは**Your branch is ahead of 'origin/master' by 1 commit.
**をグラフィカルに示しているようです。
リモートブランチから進んだコミットがあるよ、という意味ですね。
面倒なのでpushはしませんけど、こんな感じです。
便利ですね。
あとこれは余談なんですけど、oh-my-fish/theme-bobthefish
は実はOh My Fishのプラグインです。
名前を見て「あれ?」と思った方もいるかと思いますけど、https://github.com/oh-my-fishがOh My Fishのプラグイン用のGitHubアカウントになっているんですね。
Fisherのところでも書いたように、FisherではこれらOh My Fishのプラグインもインストールすることができます。
以上、bobthefish
プラグインの説明のつもりだったんですけど、余談ばっかりだった気がしますね。
ところでbobthefish
ってなんて読むんでしょう。
Bob the fish?
jethrokuan/z
fisher add jethrokuan/z
移動系のプラグインです。
簡単に言うと、すべてのディレクトリへ直接移動できるプラグインですね。
以下はz fish
で~/.config/fish
に移動する例です。
z fish
ではカレントディレクトリに関係のない相対パスを指定しているのに、ちゃんと~/config/fish
に移動できていますね。
原理としては、コマンドの履歴のパスから指定された相対パスに部分一致するパスを検索しています。
なので行ったことあるディレクトリにしか行けないです。
もちろんTabでの補完もできます。
ちなみにですけど、部分一致なのでz foo
で/hoge/foo/bar
に移動したりもします。
FabioAntunes/fish-nvm
NVM使ってない人はいらないですね。
これは何のためにあるのかといいますと、NVMってBashに依存している部分があるんですよね。
なので、そのままではfishでは動きません。
それに対応するためのプラグインです。
ちなみに内部ではedc/bassという、Bash互換のスクリプトをfishで実行するためのプラグインを利用しています。
jethrokuan/fzf
fzfというコマンドのラッパーです。
fish用の便利なキーバイドを提供してくれます。
そもそもfzf自体を使ったことがないという人が多そうですけど、使いましょう。
とても便利です。
fzf自体は、**入力された行データからインタラクティブに曖昧(fuzzy)検索を行ってくれるコマンド(fuzzy finder)**です。
ちなみにGo言語製のツールです。
似たようなツールに同じくGo言語製のpecoがありますけど、こちらはfzfとは違い部分検索です。
最近はpecoでも曖昧検索ができるみたいです。
今回はfzfを使ってみたいと思います。
まずはfzfをそれぞれのパッケージマネージャなどで入れましょう。
yay -S fzf
次に、Fisherでfzfを入れます。
fisher add jethrokuan/fzf
そして、~/.config/fish/config.fish
(fishの設定ファイル、設定を参照)がなければ作成し、以下の設定を書き込んでください。
set -U FZF_LEGACY_KEYBINDINGS 0
これはこのプラグインの古いキーバインドを使わないための設定です。
なぜキーバインドが新しくなったかというと、fish 2.4.0でキーバイドがコンフリクトしたからだそうです。
詳しい説明や使い方はjethrokuan/fzfのREADMEに書いてあります。
Ctrl+f
でファイルの曖昧検索ができます。
これは今回の記事で使うのに撮ったスクリーンショットですね。
Ctrl+r
でコマンド履歴の曖昧検索です。
ci
と入力してるのにconfig
とかひっかかってますね。
曖昧検索すごい。
最後に、Alt+o
でディレクトリを検索して移動ですね。
Alt+Shift+o
で隠しファイルも検索できるようです。
あれ、これzの存在意義……?
fsh
なんていうタイポ検索でも安心ですね。
あとこれは余談なんですけど、fzf
、fish関係ないところでも結構使いやすいです。
例えばホームディレクトリでls -a
とかすると、ものすごい量の隠しファイルが表示されたりしますよね。
こういうとき、grepを使ってls -al | grep bash
とする人が多いかもしれません。
そこでgrepの代わりにfzf
を使うと……
インタラクティブな上にファジーに検索できますね。
decors/fish-ghq
ghqというコマンドのラッパーです。
補完とキーバインドを提供してくれます。
「あれ?fishはデフォルトでmanから補完できるんじゃなかったっけ?」と思った人がいるかもしれませんけど、いくつか追加で補完を入れてくれてるみたいです。
これもそもそもghqを使ったことがないという人が多いかもしれないですね。
でもとても便利なのでぜひ使いましょう。
そしてこれもまたGo言語製のツールです。
Go言語ってコマンドラインツール作るのにいい言語なんでしょうかね。
ghqはgit cloneを一箇所で管理してくれるツールです。
まずはお使いのパッケージマネージャでghqを入れましょう。
Go言語の環境がある人はgo get
してmake
でもいいですけど。
yay -S ghq
そしてFisherでfish-ghqを入れます。
fisher add decors/fish-ghq
使い方は簡単です。
まずghq get url
でリポジトリを持ってくることができます。
ここではhttps://github.com/utatatata/sushi
をクローンしてみます。
git clone
そのまんまです。
~/.ghq/github.com/utatatata/sushi
に入っていますね。
どうやら~/.ghq
以下に<git host name>/<username>/<repository>
という形でクローンされているみたいですね。
<git host name>
はgithub.com
、gitlab.com
、bitbucket.org
などです。
ちなみにですけどghq root
でクローンされるディレクトリを確認できます。
デフォルトでは~/.ghq
ですね。
これはghqの設定で変えることができます。
ghqの設定はGitの設定ファイルである~/.gitconfig
に書き込むみたいですね。
[ghq]
root = ~/Repositories
root = ~/.roswell/local-projects
ghq.root
は複数指定することができて、ghq get
したときリポジトリは一番上のパスの下にcloneされます。
そしてfishでghqを使う利点ですけど、とりあえずCtrl+g
を押してみてください。
見たことある表示ですね。
これはfzfでghq get
してきたリポジトリを曖昧検索しています。
これはdecor/fish-ghq
が、fzfやpecoが入っているとCtrl+g
で検索を行ってくれるようになっているからですね。
とどのつまり、これを使えば**Ctrl+g
で目的のリポジトリに素早く移動できる**わけですね。
まとめ
fish、どうでしたでしょうか。
ほとんどのプラグインで設定ファイルを書いていませんでしたよね。
そして設定も簡単にいじれます。
またこの記事を読みながら手を動かしてくださっていた人ならもうわかっていただけたと思いますけど、補完とサジェストとシンタックスハイライト、とても強力ですよね。
とにかく楽だ……
しばらくはfishを使っていきたいと思います。
参考文献
Public Domain Lisp Logo Set
POSIX - Wikipedia
Unixシェル - Wikipedia
Friendly interactive shell - Wikipedia
h・bash・zsh等, shellの違いでハマりやすい部分とか - 水底