web-dev-qa-db-ja.com

シフトキーがtmux内のemacsで機能しない

最近tmux(以前はスクリーンユーザーでした)を使い始めましたが、1つの小さな問題を除いてそれを気に入っています。私はtmuxセッション内でemacsを使用し、Shift矢印キーを使用して(tmuxウィンドウではなく)emacsウィンドウ間を移動することに慣れています。 tmux内で実行すると、これらのバインディングは完全に機能しなくなったように見えます(まるでemacsに登録されていないようです)。 tmuxを終了してシェルでemacsを実行すると、問題なく動作します。

私はiTerm2を使用し、Linuxボックスにsshして、そこでtmux/emacsを実行しています。 .emacsでShift-矢印キーバインディングを次のように設定しています。

(global-set-key "\M-[1;2A" 'windmove-up)
(global-set-key "\M-[1;2B" 'windmove-down)
(global-set-key "\M-[1;2C" 'windmove-right)
(global-set-key "\M-[1;2D" 'windmove-left)

Tmuxで実行していないときは、emacsでC-qを実行してからキーシーケンスを押すことで、シフト矢印キーの組み合わせに適切な文字シーケンスであることを確認できます。 tmux内では、Shift-矢印キーを押したときの入力が表示されないように見えるため、それでも機能しません(C-qプロンプトに座っているだけです)。

Tmuxのキーバインディングを見ると、Shiftキーと矢印キーにバインドされているものは何もないと思います。そうであったとしても、プレフィックス(私の場合はC-oにバインドされています)を入力した後にのみ登録されます。

シフト矢印キーをtmux内で再び機能させる方法に関するアイデアはありますか?

26
triangle_man

まず、各場所でTERMが正しいことを確認してください:

  • xterm- something(例:xterm-256coloriTerm2ウィンドウで実行されているローカルシェル内
  • xterm- LinuxシステムにSSH接続した後のシェル内の何か
    これはiTerm2でローカルに使用しているものと同じである必要があります。SSHがリモート側にSSHを渡す必要があるためです(重要なことに、リモート側が盲目的にオーバーライドしてはなりません。シェル初期化ファイルの値)。
  • screen- something(例:screen-256color)Linuxシステムでtmuxの下で実行されているシェル内
    tmux内では常にscreenベースのTERMを使用する必要があります。

tmuxのすぐ外側にxterm TERMを指定すると、tmuxが変更された矢印キーを認識できるようになりますが、xterm-keysウィンドウオプションがオンになりました。これを~/.tmux.conf Linuxシステムの場合:

set-window-option -g xterm-keys on

シフトされたキーのシーケンスは、Emacsに到達し、tmux内で、SSH接続を介してiTerm2ウィンドウ内で実行されます。

13
Chris Johnsen

まず、tmux設定でxterm-keysを有効にする必要があります。したがって、以下を~/.tmux.confに入れます

setw -g xterm-keys on

しかし、これは他のキーの組み合わせを壊します。それらを修正するには、以下をyour~/.emacsまたは~/.emacs.d/init.el configに配置します

;; handle tmux's xterm-keys
;; put the following line in your ~/.tmux.conf:
;;   setw -g xterm-keys on
(if (getenv "TMUX")
    (progn
      (let ((x 2) (tkey ""))
    (while (<= x 8)
      ;; shift
      (if (= x 2)
          (setq tkey "S-"))
      ;; alt
      (if (= x 3)
          (setq tkey "M-"))
      ;; alt + shift
      (if (= x 4)
          (setq tkey "M-S-"))
      ;; ctrl
      (if (= x 5)
          (setq tkey "C-"))
      ;; ctrl + shift
      (if (= x 6)
          (setq tkey "C-S-"))
      ;; ctrl + alt
      (if (= x 7)
          (setq tkey "C-M-"))
      ;; ctrl + alt + shift
      (if (= x 8)
          (setq tkey "C-M-S-"))

      ;; arrows
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))
      ;; home
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))
      ;; end
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))
      ;; page up
      (define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))
      ;; page down
      (define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))
      ;; insert
      (define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
      ;; delete
      (define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
      ;; f1
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))
      ;; f2
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))
      ;; f3
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))
      ;; f4
      (define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))
      ;; f5
      (define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))
      ;; f6
      (define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))
      ;; f7
      (define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))
      ;; f8
      (define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))
      ;; f9
      (define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))
      ;; f10
      (define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))
      ;; f11
      (define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))
      ;; f12
      (define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))
      ;; f13
      (define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))
      ;; f14
      (define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))
      ;; f15
      (define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))
      ;; f16
      (define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))
      ;; f17
      (define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))
      ;; f18
      (define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))
      ;; f19
      (define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))
      ;; f20
      (define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))

      (setq x (+ x 1))
      ))
    )
  )      

また、私は archlinux wiki に私の解決策を持っています

4
oblique

tmux FAQ 次のエントリを含めるために使用

EmacsでCtrlキーとShift矢印キーを機能させるにはどうすればよいですか?

terminal-init-screenterm/screen.el関数は、新しいフレームに対して呼び出されますが、ファンクションキーを構成しません。

Tmux xterm-keysオプションがオンの場合、xtermと同じキーを定義するだけで十分です。これを行うには、以下をinit.elまたは.emacsに追加します。

(defadvice terminal-init-screen
  ;; The advice is named `tmux', and is run before `terminal-init-screen' runs.
  (before tmux activate)
  ;; Docstring.  This describes the advice and is made available inside emacs;
  ;; for example when doing C-h f terminal-init-screen RET
  "Apply xterm keymap, allowing use of keys passed through tmux."
  ;; This is the elisp code that is run before `terminal-init-screen'.
  (if (getenv "TMUX")
    (let ((map (copy-keymap xterm-function-map)))
    (set-keymap-parent map (keymap-parent input-decode-map))
    (set-keymap-parent input-decode-map map))))

また、.tmux.confに「set -g xterm-keys on」が含まれていることを確認してください。

または、screen.elファイルをロードパスにコピーしてカスタマイズすることもできます。

Tmux issue#1349 を開いて、FAQエントリの復元をリクエストしました。

1
sorsasampo

一般に、このような問題は、ターミナルエミュレータが送信するものとクライアントアプリケーションが期待するものとの間にミスマッチがあるために発生します。

端末エミュレーターごとにカスタマイズの度合いが異なるため、特定のエミュレーターのエミュレーション調整パラメーターに慣れる必要があります。

クライアントアプリケーションは、terminfo(またはtermcap)データベースで端末(エミュレーター)の機能を検索するために使用される$TERMの値に依存します。

あなたの場合、emacsバインディングは明示的なシーケンスを使用するため、$TERMとterminfoは無関係です。特定の端末エミュレーターが予期されます-すでにわかっているように、xterm互換のエミュレーター。

0
yrk