zsh中的Home / End键不适用于putty

时间:2008-10-02 10:30:12

标签: keyboard terminal zsh terminal-emulator

我正在运行zsh作为Ubuntu盒子上的默认shell,并且使用gnome-terminal(据我所知模仿xterm)一切正常。当我通过ssh和putty(也模仿xterm)从Windows框登录时,主/端密钥不再有效。

我已经能够解决将这些行添加到我的zshrc文件...

bindkey '\e[1~' beginning-of-line
bindkey '\e[4~' end-of-line

......但我仍然想知道这里有什么问题。有什么想法吗?

7 个答案:

答案 0 :(得分:64)

我发现它是一个组合:

<强>一

ZSH开发人员不认为ZSH应该定义 Home End Del ,... keys的动作。 / p>

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作为终端类型发送到远程主机。但是在某个地方搞砸了并且没有为 Home End 发送正确的控制代码,......人们期望从xterm获得。或者xterm终端不会发送那些或其他...( Del 键在xterm中有效,但是,如果在ZSH中配置它。另请注意,您的Numpad-keys在Vim中表现得很有趣,例如使用xterm终端。

解决方案是将Putty配置为发送另一种终端类型。我试过了xterm-colorlinuxxterm-color修复了 Home / End 问题,但是Numpad仍然很有趣。将其设置为linux可以解决这两个问题。

您可以在连接下的Putty中设置终端类型 - &gt;数据。不要试图在.zshrc export TERM=linux中设置您的终端类型,这是错误的。终端类型应由终端应用程序指定。因此,例如,如果您从Mac机箱与Mac SSH客户端连接,它可以设置它自己的终端类型。

请注意,TERM指定了您的终端类型,与您要连接的主机无关。我可以在Putty中将终端类型设置为linux并连接到FreeBSD服务器而没有问题。

所以,解决这两件事你应该没问题。)

答案 1 :(得分:13)

在PuTTY配置对话框中,转到Connection - &gt;数据并在连接前将 linux 键入Terminal类型字符串。

答案 2 :(得分:6)

这对我有用

bindkey -v

bindkey '\eOH'  beginning-of-line
bindkey '\eOF'  end-of-line

答案 3 :(得分:3)

这似乎是一件腻子。 Gnome-terminal分别为Home和End发送代码^[OH^[OF,而putty发送^[[1~^[[4~。 putty中有一个选项可以将Home / End键从标准模式更改为 rxvt 模式,这似乎可以修复Home键,但不能修复End键(现在发送^[Ow)。猜猜是时候在某处提交错误报告......: - )

答案 4 :(得分:3)

应该可以在所有发行版中移植的适当答案(不一定是zsh的所有版本,但这里是ymmv)是使用zkbd中的zkbd帮助程序实用程序。

  

键盘定义
  键盘,工作站,终端,仿真器和窗口系统的大量可能组合使zsh无法为每种情况都具有内置的键绑定。函数/杂项中的zkbd实用程序可以帮助您快速创建配置的键绑定。

     

将zkbd作为自动加载的函数或shell脚本运行:

zsh -f ~/zsh-4.3.17/Functions/Misc/zkbd
  

当你运行zkbd时,它会先要求你输入你的终端类型;如果它提供的默认值是正确的,只需按返回。然后它会要求您按下许多不同的键来确定键盘和终端的特性; zkbd警告你          如果它发现任何不寻常的东西,例如既不发送^ H也不发送^的删除键。

     

zkbd读取的击键记录为名为key的关联数组的定义,写入HOME或ZDOTDIR目录中子目录.zkbd中的文件。文件名由TERM,VENDOR和OSTYPE组成          参数,用连字符连接。

     

您可以使用source' or将此文件读入.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”起作用,zkdb文件必须位于fpath数组中指定的目录之一(请参阅zshparam(1))。如果你有一个标准的zsh安装应该已经是这种情况了;如果不是,请将Functions / Misc / zkbd复制到适当的目录。

请参阅man -P "less -p 'keyboard definition'" zshcontrib,或搜索元联机帮助页zshall

答案 5 :(得分:1)

此问题首次发布至今已经快11年了。当时,某些发行版的确附带了putty terminfo条目,但充其量只是中等水平。此后的几年里,情况有所改善,不再需要十多年来必须的黑客攻击。 PuTTY仍然默认将TERM设置为xterm以获得兼容性,但是如果您要连接到最新的现代系统,则可能会很幸运将其覆盖并将其设置为{{1 }}:

  1. 确保主机具有putty-256color的terminfo条目:putty-256color
  2. 撤消您可能已启用的所有hack,以使PuTTY与zsh或其他程序一起正常工作。
  3. 确保腻子是最新的。当有可用更新时,它不会通知您,如果更新已过期,您可能会遇到很多相同的问题。您可能需要使用Chocolatey之类的工具自动将其更新。
  4. 在PuTTY的配置对话框中,转到“连接”->“数据”,然后将“终端类型的字符串”设置为toe -a | grep -F putty
  5. 在相同的配置屏幕上,同时添加一个新的环境变量以启用24位颜色。这个变量不是标准化的,但是它是由许多其他主流终端仿真器(例如iTerm2)发送的,许多程序都可以理解。
    1. 变量:putty-256color
    2. 值:COLORTERM
  6. 在撰写本文时,我还没有找到默认情况下可以通过SSH接受COLORTERM变量的发行版。您需要在主机上编辑您的OpenSSH配置以允许它。例如,在类似Debian的发行版上,编辑truecolor并将/etc/ssh/sshd_config添加到COLORTERM行。
  7. 现在一切都应该“正常”。如果没有:
    1. 确保进行更改后已重新连接,或者至少在更改AcceptEnv后运行exec zsh。 zsh在运行时不会对TERM中的更改做出反应。
    2. 确保TERM实际上设置为您想要的设置:TERM
    3. 您是否正在使用最新版本的发行版?例如,如果您使用的是长期支持生命周期构建,即使您的版本在技术上仍受支持,则它可能没有最新的terminfo条目。
    4. 您使用的是echo $TERM还是screen?那是另一整个蠕虫罐头。无需先进行测试即可缩小问题发生位置的范围。在tmux中,尝试设置tmux。在屏幕上,尝试TERM=tmux-256color
    5. 您在使用最新版本的PuTTY吗?
    6. 您是否有实现键绑定或其他黑客手段的RC文件?尝试使用默认的RC文件。
    7. 您是否已更改各种PuTTY设置以尝试解决terminfo修复之前尝试解决此问题?您可能需要重置这些设置。

答案 6 :(得分:0)

这些绑定似乎不是emacs模式中设置的默认绑定的一部分。

在运行“bindkey -e”后在我的默认zsh安装上执行“where-is-line-line”,表明它只绑定到^ a。也许你应该问zsh开发人员为什么: - )