+++ date = "2017-05-03" tags = ["shell"] title = "fish+shell" slug = "shell" +++ `fish`を使う機会が増えていて、なんかfishに関する記事でも書こうかなと思いつつ書けていないので、ここらへんで思いつく限り適当なことを書いてく。 まず、fishは他のshellとの互換性を完全に捨ててる。考慮もあんまりしてない感じだけど、それ故に可読性は良いと思う。が、shellの強みって一貫した書き方だったりするわけで、その点では触っていてめんどくささはかなりある。まあ、これをshellと見ること無く、アプリとか言語の一つとかとして見る場合は普通なんだけど、そんな感じです。これは何が問題なのかというと、例えば、他のアプリがshell変数なんかをあてにしてたりする場合、fishを使うことによって思わぬ動作不良を招くことも多いため、あくまで嗜好品とか、楽しんで使うアプリとしてみるほうが良いのかもしれません。 fishはあまり設定書かなくても使える。補完とかプロンプトだったり。あと、プラグインが読みやすいし、オリジナルの設定を書きやすい、改変しやすい感じ。但し、補完も書かないと不便なところは多くて、それは例えば特殊文字の扱いとか色々なんだけど、zshのほうが便利な部分もある。 最初に嵌りそうな点は以下。 ```bash # export a="word" set a "word" # a=`echo word` set a (echo word) # if which ls;then echo ok ls;fi if which ls end # case $1 in switch (echo arvg[1]) case test echo ok end end # function a (){echo a} # functionは付けなくてもいいが、内容によってはバッティングするため動作不良を引き起こす可能性あり function a echo a end # alias v="vim" alias v="vim" # aliasで書いた文はfunctionで再定義されるのでそのまま書いてもいい $ type v function v vim end # case $OSTYPE in # fishではいくつかの環境変数が設定されていない switch (uname) case Darwin echo mac case Linux echo linux case '*' echo other end end # . ~/.zshrc && exec $SHELL # fishは設定を再度読み込むより再起動したほうがいい事が多い exec fish ``` いろんなものをインストール。よく使うのは`z, fzf, ghq, hub, tmux`なのでそれらと連携するプラグインなど。 ```bash $ curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs git.io/fisher $ fisher fzf z edc/bass omf/thefuck omf/theme-bobthefish decors/fish-ghq ``` fishでは`~/.config/fish/config.fish`に書いたバインドは有効になる場合とならない場合があり、基本的には有効になるが、`~/.config/fish/functions/`以下に置いた`fish_user_key_bindings`関数が無効になる。つまり、fish_user_key_bindings関数に書くのが順当であり、かつその関数ファイルは`functions/`に置くのが一般的。内容によっては`commandline -f repaint`を入れないとプロンプトでEnterを押す必要が出てくるので必要な場合あり。 > ~/.config/fish/functions/fish_user_key_bindings.fish ```bash function fish_user_key_bindings bind \cf peco_select_ghq_repository bind \ck __fish_cd_up bind \cs __fzf_find_file bind \cx __fzf_find_and_execute bind \ec __fzf_cd bind \eC __fzf_cd_with_hidden bind -M insert \eD __fzf_cd_with_hidden end function __fish_cd_up cd .. ls -slFa commandline -f repaint end ``` 注意ですが、bindの後ろは¥(半角)を入れてください。例えば、`bind ¥cf pecoとか`になります。 補完などはインストール時についてくるファイルを利用したりとか色々。PATHを通してもいいし、補完を作成したり、`~/.config/fish/completions`に置いてもいい。 ```bash # https://github.com/github/hub/blob/master/etc/hub.fish_completion $ brew install hub ls /usr/local/bin/share/fish/completions/ $ fish_update_completions $ hub alias (show shell instructions for wrapping git) browse (browse the project on GitHub) ci-status (display GitHub Status information for a commit) compare (lookup commit in GitHub Status API) create (create new repo on GitHub for the current project) fork (fork origin repo on GitHub) pull-request (open a pull request on GitHub) ``` tmuxとの連携は`~/.tmux.conf`に`set-option -g default-command "reattach-to-user-namespace -l fish"`を書くことでvimでのクリップボードとか色々な不都合が起こりにくい。 > config.fish ```bash if test $TERM != "screen" tmux new-session and exit end ``` zとの連携は以下のような感じ。`j -l`で取得したりできるので、それを元に関数を書く。キーバインドの`C-j`で移動。 > ~/.config/fish/config.fish ```bash set -U Z_CMD "j" set -U Z_DATA "$HOME/.z" ``` > ~/.config/fish/functions/fish_user_key_bindings.fish ```bash function peco_z set -l query (commandline) if test -n $query set peco_flags --query "$query" end j -l | peco $peco_flags | awk '{ print $2 }' | read recent if [ $recent ] cd $recent commandline -r '' commandline -f repaint end end function fish_user_key_bindings bind \e peco_z end ``` このようにfishは昔からある基本的なshellの決まりごとはことごとく通用しない。 https://fishshell.com/docs/current/index.html