mltermのterminfoがおかしかった件
解決済。
何度か失敗したので、必要な手順だけ読みたければ概要とまとめだけ参照。
概要
Zsh - ArchWikiを参考に以下のようなコードを書いたのだが、これが何故かmltermで動かない。
typeset -A key
key[Home]=${terminfo[khome]}
key[End]=${terminfo[kend]}
[[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line
[[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line
具体的には、HomeキーやEndキーでの挙動がおかしくなる。 どうせterminfoが合っていないんだろうと思ったらその通りだった。
mltermのソースコードと一緒に配られているterminfoのソースを使おうにも、それも駄目だった。
状況把握
$ printf '%q' "${terminfo[khome]}" $'\033'OH $ printf '%q' "(ここでCtrlvHome)" $'\033'\[H
こんな感じの方法でHomeキーを使ったときのシーケンスと違うのがわかるので、どうにかしよう。
調査
何処からかmlterm-256colorのterminfoが導入されているようなので、それを把握する。
$ infocmp mlterm-256color | head -2
# Reconstructed via infocmp from file: /usr/share/terminfo/m/mlterm-256color
mlterm-256color|mlterm 3.0 with xterm 256-colors,
ファイルパスがわかったので、どのパッケージがそのファイルを導入したのか調べる。
gentoo linux ならqfile
コマンドを使う。
$ qfile /usr/share/terminfo/m/mlterm-256color sys-libs/ncurses (/usr/share/terminfo/m/mlterm-256color) $ ncurses6-config --version 6.0.20150808
ncurses-6.0 のファイルが古いのだということがわかった。
たぶん昔ncursesに追加されてから更新されていなかったのだろう。
mltermのバージョンを見てみる。
$ mlterm --version
mlterm version 3.5.0
ソースコードを落とすなりしてChangeLogでsequence
や\x1b
といったパターンで検索し確認すると、2012-09-04に以下のような変更があった。
- Following key sequences are changed. XK_BackSpace: \x7f -> \x08 XK_Home: \x1bOH -> \x1b[H XK_End: \x1bOF -> \x1b[F XK_F1: \x1b[11~ -> \x1bOP XK_F2: \x1b[12~ -> \x1bOQ XK_F3: \x1b[13~ -> \x1bOR XK_F4: \x1b[14~ -> \x1bOS
これに追従できていなかったのだろう。
対処
本家ファイルからして古かった
mlterm本家のterminfoをユーザーローカルで導入すればいいと、この時は思っていたのだ。
現時点(2015-11-18)で最新の、mlterm-3.6.0のソースを落とす。 ChangeLogを確認したところ、前述のもの以降でこれといったterminfoの変更は無さそうなので、バージョン違いは気にせず新しいやつを使ってしまうことにしよう。
展開したソースのdoc/term/mlterm.tiがterminfoのソースだ。
まあ念のためと思って中身を確認するじゃん?
$ grep khome doc/term/mlterm.ti
kfnd=\E[1~, khome=\EOH, kich1=\E[2~, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
なんかもう、ダメダメだ。 ncurses、お前は悪くなかったんや……
自力で編集
仕方ないので、これをベースに自分でシーケンスの変更を適用していく。
以下mlterm-3.6.0.tiは、mltermのdoc/term/mlterm.tiをどこかにコピーしてきたものとする。
$ sed \
-e '1s/mlterm\|/mlterm|mlterm-256color|/' \
-e 's/khome=\\EOH,/khome=\\E[H,/' \
-e 's/kend=\\EOF,/kend=\\E[F,/' \
-e 's/kf1=\\E\[11~,/kf1=\\EOP,/' \
-e 's/kf2=\\E\[12~,/kf2=\\EOQ,/' \
-e 's/kf3=\\E\[13~,/kf3=\\EOR,/' \
-e 's/kf4=\\E\[14~,/kf4=\\EOS,/' \
-i mlterm-3.6.0.ti
どうにも泥臭くて好きではないが、こんなの実行するのは一度きりなのでこれでいいだろう。
適用した変更は2種類。
シーケンスの変更の反映と、mlterm-256color
への対応だ。
mlterm-256color
への対応であるが、公式のソースがmlterm
向けに記述されているため、TERM
環境変数がmlterm-256color
の状態でもこれを適用してほしいのであれば、その指定も追加する必要がある。
その変更が-e '1s/mlterm\|/mlterm|mlterm-256color|/'
だ。
sed
の-i
オプションは、入力ファイルをそのまま置換結果で上書きしてくれるので、これでmlterm-3.6.0.tiは正しくmltermのシーケンスを解釈するterminfoのソースファイルとなった。
これをコンパイルし、~/.terminfo/m/mlterm-256colorというファイルとして置いてやればよい。
terminfoのソースのコンパイル
これといって特筆することもない。 本当にコンパイルするだけだ。
$ ls ~/.terminfo ls: cannot access /home/larry/.terminfo: No such file or directory $ tic mlterm-3.6.0.ti $ ls -l ~/.terminfo/m/ total 8 -rw-r--r-- 1 larry larry 1990 2015-11-18 13:24 mlterm lrwxrwxrwx 1 larry larry 6 2015-11-18 13:24 mlterm-256color -> mlterm
配置先のディレクトリがなくてもtic
は勝手にディレクトリを作ってくれるので、
頭を空っぽにして実行すればいい。
これにて問題は解決した...と思うじゃん?
解決
残念ながらこの状態だと、tmux
が256色出してくれない。


つらい。
原因を探ったところ、setab
とsetaf
の指定が問題であることがわかった。
setab=\E[4%p1%dm, setaf=\E[3%p1%dm,
setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
結局、ncursesの方が正しかったらしい。
terminfo.src (colored) for NCURSESを見ると、mlterm3
の項目のコメントに以下のようにあった。
# Tested mlterm 3.2.2: # mlterm 3.x has made changes, but they are not reflected in the included # mlterm.ti; this entry is based on testing with tack and vttest -TD
そういうわけで、折角一部キー以外問題ないものがあるのだから、それを使おう。
mlterm|mlterm-256color|multi lingual terminal emulator, khome=\E[H, kend=\E[F, kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, use=mlterm-256color,
use=
で他のterminfoを参照できる。
ここではncursesが入れてくれたmlterm-256color
を参照する。
循環参照っぽさがあるが、とりあえず動いたので良しとしよう。
心配なら以下のようにしてやれば同じ結果が得られるだろう。
$ infocmp -A /usr/share/terminfo mlterm-256color \ | sed \ -e 's/khome=\\EOH,/khome=\\E[H,/' \ -e 's/kend=\\EOF,/kend=\\E[F,/' \ -e 's/kf1=\\E\[11~,/kf1=\\EOP,/' \ -e 's/kf2=\\E\[12~,/kf2=\\EOQ,/' \ -e 's/kf3=\\E\[13~,/kf3=\\EOR,/' \ -e 's/kf4=\\E\[14~,/kf4=\\EOS,/' \ >mlterm-256color.ti $ tic mlterm-256color.ti
これでやっと意図した結果が得られた(何を隠そう、先の「期待される結果」の画像はこのファイルを使ったものだ)。
まとめ
問題
ncurses6
に含まれているmlterm-256color
のterminfoは古く、一部キーが正常に認識されない原因になる。-
かといって
mlterm
のソースコードに含まれているものを使おうにも、これもまた古く、256色が正しく扱えないことがある。 -
よって、
ncurses6
のmlterm-256color
のファイルをベースに、一部キーのシーケンスを変更し、これを優先的に使うことにした。-
古いバージョンから変更されたシーケンスは、
mlterm
のChangeLogに記録されているため追跡できた。
-
古いバージョンから変更されたシーケンスは、
手順
mlterm-256color
のterminfoのファイルがインストールされているか確認する。
このファイルがncurses
によるものであるのが理想的だ。
$ ncurses6-config --version 6.0.20150808 $ infocmp -D /home/larry/.terminfo /etc/terminfo /usr/share/terminfo $ ls /usr/share/terminfo/m/mlterm-256color /usr/share/terminfo/m/mlterm-256color
ファイルがあったら、これを以下のコマンドで編集する。
$ infocmp -A /usr/share/terminfo mlterm-256color \
| sed \
-e 's/khome=\\EOH,/khome=\\E[H,/' \
-e 's/kend=\\EOF,/kend=\\E[F,/' \
-e 's/kf1=\\E\[11~,/kf1=\\EOP,/' \
-e 's/kf2=\\E\[12~,/kf2=\\EOQ,/' \
-e 's/kf3=\\E\[13~,/kf3=\\EOR,/' \
-e 's/kf4=\\E\[14~,/kf4=\\EOS,/' \
>mlterm-256color.ti
このファイルをコンパイルし、インストールする。 このときroot権限だとシステムディレクトリに入れてしまう可能性があるので注意。
$ tic mlterm-256color.ti
これでおしまい。