チュートリアル:prompt_toolkitカスタムキーバインド

あなたは本当にいくつかの特殊なキーバインドのためにジーンズしていますか?私たちはあなたを助けることができます。最初の時間は無料であり、これは毎回です!

警告

このチュートリアルでは、prompt_toolkitキーバインドマネージャーに直接フックさせることができます プロンプトを完全に使用できないようにすることを止めるものではないので、軽く踏み込んでください。

概要

prompt_toolkitシェルは、カスタムキーバインドを処理するためのレジストリを持っています。xonshのデフォルトのキーバインディングが気に入らないか、新しいキーバインディングを追加することができます。

prompt_toolkitキーバインディングを定義し、潜在的な落とし穴について警告するツールを使用してこれを行う方法を説明します

以下のすべてのコードをxonshrcに入力することができます

制御文字

私たちはあなたが望むことをすることはできませんし、止めることもできませんが、機能するシェルのために、おそらく以下のキーストロークを混乱させるべきではありません。それらのうちのいくつかはASCII制御文字であり、_really_は使用すべきではありません。他のものはxonshによって使用され、機能の一部が失われます(他の場所で再バインドする時間が少なくて済みます)。

キーストローク ASCIIコントロール表現 デフォルトコマンド
Control J <Enter> コマンドを実行する
Control I <Tab> インデント、オートコンプリート
Control R   後方履歴検索
Control Z   現在のジョブのSIGSTOP
Control C   現在のジョブのSIGINT

便利なインポート

prompt_toolkitより良いバインディングを作成するのに役立つツールがいくつかあります:

from prompt_toolkit.keys import Keys
from prompt_toolkit.filters import Condition, EmacsInsertMode, ViInsertMode

カスタムキーロード機能

シェルを初期化した後にロードするために追加のキーバインドが必要なので、すべてのカスタムキーバインディングを含む関数を定義し、適切なイベントでこの場合は装飾しon_ptk_createます。handlerバージョンの違いによって方法が異なりますのでご注意くださいprompt_toolkit

まず、プロンプトの現在の行に "hi"という文字列を挿入するというおもちゃの例から始めます。

@events.on_ptk_create
def custom_keybindings(bindings, **kw):
    # prompt_toolkit 1.x
    # handler = bindings.registry.add_binding
    # prompt_toolkit 2.x
    handler = bindings.add

    @handler(Keys.ControlW)
    def say_hi(event):
        event.current_buffer.insert_text('hi')

あなたのxonshrcに入れて、xonshを再起動してからCtrl-w何かが押されたかどうか確認してください(それはすべきです!)

注意

prompt_toolkit 2.xから書くことも可能であるKeys.ControlWようにc-w

キーバインドはどのようなコマンドで実行できますか?

かなり何でも!xonshの起動後にこれらのコマンドを定義するので、ほとんど何の努力もせずにサブプロセスコマンドを実行するキーバインドイベントを作成することができます。たとえば、カレントディレクトリで実行れるコマンドがあるとしますls -l

@handler(Keys.ControlP)
def run_ls(event):
    ls -l
    event.cli.renderer.erase()

注意

event.cli.renderer.erase()に情報を送信するために、別のコマンドを求めた後、プロンプトを再描画するために必要とされますSTDOUT

フィルターでアクションを制限する

特定の条件が満たされている場合にのみ、重要なコマンドを実行することがしばしば必要です。たとえば<TAB>、xonsh キーは補完メニューを表示しますが、利用可能な補完も循環します。フィルタを使用してこの動作を作成します。

それぞれの挿入モードがアクティブなときに戻ってくるprompt_toolkitようなViInsertMode、およびのような いくつかの有益なフィルタが含まれていますEmacsInsertModeTrue

しかし、xonshの美しい奇妙さを利用する独自のフィルタを作成することも簡単です。特定のディレクトリに10個未満のファイルがある場合にのみ、指定されたコマンドを実行するようにフィルタを制限するとします。その要件に合致するBoolを返す関数が必要なだけで、それを飾っています!これらの関数は純粋なPythonだけではなく、xonsh言語でも使えることを覚えておいてください。

@Condition
def lt_ten_files(cli):
    return len(g`*`) < 10

注意

より多くのグロブオプションについては、グローブに関するチュートリアルのセクションを参照してください

条件が定義されたので、これをfilterキーワードとしてキーバインディング定義に渡すことができます。

@handler(Keys.ControlL, filter=lt_ten_files)
def ls_if_lt_ten(event):
    ls -l
    event.cli.renderer.erase()

あなたのそれらの両方で.xonshrc、押すと、その中に10未満の項目がある場合は、あなたの現在のディレクトリの内容を一覧表示します。有用?議論の余地がある。強力ですか?はい。Control L