平衡点


2026/11/02

_ ターミナルの設定: Ghostty → foot に戻る

どこかにまとめて書こうとは思うものの.

先日 kitty を試してみたのだけれど, 開発者自ら「Terminal Multiplexers are a bad idea」としていて (「いや, remote session 使いたいだけなんだけれど…」というか).

というわけで, 巷で噂(?)の Ghostty を試してみた → いや, これなら foot で良いな, となったお話.

Ghostty

Ghostty は 高速で, 多機能で, cross-platform なターミナルエミュレータ. 実際, イロイロと設定を試行錯誤した結果, 好みの多い私が満足できる状況になった.

なお, 開発者の Mitchell Hashimoto さんは Unicode での文字幅表示についても しっかり考察されている

こういう考察を踏まえた上での実装なので, 絵文字や VS16 での幅勘定で困る事はない …筈だったのだけれどねぇ….

Ghostty のインストール

Debian パッケージは無いのでビルドします.

  1. Zig を asdf でインストール
    % asdf plugin add zig
    % asdf install zig latest
    
  2. Ghostty を clone してきてビルド
    % ghq get https://github.com/ghostty-org/ghostty
    ... 移動: cd $(ghq list --fullpath| grep ghostty) とか?
    % asdf set zig latest
    % mkdir -p /usr/local/stow/ghostty
    % zig build -p /usr/local/stow/ghostty -Doptimize=ReleaseFast
    
  3. GNU Stow で有効化
    % cd /usr/local/stow
    % sudo stow ghostty
    

といった塩梅

なお ilvez/asdf-ghostty: ASDF plugin for ghostty というのもある. …試してないけど.

Ghostty の設定

…いや, 結構ガッツリ弄ったな. 「Zero Configuration Philosophy」とは何だったのか.

何が問題だったのか, と言えば fontconfig の fallback を半端に理解する所.

やりたい事:

私は等幅フォントの Regular が太く感じて 目が痛い ので, 通常の表示を Light, 太い表示を Medium か SemiBold にしたかった.

最初の結果:

fontconfig では,

<alias binding="strong">
  <family>monospace</family>
  <prefer>
    <family>Iosevka Term</family>
    <family>JuliaMono</family>
    <family>Noto Sans Math</family>
    <family>PlemolJP Console</family>
    <family>Rounded-X Mgen+ 1mn</family>
    <family>Migu 1M</family>
    <family>Noto Sans Mono CJK JP</family>
    <family>VL Gothic</family>
    <family>Symbols Nerd Font</family>
    <family>Noto Color Emoji</family>
    <family>Noto Emoji</family>
    <family>Symbola</family>
  </prefer>
</alias>

としていた. これは Fontconfig を見に行くアプリケーションで Unicodeの言う所の「文脈」で文字幅がひょこひょこ変わるのを防ぐための強制.

で, これをしていると, Ghostty の font-family の設定が効かない. というか, 日本語の文字列があると PlemolJP Console Bold に match してしまう せめて Regular じゃないの? とか思うけど, どういう理屈かなぁ….

fontconfig の調整:

というわけで

<match target="pattern">
  <test name="prgname" compare="not_eq">
    <string>ghostty</string>
  </test>
  <test name="family" qual="any" compare="eq">
    <string>monospace</string>
  </test>
  <edit name="family" mode="prepend_first" binding="strong">
    <string>Iosevka Term</string>
    <string>JuliaMono</string>
    <string>Noto Sans Math</string>
    <string>PlemolJP Console</string>
    <string>Rounded-X Mgen+ 1mn</string>
    <string>Migu 1M</string>
    <string>Noto Sans Mono CJK JP</string>
    <string>VL Gothic</string>
    <string>Symbols Nerd Font</string>
    <string>Noto Color Emoji</string>
    <string>Noto Emoji</string>
    <string>Symbola</string>
  </edit>
</match>

としておく.

また fontconfig で OTF の font features を設定してあるんだけれど, どうも設定を見ておらず, 設定ファイル内で font-feature を設定しないと いけない模様. 例えば

font-feature = "-calt,cv01=3,cv03=1,cv06=1,cv07=2,cv09=1,cv36=20,cv42=1,cv44=8,cv45=10,cv56=1,cv59=13,cv60=2,cv78=6,cv86=2,cv87=2,cv91=4,cv93=21,cv94=21,cv97=3,cv98=3,cv99=6,VAAA=5,VAAF=3,VAAG=4,VDAA=1,VSAB=3,VSAS=2"

みたいに.

さすがにシンドいので Iosevka Term をカスタマイズしてビルドした Iosevka Custom というフォントを利用することにした.

最終的な設定:

という訳で, font 関連の設定は以下の通り. キュッと「詰ってる」のが好きなので cell width/height を削ってる

font-family = ""
font-family = "Iosevka Custom"
font-family = "Julia Mono"
font-family = "Noto Sans Math"
font-family = "PlemolJP Console Light"
font-family = "Symbols Nerd Font"
font-family = "Noto Color Emoji"
font-family = "Noto Sans Symbols2"
font-family-bold = ""
font-family-bold = "Iosevka Custom"
font-family-bold = "Julia Mono Medium"
font-family-bold = "Noto Sans Math"
font-family-bold = "PlemolJP Console Medium"
font-family-bold = "Symbols Nerd Font"
font-family-bold = "Noto Color Emoji"
font-family-bold = "Noto Sans Symbols2"
font-family-italic = ""
font-family-italic = "Iosevka Custom"
font-family-italic = "Julia Mono"
font-family-italic = "Noto Sans Math"
font-family-italic = "PlemolJP Console Light"
font-family-italic = "Symbols Nerd Font"
font-family-italic = "Noto Color Emoji"
font-family-italic = "Noto Sans Symbols2"
font-family-bold-italic = ""
font-family-bold-italic = "Iosevka Custom"
font-family-bold-italic = "Julia Mono"
font-family-bold-italic = "Noto Sans Math"
font-family-bold-italic = "PlemolJP Console Medium"
font-family-bold-italic = "Symbols Nerd Font"
font-family-bold-italic = "Noto Color Emoji"
font-family-bold-italic = "Noto Sans Symbols2"
font-style = Light
font-style-bold = Regular
font-style-italic = Light Italic
font-style-bold-italic = Italic
font-synthetic-style = bold,no-italic,no-bold-italic
font-size = 13.5
adjust-cell-width = -5%
adjust-cell-height = -20%

このキュッとした感じは Kitty ではできなかったので満足.

East Asian Ambiguous char Width, Emoji, VS16, …

さて(多分コレが)本題.

これまで East Asian Ambiguous char Width やら Emoji + VS16 やら Icon font やらの 「文字幅」の勘定をどうするか, という事で

  1. ターミナル
  2. tmux
  3. Emacs

で, どう扱うか, みたいな事をジタバタしていたのだけれど.

  • 新し目の tmux では
    # VS16 を含む emoji presentation は wide として扱う
    set -s variation-selector-always-wide on
    

    という設定ができる様になった. また, 表示やカーソル移動の際の幅の勘定は en_US.UTF-8 を見に行くので, EAW での N, A は半角幅 である.

  • Emacs は LANG が ja_JP.UTF-8 だと
    (set-language-environment "Japanese")
    

    と同じ処理を行ない「EAW を全角幅にする」するが, これは

    (setopt cjk-ambiguous-chars-are-wide nil)
    

    とすれば無効化できる. つまり EAW での N, A は半角幅 となる.

  • Ghostty は
    Ambiguous width (A) characters are treated as width 1.
    Per UAX #11 §5 Recommendations:
    "If the context cannot be established reliably, they should be treated as narrow characters by default"
    

    ということで, そもそも EAW での N,A は半角幅 である (Wezterm の cell_widths や treat_east_asian_ambiguous_width_as_wide に対応するオプションは無い). また, Emoji + VS16 の処理も完璧. ただし 絵文字は全角幅 の模様.

… あれ, 無理に EAW の A を全角幅する必要は無いんじゃないか?

まあ, ① とか ⓐ を半角幅で 綺麗に 視認性良く表示するフォントが無いのが難点といえば難点かもしれないけれど, とにかくズレない方が気持ちが良い. 特に Claude とか Codex とかの CLI は 応答待ちの時に EAW A の文字列を利用してアニメーション(?)を表示するので, EAW A が全角幅だとガチャガチャと表示が崩れてシンドかったのだけれど, これも解決できてしまう.

難点は AA が綺麗に表示できないこと, だろうか

というわけで, これまでお世話になっていた hamano/locale-eaw: East Asian Ambiguous Width問題のための修正ロケール は外して, EAW の A と N は半角幅で生きていく事に.

Emacs の設定変更

実際に設定を変更するのは Emacs で, これは

(leaf *handle-eaw-char-width
  :hook (emacs-startup-hook
         . (lambda ()
             (setopt cjk-ambiguous-chars-are-wide nil)
             (aset char-width-table #xFE0F 1)
             ;; 肌色修飾子 (U+1F3FB〜U+1F3FF) の幅を 2 → 0 (結合文字扱い) に
             (set-char-table-range char-width-table '(#x1F3FB . #x1F3FF) 0)
             (auto-composition-mode 1)
             ))
  )

としたぐらい.

  • VS16 で利用する #xFE0F に幅を持たせることで, Emoji Presentation に対応.
  • 肌色修飾子の幅を 0 とすることで, 結合して色が変わった文字の幅にも対応.

としてみた.

ここまでやって, foot に戻る.

普段の生活環境 = emacs on tmux on Ghostty で, 文字幅が綺麗に揃って とても気持ちが良くなった. いや, 素晴しいね.

…と考えたけれど, そもそも Ghostty のリッチなアレやコレの機能って, 私は殆ど使ってないよね, という事に気がついたり(あと, ちょっと重い?).

これなら foot が軽量だし良いのでは, ということで, 試しに

font=Iosevka Custom Light:size=13.5,PlemolJP Console Light:size=13.5,Symbols Nerd Font:size=10,Noto Color Emoji:size=10
font-bold=Iosevka Custom Medium:size=13.5,PlemolJP Console Medium:size=13.5,Symbols Nerd Font:size=10,Noto Color Emoji:size=10
font-italic=font=Iosevka Custom:size=13.5,PlemolJP Console Light:size=13.5,Symbols Nerd Font:size=10,Noto Color Emoji:size=10
font-bold-italic=Iosevka Custom Medium:size=13.5,PlemolJP Console Medium:size=13.5,Symbols Nerd Font:size=10,Noto Color Emoji:size=10
font-size-adjustment=1.5
line-height=13.5
letter-spacing=-0.5
horizontal-letter-offset=0
vertical-letter-offset=0
box-drawings-uses-font-glyphs=no

で起動してみたら, なんかもうしっかりと 綺麗に表示されて崩れない. 軽いし, これで良いじゃん, となったり.

まとめ

これまで利用していた Wezterm, 機能に不満は無いのだけれど, ビルドするのが手間で更新を放置していたり. いや, Cross Platform なので Windows, macOS, Linux どこでも動く, というのはありがたいのだけれどね (なお, ConHost のせいで Windows ではちょっと手間がかかるけれど).

とりあえず foot で現状で幸せになったけれど, ターミナル生活は難しいねぇ…

Ghostty は VTEの互換ライブラリ(libghostty-vt)があったり emacs-libgterm なんてものもあるので, これはこれで試してみたい.


連絡先など

portrait

最近の日記

一覧

Back to Top ▲