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

发布于 2024-07-06 04:59:44 字数 310 浏览 7 评论 0原文

我在 Ubuntu 机器上运行 zsh 作为默认 shell,并且使用 gnome-terminal (据我所知它模拟 xterm)一切正常。 当我通过 ssh 和 putty(也模拟 xterm)从 windows 盒子登录时,home/end 键突然不再起作用。

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

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

...但我仍然想知道这里出了什么问题。 任何想法?

I'm running zsh as the default shell on a Ubuntu box, and everything works fine using gnome-terminal (which as far as I know emulates xterm). When I login from a windows box via ssh and putty (which also emulates xterm) suddendly the home/end keys no longer work.

I've been able to solve that adding these lines to my zshrc file...

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

...but I'm still wondering what's wrong here. Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

别靠近我心 2024-07-13 04:59:45

这对我有用。

将这些行添加到 ~/.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 "\e\d"  undo

This worked for me.

Adding these lines to ~/.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 "\e\d"  undo
も星光 2024-07-13 04:59:45

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

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

These bindings simply don't appear to be part of the default bindings set in emacs mode.

executing "where-is beginning-of-line" on my default zsh installation after running "bindkey -e" shows it is only bound to ^a. Perhaps you should ask the zsh developers why :-)

我很坚强 2024-07-13 04:59:45

看来是个腻子的东西。 Gnome 终端分别发送 ^[OH^[OF 表示 Home 和 End,而 putty 则发送 ^[[1~ 和 <代码>^[[4~. putty 中有一个选项可以将 Home/End 键从 standard 模式更改为 rxvt 模式,这似乎可以修复 Home 键,但不能修复 End 键(现在发送 ^[Ow)。 猜猜是时候在某个地方提交错误报告了......:-)

It seems a putty thing. Gnome-terminal sends the codes ^[OH and ^[OF for Home and End respectively, while putty sends ^[[1~ and ^[[4~. There's an option in putty to change the Home/End keys from standard mode to rxvt mode, and that seems to fix the Home key, but not the End key (which now sends ^[Ow). Guess it's time to file a bug report somewhere... :-)

╰◇生如夏花灿烂 2024-07-13 04:59:45

在 PuTTY 配置对话框中,转到“连接”->“连接” 数据并在连接之前在终端类型字符串中输入 linux

On the PuTTY configuration dialog, go to Connection -> Data and type linux into the Terminal-type string before connecting.

倒数 2024-07-13 04:59:45

距离这个问题首次提出已经过去近 11 年了。 当时,一些发行版确实附带了 putty terminfo 条目,但它充其量只是平庸。 从那以后的几年里,情况有所改善,十多年来所必需的黑客攻击已不再需要。 PuTTY 仍然默认将 TERM 设置为 xterm 以实现兼容性,但如果您要连接到现代的最新系统,您可能会幸运地覆盖此设置,并且将其设置为 putty-256color

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

It's now been nearly 11 years since this question was first posted. At the time, some distros did ship with a putty terminfo entry, but it was mediocre at best. In the years since, the situation has improved, and the hacks that were necessary for over a decade are no longer required. PuTTY still defaults to setting TERM to xterm for compatibility, but if you're connecting to modern, up-to-date systems, you'll likely have luck overriding this and setting it to putty-256color:

  1. Ensure the host has a terminfo entry for putty-256color: toe -a | grep -F putty
  2. Undo any hacks you may have enabled to get PuTTY working properly with zsh or other programs.
  3. Ensure PuTTY is up-to-date. It won't notify you when updates are available, and if it's out-of-date, you're likely going to run into a lot of the same issues. You may want to keep it up-to-date automatically with something like Chocolatey.
  4. In PuTTY's configuration dialog, go to Connection -> Data and set "Terminal-type string" to putty-256color.
  5. While you're at it, on the same configuration screen, add a new environment variable to enable 24-bit color. This variable isn't standardized, but it's sent by a number of other mainstream terminal emulators (e.g., iTerm2), and many programs understand it.
    1. Variable: COLORTERM
    2. Value: truecolor
  6. As of writing, I haven't found a distro that accepts the COLORTERM variable over SSH by default. You'll need to edit your OpenSSH configuration on the host to allow it. For example, on Debian-like distros, edit /etc/ssh/sshd_config and add COLORTERM to the AcceptEnv line.
  7. Everything should now "just work". If it doesn't:
    1. Ensure you've reconnected after making the change, or at least run exec zsh after changing TERM. zsh won't react to changes in TERM while it's running.
    2. Ensure that TERM is actually set to what you intended: echo $TERM
    3. Are you on the latest version of your distro? If you're on a long-term support lifecycle build, for example, even if your version is technically still supported, it may not have up-to-date terminfo entries.
    4. Are you using screen or tmux? That's another whole can of worms. Test without those first to narrow down where the issue is occurring. Within tmux, try setting TERM=tmux-256color. Within screen, try TERM=screen-256color.
    5. Are you on the latest version of PuTTY?
    6. Do you have RC-files that are implementing keybindings or other hacks? Try using default RC-files.
    7. Did you already change various PuTTY settings to attempt to fix the issue before attempting the terminfo fix? You'll probably need to reset those settings.
℡寂寞咖啡 2024-07-13 04:59:45

这对我有用

bindkey -v

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

This is working for me

bindkey -v

bindkey '\eOH'  beginning-of-line
bindkey '\eOF'  end-of-line
指尖上的星空 2024-07-13 04:59:45

应该在所有发行版(不一定是 zsh 的所有版本,这里是 ymmv)之间移植的正确答案是使用 zkbd 中的 zkbd 帮助程序实用程序。

键盘定义
键盘、工作站、终端、模拟器和窗口系统的大量可能组合使得 zsh 不可能为每种情况都提供内置的键绑定。 Functions/Misc 中的 zkbd 实用程序可以帮助您快速为您的配置创建键绑定。

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

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

当您运行 zkbd 时,它首先要求您输入终端类型; 如果它提供的默认值是正确的,只需按回车键即可。 然后它会要求您按多个不同的键来确定您的键盘和终端的特性; zkbd 警告您
如果它发现任何异常情况,例如删除键既不发送 ^H 也不发送 ^?。

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

您可以使用 source. 命令将此文件读入您​​的 .zshrc 或其他启动文件,然后在 bindkey 命令中引用 key 参数,如下所示:< /p>

          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 'keyboardDefinition'" zshcontrib,或搜索元手册页 zshall

the appropriate answer that should be portable across all distros (not necessarly all versions of zsh though, ymmv here) is to use the zkbd helper utility from zkbd.

Keyboard Definition
The large number of possible combinations of keyboards, workstations, terminals, emulators, and window systems makes it impossible for zsh to have built-in key bindings for every situation. The zkbd utility, found in Functions/Misc, can help you quickly create key bindings for your configuration.

Run zkbd either as an autoloaded function, or as a shell script:

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

When you run zkbd, it first asks you to enter your terminal type; if the default it offers is correct, just press return. It then asks you to press a number of different keys to determine characteristics of your keyboard and terminal; zkbd warns you
if it finds anything out of the ordinary, such as a Delete key that sends neither ^H nor ^?.

The keystrokes read by zkbd are recorded as a definition for an associative array named key, written to a file in the subdirectory .zkbd within either your HOME or ZDOTDIR directory. The name of the file is composed from the TERM, VENDOR and OSTYPE
parameters, joined by hyphens.

You may read this file into your .zshrc or another startup file with the source or . commands, then reference the key parameter in bindkey commands, like this:

          source ${ZDOTDIR:-$HOME}/.zkbd/$TERM-$VENDOR-$OSTYPE
          [[ -n ${key[Left]} ]] && bindkey "${key[Left]}" backward-char
          [[ -n ${key[Right]} ]] && bindkey "${key[Right]}" forward-char
          # etc.

Note that in order for autoload zkbd to work, the zkbd file must be in one of the directories named in your fpath array (see zshparam(1)). This should already be the case if you have a standard zsh installation; if it is not, copy Functions/Misc/zkbd to an appropriate directory.

see man -P "less -p 'keyboard definition'" zshcontrib, or search the meta-manpage zshall

飘落散花 2024-07-13 04:59:44

我发现它是一个组合:

One

ZSH 开发人员认为 ZSH 不应该定义 HomeEndDel 的操作,...键。

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 中。

Two

Putty 将 xterm 作为终端类型发送到远程主机。 但在某个地方搞砸了,并且没有发送 HomeEnd 的正确控制代码,...这是人们期望从 xterm 获得的。 或者 xterm 终端预计不会发送这些内容或其他内容...(Del 键在 xterm 中确实有效,但是,如果您对其进行配置在 ZSH 中)。 另请注意,您的数字键盘在 Vim 中表现得很有趣,例如在 xterm 终端中。

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

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

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

所以,解决这两个问题就可以了:)

I found it's a combination:

One

The ZSH developers do not think that ZSH should define the actions of the Home, End, Del, ... keys.

Debian and Ubuntu fix this by defining the normal actions the average user would expect in the global /etc/zsh/zshrc file. Following the relevant code (it is the same on Debian and 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

So, if you are connecting to a Debian or Ubuntu box, you don't have to do anything. Everything should work automagically (if not, see below).

But... if you are connecting to another box (e.g. FreeBSD), there might be no user friendly default zshrc. The solution is of course to add the lines from the Debian/Ubuntu zshrc to your own .zshrc.

Two

Putty sends xterm as terminal type to the remote host. But messes up somewhere and doesn't send the correct control codes for Home, End, ... that one would expect from an xterm. Or an xterm terminal isn't expected to send those or whatever... (Del key does work in xterm however, if you configure it in ZSH). Also notice that your Numpad-keys act funny in Vim for example with xterm terminal.

The solution is to configure Putty to send another terminal type. I've tried xterm-color and linux. xterm-color fixed the Home/End problem, but the Numpad was still funny. Setting it to linux fixed both problems.

You can set terminal type in Putty under Connection -> Data. Do not be tempted to set your terminal type in your .zshrc with export TERM=linux, that is just wrong. The terminal type should be specified by your terminal app. So that if, for example, you connect from a Mac box with a Mac SSH client it can set it's own terminal type.

Notice that TERM specifies your terminal type and has nothing to do with the host you are connecting to. I can set my terminal type to linux in Putty and connect to FreeBSD servers without problems.

So, fix both these things and you should be fine :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文