カーソルキーが面白いです。

カーソルキーが面白いです。

UbuntuとArchはzshシェルをデフォルトのシェルとして使用します。

私の次の行を使用して、zshシェルで履歴を自動補完するショートカット(上矢印)を設定しました.zshrc

bindkey "^[[A" history-beginning-search-backward

ただし、Ubuntuで.zshrc起動および/または再起動すると、ショートカットは機能しません(入力を開始しても最後のコマンドのみが取得されます)。一方、Archではうまく動作します(最後のコマンドのみを取得します)what)I type)で始まります。

この問題を解決する方法を知っている人はいますか?

答え1

ほとんどのxtermに似た端末では、Up(ほとんどのナビゲーションキーと同様に)端末が入力したかどうかに応じて送信または送信します␛[A␛OAキーボード転送モードかどうか。そして、terminfosmkxエントリは、rmkx端末をこのモードに切り替えるか終了するために使用することができます。

kcuu1(キーカーソル上へ1)terminfoエントリは、次の場合に送信されるUpシーケンスを記述します。キーボード転送モード、すなわち␛OA

Debian とその派生物には、/etc/zsh/zshrc次のことを行うファイルがあります。

function zle-line-init () {
   emulate -L zsh
   printf > /dev/tty '%s' ${terminfo[smkx]}
}

これにより、zleがアクティブになると端末がこのモードに切り替わります。つまり、terminfoデータベースを使用してキーストロークに送信される文字の順序を理解することができます。

この文書も$key連想配列の定義ウィジェットにマッピングするのに役立つterminfoエントリに基づいています。したがって、これらのシステムでは次のことができます。

(($+key[Up])) && bindkey $key[Up] history-beginning-search-backward

端末があるシステムで実行されているジョブの場合キーボード転送パターンとハッシュがほとんどまたはまったくないパターンの場合は、$key次のようにできます。

bindkey $terminfo[kcuu1] history-beginning-search-backward
bindkey ${terminfo[kcuu1]/O/[} history-beginning-search-backward

また見なさい:

答え2

カーソルキーが面白いです。

編集キーほど面白くないけど本物喜び。

あなたは2セットキーボードのカーソルキー、カーソルキーボードそしてそれについて電卓キーボード

ほとんどの端末エミュレータは、各キーセットを個別に使用できるDEC VTモデルを採用しようとします(時には非常に悪い)。申請方法そしてノーマルモードパーソナルモード設定 DECCKM(カーソルキーボードモード)とDECNKM(数字キーボードモード)をそれぞれ使用します。アプリケーションモードの概念は、本質的に、関連キーボードのキーが追加のアプリケーションファンクションキーになるということです。

⇐ カーソルキーボードです。
  • 通常モードでは、矢印キーは修飾子が適用されない限りECMA-48とCUB制御CUFシーケンスを送信しますCUU。この場合、制御シーケンスを送信します。CUD⎇ AltDECFNK
  • アプリケーションモードでは、矢印キーはSS3単一のShift 3シーケンスを送信します。
⇐電卓キーボードです。
  • 通常モードでは、矢印キーは、修飾子が適用されない限り(制御シーケンスを送信する場合)、または数値ロックとShiftの組み合わせによって番号が送信されない限り、ECMA-48 CUBCUFおよび制御シーケンスをCUU送信します。CUD⎇ AltDECFNK
  • アプリケーションモードでは、矢印キーは次を送信します。その他のセット SS3単一のシフト3シーケンス(数値ロックとシフトの組み合わせのために番号が送信されない限り)。

[ AZLEにウィジェットにバインドするように指示するシーケンスは、制御シーケンスのECMA-48 7ビットエイリアス、CSI AつまりCUP(「カーソル上」)制御シーケンスです。この制御シーケンスは、キーボードがノーマルモードで修飾子が無効になっている場合は、⎇ AltDEC VTとそのエミュレータターミナルエミュレータによってのみ生成されます。接続されたキーボードがアプリケーションモードのときに送信されたシフトシーケンスと一致しません。

terminfoデータベースはターミナルI / Oにこのモデルを使用しないため、状況をさらに混乱させ、追加の楽しさを提供します。代わりにそれ自身を使用します。その他「ローカル」および「リモート」キーの概念を実装したモデルで、これは実際にはDEC VTアプリケーション/ノーマルモード切り替えとは無関係であり、最終的に切り替えるローカル/リモート切り替えメカニズムを持っています。両方キーボードはアプリケーション/通常モード間で切り離すことはできません。

terminfo は、DEC VT をエミュレートしない端末や端末エミュレータを使用する場合に備えて、ZLE を構成する特定の端末タイプに直接接続しない方法です。 Zシェルは、データベースレコードから必要な機能項目にアクセスする方法を提供します。したがって、terminfoは上/下/左/右カーソルキーが生成すると予想される制御シーケンスを読み取ることができ、そのbindkey制御シーケンスをウィジェットにマッピングする適切なコマンドを実行できます。

問題は、terminfoが作業に十分ではないということです。録音する方法は1つだけです一つ各キーの制御順序を確認できますが、見てわかるように、少なくとも押したモードと修飾子に応じて、3つの異なるシーケンスが表示されます。 (DEC VTモデルでは、修飾子は送信された制御シーケンスに大きな影響を与える可能性があります。)したがって、端末をterminfoが期待するものを生成するモードに切り替える必要があります。

しかし、状況はさらに悪化します。情報という用語は一貫性がありません。単一の制御シーケンスは、時にはterminfoレコードなどのDEC VTアプリケーションモードシーケンスです。端子puttyタイプ、時にはterminfoレコードなどのDEC VTノーマルモードシーケンス端子rxvtタイプしかし、DECFNK順番ではありません。したがって、特定の端末または端末エミュレータを使用してアプリケーションモードに切り替える必要があるのか​​、通常モードに切り替えるべきかを知る方法はありません。ある人には正しいことが他の人にはそうだ。

したがって、別のアプローチはterminfoを無視し、すでにbindkeyそして、元のコマンドを使用すると、端末が常にDEC VTのように見えると仮定することをお勧めします。端末がアプリケーションモードであるか通常モードであるかを確認するには、次のいずれかが必要で、送信される制御シーケンスが一致します。

バインディングキー「^ [OA」」の履歴が後方に検索され始めます。

ただし、これはCUPコントロールシーケンスに追加のパラメータを追加する押された修飾キーに対処できないため、ZLEが探しているすべてがパラメータのない通常の文字列の場合、ZLEが使用する単純な文字列の一致は失敗しますCUP。可能なすべての修飾子の組み合わせによって生成されたすべての可能な制御シーケンスに対して、追加のbindkeyコマンドを手動で実行する必要があります。CUP

シーケンス1 8 |
-riを読むとき
する
    バインディングキー "^[[1;${i}A"" レコードが後方に検索され始めます。
完璧

ZLEは一人ではありません。他のterminfoベースのプログラム(fishシェルなど)でも同じ問題が発生します。 (fishシェルの人々はまた、ある端末エミュレータの正しいアプリケーション/通常モードの選択が別の端末エミュレータに間違っている可能性があることを発見しました。)これを再構築してください(比較libtermkeyこれらのプログラムが入力用の実際のECMA-48制御シーケンスパーサーを持つようになったのは長い間です。しかし、まだこの問題を解決した人は誰もいません。

追加読書

関連情報