Ink

Contents related to tech, hobby, etc

xmobarでwith_utf8してるのにUTF8出来なかった理由

|

xmobarでwithutf8してるのにUTF8出来なかった理由

LANG の設定を確認して。 bashrc 等で設定していても、xmonadから呼び出される場合は それらは反映されない。

xmobarを呼び出している場所でそのまま設定できる 詳しい方法は以下

xmobarは、ビルド時のフラグ with_utf8 を付けることで UTF-8文字列を扱えるようになる。 そしてこのフラグはデフォルトで True (=有効)なので、特に 何もしなくても使えるはずだった。

が、上手くいかなかった。

試したが上手くいかなかったこと

  • xmobarのビルドフラグの確認

    • archlinuxユーザーなのでPKGBUILDを確認したがフラグは全て有効になっている

  • フォントの確認

    • 普段使いのフォントなので、日本語は対応しているはず

判明した原因

bashからではなくxmonadから起動していた影響で 環境変数が伝搬されておらず、 LANG=ja_JP.UTF-8 でない環境で 実行されていた。

証拠に、ターミナルから srcsh{LANG=C xmobar} と実行してみると 日本語が表示できなくなった。

解決策

XMonad.Hooks.DynamicLogを使用している場合

多分大半がこちらなのではないか...??

とは思うんだけど時間がない&&私やってないので割愛、 xmobar関数の定義を少し弄ってあげた以下のような関数を作れば動くはず。 理由は [[* XMonad.Hooks.StatusBar を使用している場合]] を参照。

xmobar' conf = statusbar "LANG=ja_JP.UTF-8 xmobar" xmobarPP toggleStructsKey conf

XMonad.Hooks.StatusBar を使用している場合

実はこちらの方が新しいらしく、もう DynamicLog は推奨されていないのだそうだ。

知るか!!!!!

と怒鳴ってもしかたないのだけど怒鳴られても仕方ない事情もある。 (それはそれで別で書こう。 )

さて。 StatusBar を使用している場合、 StatusBarConfig 型の 値を使っているはず。 今はみんなここで srchaskell{statusBarProp "xmobar" (pure xmobarPP)} とかしているのではないだろうか。

ここを以下のように書き換えればよい:

statusBarProp "LANG=ja_JP.UTF-8 xmobar" (pure xmobarPP)

そう、 先頭に LANG=ja_JP.UTF-8 を付け加えるだけ である。 かんたん!!

仕組み

実は statusBarProp の中を見てみても分かりづらいのだが、 StatusBarConfig から読み解くとわかる。

StatusBarConfig では、 sbStartUpHook を使って 「ステータスバーを起動する X () アクション」を定義している。

statusBarProp 関数にて引数に取った文字列 ( LANG=ja_JP.UTF-8 xmobar なり xmobar なり)は statusBarPropstatusBarPropTostatusBarGenericspawnStatusBar とそのまま受け渡されていき、

そこからspawnPIDへと渡される。 そしてこの中では executeFileなんと /bin/sh -c の引数として 渡され、最終的に execv システムコールによって実行される。

ここが大事で、 shの上で実行される ことによって環境変数を その場で設定したりといったシェルの機能を使うことができる。