メモ:put {*|+} の実装
レジスタ*のプットは :put * でできるので、まずは :ta ex_put を見てみる。
すぐに do_put() に飛んでいるので do_put にタグジャンプ。
#ifdef FEAT_CLIPBOARD /* Adjust register name for "unnamed" in 'clipboard'. */ adjust_clip_reg(®name); (void)may_get_selection(regname); #endif
FEAT_CLIPBOARD は :h +clipboard に対応し、GUI のクリップボード機能の有効・無効を意味する。
adjust_clip_reg()は以下の通り大したことはやっていない。
void adjust_clip_reg(rp) int *rp; { /* If no reg. specified, and "unnamed" is in 'clipboard', use '*' reg. */ // レジスタが指定されておらず、オプション'clipboard'に"unnamed"が含まれているならば*を使う if (*rp == 0 && clip_unnamed) *rp = '*'; // レジスタ*が使えないのに*が指定されたときは無名レジスタを使う if (!clip_star.available && *rp == '*') *rp = 0; // レジスタ+が使えないのに+が指定されたときは無名レジスタを使う if (!clip_plus.available && *rp == '+') *rp = 0; }
may_get_selection(regname) はregname が*か+ならclip_get_selectionを呼んでセレクションの中身を取得する。
clip_get_selectionの中では現在vimがセレクションを取得しているかどうかを判定。
取得しているならカレントバッファからテキストをとってくる。
取得していないならclip_gen_request_selectionに入る。
この中でプラットフォームごとに場合分け。
ターミナルエミュレータ上で実行している場合は
clip_xterm_request_selection()→clip_x11_request_selection()ともぐっていく。
ここでいよいよXtの関数を呼ぶ。
for (i = #ifdef FEAT_MBYTE 0 #else 1 #endif ; i < 5; i++) { switch (i) { #ifdef FEAT_MBYTE case 0: type = vimenc_atom; break; #endif case 1: type = vim_atom; break; case 2: type = compound_text_atom; break; case 3: type = text_atom; break; default: type = XA_STRING; } XtGetSelectionValue(myShell, cbd->sel_atom, type, clip_x11_request_selection_cb, (XtPointer)&success, CurrentTime);
ループで回してswitchしているのは、それぞれのtypeで取得を試みて、成功したらreturn
しているため。
type の意味はここで決まっている:
void x11_setup_atoms(dpy) Display *dpy; { vim_atom = XInternAtom(dpy, VIM_ATOM_NAME, False); // vim の独自セレクションフォーマット #ifdef FEAT_MBYTE vimenc_atom = XInternAtom(dpy, VIMENC_ATOM_NAME,False); // vim の拡張セレクションフォーマット #endif compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False); text_atom = XInternAtom(dpy, "TEXT", False); targets_atom = XInternAtom(dpy, "TARGETS", False); clip_star.sel_atom = XA_PRIMARY; clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD", False); }
ただし gtk 使用の場合は gtk 用の値が入る。
さて、セレクション取得に成功するとコールバックclip_x11_request_selection_cbが呼ばれる。
_cb はコールバックを意味しているようだ。
セレクションのオーナーが firefox だったりした場合は当然 type は compound text であり、
status = XmbTextPropertyToTextList(X_DISPLAY, &text_prop, &text_list, &n_text);