0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[fish-shell] [10] プラグイン実装例「zf」... 対話形式でのファイルランチャ

Last updated at Posted at 2021-09-18

機能概要

コマンドラインにて「zf パス」として実行すると、fzf によって
対話的に開きたいファイルを選択する.

但し、使用するアプリは nvim 決め打ちとする.

なお、一度開いたファイルは繰り返し開く傾向にあるので、
fish の HISTORY にマージするようにしている.

fish-shell V2.7.1 で動作確認済み.

使用方法

下記コードを $HOME/.config/fish/functions/zf.fish として配置すること.

また、fzf をインストールしておくこと.

コード

#!/usr/bin/env fish

function zf
    # 独自関数: fish のコマンド履歴ファイル (fish_history) に対して、
    #           本スクリプトで実行したコマンド (nvim 〜 か sudo nvim 〜) を追記する.
    function _add_history
        # コマンド実行履歴ファイルがあるかチェックする.
        # ここでは「/home/foo」としているので適宜読み替えること
        set -l hist_file /home/foo/.local/share/fish/fish_history
        if test ! -f "$hist_file"
            # fish_history ファイルが無ければ作成する
            touch $hist_file
        end

        # 現在実行したコマンドが fish_history ファイルにすでに存在しているかチェックする
        set -l pattern ( grep -w "\- cmd: $argv[1]" $hist_file )

        # 現在実行したコマンドがこれまでに存在していなければ追加する
        if test -z "$pattern"
            # 次のような書式
            echo "- cmd: $argv[1]"   >> $hist_file  # 本例では $argv[1] の値は「nvim」である
            echo "  when: $argv[2]"  >> $hist_file  # 本例では $argv[2] の値は ファイルパスである
            history merge # fish 組込みコマンド「history merge」を実行すると反映される
        end
    end

    #------------------------------------------------------------
    # ここから本処理開始
    #------------------------------------------------------------
    set -l filename
    set -l timestr (date "+%s")

    # zf コマンド実行時に引数が指定されていない場合
    if test (count $argv) -eq 0
        # カレント直下のファイルを fzf で表示させて、ユーザに選択させる
        set filename ( find . -type f 2>/dev/null | fzf )
        if test -n "$filename"
            if test -r "$filename"
                # これから実行するコマンドを fish_history に書き込んでおく
                _add_history     "sudo nvim $filename" $timestr
                # ファイルが読み取り専用なら sudo nvim として開く
                sudo nvim $filename
            else
                # これから実行するコマンドを fish_history に書き込んでおく
                _add_history     "nvim $filename" $timestr
                # ファイルが読み書き可能なら nvim として開く
                nvim $filename
            end
        end
        # 正常終了したので return 0 で関数を終える
        return 0
    # zf コマンド実行時に引数が指定されていた場合
    else if test (count $argv) -eq 1
        # 引数がファイルであれば、nvim で開くことを試みる
        if test -f $argv[1] 
            if test -r "$argv[1]"
                _add_history     "sudo nvim $argv[1]" $timestr
                sudo nvim $argv[1]
            else
                _add_history     "nvim $argv[1]" $timestr
                nvim $argv[1]
            end
        # 引数がディレクトリであれば、find でファイルを探索してから、
        # fzf によって対話形式でユーザにファイルを選択させる.
        else if test -d $argv[1] 
            set filename ( find $argv[1] -type f 2>/dev/null | fzf )
            if test -n "$filename"
                if test -r "$filename"
                    # これから実行するコマンドを fish_history に書き込んでおく
                    _add_history     "sudo nvim $filename" $timestr
                    # ファイルが読み取り専用なら sudo nvim として開く
                    sudo nvim $filename
                else
                    # これから実行するコマンドを fish_history に書き込んでおく
                    _add_history     "nvim $filename" $timestr
                    # ファイルが読み書き可能なら nvim として開く
                    nvim $filename
                end
            end
            # 正常終了したので return 0 で関数を終える
            return 0
        else
            echo "Error: could not found $argv[1]"
            return 1
        end
    else if test (count $argv) -gt 1
        # 引数が 2個以上指定された場合は、異常終了させる.
        echo "Usage: $argv[0] [directory]"
        return 1
    end
end

実行例

引数なしで実行する場合

カレントディレクトリ直下のファイルが候補として表示される

$ zf

ファイルを指定する場合

nvim で開く

$ zf ~/.bashrc

ディレクトリを指定する場合

指定したディレクトリ直下のファイルが候補として表示される

$ zf ~/.config/

引数を 2個以上指定した場合

エラー終了する. 下記のように終了コードは「1」となっている.

$ zf ~/.bashrc ~/.config/
Usage:  [directory]

$ echo $status
1 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?