こちらは、Z.OOL.ネット信託統治領 Qrunch 諸島です。

追記 (2018/11/16)

HEAD 版の tmux のバージョン番号の修正に基づく問題回避の手法の確認に伴い、本稿を加筆及び修正しました。どうか御了承下さい。

追記 (2018/11/18)

本稿について、大幅な加筆及び修正・訂正を行い、以下の通り、 Qiita 半島にて投稿を行いました。

今後の本稿の修正及び訂正等については、 Qiita 半島にて行いますので、どうか御了承下さい。

はじめに

powerline は、 tmux 及び zsh 等の各種コマンドシェルのステータスライン及びプロンプトの表示を装飾するためのソフトウェアです。

powerline を用いることで、 tmux のステータスライン等に、端末の状態等の各種状態等を明瞭に表示させることが出来ます。

しかし、 Github 上における HEAD 版の tmux 上において、 powerline を起動する設定を行うと、 tmux のステータスラインの装飾が全く行われず、 powerline が正常に起動しない問題が発生する場合があります。

この問題は、 powerline を構成するコマンドの一つである powerline-config が、端末上の tmux のバージョンを検出する際に、 tmux コマンドが異常なバージョン番号を返すために powerline-config が異常終了する事が原因であると考えられます。

そこで、 powerlinetmux に関する設定を行うコードにおいて、 tmux のバージョン番号を検出する関数を修正するか、若しくは HEAD 版の tmux のバージョン番号を修正することにより、 Github 上における HEAD 版の tmux 上において、 powerline を正常に動作させることが可能となりました。

問題の概要

まず最初に、 powerline の公式ページを参考に、以下のようにして、 powerline をディレクトリ ${HOME}/.local 以下に導入します。

  $ tar -zxvf powerline-2.7.tar.gz  
  $ pip install --user ./powerline-2.7

そして、 tmux の設定ファイルである ${HOME}/.tmux.conf に以下の設定を追記します。

...  
run-shell "/home/u0_a216/.local/bin/powerline-daemon -q"  
source "/home/u0_a216/.local/lib/python2.7/site-packages/powerline/bindings/tmux/powerline.conf  
...

以上の設定の後、 tmux の再起動を行っても、 tmux のステータスラインはデフォルトの状態で変化が無く、 powerline が正常に動作していないことが判ります。

問題の原因

ここで、 powerline-daemon デーモンが起動している状態で、コマンド powerline-config を以下のように起動すると、以下のようなエラーメッセージを出力して停止することが判ります。

  $ ~/.local/bin/powerline-config tmux setup  
Traceback (most recent call last):  
  File "/home/u0_a216/.local/bin/powerline-config", line 22, in <module>  
    args.function(pl, args)  
  File "/home/u0_a216/.local/lib/python2.7/site-packages/powerline/commands/config.py", line 15, in __call__  
    self.function(*args, **kwargs)  
  File "/home/u0_a216/.local/lib/python2.7/site-packages/powerline/bindings/config.py", line 184, in tmux_setup  
    tmux_version = get_tmux_version(pl)  
  File "/home/u0_a216/.local/lib/python2.7/site-packages/powerline/bindings/tmux/__init__.py", line 84, in get_tmux_version  
    return TmuxVersionInfo(int(major), int(minor), suffix)  
ValueError: invalid literal for int() with base 10: 'next-2'  
  $

上記のエラーメッセージの内容から、 powerline を構成するファイルの一つである ${HOME}/.local/lib/python2.7/site-packages/powerline/bindings/tmux/__init__.py 内の関数である get_tmux_version で異常終了を起こしており、メソッド get_tmux_version の処理内容より、このメソッドは、 tmux のバージョン番号を検出するためのメソッドである事が判ります。

また、端末上の tmux のバージョン番号を表示させるために、 tmux コマンドに -V オプションを付与して実行すると、以下のバージョン番号を出力することが判ります。

  $ tmux -V  
  tmux next-2.9  
  $

ここで、関数 get_tmux_version の内容は以下のようになっています。

...  
def get_tmux_version(pl):  
        version_string = get_tmux_output(pl, '-V')  
        _, version_string = version_string.split(' ')  
        version_string = version_string.strip()  
        if version_string == 'master':  
            return TmuxVersionInfo(float('inf'), 0, version_string)  
        major, minor = version_string.split('.')  
        suffix = DIGITS.subn('', minor)[0] or None  
        minor = NON_DIGITS.subn('', minor)[0]  
        return TmuxVersionInfo(int(major), int(minor), suffix)

上記の関数 get_tmux_version の処理内容より、 tmux のバージョン番号として、 2.6 や 2.7 等の安定版のバージョン番号もしくは、 git のリポジトリからビルドされたことを示す “master” 以外の文字列が出力される場合は、関数 get_tmux_version は例外を発生し、 powerline-config コマンドが異常終了する事が判りました。

以上で述べた不具合が、 Github 上における HEAD 版の tmux 上において、 powerline が正常に動作しない原因であると考えられます。

問題の回避

以上で述べた原因を踏まえて、前述した Github 上における HEAD 版の tmux 上において、 powerline が正常に動作しない問題を回避するには、以下の2通りの手法を用いれば良いことが判ります。

  • powerline を構成するファイル ${HOME}/.local/lib/python2.7/site-packages/powerline/bindings/tmux/__init__.py 内の関数 get_tmux_version において、 tmux のバージョン番号が安定版のバージョンを返さない場合は、 git のリポジトリからのビルド版を始めとした HEAD 版の tmux として扱うように、関数 get_tmux_version を修正する。
  • HEAD 版の tmux のコマンド tmux にオプション -V を付与して起動すると、 tmux master を出力結果として返すように、 tmux のソースコードを修正する。

以下に、それぞれの問題回避手法について述べます。

powerline の修正による問題回避

まず、 powerline の修正に基づいて前述した問題を回避するには、 powerline のソースコードに、以下に示す差分ファイルを適用すれば良い事が判ります。

diff --git a/powerline/bindings/tmux/__init__.py b/powerline/bindings/tmux/__init__.py  
index 011cd689..26cc7dfd 100644  
--- a/powerline/bindings/tmux/__init__.py  
+++ b/powerline/bindings/tmux/__init__.py  
@@ -78,7 +78,11 @@ def get_tmux_version(pl):  
     version_string = version_string.strip()  
     if version_string == 'master':  
         return TmuxVersionInfo(float('inf'), 0, version_string)  
-    major, minor = version_string.split('.')  
-    suffix = DIGITS.subn('', minor)[0] or None  
-    minor = NON_DIGITS.subn('', minor)[0]  
-    return TmuxVersionInfo(int(major), int(minor), suffix)  
+    try:  
+        major, minor = version_string.split('.')  
+        suffix = DIGITS.subn('', minor)[0] or None  
+        minor = NON_DIGITS.subn('', minor)[0]  
+        return TmuxVersionInfo(int(major), int(minor), suffix)  
+    except:  
+        # If version_string == "next-2.9", and etc., then version of tmux is 'master'.  
+        return TmuxVersionInfo(float('inf'), 0, version_string)

上記の差分ファイルを適用した後、 powerline の再インストールを行い、 tmux の再起動を行った所、正常に powerline が動作したことを確認しました。

tmux の修正による問題回避

まず、 HEAD 版の tmux における tmux -V コマンドの出力結果を修正するには、 HEAD 版の tmux におけるバージョン番号を修正する必要があり、このバージョン番号は、ソースコードのファイル confifgure.acAC_INIT マクロに示されていることが判ります。

# configure.ac  

AC_INIT([tmux], next-2.9)  # ここでは、バージョン番号が "next-2.9" に設定されている  
AC_PREREQ([2.60])  
...

そこで、以下の通りに、ファイル configure.acAC_INIT マクロが書かれている行を修正します。

# configure.ac  

AC_INIT([tmux], master)  # next-2.9 → master に修正。  
AC_PREREQ([2.60])  
...

ファイル configure.ac を修正した後は、以下に示す手順で、 configure スクリプトを生成し、 ./configure スクリプトの実行と tmux のビルド及びインストールを行います。

  $ sh ./autogen.sh  
  $ ./configure  
  $ make  
  $ make install

以上の tmux のインストールが完了した後は、以下のようにして、コマンド tmux -V を実行して出力結果を確認します。

  $ tmux -V  
  tmux master  
  $

上記の修正を行った後、 tmux の再起動を行った所、正常に powerline が動作したことを確認しました。

この記事へのコメント

まだコメントはありません