tmux 干扰 emacs 命令? (windmove-default-keybindings)

tmux interfering with emacs commands? (windmove-default-keybindings)

(windmove-default-keybindings 'meta) 提供在 emacs windows 之间移动的命令(例如 M-<up> 向上移动 window)。当 emacs -nw 在终端中为 运行 时,它们对我来说工作正常,但在 tmux 中它们失败了。

个别命令有效,例如winmove-up;当 运行 他们告诉我:

You can run the command winmove-up with M-<up>

但是对于 M-<up> 本身,我得到:

ESC <up> is undefined

与任何其他前缀键(shiftcontrol)的问题相同。

这分别在 Ubuntu 12.04 和 14.04 下的 tmux 1.9a/emacs 23.3.1 和 tmux 2.0/emacs 24.5.1 中。在第一种情况下,我使用 "gnome-terminal"。在第二个......我正在进入服务器并且 TERM 环境变量是 "xterm"。一旦我启动 tmux,它就会变成 "screen-256color";那是因为我用过 set -g default-terminal

想法?

Emacs 并不总能正确翻译功能键上的修饰符。

首先,看看 tmux 选项 set -g xterm-keys on 是否有任何区别。 (这可能需要一个新的 terminfo 条目才能完全工作;如果它做出任何更改甚至说出 ESC <up> 以外的内容,请在评论中说)

此外,在没有打开 xterm-keys 的情况下,尝试从 this answer:

进行键翻译
(define-key input-decode-map "\e\eOA" (kbd "<M-up>"))
(define-key input-decode-map "\e\eOB" (kbd "<M-down>"))

xterm-keys 解决方案的优点是,如果可行,它也适用于 shift 和 ctrl。

无需修改功能键映射,使用 xterm 键,您可以使用适当的键安装新的 terminfo 条目:

# Note: tmux does translate Home and End (\EOH, \EOF) to \E[1~, \E[4~
# But leaves the modified versions (\E[1;?H etc) alone.

xterm+modkeys|xterm-style modifier keys,
    kb2=\EOE, kent=\EOM,
    kind=\E[1;2B, kri=\E[1;2A,
    kf13=\E[1;2P, kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S,
    kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf20=\E[19;2~,
    kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~,
    kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S,
    kf29=\E[15;5~, kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~,
    kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~, kf36=\E[24;5~,
    kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf40=\E[1;6S,
    kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~, kf44=\E[19;6~,
    kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~,
    kf49=\E[1;3P, kf50=\E[1;3Q, kf51=\E[1;3R, kf52=\E[1;3S,
    kf53=\E[15;3~, kf54=\E[17;3~, kf55=\E[18;3~, kf56=\E[19;3~,
    kf57=\E[20;3~, kf58=\E[21;3~, kf59=\E[23;3~, kf60=\E[24;3~,
    kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R,
    kDC=\E[3;2~, kDC3=\E[3;3~, kDC4=\E[3;4~, kDC5=\E[3;5~, kDC6=\E[3;6~, kDC7=\E[3;7~,
    kDN=\E[1;2B, kDN3=\E[1;3B, kDN4=\E[1;4B, kDN5=\E[1;5B, kDN6=\E[1;6B, kDN7=\E[1;7B,
    kEND=\E[1;2F, kEND3=\E[1;3F, kEND4=\E[1;4F, kEND5=\E[1;5F, kEND6=\E[1;6F, kEND7=\E[1;7F,
    kHOM=\E[1;2H, kHOM3=\E[1;3H, kHOM4=\E[1;4H, kHOM5=\E[1;5H, kHOM6=\E[1;6H, kHOM7=\E[1;7H,
    kIC=\E[2;2~, kIC3=\E[2;3~, kIC4=\E[2;4~, kIC5=\E[2;5~, kIC6=\E[2;6~, kIC7=\E[2;7~,
    kLFT=\E[1;2D, kLFT3=\E[1;3D, kLFT4=\E[1;4D, kLFT5=\E[1;5D, kLFT6=\E[1;6D, kLFT7=\E[1;7D,
    kNXT=\E[6;2~, kNXT3=\E[6;3~, kNXT4=\E[6;4~, kNXT5=\E[6;5~, kNXT6=\E[6;6~, kNXT7=\E[6;7~,
    kPRV=\E[5;2~, kPRV3=\E[5;3~, kPRV4=\E[5;4~, kPRV5=\E[5;5~, kPRV6=\E[5;6~, kPRV7=\E[5;7~,
    kRIT=\E[1;2C, kRIT3=\E[1;3C, kRIT4=\E[1;4C, kRIT5=\E[1;5C, kRIT6=\E[1;6C, kRIT7=\E[1;7C,
    kUP=\E[1;2A, kUP3=\E[1;3A, kUP4=\E[1;4A, kUP5=\E[1;5A, kUP6=\E[1;6A, kUP7=\E[1;7A,

screen-xtermkeys|screen with xterm-style modifier keys,
    use=xterm+modkeys, use=screen,

screen-xtermkeys-256color|screen with xterm keys and 256 colors,
    use=xterm+modkeys, use=screen-256color,

tmux-xtermkeys|tmux with xterm-style modifier keys,
    use=xterm+modkeys, use=tmux,

tmux-xtermkeys-256color|tmux with xterm keys and 256 colors,
    use=xterm+modkeys, use=tmux-256color,

使用 tic -x tmux-xtermkeys.ti 编译,然后根据需要将 TERM 设置为 {tmux,screen}-xtermkeys{,-256color}。我包含 screen 有两个原因:首先,默认情况下 emacs 不将 tmux 识别为 256 色终端。其次,某些系统的 terminfo 数据库版本太旧,无法包含 tmux 信息(删除这些条目以获取要编译的文件)。

最好使用 screen terminfo 条目而不是 xterm 条目,因为 tmux 曾经推荐使用 screen 并且它的仿真更接近它。在某些情况下您可能会注意到的一件事是 text meant to be in standout mode will be in italics - 如果是这样,请升级您的 terminfo 数据。

这也适用于支持这些键的其他应用程序(即它们现在在 xterm 中工作的大多数地方)。

在@Random832的帮助下,this question and the first answer to this one, along with some useful information about how emacs handles function keys in the answer to this question的答案,有两种方法:

方法 #1: 在您的 .tmux.conf 中,使用 xterm-keys on,而且,如果您使用 256 色,则设置您的 default-terminal正确:

set -g xterm-keys on
set -g default-terminal "xterm-256color"

方法 #2: 在终端中,运行 cat 然后键入 M-<up> 等以查找输出。在我的例子中是:^[[1;3A(和 B & C & D)。然后,在您的 .emacs 文件中使用此代码:

(add-hook 'term-setup-hook
  '(lambda ()
     (define-key function-key-map "\e[1;3A" [M-up])
     (define-key function-key-map "\e[1;3B" [M-down])
     (define-key function-key-map "\e[1;3C" [M-right])
     (define-key function-key-map "\e[1;3D" [M-left])))

注意第二种方法也适用于其他前缀键(ShiftControl)并且同样的问题出现在screen.

另请注意 除了 gnus 文章摘要缓冲区外,其他一切似乎都运行良好,其中 M-<up>M-<dn> 表现得像<up><dn>(尽管 M-<rt>M-<lft> 工作正常)。

只有这个对我有用:

在init.el

;; Try to move direction, which is supplied as arg
;; If cannot move that direction, send a tmux command to do appropriate move
(defun windmove-emacs-or-tmux(dir tmux-cmd)
  (interactive)
  (if (ignore-errors (funcall (intern (concat "windmove-" dir))))
      nil                       ;; Moving within emacs
    (shell-command tmux-cmd)) ;; At edges, send command to tmux
  )

;Move between windows with custom keybindings
(global-set-key (kbd "C-k")
        '(lambda () (interactive) (windmove-emacs-or-tmux "up"  "tmux select-pane -U")))
(global-set-key (kbd "C-j")
        '(lambda () (interactive) (windmove-emacs-or-tmux "down"  "tmux select-pane -D")))
(global-set-key (kbd "C-l")
        '(lambda () (interactive) (windmove-emacs-or-tmux "right" "tmux select-pane -R")))
(global-set-key (kbd "C-h")
        '(lambda () (interactive) (windmove-emacs-or-tmux "left"  "tmux select-pane -L")))

在.tmux.conf:

bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|emacs?)(diff)?$' && tmux send-keys C-h) || tmux select-pane -L"
bind -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|emacs?)(diff)?$' && tmux send-keys C-j) || tmux select-pane -D"
bind -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|emacs?)(diff)?$' && tmux send-keys C-k) || tmux select-pane -U"
bind -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|emacs?)(diff)?$' && tmux send-keys C-l) || tmux select-pane -R"
bind -n C-\ run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)g?(view|emacs?)(diff)?$' && tmux send-keys 'C-\') || tmux select-pane -l"

https://blog.kdheepak.com/emacsclient-and-tmux-split-navigation.html