Humanity

Edit the world by your favorite way

Vim の :terminal で動かしているシェルで cd したら Vim のカレントディレクトリも変えるプラグイン

github.com

Vim:terminal で動かしているシェルで cd したら、 Vim のカレントディレクトリも同じパスに :cd するプラグインを作りました。

セットアップ

.bashrc / .zshrc に以下を追加してください。

source (sync-term-cwd.vim のリポジトリ)/macros/synctermcwd.sh

仕組み

実質これだけです。

plugin/synctermcwd.vim

function! Tapi_SyncTermCwd(_, cwd) abort
  let cd = get(g:, 'synctermcwd_cd_command', 'cd')
  execute cd a:cwd
endfunction

macros/synctermcwd.sh

cd() {
  builtin cd "$@" || return $?
  if [ "$VIM_TERMINAL" ]; then
    printf '\e]51;["call","Tapi_SyncTermCwd","%s"]\x07' "$PWD"
  fi
}

追記 (2019-12-28 02:30): cd コマンドを書き換えると他の cd コマンドを書き換えるスクリプトとバッティングするので PS1 に追加するようにしました。

if [ "$VIM_TERMINAL" ]; then
  _synctermcwd_ps1() {
    printf '\e]51;["call","Tapi_SyncTermCwd","%s"]\x07' "$PWD"
  }
  PS1="\$(_synctermcwd_ps1)$PS1"
fi

sync-term-cwd.vim/synctermcwd.sh at 141dfbad64ce6c08d0867c98e8846bd983a624bc · tyru/sync-term-cwd.vim · GitHub

便利な設定

デフォルトだと :cd {path} を実行しますが、現在タブページのみカレントディレクトリを変えたければ以下を .vimrc に追加すればできます。

let g:synctermcwd_cd_command = 'tcd'

追記 (2019-12-28 02:30): 追加した SyncTermCwdConditionalCd を指定する方が大体の場合便利です。

let g:synctermcwd_cd_command = 'SyncTermCwdConditionalCd'

詳しくは

tyru.hatenablog.com

追記: :tcd について

:tcdVim 8.1.1218 からあるコマンドです。 現在タブページ固有のカレントディレクトリを設定する事ができます。

プラグインを作った当初は

let g:synctermcwd_cd_command = 'windo lcd'

と README にも書いていたのですが、 :windo は現在のウィンドウから移動してしまう事に気付き、 :SyncTermCwdTabLcd という Ex コマンドを実装したのですが*1

k-takata さんに :tcd があるよと教えてもらい、revert しました。 よって結局記事冒頭のシンプルな仕組みのままです。 素晴らしい… :tcd 便利すぎる…

あわせて読みたい

ちなみに sync-term-cwd.vim では :help terminal-api という機能を使っていますが、 過去も Terminal API を使った類似のプラグインとして以下があります。

tyru.hatenablog.com