LoginSignup
7
9

More than 5 years have passed since last update.

俺はzshからxonshに乗り換えるぞ!ジョジョーーッ!

Last updated at Posted at 2017-12-10

zshからxonshに乗り越えるために

基本的にxonshは、source-zshを利用することで、zshの設定をある程度読み込むことができます。
しかし、zshで利用していたzの設定をうまく読み込めなかったので、xonshで書き換えてxonshをメインのshellとして利用することを目指します。

zについて

過去のディレクトリの移動履歴をカウントするものです。
自分はzとpecoを使って、よく移動するディレクトリを選択し、移動するインターフェースを常時利用しており、これがないままのxonshの利用は快適ではありません。

zshでzの結果をpecoって爆速でディレクトリ移動する

z

zは引数なしで実行した時,よく移動するディレクトリ順と,頻度の指標が表示されます

z

参考: https://qiita.com/maxmellon/items/23325c22581e9187639e

zをxonshで読み込んでみる

zの利用は、z.shをshellでsourceすることにより利用できる仕組みになっています。.zshrcでの設定は、下記の感じです。

.zshrc
export _Z_CMD=z
. $(brew --prefix)/etc/profile.d/z.sh

xonshは外部のshellを読み込む機能があるため、xonshでz.shをsourceしてみましたが、うまく動作しないようです。

a.sh
$ source-bash /usr/local/etc/profile.d/z.sh
$ z
xonsh: subprocess mode: command not found: _z
Did you mean one of the following?
    z:   Alias
    xz:  Command (/Users/htaguchi/.pyenv/versions/anaconda3-5.0.1/bin/xz)
    w:   Command (/usr/bin/w)
    [:   Command (/bin/[)
    cd:  Alias
$ _z
xonsh: subprocess mode: command not found: _z
Did you mean one of the following?
    z:   Alias
    xz:  Command (/Users/htaguchi/.pyenv/versions/anaconda3-5.0.1/bin/xz)
    w:   Command (/usr/bin/w)
    [:   Command (/bin/[)
    cd:  Alias

何かうまくsourceする方法がありそうですが、.xonshrcにてzと同等の機能を作成した方が、目的をすぐに達成できそうなので、今回はそちらの手法を試みます。

zの書き換え

zで利用していた機能は、「よく移動するディレクトリ順と,頻度の指標の表示」でした。
そのため、zと同等の機能を得るために

  1. ディレクトリ移動のタイミングで、カレントディレクトリのパスのログを落とす
  2. カレントディレクトリのパスのログから、頻度順にパスを並び替える

の順番で実装を行っていこうと思います。

実装

xonshのチュートリアルを確認すると、関数に@events.on_chdirのデコレータを利用するだけで、ディレクトリ移動をフックできるようなので、これを利用します

参考: http://xon.sh/tutorial_events.html

.xonsh
from collections import Counter
from prompt_toolkit.keys import Keys

$DIR_HIST_PATH = "/Users/htaguchi/.dirhist"

"""
1. ディレクトリの移動タイミングで、カレントディレクトリのパスをファイルに保存
"""
@events.on_chdir
def add_to_file(olddir, newdir, **kw):
    with open($DIR_HIST_PATH[0], 'a') as dh:
        print(newdir, file=dh)

"""
2. パスの出現頻度を算出し、降順に並べる
"""
def z():
    lines = open($DIR_HIST_PATH[0]).read().rstrip("\n").split("\n")
    return("\n".join([p for p, c in Counter(lines).most_common()]))

"""
3. CTRL-F + CTRL-R のキーで関数を呼び出し
"""
@events.on_ptk_create
def custom_keybindings(bindings, **kw):
    handler = bindings.registry.add_binding

    @handler(Keys.ControlF, Keys.ControlR)
    def _z(event):
        selected = $(echo @(z()) | peco)
        cd_cmd = "cd " + selected.strip()
        event.current_buffer.insert_text(cd_cmd)

まとめ

zの設定を乗り越えたので、これでxonshをメインのshellとして利用できそうです。
Pythonの資産を利用したshellの拡張がすぐできるのは、とても良いですね。

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9