Shift-panah tidak bekerja di emacs dalam tmux

26

Saya baru-baru mulai menggunakan tmux (adalah pengguna layar sebelumnya) dan saya menyukainya, kecuali untuk satu masalah kecil. Saya menggunakan emacs dalam sesi tmux saya dan saya terbiasa menggunakan tombol Shift-panah untuk berpindah di antara windows emacs (bukan windows tmux). Ketika menjalankan dalam tmux, binding ini tampaknya berhenti bekerja sepenuhnya (seperti mereka tidak mendaftar ke emacs sama sekali). Jika saya keluar dari tmux dan menjalankan emacs di shell saya, mereka bekerja dengan baik.

Saya menggunakan iTerm2, ssh'd ke dalam kotak Linux, menjalankan tmux / emacs di sana. Saya memiliki binding kunci panah-diatur sebagai berikut di .emacs saya:

(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)

Ketika tidak berjalan di tmux, saya dapat mengonfirmasi bahwa itu adalah urutan karakter yang tepat untuk kombinasi tombol shift-panah dengan melakukan Cq di emacs dan kemudian menekan urutan tombol. Di dalam tmux, bahkan itu tidak berfungsi karena sepertinya tidak melihat input dari penekanan tombol shift-panah (itu hanya duduk di prompt Cq).

Melihat binding kunci untuk tmux, saya tidak berpikir ada yang terikat dengan tombol Shift-panah dan bahkan jika itu, mereka hanya akan mendaftar setelah memasukkan awalan (yang terikat ke Co dalam kasus saya).

Adakah ide tentang cara membuat tombol shift-panah berfungsi kembali dalam tmux?

Triangle_man
sumber
1
Saya sebenarnya menemukan jawabannya sendiri tetapi StackExchange tidak akan membiarkan saya secara resmi menjawab pertanyaan saya sendiri selama 7 jam karena saya belum memiliki reputasi yang cukup. Pokoknya kalau ada yang tertarik, melakukan set-window-option xterm-keys pada tampaknya memperbaikinya. Saya menetapkan ini sebagai opsi global dengan meletakkannya di .tmux.conf saya dan sepertinya saya akan kembali ke bisnis: set-window-option -g xterm-keys aktif
triangle_man
Cobalah untuk memilih untuk menutup pertanyaan jika Anda benar-benar tidak bisa
Eir Nym

Jawaban:

13

Pertama, pastikan TERM Anda benar di setiap lokasi:

  • xterm-sesuatu (misalnya xterm-256color) di dalam shell lokal Anda berjalan di jendela iTerm2 Anda
  • xterm-sesuatu di dalam shell Anda setelah SSHing ke sistem Linux
    Ini harus sama dengan apa pun yang Anda gunakan secara lokal di iTerm2 , karena SSH harus meneruskannya ke sisi remote (dan, yang penting, sisi remote tidak boleh secara membabi buta menimpa nilai dalam file inisialisasi shell).
  • screen-sesuatu (misalnya screen-256color) di dalam shell Anda berjalan di bawah tmux pada sistem Linux
    Anda harus selalu menggunakan screenTERM di dalam tmux .

Memiliki xtermTERM segera di luar tmux akan memungkinkan tmux mengenali tombol panah yang dimodifikasi, tetapi itu tidak akan melewatinya kecuali Anda juga xterm-keysmengaktifkan opsi jendelanya. Masukkan ini di ~/.tmux.confsistem Linux Anda:

set-window-option -g xterm-keys on

Urutan untuk tombol yang bergeser sekarang harus melalui Emacs , berjalan di dalam tmux , melintasi koneksi SSH, di dalam jendela iTerm2 .

Chris Johnsen
sumber
Inilah yang saya butuhkan untuk menggunakan textadept di tmux.
William Hilton
1
Solusi ini tidak berhasil untuk saya. Saya menggunakan Fedora-23 menggunakan terminal gnome. JANGKA dan .tmux.conf saya diatur sebagaimana dijelaskan dalam jawaban. Namun, pengaturan binding seperti yang dijelaskan dalam pertanyaan tidak berhasil. Saya benar-benar ingin menyelesaikan misteri ini karena ini juga membuat aplikasi ncurses yang sedang saya kerjakan.
gogators
1
@ gogator sama di sini; solusi di atas tidak bekerja untuk saya walaupun saya memiliki apa yang disarankan.
Fingolfin
Ctrl + Shift tidak berfungsi, Ctrl + <f #> tidak bekerja dan sebagainya. Ctrl + d tidak bekerja.
avp
Dalam praktiknya ini berarti: export XTERM=xterm-256color(Saya menulis ini karena saya tidak tahu apa artinya "JANGKA ANDA" dalam jawaban, saya mencari komentar yang menjelaskan bahwa ... tidak ada, dan sekarang ada.)
jhegedus
3

Pertama, Anda harus mengaktifkan xterm-keyskonfigurasi tmux Anda. Jadi masukkan berikut ini~/.tmux.conf

setw -g xterm-keys on

Tapi, ini akan memecah kombinasi kunci lainnya. Untuk memperbaikinya, masukkan berikut ini di ~/.emacsatau ~/.emacs.d/init.elkonfigurasi Anda

;; 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))
      ))
    )
  )      

Saya juga punya solusi di archlinux wiki

miring
sumber
komentar yang ditinggalkan oleh @JeffKlukas: "jawaban miring adalah hanya apa yang saya butuhkan untuk mendapatkan ini bekerja melalui Putty pada Windows juga (saya tidak memiliki reputasi untuk menambahkan ini sebagai komentar, jadi membuat jawaban sebagai gantinya). Ketika saya menghidupkan opsi xterm-keys di tmux, Shift-panah akan menghasilkan teks seperti 2C di emacs. Dengan menambahkan kode elisp di atas ke init.el saya, saya mendapatkan fungsionalitas yang diharapkan (terutama berguna dalam mode org). "
slm
1

tmux FAQ digunakan untuk memuat entri berikut :

Bagaimana cara membuat tombol panah ctrl dan shift bekerja di emacs?

Itu terminal-init-screen fungsi dalam term/screen.eldisebut untuk frame baru, tetapi tidak mengkonfigurasi tombol fungsi apapun.

Jika xterm-keysopsi tmux aktif, cukup untuk mendefinisikan kunci yang sama dengan xterm. Tambahkan yang berikut ke init.elatau .emacsuntuk melakukan ini:

(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))))

Dan pastikan .tmux.confberisi "set -g xterm-keys on ".

Atau, screen.elfile dapat disalin ke jalur pemuatan dan disesuaikan.

Saya membuka masalah tmux # 1349 untuk meminta pengembalian untuk entri FAQ.

sorsasampo
sumber
0

Secara umum, masalah seperti ini terjadi karena ketidakcocokan antara apa yang dikirim terminal emulator dan apa yang diharapkan oleh aplikasi klien.

Emulator terminal yang berbeda memiliki tingkat kemampuan penyesuaian yang berbeda, jadi membiasakan diri dengan tunable emulasi dari yang khusus diperlukan.

Aplikasi klien bergantung pada nilai $TERMyang digunakan untuk mencari kemampuan terminal (emulator) dalam terminfo(atau termcap) basis data.

Dalam kasus Anda, binding emacs Anda menggunakan urutan eksplisit sehingga $TERMdan terminfo tidak relevan: emulator terminal spesifik diharapkan - seperti yang sudah Anda xtermketahui , yang kompatibel satu.

yrk
sumber
Lihat Memperbaiki Terminal - Mohon proposal untuk menstandarkan beberapa perbedaan / kekurangan ini dalam input terminal. Sudah diangkat pada iterm2-mendiskusikan tapi saya tidak berpikir ada yang mengimplementasikannya.
ephemient