Стрілка Shift не працює в emacs в межах tmux


26

Нещодавно я почав використовувати tmux (раніше був користувачем екрана) і люблю його, за винятком однієї невеликої проблеми. Я використовую emacs під час мого сеансу tmux, і я звик використовувати клавіші Shift для переміщення між вікнами emacs (не tmux windows). Під час запуску в межах tmux ці зв'язки, здається, повністю припиняють свою роботу (це схоже, що вони взагалі не реєструються в emacs). Якщо я виходжу з tmux і просто запускаю emacs у своїй оболонці, вони прекрасно працюють.

Я використовую iTerm2, ssh'd у вікно Linux, запускаючи 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, я можу підтвердити, що це правильні послідовності символів для комбінацій клавіш зі стрілкою shift, виконавши Cq в emacs та натиснувши послідовність клавіш. У tmux навіть це не працює, тому що він, здається, не бачить жодного вводу з натискання клавіші shift (він просто сидить у запиті Cq).

Дивлячись на ключові прив’язки для tmux, я не думаю, що нічого не пов’язане з клавішами зі стрілками Shift, і навіть якщо це було, вони реєструватимуться лише після введення префікса (який у моєму випадку пов'язаний з Co).

Будь-яка ідея про те, як змусити клавіші-стрілки знову працювати в межах tmux?


1
Я фактично сам знайшов відповідь на це, але StackExchange не дозволить мені офіційно відповісти на моє власне питання ще протягом 7 годин, оскільки у мене ще недостатньо репутації. У будь-якому разі, якщо когось цікавить, начебто виправлення xterm-клавіш із встановленням вікна начебто це виправить. Я встановив це як глобальний варіант, додавши це до свого .tmux.conf, і я, здається, повернувся до бізнесу: set-window-option -g xterm-keys on
trian_man

Спробуйте проголосувати, щоб закрити питання, якщо ви насправді не можете
Еїр Нім

Відповіді:


13

По-перше, переконайтеся, що ваш УМОВ є правильним у кожному місці:

  • xterm-що (наприклад xterm-256color) всередині вашої локальної оболонки, що працює у вашому вікні iTerm2
  • xterm-що у вашій оболонці після SSHing до системи Linux
    Це має бути таким же, як і все, що ви використовуєте локально в iTerm2 , оскільки SSH повинен передавати його на віддалену сторону (і, що важливо, віддалена сторона не повинна сліпо перекривати значення у файлі ініціалізації оболонки).
  • screen-що (наприклад screen-256color) всередині вашої оболонки, що працює під tmux в системі Linux.
    Ви завжди повинні використовувати screenтермін-базується всередині tmux .

Наявність термінуxterm безпосередньо поза tmux дозволить tmux розпізнавати змінені клавіші зі стрілками, але він не пропустить їх, якщо ви також не xterm-keysувімкнули опцію вікна. Помістіть це у вашій ~/.tmux.confсистемі Linux:

set-window-option -g xterm-keys on

Послідовності зміщених клавіш тепер повинні перейти до Emacs , що працює всередині tmux , через з'єднання SSH, всередині вікна iTerm2 .


Це саме те, що мені потрібно було використовувати textadept в tmux.
Вільям Хілтон

1
Це рішення для мене не спрацювало. Я в Fedora-23 за допомогою gnome-терміналу. Мої терміни та .tmux.conf встановлюються так, як описано у відповіді. Встановлення прив'язок, як описано в запитанні, працює. Я дуже хотів би розгадати цю таємницю, оскільки це також вимикає програму ncurses, над якою я працюю.
gogators

1
@gogators ж тут; вищезазначене рішення не працює для мене, хоча я мав саме те, що було запропоновано.
Фінгольфін

Ctrl + Shift не працює, Ctrl + <f #> не працює тощо. Однак Ctrl + d працює.
AVP

На практиці це означає: export XTERM=xterm-256color(Я пишу це, оскільки я не знав, що означає "ваш ТЕРМІН" у відповіді, я шукав коментар, пояснюючи, що ... його не було, а зараз є.)
jhegedus

3

Спершу потрібно включити xterm-keysв налаштуваннях tmux. Тому покладіть наступне~/.tmux.conf

setw -g xterm-keys on

Але це порушить інші ключові комбінації. Щоб виправити їх, поставте наступне у своєму ~/.emacsабо ~/.emacs.d/init.elconfig

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

Також у мене є рішення у архіві Linux


коментар, залишений @JeffKlukas: "Відповідь косого - це саме те, що мені було потрібно, щоб я також працював через PuTTY в Windows (я не маю репутації додавати це як коментар, тому замість цього відповідаю). Коли я ввімкнув опція xterm-keys в tmux, стрілка Shift створює такий текст, як 2C в emacs. Додаючи вищезгаданий код elisp до свого init.el, я отримую очікувану функціональність (особливо корисну в режимі org). "
slm

1

tmux FAQ використовував такий запис :

Як змусити ctrl та клавіші зі стрілками Shift працювати в emacs?

terminal-init-screenФункція term/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 №1349, щоб подати запит на відновлення для запису FAQ.


0

Взагалі подібні проблеми трапляються через невідповідність між тим, що надсилає термінальний емулятор, і тим, що очікує клієнтська програма.

Різні термінальні емулятори мають різний ступінь налаштування, тому необхідно ознайомитись із перестановкою емуляції конкретного.

Клієнтські програми залежать від того, $TERMяке значення використовується для пошуку можливостей терміналу (емулятора) в базі даних terminfo(або termcap).

У вашому випадку прив'язки до emacs використовують явні послідовності, таким чином $TERMтермінфо не мають значення: очікується конкретний термінальний емулятор - як ви вже з'ясували, - xtermсумісний.


Див. Розділ Виправлення терміналів. Будь ласка, запропонуйте пропозицію щодо стандартизації деяких із цих відмінностей / недоліків у введенні терміналів. Він був піднятий на iterm2-обговоріть, але я не думаю, що ще ніхто його не реалізував.
ефеміент
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.