Vimで:suspend時にシェルのカレントディレクトリを変えたい件の解決編パート1: 間接法 = GNU screenを併用する方法について。

" Pseudo :suspend with automtic cd.
" Assumption: Use GNU screen.
" Assumption: There is a window with the title "another".
noremap <silent> <C-z>  :<C-u>call <SID>PseudoSuspendWithAutomaticCD()<Return>

if !exists('s:gnu_screen_availablep')
  " Check the existence of $WINDOW to avoid using GNU screen in Vim on
  " a remote machine (for example, "screen -t remote ssh example.com").
  let s:gnu_screen_availablep = len($WINDOW) != 0
endif
function! s:PseudoSuspendWithAutomaticCD()
  if s:gnu_screen_availablep
    " \015 = <C-m>
    silent execute '!screen -X eval'
         \         '''select another'''
         \         '''stuff "cd \"'.getcwd().'\"  \#\#,vim-auto-cd\015"'''
    redraw!
    let s:gnu_screen_availablep = (v:shell_error == 0)
  endif

  if !s:gnu_screen_availablep
    suspend
  endif
endfunction

こんな感じでどうでしょう。GNU screenが使用できない場合は普通に:suspendします。

問題点は、シェル側のウィンドウ"another"が存在しない場合、本来そちらに送られるcdのためのコマンドがVim側のウィンドウに送られてしまうことです。どうにかしてウィンドウ切り替えの失敗を検出できればパーフェクトなんですけどね。

取り敢えずはこれを試用してみます。上記問題点の解決や直接法による解決についてはまた次回。

s:gnu_screen_availablepの初期値を修正しました。

最初は「取り敢えずGNU screenの使用を試みて、失敗したら:suspendを使う」という風にしていたのですが、それだとSSH等で接続したリモートの環境でVimを使った場合、ローカルとリモートで二重にGNU screenが起動することになり、凄まじく混乱することになります。また、GNU screenが起動されていない状態で使用した場合にも混乱を招きます。

と言う訳で、$WINDOWの存在をチェックしてGNU screenを使用するかどうかを判定するようにしました。