tmuxのコピーモードの時に幅が2以上の文字を扱う時の挙動をいじったpatchを1.8用に書き換えた時のメモ

一応前の記事
http://d.hatena.ne.jp/silenvx/20121016/1350335269

tmuxのpatch置き場

https://github.com/silenvx/PKGBUILD/tree/master/tmux
今のところはここの
https://github.com/silenvx/PKGBUILD/blob/master/tmux/copy_cursor_width.patch
ここに置いてますがtmuxのバージョンがさらに上がったり、私が不要になったりすると消したり書き換えられたりするので悪しからず

いじった時のメモ

tmux-1.7までのutf8の文字はgrid_utf8などの変数や関数などでascii文字とは別けられていましたが
今回、tmux-1.8のソースコードを見る限りでは統合されたもよう(?)です
注目すべきなのは

tmux-1.7/tmux.h
    /* Grid cell data. */
    struct grid_cell {
        u_char>.attr;
        u_char>.flags;
        u_char>.fg;
        u_char>.bg;
        u_char>.data;
    } __packed;

    /* Grid cell UTF-8 data. Used instead of data in grid_cell for UTF-8 cells. */
    struct grid_utf8 {
        u_char>.width;
        u_char>.data[UTF8_SIZE];
    } __packed;

このようにascii文字の場合はwidthは必ず1なので明記されず、utf8はu_char>.widthに収められていましたが

tmux-1.8/tmux.h
    /* Grid cell data. */
    struct grid_cell {
        u_char>.attr;
        u_char>.flags;
        u_char>.fg;
        u_char>.bg;

        u_char>.xstate; /* top 4 bits width, bottom 4 bits size */
        u_char>.xdata[UTF8_SIZE];
    } __packed;

xstateとxdataというのが新たに追加されまして、xstateの上位4bitにwidthが入っているみたいです
下位4bitは恐らく文字のデータ的なサイズでしょうが、今回のpatchを書くのに大して重要ではないので無視します
このxstateが使われているのは

    % find tmux-1.8 -type f -exec grep -nH 'xstate' {} \;
    tmux-1.8/grid-cell.c:29:        return (gc->xstate >> 4);
    tmux-1.8/grid-cell.c:36:        ud->size = gc->xstate & 0xf;
    tmux-1.8/grid-cell.c:37:        ud->width = gc->xstate >> 4;
    tmux-1.8/grid-cell.c:46:        gc->xstate = (ud->width << 4) | ud->size;
    tmux-1.8/grid-cell.c:54:        gc->xstate = (1 << 4) | 1;
    tmux-1.8/tmux.h:724:    u_char  xstate; /* top 4 bits width, bottom 4 bits size */

こんな感じなので、そのままずらしてwidthを取得すればいいみたいですね
というわけで後は改変するだけなので端折ります

後書き

この1.8用のpatchを書いてる時に、前に書いた1.7用のpatchがなぜ動くのかわからなくなってしまった…
なんかおかしいような気がしなくもないので使うのはあまり推奨しないでおきます
本来は if (gc->flags & GRID_FLAG_PADDING) でもして埋めるためのデータなのか判定して色々とやるべきだったはず

それとsourceforgeからソースコードをダウンロードする時はPKGBUILDに書いてある
http://downloads.sourceforge.net/tmux/tmux-1.8.tar.gz
こうではなく
http://jaist.dl.sourceforge.net/project/tmux/tmux/tmux-1.8/tmux-1.8.tar.gz
こうしないとダウンロードできない*1のですが何かわかる人がおられましたら、ぜひ教えてください

追記 2013/11/07:useragentをよくあるブラウザの奴にしてたせいでした。~/.curlとか~/.wgetrcの設定でuseragentの設定をコメントアウトしたらダウンロードできましたとさ。makepkgだけに適用したければ/etc/makepkg.confでcurlなら-A ""オプション足しとくと良い

*1:tar.gzではなく、htmlが落ちてくる