Xサーバの突然死に備える

ばよえ〜ん(訳:Vim Advent Calendar 2012への17回目の投稿です)
この記事はVim Advent Calendar 2012

_人人人人人_
> 154日目 <
 ̄Y^Y^Y^Y ̄

...の記事になります。アホか*1

153日目は@deris0126さんでvimでキーマッピングする際に考えたほうがいいことでした。


序文

さてあなたは少なからずXサーバをkillする羽目に陥った事があるはずです。
実は、Vimは端末版であっても(もしXサーバが起動している場合は)クリップボードを取得するためにXサーバと通信しているため、Xサーバが落ちると端末で動いているVimも落ちます。
スワップファイルからバッファの内容はサルベージできますが、screen上で動かしていたVimがXの巻き添えになるのは何か納得いかないものがあります。

Xサーバと勝手に通信させない

以下の設定を.vimrcに追加します。

" When running on terminal, use |clipboard-exclude|
" to disable connecting to X server
" not to be killed with X server.
if !has('gui_running')
    set clipboard+=exclude:.*
endif

どのような意味でしょうか?
日本語helpから引用します。

exclude:{pattern}
ターミナルの名前 'term' にマッチするパターンを定義す
る。パターンがマッチすると、Xサーバとの通信がなされな
くなる。
このオプションは以下の場合に便利である。
- Vimをコンソールで使用しているとき。
- アプリケーションを別のディスプレイで使うため、環境変
数 $DISPLAY が設定されているとき。
- コンソールではXサーバと通信してほしくないが、ターミ
ナルエミュレータ上では通信してほしいとき。
- コンソールでVimを使用している最中にXサーバが終了させ
られ、Vimをkillせざるを得ないかもしれないとき。
Xサーバと全く通信しないようにするには、次のようにする。 >
exclude:.*

つまり、「もし端末版で起動していたら」「Xサーバと全く通信しない」という設定です。
これを.vimrcに入れておくことによって、不意にXサーバが落ちてしまっても端末で起動しているVimは落ちません。

Xの影響を受けずにクリップボードを取得する

代わりにクリップボードの取得にはfakeclip.vimというVimプラグインを使います。
しかしこのプラグインは「クリップボード機能が使えない場合にはXサーバと通信する以外の手段でそれを実現する」というコンセプトの元に作られており、
今回のように「クリップボード機能は使えるが、Xサーバとの接続はあえて無効にした上でクリップボードの内容を取得したい」というケースは考えられていませんでした。
そのため、「クリップボード機能が使える→必要ないのでクリップボード関連のデフォルトキーマッピングは提供しない」となっていました。


一応キーマッピング自体は定義されているので一つ一つ手動で定義すれば解決しますが、とても面倒です。
という訳で、クリップボード機能が使える場合にもあえてクリップボード機能は使わないという私のような人向けの変数を追加してPull Requestを投げてみました
まだマージされていないので、使うには

  1. 私のリポジトリのvariable-to-provide-clipboard-mappingsブランチをcheckoutして
  2. 次の設定を追加してください。
let g:fakeclip_always_provide_clipboard_mappings = 1


参考に私の設定も晒してみます。

if s:has_plugin('vim-fakeclip') "{{{
    if !s:is_win && has('unix') && !has('gui_running')
        set clipboard+=exclude:.*
        let g:fakeclip_always_provide_clipboard_mappings = 1
    endif
endif "}}}

「s:has_plugin()」「s:is_win」の2つの定義がないためこのままでは使えないですが、
やってることとしては

  1. vim-fakeclipプラグインがインストールされていて
  2. Unix系であり、端末版のVimなら

冒頭で挙げたclipboardの設定とfakeclipプラグインの設定をしています。


また、Mac OS Xなどの環境も考慮するなら2の条件をさらに複雑にする必要があります。
ただし私はMacは使っていないのでWindowsUnix系かを考慮すればXサーバの有無は判定できるのでこのようになっています。
いっそ「executable('X')」としてPATHにXのバイナリが含まれてるかで判定した方がいいかもしれません。

*1:一番アホなのは「Vim Advent Calendar 2012への17回目の投稿です」の部分な気がしなくもない