💻

tmux, neovim環境下でもundercurl表示に対応する

2022/12/30に公開

undercurl, テキストの下に波線で装飾するもののことだが、tmux, neovim環境下ではうまく動作せずにunderline表示にfall backされていることがある。

こちらのterminalの見直しの続き。 terminal, tmux, neovimでTrueColor対応が終わっている前提のお話。
https://zenn.dev/yushin_hirano/articles/28e7ea8cd11bc1

確認コマンド

  • そもそもterminalが対応しているか?下記コマンドを打ってみる。tmux環境下、環境外の両方で。
echo -e "\e[4:3mTEST"

これでunderlineとして見えたら対応していない。

undercurl表示に対応していれば波線が文字の下に引かれている。

  • neovimが対応しているか?
    適当なファイルを開いてspell checkを有効にしてみよう。
    もしくは、neovimのterminal機能を使って、その環境で上記のechoを打ってみる。
:set spell
  • spell checkに引っかかるとhighlightでctermやguiがundercurlとなっているので、そうであればspell checkに引っかかった箇所が文字の下に波線が引かれる。(highligtを確認しておこう。undercurlになっていればOK)
:hi SpellBad

SpellBad       xxx cterm=undercurl,italic gui=undercurl,italic guifg=#f07178
  • これがunderlineだと、neovimでは対応していないということになる。

  • undercurl対応済みならこのようになる。

tmux環境下でのターミナル対応

  • tmux.confに下記のように記述。(その後tmux.conf再読み込みor再起動)
# undercurl表示対応
set -sa terminal-overrides ',*:Smulx=\E[4::%p1%dm'
  • こうすると、 ターミナル上のecho結果では 上記の確認echoコマンドを使って表示できることが確認できる。
  • この方法はneovimに対しては完全には効かないようだ。 (直接terminfoを見ている?そもそもこのoverridesがどのように適用されているのかも不明だが)

neovimにもundercurl対応する

  • 方法としては、 undercurl対応されているterminfoを使うか、生成し、TERMにセットする。

方法1. alacrittyやwezterm のterminfoを使う

  • 私はターミナルエミュレータとしてalacrittyやweztermを使っているが、どちらもそれぞれのterminfoを生成する手順がある。これをTERMとして使えばundercurlに対応している。

  • 単にお使いのshellのrcファイルなどに、例えばalacrittyなら export TERM=alacritty としてしまうか、あるいはアプリケーション起動時にのみセットすればいい。 TERM=alacritty nvim

  • tmux環境外ならこれでOK。

  • ただ、実行時のみTERMを変えて起動する方法で、tmux環境下のneovimを使うと、: checkhealth の結果で怒られる。

  - INFO: $TERM: alacritty
  - INFO: default-terminal: tmux-256color
  - ERROR: $TERM differs from the tmux `default-terminal` setting. Colors might look wrong.
    - ADVICE:
      - $TERM may have been set by some rc (.bashrc, .zshrc, ...).
  - WARNING: Neither Tc nor RGB capability set. True colors are disabled. |'termguicolors'| won't work properly.
    - ADVICE:
      - Put this in your ~/.tmux.conf and replace XXX by your $TERM outside of tmux:
          set-option -sa terminal-overrides ',XXX:RGB'
      - For older tmux versions use this instead:
          set-option -ga terminal-overrides ',XXX:Tc'
  • まぁ色々言われる。
    tmux.confで設定していたdefault-terminalと$TERMが異なる、など。やはり実行時のみ変えるのも行儀がよろしくないようだ。
    よってtmux.confを下記のように対応し、shellではexport TERM=alaccrittyを打って全てalacrittyにしてみる。
set -g default-terminal "alacritty"
set-option -sa terminal-overrides ',alacritty:RGB'
  • ただ、こうしてterminfoをalacrittyに合わせていくと、それでもtmux環境下でのneovimではcheckhealthでERRORを出してくる。
  - INFO: $TERM: alacritty
  - ERROR: $TERM should be "screen-256color" or "tmux-256color" in tmux. Colors might look wrong.
    - ADVICE:
      - Set default-terminal in ~/.tmux.conf:
          set-option -g default-terminal "screen-256color"
      - https://github.com/neovim/neovim/wiki/FAQ
  • screen-256colorかtmux-256colorを使えということらしい。そうでなければカラーリングに影響が出るかもね、と。
    alacritty, weztermともに使っていた感じでは問題なさそうではあるが、具体的に何の問題があるのかにたどり着けず...

方法2. TERMにtmux-256colorを使いながらundercurl対応する

  • alacrittyやweztermを使っていない場合など。
  • tmux-256colorのterminfoを生成する際に、先程のterminal-overridesの情報を埋め込んでしまうもの。
infocmp tmux-256color > ~/tmux-256color.info

この後、この ~/tmux-256color.info を編集し、 smkx=... となっている行末に、下記を加える。

Smulx=\E[4\:%p1%dm,

その後、従来手順のようにticを打つ

tic -xe tmux-256color ~/tmux-256color.info

こうすることで、tmux + nvimでTERMにtmux-256colorを使いながら、neovimのcheckhealthにも怒られないようになった。

方法1でも現状問題なさそうだが、tmux環境下でTERMにalacrittyやweztermを入れるようにするのが怖い、もしくは両方のterminalを使いたいから(そんな奴おるかい)tmux起動時にどちらかに依存するようなTERMの設定はやめたい、というのであれば方法2がいいかもしれない。

Discussion