友人がシェルを fish にしたっていうので、便乗してfishにしてみました。 とりあえず環境作ってしばらく使ってみようかなという気持ちです。
そもそもfishにしなかった理由
今まで何回かfishに移行しようと思ったことはあったのですが、 以下の理由からzshのままで良いかなーと考えていました。
- POSIX非互換シンタックスでシェルスクリプト全滅
- つまりfish用に書いたシェルスクリプトはよそで動かない
- zshリソース全滅するのなんかもったいない
fishにしてみて
- 諸々の挙動含め、zshより軽い(気がする)
- fishスクリプトは直感的ではあると思う
- シェルスクリプトだと思うと死ぬ
- zshより補完書きやすいかな?
fish_config
かわいい
環境移行
移行時に詰まったところです。
zsh自作プラグイン
自分用のシェルスクリプトをまとめてzplugのプラグインにしてたりしたんですが、 その一部をfish用に書き直しました。 パッケージマネージャは fisherman にしました。
https://github.com/matsub/fishtools
nvimの起動が重くなった
vimのstatuslineで system
を使ってVCSのブランチ情報を抜いてきているんですが、
これがなんか重かったっぽいです。詳しくは調べてねえです。
vim起動時にfishが見えたら /bin/sh
に逃すのが正解っぽい
if &shell =~# 'bin/fish$'
set shell=/bin/bash
endif
anyenv init
シンタックスがだいぶ違うので、
evalでアクティベートする系のプラグインは概ね機能しなくなります。
docker-machine env
も潰れるかなーとか思ったのですが、
docker-machine env
はfish上で実行されると自動的に
fish 用のスクリプトを吐くので、共通の記述で健全に動きます。賢い。
で、eval $(anyenv init -)
は潰れました。
eval $(anyenv init -)
は、
anyenv init
で吐かれるスクリプトを毎行実行することで機能します。
PATHに各envの実行パスを加えて、各envをアクティベートするというスクリプトです。
ですがfishのevalは中身を関数のように実行するらしく、
中で PATH
が変更されてもeval全体が終了するまで評価されないようになっているようです。
ファイルの実行 (source
) は通常通り行ごとに実行されるので、
anyenv init
の結果を一旦吐くことで解決しました。
以下 $XDG_CONFIG_HOME/fish/config.fish
の一部です。
anyenv init - fish > tmp
source tmp
rm tmp
だせえ
余談 - anyenvの問題
anyenv、vmやコンテナでなしにかなり気軽に環境整備できて結構気に入ってるのですが、
メンテナンスされておらず、今回の移行時も上記とは別に goenv
で問題が発生していました。
これは goenv init - fish
が存在しないことが原因で、
私はsedで無理やり解決しました。全部まとめると以下のようになります。
anyenv init - fish > tmp
sed -e 's/export \(.*\)=/set -gx \1 /' -e 's/:\${\(.*\)}\"/\" \$\1/' tmp >tmp2
source tmp2
rm tmp tmp2
きめえ
そもそもanyenvのインストール対象になっている goenv
が最も活発なリポジトリと別のリポジトリで、
活発な方は fish 対応しています。
もちろんこの話題はanyenvのPRに出ていますが放置されている状況。
誰かanyenv forkのアップストリーム作ってくんねえかな。
あるいは自分で建てて浮いてるforkマージしまくるのもいいかな
未解決問題
auto-fuが恋しい。
余談2
今回はfishをログインシェルにしましたが、 ログインシェルはbashにして環境を解決してからfishに入るようにするのも正解っぽい。 まあ私はそれ気持ち悪いんでログインシェルにしちゃいましたけど。 そういう選択肢もあるんじゃね。