我在 Ubuntu 盒子上运行 zsh 作为默认 shell,使用 gnome-terminal 一切正常(据我所知,它模拟 xterm)。当我通过 ssh 和腻子(也模拟 xterm)从窗口框登录时,主页/结束键突然不再起作用。
我已经能够解决将这些行添加到我的 zshrc 文件中的问题......
bindkey 'e[1~' beginning-of-line
bindkey 'e[4~' end-of-line
。但我仍然想知道这里有什么问题。知道吗?
我发现这是一个组合:
一
ZSH 开发人员不认为 ZSH 应该定义 Home、End、Del、...钥匙。
Debian 和 Ubuntu 通过定义普通用户在全局/etc/zsh/zshrc
文件中期望的正常操作来解决这个问题。遵循相关代码(在 Debian 和 Ubuntu 上是相同的):
if [[ "$TERM" != emacs ]]; then
[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M emacs "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M vicmd "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history
[[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char
[[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
[[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
[[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
[[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
# ncurses fogyatekos
[[ "$terminfo[kcuu1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
[[ "$terminfo[kcud1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
[[ "$terminfo[kcuf1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
[[ "$terminfo[kcub1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line
fi
所以,如果你连接到 Debian 或 Ubuntu 机器,你不需要做任何事情。一切都应该自动工作(如果没有,见下文)。
但。。。如果你连接到另一个盒子 (例如 FreeBSD), 可能没有用户友好的默认zshrc
。解决方案当然是将 Debian/Ubuntu zshrc
中的行添加到您自己的.zshrc
中。
二
Putty 将xterm
作为终端类型发送到远程主机。但是在某处搞砸了,并且没有为主页,结束,...人们会期望从xterm
.或者xterm
终端预计不会发送这些或其他东西......(Del key确实可以在xterm
中工作,但是,如果您在ZSH中配置它)。另请注意,您的 Numpad 键在 Vim 中表现得很有趣,例如xterm
终端。
解决方案是将 Putty 配置为发送另一种终端类型。我已经尝试过xterm-color
和linux
. xterm-color
修复了Home/End问题,但Numpad仍然很有趣。将其设置为linux
解决了这两个问题。
您可以在"连接 ->数据"下的 Putty 中设置终端类型。不要试图用export TERM=linux
在.zshrc
中设置终端类型,这是错误的。终端类型应由终端应用指定。因此,例如,如果您从Mac机箱与Mac SSH客户端连接,则可以设置自己的终端类型。
请注意,TERM 指定您的终端类型,与要连接到的主机无关。我可以在 Putty 中将我的终端类型设置为 linux
并毫无问题地连接到 FreeBSD 服务器。
所以,解决这两件事,你应该没事:)
在 PuTTY 配置对话框中,转到 Connection -> Data 并在连接之前在终端类型字符串中键入 linux。
这个问题首次发布已经快 11 年了。 当时,一些发行版确实附带了一个putty
terminfo条目,但它充其量是平庸的。 从那以后的几年里,情况有所改善,不再需要十多年来必要的黑客攻击。 PuTTY 仍然默认将TERM
设置为 xterm
以实现兼容性,但如果您要连接到现代的最新系统,您可能会幸运地覆盖它并将其设置为 putty-256color
:
- 确保主机具有
putty-256color
的术语信息条目:toe -a | grep -F putty
- 撤消您可能已启用的任何黑客,以使PuTTY与zsh或其他程序正常工作。
- 确保 PuTTY 是最新的。 当更新可用时,它不会通知您,如果它已过时,您可能会遇到很多相同的问题。 您可能希望通过巧克力之类的东西自动保持最新状态。
- 在 PuTTY 的配置对话框中,转到 连接 -> 数据并将"终端类型字符串"设置为
putty-256color
。
当您使用它时,在同一 - 配置屏幕上,添加新的环境变量以启用 24 位颜色。 这个变量不是标准化的,但它是由许多其他主流终端模拟器(例如,iTerm2)发送的,许多程序都可以理解它。
- 变量:
COLORTERM
- 值:
truecolor
- 变量:
- 在撰写本文时,我还没有找到默认情况下通过SSH接受COLORTERM变量的发行版。 您需要在主机上编辑 OpenSSH 配置以允许它。 例如,在类似 Debian 的发行版上,编辑
/etc/ssh/sshd_config
并将COLORTERM
添加到AcceptEnv
行。 - 现在一切都应该"正常工作"。 如果没有:
- 确保在进行更改后重新连接,或者至少在更改
TERM
后运行exec zsh
。 zsh 在运行时不会对TERM
的变化做出反应。 - 确保
TERM
实际设置为您的预期:echo $TERM
- 您是否使用的是最新版本的发行版? 例如,如果您使用的是长期支持生命周期构建,即使您的版本在技术上仍受支持,也可能没有最新的 terminfo 条目。
- 您使用的是
screen
还是tmux
? 那是另一整罐蠕虫。 在没有那些人的情况下进行测试,以缩小问题发生的位置。 在 tmux 中,尝试设置TERM=tmux-256color
。 在屏幕中,尝试TERM=screen-256color
。 - 您使用的是最新版本的 PuTTY 吗?
- 您是否有实现键绑定或其他黑客的 RC 文件? 尝试使用默认的 RC 文件。
- 在尝试术语信息修复之前,您是否已经更改了各种 PuTTY 设置以尝试解决问题? 您可能需要重置这些设置。
- 确保在进行更改后重新连接,或者至少在更改
我有用
bindkey -v
bindkey 'eOH' beginning-of-line
bindkey 'eOF' end-of-line
发行版中移植的适当答案(不一定是所有版本的 zsh,这里的 ymmv)是使用 zkbd 的 zkbd 助手实用程序。
键盘定义
键盘、工作站、终端、仿真器和窗口系统的大量可能组合使得 zsh 不可能为每种情况都内置键绑定。 在 Functions/Misc 中找到的 zkbd 实用程序可以帮助您快速为配置创建键绑定。
将 zkbd 作为自动加载函数或 shell 脚本运行:
zsh -f ~/zsh-4.3.17/Functions/Misc/zkbd
当你运行zkbd时,它首先要求你输入你的终端类型;如果它提供的默认值是正确的,只需按回车键。 然后,它会要求您按许多不同的键来确定键盘和终端的特性;ZKBD警告你如果它发现任何异常,例如既不发送 ^H 也不发送 ^?的 Delete 键。
zkbd 读取的击键记录为名为 key 的关联数组的定义,写入 HOME 或 ZDOTDIR 目录中子目录 .zkbd 中的文件。 文件的名称由术语、供应商和操作系统类型组成参数,由连字符连接。
您可以使用
source
或.
命令将此文件读入 .zshrc 或其他启动文件中,然后在 bindkey 命令中引用 key 参数,如下所示:
source ${ZDOTDIR:-$HOME}/.zkbd/$TERM-$VENDOR-$OSTYPE
[[ -n ${key[Left]} ]] && bindkey "${key[Left]}" backward-char
[[ -n ${key[Right]} ]] && bindkey "${key[Right]}" forward-char
# etc.
请注意,为了使
autoload zkbd
工作,zkbd
文件必须位于 fpath 数组中命名的目录中(参见 zshparam(1))。 如果您有标准的 zsh 安装,应该已经是这种情况; 如果不是,请将 Functions/Misc/zkbd 复制到相应的目录。
请参见man -P "less -p 'keyboard definition'" zshcontrib
,或搜索元手册页zshall
这似乎是腻子的事情。侏儒终端分别发送^[OH
和^[OF
用于Home和End的代码,而putty发送^[[1~
和^[[4~
。腻子中有一个选项可以将主页/结束键从标准模式更改为 rxvt 模式,这似乎修复了主页键,但不能修复结束键(现在发送^[Ow
)。猜猜是时候在某个地方提交错误报告了... :-)
这些绑定似乎根本不是在 emacs 模式下设置的默认绑定的一部分。
运行"bindkey -e"后,在我的默认 zsh 安装上执行"where-is 开头"表明它只绑定到 ^a。也许你应该问问 zsh 开发人员为什么 :-)
这对我有用。
将这些行添加到 ~/.zshrc
bindkey "e[1;5D" backward-word
bindkey "e[1;5C" forward-word
# ctrl-bs and ctrl-del
bindkey "e[3;5~" kill-word
bindkey "C-_" backward-kill-word
# del, home and end
bindkey "e[3~" delete-char
bindkey "e[H" beginning-of-line
bindkey "e[F" end-of-line
# alt-bs
bindkey "ed" undo