C- [を実際にバインドする方法は?


10

C-[これは、米国英語キーボードのエスケープキーに相当します。したがって、バインドしようとすると、M-動作が台無しになります。

EmacsはGUIフレーム<escape>C-[区別するのに問題がないようです。以下は正常に動作し、バインディングはM-引き続き機能します。

(global-set-key (kbd "<escape>") (lambda () (interactive) (message "<escape>")))

しかし、私がバインドした場合

(global-set-key (kbd "C-[") (lambda () (interactive) (message "C-[")))

突然、emacsがクレイジーになり、M-xブレークのように拘束されます。さらに、押すとC-[バインドされたラムダのトリガーが拒否されます。興味深いことに、C-x @ c [(修飾子コントロールを開き角かっこに適用して)まだ言いC-[ is undefinedます。

C-[emacsを壊さずに何かをバインドする方法はありますか?

回答:


7

C-[場合のように、ユーザーレベルのマップで実際にバインディングを変更することはできませんglobal-set-key。ただし、キーマップに到達する前に、キーボードイベントとして変更することができます。たとえば、次のように言うことができます。

(define-key input-decode-map 
    (kbd "C-[") 
    [control-bracketleft])

[control-bracketleft]キーマップで使用します。とても簡単ですね。

ディレクターズカット

残念ながら、それはそれほど単純ではなく、この解決策はいくつかの調整を必要とし、それは非常に苦痛であるように見えます。あなたは警告されました。しかし、まずユーザーレベルのマップが質問に答えられない理由を見てみましょう。以下では、より正確に「何かを見る」と言ったときに、emacs 26.1のEmacs Lispマニュアルを参照します。

C-[非常に早い段階でASCII制御文字として解釈されますESC(21.7.1- キーボードイベントを参照)。このコードは、より長いシーケンスの接頭辞として他のすべての場所に広がっています。これには理由があります。ESC実際にはメタプレフィックス(を参照meta-prefix-char)であり、M-何かを読み取るすべてのバインディングは、 で始まるシーケンスに変換されESCます。したがって、グローバルマップを変更するだけでは十分ではありません。最初にを変更しmeta-prefix-char、次に、を安全にマップする前に、を使用するすべてのマップでESC新しいマップに再マップする必要があります。meta-prefix-charM-C-[

それではもちろん、OKを使いましょうinput-decode-map。使いたくなるかもしれない同様のマップがいくつかありますが(セクション21.8.3と22.14を参照)、これに固執しましょう。そして、これはうまくいきます!完了しましたね。

実際、いいえ、話はここで終わりません。これは動作します...ウィンドウシステムを使用している限り。不運のために緊急状態でLinuxコンソールに投獄されている場合、状況が劇的になっていることに気づきます。矢印キー、、HomeそしてもちろんM-バインディングはすべてゴミです。どうして?端末が言うときESC(それはタイプするときにそれを行うC-[)、それは本当に意味し ESC、非ASCII文字の送信に使用するのと同じ種類のシーケンスを開始します。

災害を観察しinput-decode-map、ウィンドウシステムがキーボードを制御している場合にのみアクティブになるように、上記の変更を保護することをお勧めします。

(let ((frame (framep (selected-frame))))
  (or (eq  t  frame)
      (eq 'pc frame)

      (define-key input-decode-map 
                  (kbd "C-[") 
                  [control-bracketleft])
     )))

その後、端末は以前と同じように動作します。

さて、C-[端末で対応できますか?実際、そうです、Linuxコンソールや、他のターミナルエミュレータで遊ぶことができます。ただし、新しいキャラクターが登場するため、ストーリーはかなり長くなります。なぜなら、これはもはや単独のemacsではなく、端末が中心的な役割を果たしているからです。

Linuxコンソールの発言に耳を傾けましょう。C-v何かのキーの前にタイプすると、分かりやすくなります。C-[ですESC。そうですEsc。上矢印はのようESC [ Aに聞こえますが、M-aです ESC A。うーん... emacsのこのメタキーの循環のようですね。とにかく。

キャラクターイベント間の経過時間に基づいていくつかのトリックをプレイする準備ができていない限り(これはとは区別さEscれません C-[)、コンソールに実際に意味しないことを伝えるしかないようです。ESC入力したときC-[。さらに、それはかなりすぐにそれが標準のC-[端末コードの唯一の問題ではないように見えます:修飾子はほとんどの場合、送信された情報を消去します。emacsをカスタマイズするのと同じ理由でターミナルをカスタマイズする必要があります。そうすれば、はるかに実用的です。

この時点で、ターミナルのドキュメンテーションの目を詳細に確認する必要がありますloadkeys(1)。Linuxコンソールのマニュアルページ、「カスタムキーバインディングxterm(1)セクションのxterm 、および他のターミナルのwhat-i-dont-knowです。あなたがでカスタム変換を定義することができます...設定/編集現在のプロフィール そしてキーボード。以下は、 この後者のダイアログで遊んだ後の抜粋です。KDE konsole~/.local/share/konsole/Test.keytab

key [+Ctrl+AnyModifier : "\EO*["

(上記の構成のように)ターミナルが送信さESC O 5 [C-[たら、emacsに戻ることができます。もちろん、あなたはまだ終わっていません。

特定の端末が使用する方言をemacsに指示するには、を調整しinput-decode-mapます。はい、これは偶然にも、このストーリーの冒頭で変更したものであり、 term/xterm.elxtermが関係するときに触れるものです。調整に適した場所は次のtty-setup-hookとおりです(セクション40.1.3を参照)。

(add-hook 'tty-setup-hook 
   (lambda ()
    (let ((term (getenv "TERM")))
      (cond 
        (;; xterm-function-map not in doc, but in term/xterm.el
         (boundp 'xterm-function-map) 
         (map-my-term-codes xterm-function-map))

        ((equal term "linux")
         (map-my-term-codes input-decode-map))
        )
      )))

このフックは、ターミナルにいる場合にのみ実行されることに注意してください。したがって、ウィンドウシステムの初期化用のコードをここに挿入することはできません。ここにそれ自身の翻訳機能があります:

(defun map-my-term-codes (map)
      (define-key map (kbd "M-O 5 [") 
                      [control-bracketleft])
      )

そして、あなたは少し休むことができます:それは旅の終わりです。もちろん、端末を気にしないのであれば、苦痛な部分をすべてスキップするので、迅速です。しかし、それもかなり不完全であることを認めます。

2つの最後のメモ:

  • ESC O 5 [はコーディングすることを選択しますC-[。これはほんの一例です。私はそれが良い選択であるとは思わないでしょう。5 という意味の部分だけが、C-何らかの確立された慣習に従っているようです

  • Linuxコンソールを構成すると、味が悪くなります。中間の既存のシンボルを使用せずにバインドを実行することは不可能に思われ、必要 なものは存在しません。ほとんどのインターネットの例のように、F21-のF246範囲で記号を使用しますが、満足のいくものではありません。いくつかの無関係なバインディングには問題ありませんが、体系的なスキーマには役立ちません。

編集する

  • Esc独自の個性を持つケースでこれを完了しました-別の投稿:ESCプレフィックスキーへのバインディングを削除する方法
  • これは、フィードする構成のフラグメントですloadkeys。これを/root/custom.kmapに入れ、必要なときにロードします(これはまれです)。実際の設定では、矢印と修飾子のさまざまな組み合わせもマッピングしていますが、かなり長く、記号とシーケンスの選択には疑問があり、キーボードのキーコードがあなたのキーコードと一致するかどうかはわかりません。したがって、それを適切なレベルに保ちましょう。これは単なる実例です。

    keymaps 0-127
    
    # http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
    # web+man:keymaps
    # web+man:loadkeys
    
    # escape
    keycode  1  = F100
        alt keycode  1 = Escape # keep the Escape behavior somewhere          
    
    # keycode  26 = bracketleft
        control keycode 26 = F115 # Control_bracketleft does not exist          
    
    string F100     = "\033OO" # map this to [escape] in map-my-term-codes
    string F115     = "\033O5["
    

1
ありがとう、それは素晴らしい答えです。しかし、確かにこのような素晴らしい答えであっても、最初のページの上部に34回ぶつける必要はありません。各バンプには、コミュニティによって共有される小さなコストがあります:スパムのチェック、新しい興味深いコンテンツがあるかどうかの確認など。または、あなたが持っているものに固執してください。経験から言えば、完璧な投稿というものはありません。ある時点で先に進む必要があります。
Gilles 'SO-悪をやめる'

@ギレス了解しました。ごめんなさい。これを思いのままに調整するのに問題があることは知りませんでした。
シャンピニャック

0

次の解決策は少し不器用ですが、うまくいくようです:

~/.xbindkeysrc以下を含めましょう:

"xvkbd -xsendevent -text '\[Control_L]\[F13]'"
  m:0x14 + c:34

"xvkbd -xsendevent -text '\[Control_L]\[F14]'"
  m:0x14 + c:35

xbindkeys翻訳するC-[C-<f13>してC-]までC-<f14>、彼らは自由のemacsにバインドすることができますので、。たとえば、abort-recursive-edit以外のものにバインドする必要があるでしょう。C-]C-S-g

欠点は、C-[Emacsを除くすべてのアプリケーションで問題が発生することです。これは、キーの組み合わせがemacsに送信されているかどうかをテストするロジックを追加することで修正できます...


FWIW、私は何か特別なことはないと思いますC-]
マラバルバ2015年

ええ、私もそうではありませんが、奇妙な理由で、C-]Xbindkeysを起動した後、バインディングが機能しなくなったため、Xbindkeysもリバウンドしました。
クリストフMarussy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.