技術メモ帳 このページをアンテナに追加 RSSフィード

2006-11-18

[]フルスクリーンアプリを終了したときに元のコンソールの状態に復元する 09:47 フルスクリーンアプリを終了したときに元のコンソールの状態に復元するを含むブックマーク フルスクリーンアプリを終了したときに元のコンソールの状態に復元するのブックマークコメント

vim や emacs、less などのフルスクリーンアプリを終了したときに、

元のコンソールの状態に戻る環境と、戻ってくれない環境というのがあり、

前々からすごく疑問だったので、この際だからと調べてみた。

もしかしたら誰かの役に立つかもしれないので書いておく。


肝心の原因は、端末データベースの

enter_ca_mode / exit_ca_mode ケーパビリティ が

適切に設定されてないということにあった。


本当は vim などのフルスクリーンアプリは

"元のコンソール状態" に復元しようと、

enter_ca_mode / exit_ca_mode というものを出力するのだが、

このときに、端末データベースから

"実際に出力すべきエスケープシーケンス" というものを取得しており、

ここが正しく設定されていないため、うまく元のコンソールに戻らない。


これらを適切に設定すれば良いのだが、

端末データベースには、termcap, terminfo と2種類存在しており、

それぞれ設定方法に違いがある。設定項目名が違っているので注意が必要だ。

それぞれの関連する設定項目名を以下の図に示す。

enter_ca_modeexit_ca_mode
termcaptismcup
terminfotermcup

なお、設定すべきエスケープシーケンスについては、

使用している端末のマニュアルを参照していただく必要がある。

とりあえず、Mac の Terminal.app の端末 xterm-color では、

enter_ca_mode が

\E7\E[?47h

exit_ca_mode が

\E[2J\E[?47l\E

だった。


termcap の設定変更方法

(MacOSX では termcap が見つからなかった。

もしかしたら使われてないのかもしれない。

とりあえず、cygwin の場合を説明する)


設定ファイルは、/etc/termcap にあり、

ココを変更すると即座に反映される。

$ vi /etc/termcap

このファイルには、

それぞれの端末名とその設定が組で記述されている。

以下は、xterm-color 端末の設定例である。

vc|xterm-color|generic "ANSI" color xterm:\
  :Co#8:NC@:pa#64:\
  :AB=\E[4%dm:AF=\E[3%dm:ac=:op=\E[m:tc=xterm-r6:

先ほど示した図の通り、termcap の場合

te / ti が該当している。


コンソールを復元したい場合は、ここに適切なエスケープシーケンスを、

復元せずにそのまま画面を残しておきたい時は

te, ti を記述を削除するか、te@:ti@ と記述しておく。

  :AB=\E[4%dm:AF=\E[3%dm:ac=:op=\E[m:te=hoge:ti=fuga:tc=xterm-r6:

ちなみに、tc というのは、

指定された端末の設定を include するという意味だ。

tc=端末名

terminfo の設定変更方法

terminfo の設定ファイルの場所だが、

$TERM の 値によって変わる。

たとえば、cygwin だった場合

/usr/share/terminfo/c/cygwin

と言ったように頭文字ごとにディレクトリが区切られている。

が、実際にはこのファイルをいじる事は無いので特に意味はない。


infocmp コマンドで、

現在の環境変数 $TERM に設定されている端末の設定を

標準出力に出力する事が出来る。

とりあえず、現在の設定をバックアップしておく。

$ infocmp > backup_$TERM

次に現在の設定を元に設定を変更していくので

適当な名前で保存しておき、お気に入りのエディタで編集する。

$ infocmp > customize.tic
$ vi ./customize.tic

ファイルの中身はこのような感じになっている。

#    Reconstructed via infocmp from file: /Hoge/Fuga/.terminfo/78/xterm-color
xterm-color|nxterm|generic color xterm,
    am, km, mir, msgr, xenl,
    colors#8, cols#80, it#8, lines#24, ncv@, pairs#64,
    acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
    bel=^G, bold=\E[1m, clear=\E[H\E[2J, cr=^M,
    csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
    cud=\E[%p1%dB, cud1=^J, cuf=\E[%p1%dC, cuf1=\E[C,
    cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
    dch=\E[%p1%dP, dch1=\E[P, dl=\E[%p1%dM, dl1=\E[M, ed=\E[J,
    el=\E[K, enacs=\E)0, home=\E[H, ht=^I, hts=\EH, il=\E[%p1%dL,
    il1=\E[L, ind=^J,
    is2=\E7\E[r\E[m\E[?7h\E[?1;3;4;6l\E[4l\E8\E>, kbs=^H,
    kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
    kdch1=\E[3~, kf1=\E[11~, kf10=\E[21~, kf11=\E[23~,
    kf12=\E[24~, kf13=\E[25~, kf14=\E[26~, kf15=\E[28~,
    kf16=\E[29~, kf17=\E[31~, kf18=\E[32~, kf19=\E[33~,
    kf2=\E[12~, kf20=\E[34~, kf3=\E[13~, kf4=\E[14~,
    kf5=\E[15~, kf6=\E[17~, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
    kfnd=\E[1~, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
    kslt=\E[4~, op=\E[m, rc=\E8, rev=\E[7m, ri=\EM, rmacs=^O,
    rmir=\E[4l, rmkx=\E[?1l\E>, rmso=\E[m, rmul=\E[m,
    rs2=\E7\E[r\E8\E[m\E[?7h\E[?1;3;4;6l\E[4l\E>, sc=\E7,
    setab=\E[4%p1%dm, setaf=\E[3%p1%dm, sgr0=\E[m, smacs=^N,
    smir=\E[4h, smkx=\E[?1h\E=, smso=\E[7m, smul=\E[4m,
    tbc=\E[3g, u6=\E[%i%d;%dR, u7=\E[6n, u8=\E[?1;2c, u9=\E[c,

先ほど示した図の通り、terminfo の場合

smcup / rmcup が該当している。

コンソールを復元したい場合は、ここに適切なエスケープシーケンスを、

復元せずにそのまま画面を残しておきたい時はこの項目ごと削除してしまえば良い。


作業が終わりしだい、

terminfo の設定ファイルをコンパイルし反映させる。

tic コマンドを使えばこれらを行う事が出来る。

tic ./customize.tic

一般ユーザー権限でこのコマンドを実行した場合、

$HOME/.terminfo/?/$TERM という名前で

設定ファイルが作成される。

システムに影響を与えないのが健全で良い。

root でやれば、/usr/share/terminfo/?/* に反映される。


terminfo, termcap の設定を統一する

termcapの設定をし、全く同じ設定にterminfo側も変更したい場合は、captoinfo コマンドを、

terminfoの設定をし、全く同じ設定にtermcap側も変更したい場合は、infotocap コマンドを利用すれば良い。

$ captoinfo termcapの設定ファイル
$ infotocap terminfoの設定ファイル

これらのコマンドを実行すると、

設定ファイルが自動生成され、適用される。


参考文献:

http://www.linux.or.jp/JM/html/LDP_man-pages/man5/termcap.5.html

http://docs.hp.com/ja/B2355-90857/terminfo.4.html

http://iris.homeunix.net/yayoi/freebsd/xsetting/changepager.asp

http://www.linux.or.jp/JF/JFdocs/Text-Terminal-HOWTO.html