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を使用するかどうかを判定するようにしました。