Shift-arrow não funciona no emacs no tmux

26

Recentemente, comecei a usar o tmux (já era usuário de tela) e estou adorando, exceto por um pequeno problema. Eu uso o emacs na minha sessão do tmux e estou acostumado a usar as teclas de seta Shift para mover entre as janelas do emacs (não as janelas do tmux). Quando executadas no tmux, essas ligações parecem parar de funcionar completamente (é como se elas não se registrassem no emacs). Se eu sair do tmux e apenas executar o emacs no meu shell, eles funcionarão bem.

Estou usando o iTerm2, ssh'd em uma caixa Linux, executando o tmux / emacs lá. Eu tenho as ligações das teclas Shift-seta configuradas da seguinte maneira no meu .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)

Quando não estou executando o tmux, posso confirmar que essas são as seqüências de caracteres corretas para as combinações de teclas com seta de deslocamento, fazendo Cq no emacs e pressionando a sequência de teclas. No tmux, mesmo isso não funciona porque parece não ver nenhuma entrada do pressionamento de tecla shift-arrow (apenas fica no prompt Cq).

Olhando para as ligações de teclas do tmux, acho que nada está vinculado às teclas de seta Shift e, mesmo que fosse, elas só seriam registradas após inserir o prefixo (que é vinculado a Co no meu caso).

Alguma idéia de como fazer com que as teclas com seta para Shift funcionem novamente no tmux?

triangle_man
fonte
11
Na verdade, eu mesmo encontrei a resposta, mas o StackExchange não me permite responder oficialmente minha própria pergunta por mais sete horas, pois ainda não tenho reputação suficiente. De qualquer forma, se alguém estiver interessado, fazer xterm-keys com opção de janela de configuração parece corrigi-lo. Eu definir isso como uma opção global, colocando isso no meu .tmux.conf e eu parecem estar de volta no negócio: xterm-keys set-window-opção -G na
triangle_man
Tente voto a próxima pergunta se você realmente não pode
Eir Nym

Respostas:

13

Primeiro, verifique se o seu TERM está correto em cada local:

  • xterm-algo (por exemplo xterm-256color) dentro do shell local em execução na janela do iTerm2
  • xterm-algo dentro do seu shell após o SSHing no sistema Linux
    Deve ser o mesmo que você está usando localmente no iTerm2 , pois o SSH deve passá-lo para o lado remoto (e, o mais importante, o lado remoto não deve substituir cegamente o valor em um arquivo de inicialização do shell).
  • screen-algo (por exemplo screen-256color) dentro do seu shell executando o tmux no sistema Linux
    Você sempre deve usar um screenTERM baseado no tmux .

Ter um xtermTERM imediatamente fora do tmux permitirá que o tmux reconheça as teclas de seta modificadas, mas não as passará a menos que você também tenha a xterm-keysopção da janela ativada. Coloque isso no seu ~/.tmux.confsistema Linux:

set-window-option -g xterm-keys on

As seqüências para as teclas deslocadas agora devem chegar ao Emacs , executando dentro do tmux , através de uma conexão SSH, dentro de uma janela do iTerm2 .

Chris Johnsen
fonte
Isso é exatamente o que eu precisava para usar o textadept no tmux.
William Hilton
11
Esta solução não funcionou para mim. Estou no Fedora-23 usando um terminal gnome. Meus TERM e .tmux.conf são definidos como descrito na resposta. A configuração das ligações conforme descrito na pergunta funciona no entanto. Eu realmente gostaria de resolver esse mistério, já que ele também está estragando um aplicativo ncurses em que estou trabalhando.
gogators
11
@gogators mesmo aqui; a solução acima não funciona para mim, embora eu tivesse exatamente o que foi sugerido.
Fingolfin
Ctrl + Shift não funciona, Ctrl + <f #> não funciona e assim por diante. Ctrl + d funciona embora.
avp
Na prática, isso significa: export XTERM=xterm-256color(estou escrevendo isso porque não sabia o que "seu TERM" na resposta significa, estava procurando um comentário explicando que ... não havia nenhum e agora existe um.)
jhegedus
3

Primeiro você deve habilitar xterm-keysna sua configuração tmux. Então coloque o seguinte em~/.tmux.conf

setw -g xterm-keys on

Mas isso quebrará outras combinações de teclas. Para corrigi-los, coloque o seguinte em sua configuração ~/.emacsou~/.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))
      ))
    )
  )      

Também tenho minha solução no archlinux wiki

oblíquo
fonte
comentário deixado por @JeffKlukas: "a resposta do oblique é exatamente o que eu precisava para que isso funcionasse através do PuTTY no Windows (eu não tenho a reputação de adicionar isso como um comentário, por isso, faça uma resposta). a opção xterm-keys no tmux, Shift-arrow produziria texto como 2C no emacs. Ao adicionar o código elisp acima ao meu init.el, obtenho a funcionalidade esperada (especialmente útil no modo organizacional). "
Slm
1

O FAQ do tmux costumava conter a seguinte entrada :

Como faço para que as teclas de seta ctrl e shift funcionem no emacs?

o terminal-init-screen função in term/screen.elé chamada para novos quadros, mas não configura nenhuma tecla de função.

Se a xterm-keysopção tmux estiver ativada , basta definir as mesmas chaves que o xterm. Adicione o seguinte a init.elou .emacspara fazer isso:

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

E garantir .tmux.conf contém " set -g xterm-keys on".

Como alternativa, o screen.el arquivo pode ser copiado para o caminho de carregamento e personalizado.

Abri o problema # 1349 do tmux para solicitar a restauração da entrada de Perguntas frequentes.

sorsasampo
fonte
0

Em geral, problemas como esse acontecem devido a uma diferença entre o que o emulador de terminal envia e o que o aplicativo cliente espera.

Emuladores de terminal diferentes têm diferentes graus de personalização, portanto, é necessário familiarizar-se com os ajustes de emulação de um determinado.

Os aplicativos clientes dependem do valor $TERMusado para pesquisar os recursos do terminal (emulador) no banco de dados terminfo(ou termcap).

No seu caso, as ligações do emacs usam sequências explícitas $TERMe o terminfo é irrelevante: é esperado um emulador de terminal específico - como você já descobriu, um emulador xtermcompatível.

yrk
fonte
Consulte Fix Terminals - Por favor, para uma proposta de padronizar algumas dessas diferenças / deficiências na entrada do terminal. Isso foi discutido no iterm2-discuss, mas acho que ninguém o implementou ainda.
ephemient 18/03/12