別の端末のカレントディレクトリに移動

zshで別のscreenの窓(?)のカレントディレクトリにcdするのを見て、screen限定じゃないのが欲しいという人*1がいたので作ってみた。
本家と違ってやたらゴミファイルを作る。

TMPDIR=${TMPDIR:-/tmp}
export CDD_PWD_DIR="${TMPDIR}/cdd_pwd_dir.$UID"
SED=/bin/sed

function _reg_pwd_tty() {
    local tty_file
    tty_file=${CDD_PWD_DIR}/$(echo "${TTY}" | ${SED} -e 's|-|-h|g' -e 's|/|-s|g')
    if [ ! -d ${CDD_PWD_DIR} ]; then
        mkdir ${CDD_PWD_DIR}
        if [ $? != 0 ]; then
          return 1
        fi
    fi

    pwd > "${tty_file}"
    if [ $? != 0 ]; then
      echo "Error: Don't wrote ${tty_file}."
      return 1
    fi
}

function _print_dirs() {
    ls -1 ${CDD_PWD_DIR} | while read i; do
        echo -n "${i} => " | ${SED} -e 's|-s|/|g' -e 's|-h|-|g'
        cat -- ${CDD_PWD_DIR}/${i}
    done
}

function cdd() {
  local tty_file

  if [ -z "$1" ];then
    _print_dirs
    return 0
  fi

  tty_file=${CDD_PWD_DIR}/$(echo "${1}" | ${SED} -e 's|-|-h|g' -e 's|/|-s|g')

  if [ -r ${tty_file} ];then
    cat ${tty_file}
    cd $(cat ${tty_file})
  else
    _print_dirs
  fi
}

使い方は本家とほぼ同じ。$HOME/.zshrcで上記のファイルをインポートして、以下を記述する。

function chpwd() {
    _reg_pwd_tty
}

補完関数、fpath通ってるところに"_cdd"という名前で置くと動くと思う。

#compdef cdd

local CDD_PWD_DIR="${TMPDIR}/ccd_pwd_dir.$UID"
local curcontext="$curcontext" state line expl ret=1 list disp cdd_pwd files

_arguments -C \
    '1:cdd_dir:->cdd-dir' \
    && ret=0

if [[ -n "$state" ]]; then
    case $state in
        cdd-dir)
            files=($(ls -1 ${CDD_PWD_DIR}))
            cdd_pwd=($(echo $files | sed -e 's|-s|/|g'  -e 's|-h|-|g'))
            for (( i = 1; i <= $#cdd_pwd; i++ )); do
                cdd_pwd[$i]="$cdd_pwd[$i] -- $(cat $CDD_PWD_DIR/$files[$i])"
            done
            list=( ${^cdd_pwd%% *} )
            disp=( -ld cdd_pwd)
            _wanted -V cdd-dir expl 'cdd_dir' compadd "$@" "$disp[@]" -Q -a list
        ;;
    esac
fi

return ret

zshの補完関数はわかりづらいなぁ。かかった時間の99%補完関数。