ディレクトリをブックーマーク

zsh で移動するディレクトリをブックマークできたら便利なんじゃないかと思い、探したがあまり見つからない。ということでbd (bookamrk directory) という簡単なコマンドを自作。

ディレクトリをブックマークに登録

$ bd /tmp /usr /usr ../../etc/apache2
push new dir /tmp
push new dir /usr
push new dir /usr
push new dir /etc/apache2
0 /tmp
1 /usr
2 /etc/apache2

移動ディレクトリをブックマークから選択

bd コマンドを引数なしで実行すると、select number:と出てくるので、番号を指定するとそのディレクトリに移動する。

$ bd
0 /tmp
1 /usr
2 /etc/apache2
select number: 2
$ pwd
/etc/apache2

ブックマークからディレクトリ削除

bd コマンドを引数なしで実行して、select number:と出てきたときに 「d 番号」とするとそのディレクトリをブックマークから削除。

$ bd
0 /tmp
1 /usr
2 /etc/apache2
select number: d 1
Delete /usr from bookmark
0 /tmp
1 /etc/apache2

ソース

以下のソースをファイルに保存してsourceすれば bd コマンドが使えるようになる。zleを使えば、ブックマークを登録順にソートだとか、階層化して折り畳み表示とかできそうだけどzleは修行不足のため断念。

BOOKMARK_FILE=${BOOKMARK_FILE:-"$HOME/.zsh.bmk"}

function _bd_dump ()  {
    count=0
    while [ $# -gt 0 ]
    do
        echo "$count $1"
        shift
        count=`expr $count + 1`
    done
}

function _bd_select_dir () {
    typeset -a -U bookmarks
    bookmarks=("$@")
    _bd_dump $bookmarks
    echo -n "select number: "
    read cmd1 cmd2

    case "$cmd1" in
        d|D)
            number=`expr $cmd2 + 1`
            echo "Delete $bookmarks[$number] from bookmark"
            bookmarks[$number]=()
            typeset bookmarks > $BOOKMARK_FILE
            _bd_dump $bookmarks
            ;;
        [0-9])
            number=`expr $cmd1 + 1`
            cd $bookmarks[$number]
            ;;
        *)
            echo "Unknown command $arg1"
            ;;
    esac
}

function bd () {
    bookmarks=()
    typeset -a -U bookmarks
    if [ -f "$BOOKMARK_FILE" ]
    then
        source "$BOOKMARK_FILE"
    fi

    if [ "$#" -eq 0 ]
    then
        # Select or remove dir
        _bd_select_dir $bookmarks
    else
        # Set dir(s)
        while [ $# -gt 0 ]
        do
            if [ -d "$1" ]
            then
                if [ $#bookmarks -gt 10 ]
                then
                    echo "bookmarks full in $bookmarks"
                fi
                new_dir=`realpath $1`
                echo "push new dir $new_dir"
                bookmarks+=($new_dir)
            else
                echo "$1 is not directory"
            fi
            shift
        done
        typeset bookmarks > $BOOKMARK_FILE
        _bd_dump $bookmarks
    fi
}