Shift-стрелка не работает в emacs в tmux

26

Я недавно начал использовать tmux (раньше был пользователем экрана), и мне это нравится, за исключением одной маленькой проблемы. Я использую emacs в своей сессии tmux, и я привык использовать клавиши со стрелками Shift для перемещения между окнами emacs (не окнами tmux). При запуске в tmux эти привязки перестают работать полностью (похоже, что они вообще не регистрируются в emacs). Если я выхожу из tmux и просто запускаю emacs в моей оболочке, они работают нормально.

Я использую iTerm2, ssh'd в Linux, запускаю там tmux / emacs. У меня есть привязки клавиш Shift-стрелка, настроенные следующим образом в моем .emacs:

(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 в моем случае).

Любая идея о том, как заставить клавиши shift-стрелки снова работать в tmux?

triangle_man
источник
1
Я на самом деле нашел ответ на этот вопрос сам, но StackExchange не позволит мне официально ответить на мой собственный вопрос в течение еще 7 часов, так как у меня пока недостаточно репутации. В любом случае, если кому-то это интересно, выполнение команды set-window-option xterm-keys для этого, кажется, исправит это. Я установил это как глобальную опцию, поместив это в свой .tmux.conf, и я, похоже, вернулся к делу: set-window-option -g xterm-keys on
triangle_man
Попробуйте проголосовать, чтобы закрыть вопрос, если вы действительно не можете
Eir Nym

Ответы:

13

Во-первых, убедитесь, что ваш СРОК правильный в каждом месте:

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

Наличие xtermTERM непосредственно вне tmux позволит tmux распознавать измененные клавиши со стрелками, но не пропустит их, если у вас не xterm-keysвключена опция окна. Поместите это в свою ~/.tmux.confсистему Linux:

set-window-option -g xterm-keys on

Последовательности для сдвинутых ключей теперь должны пройти к Emacs , работающему внутри tmux , через SSH-соединение, внутри окна iTerm2 .

Крис Джонсен
источник
Это именно то, что мне нужно было использовать textadept в tmux.
Уильям Хилтон
1
Это решение не сработало для меня. Я на Fedora-23 использую гном-терминал. Мои TERM и .tmux.conf установлены так, как описано в ответе. Установка привязок, как описано в вопросе, работает, однако. Мне бы очень хотелось разгадать эту загадку, поскольку она также портит приложение ncurses, над которым я работаю.
гогаторы
1
@gogators то же самое здесь; вышеупомянутое решение не работает для меня, хотя у меня было именно то, что было предложено.
Фингольфин
Ctrl + Shift не работает, Ctrl + <f #> не работает и так далее. Ctrl + D работает, хотя.
августа
На практике это означает: export XTERM=xterm-256color(я пишу это, потому что я не знал, что означает «ваш СРОК» в ответе, я искал комментарий, объясняющий, что ... его не было, а теперь есть).
jhegedus
3

Сначала вы должны включить его xterm-keysв конфигурации Tmux. Так что вставьте следующее в~/.tmux.conf

setw -g xterm-keys on

Но это сломает другие комбинации клавиш. Чтобы исправить их, поместите следующее в ваш ~/.emacsили ~/.emacs.d/init.elконфиг

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

косой
источник
Комментарий оставлен @JeffKlukas: «Ответ oblique - это то, что мне нужно, чтобы заставить эту работу работать и через PuTTY в Windows (у меня нет репутации, чтобы добавить это как комментарий, поэтому я делаю ответ вместо этого). Когда я включил Опция xterm-keys в tmux, Shift-arrow будет генерировать текст, похожий на 2C, в emacs. Добавив приведенный выше код elisp в мой init.el, я получу ожидаемую функциональность (особенно полезно в режиме org). "
SLM
1

tmux FAQ раньше содержал следующую запись :

Как заставить клавиши ctrl и shift работать в emacs?

terminal-init-screenФункция term/screen.elвызывается для новых кадров, но не настраивайте функциональные клавиши.

Если xterm-keysопция tmux включена , достаточно определить те же ключи, что и для 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.

sorsasampo
источник
0

В общем случае подобные проблемы возникают из-за несоответствия между тем, что посылает эмулятор терминала, и тем, что ожидает клиентское приложение.

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

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

В вашем случае ваши emacs-привязки используют явные последовательности, поэтому $TERMterminfo не имеет значения: ожидается определенный эмулятор терминала - как вы уже выяснили, - xterm-совместимый.

yrk
источник
См. Fix Terminals - Пожалуйста, для предложения стандартизировать некоторые из этих различий / недостатков в вводе терминала. Он был поднят на iterm2-обсудить, но я не думаю, что кто-то еще реализовал это.
Эфимент