ぶていのログでぶログ

思い出したが吉日

bashからfishにした その2

fishに乗り換えてから1ヶ月くらい経ったのでどういう設定を入れたかのメモ。

export関数

fishをメインに使っているとbash向けに書かれたコマンドを変換するのが面倒くさい。。 例えば export FOO=BAR と書いているコマンドを set -x FOO BAR に置換するのが非常にだるい。 そこでexport関数を定義してしまった。 これならbash向けに書かれたコマンドをそのままコピペできる。

function export
    set -l s (string split -m1 = $argv)
    set -xg $s
end

abbr

aliasと違ってabbrはコマンドの略称を定義できる。 例えば abbr -a g git と設定すれば、 g<space>と打つとコマンドライン上ではgit<space>に置き換えられる。 これの何が便利かというと、例えば alias g=git とした場合fishにはgコマンドとして認識されてしまい、gitのサジェストや補完が効かなくなる。 abbrではgitコマンドに直されるのでgitコマンドのサジェストや補完が効くわけである。

2019/02/22追記。 alias g=git してもサジェストや補完は効くようです。

とりあわけよく使うコマンドを定義している。

abbr -a g git
abbr -a gg git grep
abbr -a be bundle exec
abbr -a bi bundle install

キーバインド

Ctrl+f と Ctrl+c のみ定義している。

bind \cf forward-word
bind \cr isearch

Ctrl+fをforward-wordにしているのは、例えばサジェストで foo bar と出てきた場合にfooだけ利用したい場合がある。 そういうときにデフォルトのCtrl+f(forward-char)だと、foo barまで確定されてしまい使い勝手が悪いため変更した*1。 ただこれも、サジェスト以外でCtrl+fを打ちワードごとにカーソルが動くとbashとの動きに差が出てしまってイマイチだなぁ…っと思い出しているので帰るかも知れない。 Ctrl+rに設定した内容については後述。

プロンプト

こんな感じになっている。

f:id:buty4649:20190219222154p:plain
今のプロンプト

カレントディレクトリの表示とgitの表示みたいな感じ。 これはbashを使っていた頃の名残で同じ感じの使い勝手にしている。 gitの状態表示は __fish_git_prompt*2 を使うといい感じになる。 __fish_git_promptはデフォルトでは使わず少しいじってある。

set __fish_git_prompt_showdirtystate yes
set __fish_git_prompt_showstashstate yes
set __fish_git_prompt_showuntrackedfiles yes
set __fish_git_prompt_showupstream yes
set __fish_git_prompt_color_branch magenta
set __fish_git_prompt_color_upstream_ahead green
set __fish_git_prompt_color_upstream_behind red
set __fish_git_prompt_char_untrackedfiles "?"
set __fish_git_prompt_char_upstream_equal ""
set __fish_git_prompt_char_stagedstate "+"
set __fish_git_prompt_char_dirtystate "!"
set __fish_git_prompt_char_stateseparator " "

function fish_prompt
    set -l p (set_color $fish_color_cwd)(prompt_pwd)(set_color normal)
    set -l g (__fish_git_prompt "%s")
    if test -n "$g"
      set -l gg (string split " " -- $g)
      set -a p " "$gg[1]
      set -l ggg $gg[2]
      if test -n "$ggg"
        set -a p (printf " %s[%s]%s" (set_color red) $ggg (set_color normal))
      end
    end
    set -a p \n
    set -a p (set_color $fish_color_ps)'➜'(set_color normal)" "

    echo -ns $p
end

プロンプトに関してはspacefishを使おうと思って一時期入れていたのだが、あまりに重くてやめた経緯がある。

^Cを表示しない

完全に趣味なのだけど、fishでCtrl-cすると ^C が残ってしまうのが嫌でハックしている。 bashならこんなことしなくても stty -echoctl でOKなのになぁ〜。

# ^Cを表示しない
function __fish_cancel_commandline
    # Close the pager if it's open (#4298)
    commandline -f cancel

    set -l cmd (commandline)
    if test -n "$cmd"
        commandline -C 1000000
        ####if set -q fish_color_cancel
        ####    echo -ns (set_color $fish_color_cancel) "^C" (set_color normal)
        ####else
        ####    echo -ns "^C"
        ####end
        if command -sq tput
            # Clear to EOL (to erase any autosuggestion).
            echo -n (tput el; or tput ce)
        end
        for i in (seq (commandline -L)) (seq 2 1 (count (fish_prompt)))
            echo ""
        end
        commandline ""
        commandline -f repaint
    end
end

起動時のロゴ

fish shellのロゴが出るようにしている。毎回色が違うのが楽しい!

f:id:buty4649:20190219223826p:plain
毎回違うfishのロゴ

これfisherで入れて毎回ランダムに色を変えている。 これだけのためにfisherをインストールしているのでコードコピーして埋め込んじゃうかも…。

function fish_logo_random
    set c red green yellow blue magenta cyan white brred brgreen bryellow brblue brmagenta brcyan brwhite
    set oc $c[(math (random) % (count $c) + 1)]
    set mc $c[(math (random) % (count $c) + 1)]
    set ic $c[(math (random) % (count $c) + 1)]
    fish_logo $oc $mc $ic
end

function fish_greeting
    echo $fish_greeting
    fish_logo_random
end

コマンド履歴のインクリメンタルサーチ

結局自分で実装してしまった。 そのうち公式の機能で提供されることを夢見て…。 この関数はCtrl+rにバインドしている。

function isearch
    set -l c (history | fzf-tmux --no-sort --query=(commandline))
    if test -n $c
        commandline $c
    end
end

rbenvなどの移行

これについては何もしていない。 というのも前回書いたとおりログインシェルをfishにしたわけではなくてtmuxのデフォルトシェルをfishに変えただけで運用している。 私の場合fishを起動するには、ターミナルを起動する -> bashが起動する -> tmuxを実行する -> fishが起動するみたい手順を取っている。 bashrcなどの設定はfish移行前の状態なので、このときにrbenvなどの環境変数がセットされる。 その後、その環境変数を引き継ぎてtmux経由でfishが起動するためにrbenvなどの設定を行なう必要がない。

ということに最近気がついた(ぇ 幸いrbenvはfishに対応しているものそれ以外のツールがfishに対応しているとは限らないので、この方法を取ればめんどうな移行の手間は省けるかもなぁっと思った次第*3

*1:逆に今の設定で全確定する場合はCtrl+eを押す

*2:次のバージョン?ではdeprecatedになるっぽい

*3:そもそもrbenvを使うのやめたりするのもありかなぁっと思いつつ手を入れてなかったのがいまここ