fishプラグイン紹介2025年1月版
はじめに
fishの設定をしたので情報共有します。
ドキュメントの思想通りにファイル分割していると、プラグイン化されました。
一通り紹介していくので、欲しい機能があったら使ってください。
プラグインマネージャーはfisherを使っています。
プラグイン紹介
 cdしたら自動でlsする
個人的な必須機能その1。
私がshellを設定するキッカケとなった機能です。
lsの代わりにezaを使いたい場合は以下で変更可能です。
set -U autols_cmd eza
zshでの実現方法。
zshだとこんな感じに設定した内容を実現するプラグインです。
__list_directory_contents () {
    if [[ -o interactive ]]; then
        ls
    fi
}
add-zsh-hook chpwd __list_directory_contents
 ghq listした結果をfzfで絞り込んでcdする
個人的な必須機能その2。
Ctrl + gでリポジトリ一覧がfzfで表示されるので、選択したらcdします。
これが無いと生きていけない。
元々以下を使っていたのですが、autolsの描画とpromptの描画が干渉してしまうので、必要な部分のみ自作することにしました。
zshでの実現方法。
以下のzsh実装の移植です。
ghq_fzf () {
    local selected_repo=$(ghq list -p | FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS} ${FZF_ALT_C_OPTS}" fzf)
    if [[ -z $selected_repo ]]; then
        zle redisplay
        return 0
    fi
    BUFFER="cd ${selected_repo}"
    zle accept-line
    zle reset-prompt
}
zle -N ghq_fzf
bindkey "^g" ghq_fzf
autolsを綺麗に表示するために、commandlineにcdする文字列を表示させて実行しています。
気付いたらfishもzshと同じことをしていました。
 $fish_user_pathsを$EDITORで編集する
fishインストール直後しか使わないけど、お気に入りプラグイン。
所謂PATHを通す所作、fishでは$fish_user_pathsで指定しますよね。
setで順番入れ替えたりするの大変じゃないですか。
pathedを実行すると$VISUALもしくは$EDITORが開きます。
内容は$fish_user_pathsの要素を改行区切りで表示しますので、自由に編集して保存して閉じてください。
私はファイルパスの補完を有効にしたvimで編集します。
最近は$fish_user_paths限定ではなく、汎用配列操作プラグインが欲しくなってきました。
 過去に訪れたことのあるディレクトリをfzfで選択してcd
cdfで実行する。名付けセンス無くてすみません。ドラクエで言うルーラです。
たまに使う。無いと結構困る。
zshでの実現方法。
組込みでディレクトリを記録する機能がある。
autoload -Uz chpwd_recent_dirs cdr
add-zsh-hook chpwd chpwd_recent_dirs
zstyle ':chpwd:*' recent-dirs-default true
zstyle ':chpwd:*' recent-dirs-file ${XDG_DATA_HOME}/zsh/chpwd-recent-dirs
zstyle ':chpwd:*' recent-dirs-max 500
# zstyle ':chpwd:*' recent-dirs-prune parent
zstyle ':chpwd:*' recent-dirs-pushd false
zstyle ':completion:*:*:cdr:*:*' menu selection
zstyle ':completion:*:*:cdr:*:*' recent-dirs-insert both
するとcdr -lで一覧が出せるのでfzfで絞り込んでcdすれば良い。
(番号も一緒で出てくるのでcdrにその番号渡しても良い)
↓な感じ。
function cdf () {
    clean-chpwd-recent-dirs
    local dir=($(cdr -l | fzf --preview 'f() { sh -c "$FZF_CDR_PREVIEW_OPTS ${@}" }; f {2..}'))
    if [[ -n $dir ]]; then
        cdr "${dir[1]}"
    fi
}
ちなみに履歴を綺麗にする関数として以下を用意しているが、ちょっと何やってるかわからない。
clean-chpwd-recent-dirs () {
    emulate -L zsh
    setopt extendedglob
    local -aU reply
    integer history_size
    autoload -Uz chpwd_recent_filehandler
    chpwd_recent_filehandler
    history_size=$#reply
    reply=(${^reply}(N))
    (( $history_size == $#reply )) || chpwd_recent_filehandler $reply
}
 親(の親(の親(……)))ディレクトリをfzfで絞り込んでcd
あまり使わないけど無いとストレス。
bd関数を提供しています。
階層構造のどこまで戻るのかを視覚的に把握しやすいのがお気に入りポイントです。
これはzshで自作していたのでそのままfishに移植しました。
別解として以下もあります。bdの補完で移動先を選べるのですが、私にはどこまで戻るのか判断が難しかったので↑を使うことにしました。
zshでの実現方法。
元になったzsh実装は以下です。
function bd_list () {
    local dir=$PWD
    for i in {1..20}; do
        dir=$(dirname "$dir")
        echo "$dir"
        if [[ $dir = "/" ]]; then
            break
        fi
    done
}
function bd () {
    local dir=$(bd_list | FZF_DEFAULT_OPTS="${FZF_DEFAULT_OPTS} ${FZF_ALT_C_OPTS}" fzf)
    if [[ -n $dir ]]; then
        builtin cd $dir
    fi
}
 gitのリポジトリルートにcd
うん、「また」なんだ。済まない。
cdネタが続きます。
基本的にはリポジトリルートから動かざること山の如しなのですが、稀に使います。
zshでの実現方法。
zsh実装は以下。
gcd () {
    local dir=$(git rev-parse --show-toplevel)
    if [[ -n $dir ]]; then
        builtin cd $dir
    fi
}
 fzfのshell連携をする
fzfのSetting up shell integrationを実行するだけです。
流石に不要ではと思いましたが、引っ込みつかなくなったので自作しました。
将来別のシェル統合プラグインを使う際、容易に無効化するためプラグイン化したフシがあります。
なんと中身は以下だけです。
command -q fzf
and fzf --fish | source
以前は↓を使ってました。使いはじめた頃、fzf側にfishのintegrationは無かった気がします。
色々ついてるけど持て余しているのでfzf本体の機能を使う事にしました。
最近は↓の方が更新されていてスターも多いです(使った事はない)。
プロンプト
今はtideを使っています。powerlevel10kのfish版です。
tide configureで設定できるのもp10kと一緒ですね。
こちらはfishらしくユニバーサル変数に設定が保持されます。
Leanや尖った部分を消したClassicが好みです。
fishっぽいテーマと言えばbobthefishでしょうか。
pureも好きです。
おわり
fishはデフォルトで使いやすいので、痒いところに手が届くプラグインを探していたら自作していました。
結局プロンプト以外は全て自作してしまいました。
今はfish_hybrid_key_bindingsが気になっています。
Vimmerですがshellはemacsキーバインド派です。
デフォルトemacsキーバインドで必要な時だけnormalモードを使える部分に期待しています。
Discussion