Shift-arrow在tmux中的emacs中不起作用


26

我最近开始使用tmux(以前是屏幕用户),除了一个小问题,我很喜欢它。我在tmux会话中使用emacs,并且习惯于使用Shift-箭头键在emacs窗口(而不是tmux窗口)之间移动。在tmux中运行时,这些绑定似乎完全停止工作(就像它们根本没有注册到emacs一样)。如果我退出tmux并仅在我的shell中运行emacs,它们就可以正常工作。

我正在使用iTerm2,将其安装到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中运行时,我可以通过在emacs中执行Cq然后按下键序列,来确认那些是按Shift键组合的正确字符序列。在tmux中,即使这样也不起作用,因为它似乎看不到Shift箭头按键的任何输入(它只是位于Cq提示符下)。

查看tmux的键绑定,我认为Shift箭头键没有任何绑定,即使是Shift键,它们也只会在输入前缀(在我的情况下绑定到Co)之后才注册。

关于如何使Shift键在tmux中再次起作用的任何想法?


1
我实际上自己找到了答案,但是StackExchange不允许我再花7个小时正式回答自己的问题,因为我的信誉还不够。无论如何,如果有人感兴趣,在set-window-option xterm-keys上似乎可以解决此问题。我将其放在.tmux.conf中将其设置为全局选项,并且我似乎又重新开始营业:set-window-option -g xterm-keys on
triangle_man

尝试投票解决是否真的不能结束的问题
Eir Nym

Answers:


13

首先,请确保您的TERM在每个位置都是正确的:

  • xterm- xterm-256coloriTerm2窗口中运行的本地Shell中的某些内容(例如)
  • xterm-SSH到Linux系统后,外壳程序内部的某些内容
    应该与您在iTerm2中本地使用的内容相同,因为SSH应该将其传递给远程端(而且,重要的是,远程端不应盲目地覆盖外壳初始化文件中的值)。
  • screen在Linux系统screen-256color上在tmux下运行的shell内的某些内容(例如)
    您应该始终screentmux内使用基于A的TERM 。

xtermTERM直接放在tmux外部将允许tmux识别已修改的箭头键,但是除非您还xterm-keys打开了window选项,否则它不会通过它们。将其~/.tmux.conf放在Linux系统上:

set-window-option -g xterm-keys on

现在,移位键的序列应使其通过iTerm2窗口中的SSH连接进入tmux内部运行的Emacs


这正是我在tmux中使用textadept所需要的。
威廉·希尔顿

1
此解决方案对我不起作用。我在使用gnome-terminal的Fedora-23上。我的TERM和.tmux.conf的设置如答案中所述。但是,按照问题中的描述设置绑定确实可行。我真的很想解决这个谜,因为它也掩盖了我正在开发的ncurses应用。
gogators

1
@gogators在这里一样;即使我有确切的建议,上述解决方案对我也不起作用。
Fingolfin

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.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留下的评论:“倾斜的答案正是我也需要通过Windows在PuTTY上进行此操作(我没有信誉将其添加为评论,因此请提供答案。)当我打开时在tmux中使用xterm-keys选项时,Shift-arrow会在emacs中生成类似2C的文本。通过将上述elisp代码添加到init.el中,我可以得到预期的功能(在组织模式下特别有用)。”
slm

1

tmux FAQ 包含以下条目

如何在emacs中使ctrl和shift箭头键起作用?

中的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,terminfo无关紧要:可以使用特定的终端仿真器-正如您已经知道的那样,它是一个xterm兼容的仿真器。


请参阅修复端子-请提供一些建议,以标准化这些端子输入中的一些差异/不足。它是在iterm2-discuss上提出的,但我认为还没有人实现它。
短暂
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.