fish関連のメモ

setでの変数の定義のオプション

  • ユニバーサル変数
    • -U, –universal
      • 現在のセッションだけでなく、将来のすべてのセッションでも利用できる。
        • Fishの設定ディレクトリに保存され、シェルを再起動しても保持されます
  • グローバル変数
    • -g, –global
  • ローカル変数
    • -l, –local
  • 環境変数
    • -x, –export

-e, –eraceで変数の削除ができる。

fishキーバインドのカスタマイズ

下記のようにユーザ定義のキーバインドを定義できる。 fishConfig では fisher生成物の functions/ をgit管理しないため、自前の fish_user_key_bindings~/.config/fish/my_functions/fish_user_key_bindings.fish に置く。 ghq_cd_repository~/.config/fish/my_functions/ghq_cd_repository.fish で定義する。

function fish_user_key_bindings
    bind \cg ghq_cd_repository

    ### fzf.fish ###
    bind \cr _fzf_search_history
    bind \eh __hugo_content_search_key_binding

    ### 移動をワード単位で行う
    bind \en backward-word
    bind \em forward-word
end

my_functions/*.fishconfig.fish で source するだけでは、fish の key binding 初期化後に関数が定義される構成になり、fish_user_key_bindings が自動実行されない場合がある。 現行の fishConfig では my_functions の読み込み後、interactive shell のときに fish_user_key_bindings を明示実行する。

以前使っていた hub 依存の ghb / __ghq_browse_github は削除した。 GitHub repositoryを開く操作は、カレントリポジトリのremote URLからURLを組み立てる gho に寄せる。

cd後にls -lart相当を色付きで表示する

fishConfig では ~/.config/fish/my_functions/cd.fishcd をwrapし、interactive shellでdirectory移動に成功した後だけカレントディレクトリを表示する。

ls -lart 相当の見え方を保ちつつ色を付けたい場合、LinuxとmacOS/BSDで ls の色指定が違う点に注意する。 macOS/BSDの ls -G は色表示だが、GNU coreutils/uutilsの ls -G はgroup非表示の意味になる。

現行設定では次の優先順位にしている。

  1. eza があれば eza -laaHg --icons=always --sort=modified --color=auto --time-style=long-iso .
  2. exa があれば同等のoptionでfallback
  3. Linuxでは ls -lart --color=auto .
  4. macOS/BSDでは CLICOLOR=1 ls -lartG .
  5. それ以外では plainな ls -lart .

eza-a は1回だと ... を出さないため、ls -a に寄せるには -aa にする。 -H-g でlink countとgroupを表示し、ls -l に近い列構成にする。 eza --sort=modified は古いtimestampから新しいtimestampへ並ぶため、ls -lart と同じく新しいものが下に来る。 --icons=always はNerd Font等の対応fontがある前提でiconを常に出す。 cd 後の表示はinteractive shell限定なので、非対話のpipeやlogへ流れる通常用途は想定しない。 端末側のfont fallbackが無い環境では文字化けや表示幅ずれが起きる。 ただし eza はdirectory sizeを - で表示するなど、block sizeや細部は ls -lart と完全一致ではない。 正確な ls の出力そのものが必要な調査では明示的に ls -lart を実行する。

dirty repository で assistant pane を開く

interactive shell で cd した先が git repository で、未コミット変更がある場合は、eza 表示の前に上下分割 pane で assistant CLI を起動する。 TMUX があれば tmux split-window -v を使い、tmux なしで WezTerm 直下の shell なら wezterm cli split-pane --bottom を使う。 起動後すぐにコミットを作るのではなく、初期 prompt で「このディレクトリでコミットを作るかをユーザーに聞く」ようにしている。

設定は ~/.config/fish/my_functions/cd_dirty_prompt_config.fish に分けている。

set -g fish_cd_dirty_prompt_enabled enabled
set -g fish_cd_dirty_prompt_ignore_file ~/.config/fish/cd_dirty_prompt_ignore_repos
set -g fish_cd_dirty_prompt_linux_command codex
set -g fish_cd_dirty_prompt_darwin_command claude
set -g fish_cd_dirty_prompt_wezterm_command wezterm
set -g fish_cd_dirty_prompt_text "このディレクトリでコミットを作るかをユーザーに聞いてください。ユーザーの承認なしにコミットは作らないでください。まず git status --short を確認し、変更内容を要約してから相談してください。"

fish_cd_dirty_prompt_linux_command / fish_cd_dirty_prompt_darwin_command は fish list として追加引数を持てる。 例えば Linux 側だけ profile を指定したい場合は次のようにする。

set -g fish_cd_dirty_prompt_linux_command codex --profile local_bonsai

WezTerm の実行ファイルが PATH に無い場合は、fish_cd_dirty_prompt_wezterm_command を実体パスに差し替える。 wezterm cli split-pane --bottom --cwd <repo> -- <assistant> <prompt> は現在 pane を上下分割し、新しい pane を下側に作る。

無視 repository は ~/.config/fish/cd_dirty_prompt_ignore_repos に git repository root を1行ずつ書く。 空行と # で始まる行は無視し、~/$HOME/ に展開する。 submodule は現時点では使っていない前提なので、親子 repository の解決は入れていない。

fzf.fishのキーバインド設定

GitHub - PatrickF1/fzf.fish: 🔍🐟 Fzf plugin for Fish 二つの方法がある。

  1. fzf_configure_bindings コマンドを実行してconfig.fishを書き換えてもらう方法
  2. ~/.config/fish/my_functions/fish_user_key_bindings.fishで GitHub - PatrickF1/fzf.fish: 🔍🐟 Fzf plugin for Fish の関数を呼び出す方法

私はキーバインド設定をまとめられる2の方法にする。 ただし現行の fishConfig では functions/ をfisher生成物として扱うため、置き場所は my_functions/fish_user_key_bindings.fish にする。

私はコマンドのヒストリ検索を使っている。

Hugo content を rg + fzf で検索する

Hugo のメモを素早く探すため、fishConfig では Alt-hhugo_content_search を割り当てる。 対象はデフォルトで ~/ghq/github.com/tin-machine/hugo/content。 別の tree を探したい場合は HUGO_CONTENT_SEARCH_ROOT で差し替える。

実体は ~/.config/fish/my_functions/hugo_content_search.fish に置く。 fzf は UI と preview、rg は検索本体を担当する。 fzf --bind change:reload(...) を使うことで、query を変更するたびに rg を再実行する。 空 query では候補が見えないと起動失敗に見えやすいので、初期表示では Markdown / txt file 一覧を出す。

検索語はスペース区切りで追加する。 例えば fish fzf keybind と入力した場合は、同一行に fishfzfkeybind をすべて含む行を rg --pcre2 の lookahead で検索する。 行を選択して Enter を押すと $EDITOR で該当行を開く。 右側の preview は文書冒頭から表示する。bat --highlight-line は維持するので、preview 内をスクロールすれば match 行の highlight は見える。

bind \eh __hugo_content_search_key_binding
bind -M insert \eh __hugo_content_search_key_binding

tmux の prefix key に載せる案もあるが、Hugo メモ検索は通常の shell 入力中に即座に呼びたいので fish の Alt-h に寄せる。 Ctrl-h は端末によって Backspace と同じ制御文字になる可能性があるため、この用途では避ける。

追加で下記のコマンドのインストールがお勧めされている

  • fd
    • 高速でカスタマイズ可能なfindクローン
    • ubuntuだとfd-find
  • bat
    • シンタックスハイライトできるcatクローン
      • ubuntuだとbat

TIDEによるプロンプトのカスタマイズ

IlanCosman/tide: 🌊 The ultimate Fish prompt.

プラグインインストール時に設定できるが後で設定したい場合は下記でできる。

tide configure

補完関数

補完関数のパス

パス
システムにインストールされてるもの/usr/share/fish/completions/
ユーザ固有のカスタム補完~/.config/fish/completions/

コマンドに紐づく補完関数の確認

complete -C git

↑ Cは大文字。

補完関数の書き方

補完関数は下記の流れで実行される。

  1. コマンドの特定 ユーザーが入力したコマンドに基づいて、Fishは適切な補完関数を検索する。 例えば、gitコマンドの補完を行うためには、gitに関連する補完関数が呼び出されます。

  2. 補完スクリプトの実行 関連する補完関数が見つかると、その関数が実行される。 この関数は、使用可能な引数やオプション、またはその他の補完候補を生成する。

  3. 候補の表示と選択 生成された補完候補がユーザーに提示され、ユーザーは候補から選択することができる。

Fishシェルで補完関数を定義するには、completeコマンドを使用する。

complete -c git -n __fish_git_using_command commit -a '(git branch -a)'

この例では、gitコマンドのcommitサブコマンドに対する補完を定義している。 -cオプションは補完するコマンドを指定し、 -nオプションは特定の条件下で補完を実行するための関数やコマンドを指定している。 -aオプションは補完候補を生成します。

補完関数の内部的な処理の進み方

  • コマンド解析: 入力されたコマンドラインは解析され、どのコマンドに対する補完が必要かが判断される。
  • 条件チェック: -nオプションで指定された条件が満たされているかどうかが確認される。
  • 候補の生成: 補完関数やスクリプトが実行され、補完候補が生成される。
  • ユーザーインターフェース: 候補がユーザーに提示され、ユーザーはタブキーを使って候補を選択できる。