Tmux Terminfo 与 Zsh 键绑定的问题

Tmux Terminfo 与 Zsh 键绑定的问题

Emacs 编辑模式下的 Zsh 带有默认的键绑定ALT+Backspace删除光标右侧的单词和ALT+D删除左侧的单词。我想将后一个功能另外添加到ALT+中DEL

我尝试使用terminfo数据库来正确设置每个组合键的转义序列$TERM。在man terminfo我读到关于kDC3成为 Capname 时,我可能需要将其用于ALT+ DEL

我将以下行添加到我的~/.zshrc

bindkey -e `tput kDC3` kill-word

$TERM当我直接通过 SSH ( is )连接到我的机器时,这效果很好xterm。但是当我在 Tmux-session ( $TERMis screen) 中启动 Zsh 时,我收到以下错误消息:

tput: unknown terminfo capability 'kDC3'

这真的意味着不可能在 Tmux 中将任何内容绑定到ALT+吗?DEL或者我只是做错了什么?也许kDC3顺序不正确?

我正在运行 Debian Wheezy Beta 4 x86_64。

答案1

第一个问题是你的术语信息条目screen没有定义kDC3能力;这可能是典型的。您可以将此功能添加到您自己的自定义screen条目中,也可以对命令中的序列进行“硬编码” bindkey


添加功能可能有助于其他程序了解密钥,但它会分散您的配置(当您手动将配置复制到新计算机或用户帐户时,很容易忘记此自定义)。您可以使用以下命令提取适当的条目infocmp并使用以下命令构建新条目tic

{ infocmp -xT screen ; infocmp -x1T xterm | grep -E '^\tkDC[3-8]?=' ; } >/tmp/s
tic -x /tmp/s

如果你跑抽动症作为对 terminfo 目录具有写入权限的用户(例如/usr/share/terminfo),那么新条目将被放置在那里(可能会覆盖原始条目);否则,它将被放置在~/.terminfo(或 TERMINFO,如果您设置了该环境变量)下。

为了完整起见,您可能希望使用(UP|DN|RIT|LFT|PRV|NXT|HOM|END|IC|DC)而不是DCgrep模式来捕获 Up、Down、Right、Left、PageUp、PageDown、Home、End、Insert 和 Delete 的修改版本。


如果您不喜欢因自定义 terminfo 条目而导致配置分散,那么您可以“硬编码”该值。为了使它更好一点,您可以kDC3首先检查:

bindkey -e ${$(tput kDC3 2>/dev/null):-'\e[3;3~'} kill-word

要将这种“硬编码”限制为仅screen基于 TERM 值:

altdel=$(tput kDC3 2>/dev/null)
[[ -z $altdel && $TERM == screen(|-*) ]] && altdel='\e[3;3~'
[[ -n $altdel ]] && bindkey -e $altdel kill-word
unset altdel

只要您的终端模拟器(堆栈)最终生成了xterm修改后的键的样式序列。


一旦进行绑定,您仍然需要打开该xterm-keys选项多路复用器这样它就会生成xterm传递到其窗格中的键样式序列。例如在你的~/.tmux.conf

set-option -wg xterm-keys on

答案2

这取决于:

  • ncurses 支持扩展(用户可定义)终端能力。
  • kDC3是一个扩展终端能力。
  • 没有任何一个tmuxzsh或者emacs对此一无所知全部关于kDC3
  • 虽然tmux已经kDC3在一个桌子,它不调用use_extended_names启用该功能。
  • ncursestput会知道kDC3如果它在当前终端描述中定义。

screen程序(tmux模仿的)也对kDC3.它是一个术语帽应用程序,并且(对于其本身)仅关注 2 个字符的名称。然而,screen有一个功能可以直接解决这个问题:在手册中(16.1 选择窗口的 termcap 条目)它告诉我们如何选择设置TERM 里面屏幕会话:

screen尝试为自己找出终端名称时,它首先查找名为的条目screen.学期, 在哪里学期是你的变量的内容$TERM。如果不存在这样的条目,屏幕会尝试screen(或者screen-w,如果终端很宽(132 列或更多))。如果连这个条目都找不到,vt100被用作替代品。

这个想法是,如果您的终端不支持重要功能(例如删除字符或清除 EOS),您可以为屏幕构建一个新的 termcap/terminfo 条目(名为screen.dumbterm),其中此功能已被禁用。如果您的计算机上安装了此条目,您可以进行 rlogin 并且仍然保留正确的 termcap/terminfo 条目。终端名称放入$TERM所有新窗口的变量中。 screen 还设置$TERMCAP反映模拟虚拟终端功能的变量。此外,该变量$WINDOW被设置为每个窗口的窗口号。

ncurses 的终端数据库利用此功能提供最常见的screenwith变体xterm和其他类似但有的终端不同的功能键,例如控制台,静脉血栓栓塞(例如,gnome 终端),接收值。除此以外rxvt,其他仍定TERMxterm

在默认配置中,您可能没有这些可用的终端描述(并且screen会愉快地继续设置TERM=screen并激发用户报告错误,就像这个问题一样)。例如,Debian 在其ncurses 基础terminfo 包仅提供最少的终端描述集。你必须安装ncurses-term获取完整的终端数据库。

当然,终端描述并screen没有描述任何扩展功能键。顺便说一下,它确实包括这些扩展功能:

AX, G0, E0=\E(B, S0=\E(%p1%c,

但这些应用程序(除了tput)都没有对它们做任何事情。

tmux由于不完全匹配 的行为而使情况变得复杂screen:它不检查 ncurses 提供的备用名称。无需解释原因,其手册页

对于内部运行的所有程序,必须将环境TERM变量设置为。新窗口将自动添加到其环境中,但必须注意不要在 shell 启动文件中重置它。“screen”tmux“TERM=screen”

可能的原因是开发人员不想保证screen.功能键则是另一回事。您可以按照建议修改终端描述,尽管这已被证明是一个问题而不是解决方案:

建议的脚本顺便说一句,似乎不起作用。考虑到这个问题的所有背景,显示更正的脚本是没有意义的。我倾向于在 shell 初始化中使用一个 case 语句来检查TERMset to screen,并检查终端数据库中是否已有更好的替代方案,而不是对终端数据库进行零碎的调整。由于开发人员拒绝TERM根据终端的功能进行设置,正确执行此操作会变得更加复杂,但您可以通过查看环境变量来获得大部分方法COLORTERM

供你消遣:

答案3

从我对 tmux 内部结构的了解来看,它似乎并不太关注 terminfo 设置等。例如,如果您打开 xterm 模式:

set-window-option -g xterm-keys on

与各种键相对应的实际转义序列被硬编码到程序中,并且可能与infocmp xterm告诉您的不同。

除此之外,tmux 会忽略上面的所有内容,F20因为它只有一组可以识别硬编码的键。所以像这样

set-option -g terminal-overrides "screen:kf34=\033[21;5~"

或者

tmux bind-key -t emacs-copy F34 page-up

无论 xterm 或 tput 吐出什么,都不会完成任何事情。至少目前看来是这样。

我不确定同样的问题是否会影响类似的事情,kDC3但这似乎很有可能。

相关内容