zshからfishに移行した

shellscript


友人がシェルを fish にしたっていうので、便乗してfishにしてみました。 とりあえず環境作ってしばらく使ってみようかなという気持ちです。

そもそもfishにしなかった理由

今まで何回かfishに移行しようと思ったことはあったのですが、 以下の理由からzshのままで良いかなーと考えていました。

fishにしてみて

環境移行

移行時に詰まったところです。

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に入るようにするのも正解っぽい。 まあ私はそれ気持ち悪いんでログインシェルにしちゃいましたけど。 そういう選択肢もあるんじゃね。