Shift-arrow ne fonctionne pas dans emacs dans tmux


26

J'ai récemment commencé à utiliser tmux (était un utilisateur d'écran auparavant) et je l'adore, sauf pour un petit problème. J'utilise emacs au sein de ma session tmux et j'ai l'habitude d'utiliser les touches fléchées pour se déplacer entre les fenêtres emacs (pas les fenêtres tmux). Lors de l'exécution dans tmux, ces liaisons semblent cesser de fonctionner complètement (c'est comme si elles ne s'enregistraient pas du tout sur emacs). Si je quitte tmux et que je lance juste emacs dans mon shell, ils fonctionnent très bien.

J'utilise iTerm2, ssh'd dans une boîte Linux, y exécutant tmux / emacs. J'ai les liaisons de touches Maj-flèche configurées comme suit dans mes .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)

Quand il n'est pas exécuté dans tmux, je peux confirmer que ce sont les bonnes séquences de caractères pour les combinaisons de touches Maj-Flèche en faisant Cq dans emacs puis en appuyant sur la séquence de touches. Dans tmux, même cela ne fonctionne pas car il ne semble pas voir d'entrée de la touche Maj + flèche (il se trouve juste à l'invite Cq).

En regardant les raccourcis clavier pour tmux, je ne pense pas que quelque chose soit lié aux touches Shift-arrow et même si c'était le cas, ils ne s'enregistreraient qu'après avoir entré le préfixe (qui est lié à Co dans mon cas).

Une idée sur la façon de faire fonctionner à nouveau les touches fléchées avec tmux?


1
J'ai trouvé la réponse moi-même, mais StackExchange ne me laissera pas officiellement répondre à ma propre question pendant encore 7 heures car je n'ai pas encore assez de réputation. Quoi qu'il en soit, si quelqu'un est intéressé, le fait de faire set-window-option xterm-keys sur semble le corriger. J'ai défini cela comme une option globale en le mettant dans mon .tmux.conf et je semble être de retour dans les affaires: set-window-option -g xterm-keys on
triangle_man

Essayez de voter pour fermer la question si vous ne pouvez vraiment pas
Eir Nym

Réponses:


13

Tout d'abord, assurez-vous que votre TERM est correct à chaque emplacement:

  • xterm-quelque chose (par exemple xterm-256color) à l'intérieur de votre shell local fonctionnant dans votre fenêtre iTerm2
  • xterm-quelque chose à l'intérieur de votre shell après SSHing au système Linux
    Cela devrait être le même que celui que vous utilisez localement dans iTerm2 , car SSH devrait le transmettre au côté distant (et, ce qui est important, le côté distant ne doit pas ignorer aveuglément le dans un fichier d'initialisation du shell).
  • screen-quelque chose (par exemple screen-256color) à l'intérieur de votre shell fonctionnant sous tmux sur le système Linux
    Vous devez toujours utiliser un screenTERM basé sur l'intérieur de tmux .

Avoir un xtermTERM immédiatement à l'extérieur de tmux permettra à tmux de reconnaître les touches fléchées modifiées, mais il ne les passera pas à moins que son xterm-keysoption de fenêtre ne soit également activée. Mettez ceci dans votre ~/.tmux.confsur le système Linux:

set-window-option -g xterm-keys on

Les séquences des touches décalées devraient maintenant passer à Emacs , s'exécutant à l'intérieur de tmux , via une connexion SSH, à l'intérieur d'une fenêtre iTerm2 .


C'est exactement ce dont j'avais besoin pour utiliser textadept dans tmux.
William Hilton

1
Cette solution n'a pas fonctionné pour moi. Je suis sur Fedora-23 en utilisant un terminal gnome. Mes TERM et .tmux.conf sont définis comme décrit dans la réponse. La définition des liaisons comme décrit dans la question fonctionne cependant. J'aimerais vraiment résoudre ce mystère, car il nettoie également une application ncurses sur laquelle je travaille.
gogators

1
@gogators même ici; la solution ci-dessus ne fonctionne pas pour moi même si j'avais exactement ce qui a été suggéré.
Fingolfin

Ctrl + Maj ne fonctionne pas, Ctrl + <f #> ne fonctionne pas et ainsi de suite. Ctrl + d fonctionne cependant.
avril

Dans la pratique, cela signifie: export XTERM=xterm-256color(J'écris ceci parce que je ne savais pas ce que signifie "votre TERME" dans la réponse, je cherchais un commentaire expliquant que ... il n'y en avait pas, et maintenant il y en a un.)
jhegedus

3

Vous devez d'abord activer xterm-keysdans votre configuration tmux. Mettez donc ce qui suit dans~/.tmux.conf

setw -g xterm-keys on

Mais cela rompra d'autres combinaisons de touches. Pour les corriger, mettez ce qui suit dans votre ~/.emacsou ~/.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))
      ))
    )
  )      

J'ai aussi ma solution dans le wiki archlinux


commentaire laissé par @JeffKlukas: "La réponse oblique est exactement ce dont j'avais besoin pour que cela fonctionne via PuTTY sur Windows également (je n'ai pas la réputation de l'ajouter en tant que commentaire, donc faire une réponse à la place). Quand j'ai allumé l'option xterm-keys dans tmux, Shift-arrow produirait du texte comme 2C dans emacs. En ajoutant le code elisp ci-dessus à mon init.el, j'obtiens la fonctionnalité attendue (particulièrement utile en mode org). "
slm

1

La FAQ tmux contenait l'entrée suivante :

Comment faire fonctionner les touches fléchées ctrl et shift dans emacs?

La terminal-init-screenfonction dans term/screen.elest appelée pour les nouveaux cadres, mais elle ne configure aucune touche de fonction.

Si l' xterm-keysoption tmux est activée, il suffit de définir les mêmes clés que xterm. Ajoutez init.elou .emacsprocédez comme suit :

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

Et assurez-vous qu'il .tmux.confcontient " set -g xterm-keys on".

Alternativement, le screen.elfichier peut être copié dans le chemin de chargement et personnalisé.

J'ai ouvert le problème tmux # 1349 pour demander la restauration de l'entrée FAQ.


0

Dans le cas général, des problèmes comme celui-ci se produisent en raison d'un décalage entre ce que l'émulateur de terminal envoie et ce que l'application client attend.

Différents émulateurs de terminaux ont différents degrés de personnalisation, il est donc nécessaire de se familiariser avec les paramètres d'émulation d'un paramètre particulier.

Les applications client dépendent de la valeur $TERMutilisée pour rechercher les capacités du terminal (émulateur) dans la base de données terminfo(ou termcap).

Dans votre cas, vos liaisons emacs utilisent donc des séquences explicites $TERMet terminfo ne sont pas pertinentes: un émulateur de terminal spécifique est attendu - comme vous l'avez déjà compris, un émulateur xtermcompatible.


Voir Fix Terminals - Please pour une proposition de normalisation de certaines de ces différences / lacunes dans l'entrée du terminal. Il a été soulevé sur iterm2-discut mais je ne pense pas que quiconque l'ait encore implémenté.
éphémère
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.