2022/06/05

Debian11の端末でのTERMとemacs

目的


Debian11をクリーンインストールした状態で、端末(gnome-terminal)の背景を黒にすると、emacsの文字が読みにくい状態になるので、視認性を上げてみます。

3つ方法を挙げますが、方法3が最も良い方法でしょう。

初期の状態


何もしていない手元のDebian11環境では、環境変数TERMが
TERM=xterm-256color
となっていました。

方法1


一時的にどうにかしたい場合の方法です。環境変数TERMに
TERM=screen-256color
を設定するだけです。この方法の欠点は、一部がイタリック体になってしまうことです。 また、lessにも影響があり、文字列検索時の強調表示がイタリック体になってしまいます。

方法2


次のコマンドを実行します。
$ mkdir -p ~/.terminfo/s/
$ cp /usr/lib/terminfo/x/xterm-256color ~/.terminfo/s/screen-256color
そして
TERM=screen-256color
を設定します。こうすると、設定内容はxterm-256colorのままで、名前だけscreen-256colorに変更したものが参照されるようになります。

emacsがTERMの名前でカラーテーマを決めているようで、端末の全体的な設定はもとのまま、emacsの色だけTERM=screen-256colorと同じにできます。

方法3


素直にemacsの設定を変更します。TERMの名前に依存してカラーテーマが決まらないように変更するだけです。

https://unix.stackexchange.com/questions/53467/emacs-colors-based-on-term-environment-variable によると、emacsを起動している状態で、

M-x customize-variable [ENTER]
frame-background-mode [ENTER]
を実行します。次のような画面が表示されるので、
For help using this buffer, see [Easy Customization] in the [Emacs manual].

                                         [ Search ]

Operate on all settings in this buffer:
[ Revert... ] [ Apply ] [ Apply and Save ]

Hide Frame Background Mode: [Value Menu] automatic
   [ State ]: SAVED and set.
   The brightness of the background. Hide
   Set this to the symbol ‘dark’ if your background color is dark,                                                    
   ‘light’ if your background is light, or nil (automatic by default)                                                 
   if you want Emacs to examine the brightness for you.                                                                 
                                                                                                                        
   If you change this without using customize, you should use                                                           
   ‘frame-set-background-mode’ to update existing frames;                                                             
   e.g. (mapc 'frame-set-background-mode (frame-list)).
Groups: [Faces]
[Value Menu]のところにカーソル(キャレット?)を合わせて、[ENTER]を押すと、
Available choices:

0 = dark
1 = light
2 = automatic
のように選択肢が表示されます。今回は背景が黒であるという前提ですので、0を押します。 その後、[ Apply and Save ] にカーソルを合わせて[ENTER]を押せば、設定が保存されます。

不思議なこと


infocmpでxterm-256colorの内容を見てみると、イタリック体にするためのエスケープシーケンスが
$ infocmp xterm-256color|egrep "sitm|ritm"
	rev=\E[7m, ri=\EM, rin=\E[%p1%dT, ritm=\E[23m, rmacs=\E(B,
	sgr0=\E(B\E[m, sitm=\E[3m, smacs=\E(0, smam=\E[?7h,
のようにsitmとritmに設定されているにも関わらず、対応するところでは文字の色が反転してしまいます。一方、screen-256colorでは
$ infocmp screen-256color|egrep "sitm|ritm"
のように項目が設定されていません。このscreen-256colorをTERMに使うとなぜかイタリック体になってしまいます。

さらに、https://gist.github.com/riobard/9166725を参考に、次の内容をscreen-256color-noitalic.terminfoとして保存し(ファイル名は任意)、

screen-256color-noitalic|screen with 256 colors with no italic,
	sitm=\E[7m, ritm=\E[27m,
	use=screen-256color,
次のコマンド
$ tic screen-256color-noitalic.terminfo
を実行すると、
~/.terminfo/s/screen-256color-noitalic
というファイルができ、TERMに設定できるようになるので、
TERM=screen-256color-noitalic emacs nanika-file
で実行してみても、上部に表示されるemacsのメニューの文字列がイタリック体のまま変化しません。lessでも同じです。
$ infocmp screen-256color screen-256color-noitalic
comparing screen-256color to screen-256color-noitalic.
    comparing booleans.
    comparing numbers.
    comparing strings.
	ritm: NULL, '\E[27m'.
	sitm: NULL, '\E[7m'.
のように差があるにも関わらずです。不思議ですね。どこかで何か設定があり、優先されているのでしょう。

なお、\E[3mがイタリックの開始、\E[23mがイタリックの終了、\E[7mが色反転の開始、\E[27mが色反転の終了です。 例えば、

echo -e "\E[3mitalic\E[23m \E[7mrev\E[27m"
を端末で実行すると、イタリック体や色反転で表示されることが確認できます。