しばらくfishを使用していましたがここ1年くらいで急にxonshが話題に上がり始めたので興味が出てきました。
ずっとxonshを「エックスオンシェル」って読んでましたが「コンシュ」が正解(?)らしい。
タイトルにfishが入ってますがこの記事にfish成分はほとんどありません。
なぜxonshを使ってみようと思ったか
- fishはPOSIX非互換だし、構文全然覚えられない
- xonshはPythonの構文使えて楽しそう
- Windows(非WSL環境)でも使えそう
理由をいくつか並べて見ましたが、正直話題に上がってるからとりあえず使って見たかったことが一番大きいです。使いやすいなら常用したいと思ってました。
導入
基本的にはpipでインストールできます。
$ pip install xonsh
$ pip install prompt_toolkit
$ pip install Pygments
Pygmentsは入れなくても使用できますが一部のカラーリングがうまくできなくなるので入れた方が良いと思います。
MacOSの場合、Homebrewなどでもインストールできますが、最新バージョン(現時点での最新バージョンは0.8.12)ではないようなので、最新バージョンを使用したい場合はpipでインストールした方がよいです。
$ brew install xonsh
$ xonsh --version
xonsh/0.8.3
.xonshrc
とりあえず必要最小限の設定だと以下な感じ。
これ以外は使用しながら設定を追加していく予定。
$VI_MODE = False # emacsキーバインド派なので
$XONSH_COLOR_STYLE = 'native' # みんな使ってるっぽいカラースタイル
$XONSH_SHOW_TRACEBACK = True # エラー時にトレースを全部吐かせる
使用感
現状MacOSとubuntuに導入して使用してますがかなり使いやすいです。fishとどちらが使いやすいかはもっと使って見ないとわからないので一概には言えませんが、Pythonの構文を使用できるという利点が非常に大きいです。これからどんどん使って行きたいと思います。
Windows環境では正直WSLがあるので非WSL環境で試せてませんが他の方 が書かれているようにGit for Windows上などでは簡単に導入できて使いやすいんじゃないかなと思います。
困っていたこと
導入時に困っていた(ほぼ解決済み)ことをまとめます。
あくまで私が導入時に困っていたことで最新のxonshでは修正されている可能性があります。
内容的にここが本編みたいになってしまった・・・。
xontribを読み込むときにエラーになる
$ xontrib load powerline
/usr/local/lib/python3.7/site-packages/xontrib/powerline.xsh:213: DeprecationWarning: __xonsh_env__ has been deprecated, please use __xonsh__.env instead.
if varname not in __xonsh_env__:
xonsh: For full traceback set: $XONSH_SHOW_TRACEBACK = True
KeyError: 'Unknown environment variable: $0'
どうやら0.8.0からすべての__xonsh_*__
が非推奨になり__xonsh__.*
に置き換わっており、DeprecationWarningが出るようになり、最新バージョンだとそもそもloadもできないみたいです。
新しい仕様に追従できていないxontribが多い様なので該当する場合は、pipでインストール後手動で__xonsh_*__
を__xonsh__.*
に修正するか、修正が入っているリポジトリを見つけてpip install git+https://github.com/foo/bar
でインストールし直してます。
手動で修正する場合、vimだと該当のソースを開いて以下のコマンドを叩けば置換できます。
:%s/__xonsh_/([a-z]*/)__/__xonsh__./1/g
ちなみに私は以下の2つをforkして修正して使用しています。
環境変数LS_COLORS
が設定してあるとxonsh起動時にエラーになる
$ xonsh
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 24001, in main
args = premain(argv)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 23952, in premain
env = start_services(shell_kwargs, args)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 23887, in start_services
cacheall=shell_kwargs.get("cacheall", False),
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 23018, in __init__
load_builtins(execer=self, ctx=xonsh_ctx)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 22589, in load_builtins
builtins.__xonsh__.load(execer=execer, ctx=ctx)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 22665, in load
self.env = Env(default_env())
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 19107, in __init__
self[key] = val
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 19269, in __setitem__
val = ensurer.convert(val)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 18215, in convert
return cls.fromstring(x)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 18178, in fromstring
esc, "default", reversed_style=reversed_default
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 7124, in ansi_color_escape_code_to_name
msg.format(escape_code=escape_code, names=names, name=name, n=n)
ValueError: Could not translate ANSI color code '44;5;235;38;5;33' into a known color in the palette. Specifically, the 'SLOWBLINK_235' portion of '235' in ['BACKGROUND_BLUE', 'SLOWBLINK_', '235', 'SET_FOREGROUND_', '5', 'YELLOW'] seems to missing.
環境変数LS_COLORS
が設定してあるとエラーになる場合があります。
これは現在の最新バージョン(xonsh 0.8.12)では対応しているカラーが無くてエラーになるっぽい。今後修正される模様。
一時的な解決策としては少しめんどくさいですがLS_COLORS
をunsetしてxonshを起動すればいいです。
Bashの場合、以下のようにすればよいです。
$ unset LS_COLORS
$ xonsh
pygmentsを新しくインストールするとxonsh起動時にエラーになる
恐らく、prompt-toolkit2.0
とPygments
をインストールしているとPygmentsのキャッシュファイル(デフォルトだと~/.local/share/pygments-cache/cache.py
) 作成時にエラーになるっぽい。
$ xonsh
pygments cache not found, building...
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 24002, in main
return main_xonsh(args)
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 24031, in main_xonsh
shell.shell.cmdloop()
File "/usr/local/lib/python3.6/dist-packages/xonsh/ptk2/shell.py", line 189, in cmdloop
line = self.singleline(auto_suggest=auto_suggest)
File "/usr/local/lib/python3.6/dist-packages/xonsh/ptk2/shell.py", line 97, in singleline
self.styler.style_name = env.get("XONSH_COLOR_STYLE")
File "/usr/local/lib/python3.6/dist-packages/xonsh/__amalgam__.py", line 17559, in styler
self._styler = XonshStyle(env.get("XONSH_COLOR_STYLE"))
File "/usr/local/lib/python3.6/dist-packages/xonsh/pyghooks.py", line 438, in __init__
self.style_name = style_name
File "/usr/local/lib/python3.6/dist-packages/xonsh/pyghooks.py", line 464, in style_name
self._smap = get_style_by_name(value)().styles.copy()
File "/usr/local/lib/python3.6/dist-packages/xonsh/pygments_cache.py", line 404, in get_style_by_name
load_or_build()
File "/usr/local/lib/python3.6/dist-packages/xonsh/pygments_cache.py", line 302, in load_or_build
CACHE = build_cache()
File "/usr/local/lib/python3.6/dist-packages/xonsh/pygments_cache.py", line 246, in build_cache
cache["lexers"] = _discover_lexers()
File "/usr/local/lib/python3.6/dist-packages/xonsh/pygments_cache.py", line 106, in _discover_lexers
for longname, aliases, filenames, mimetypes in get_all_lexers():
File "/usr/local/lib/python3.6/dist-packages/pygments/lexers/__init__.py", line 53, in get_all_lexers
for lexer in find_plugin_lexers():
File "/usr/local/lib/python3.6/dist-packages/pygments/plugin.py", line 54, in find_plugin_lexers
for entrypoint in iter_entry_points(LEXER_ENTRY_POINT):
File "/usr/local/lib/python3.6/dist-packages/pygments/plugin.py", line 50, in iter_entry_points
return pkg_resources.iter_entry_points(group_name)
TypeError: 'NoneType' object is not callable
現在の最新バージョン(xonsh 0.8.12)では、prompt-toolkit2.0に対応していない部分があるためエラーになっている模様。
この修正はすでにmasterブランチにマージ済みなので、恐らく次のバージョン(0.8.13)には入ってると思われます。
解決策としてはPull requests #3049と同じようにxonsh/ptk2/__init__.py
の内容を削除すれば問題なくxonshが起動するようになります。
私の環境だと以下のファイルの内容を削除すると起動するようになりました。
$ cat /usr/local/lib/python3.6/dist-packages/xonsh/ptk2/__init__.py
# must come before ptk / pygments imports
from xonsh.lazyasd import load_module_in_background
load_module_in_background(
"pkg_resources",
debug="XONSH_DEBUG",
replacements={"pygments.plugin": "pkg_resources"},
)