web-dev-qa-db-ja.com

zshのホーム/エンドキーがパテで機能しない

Ubuntuボックスでデフォルトのシェルとしてzshを実行していますが、gnome-terminalを使用するとすべてが正常に機能します(私が知る限り、xtermをエミュレートします)。 sshとPuTTY(xtermもエミュレート)を介してWindowsボックスからログインすると、突然ホーム/エンドキーが機能しなくなります。

これらの行をzshrcファイルに追加することで解決できました...

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

...しかし、私はまだここで何が悪いのか疑問に思っています。何か案が?

35
agnul

私はそれが組み合わせであることがわかりました:

1つ

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に行を追加することです。

2

PuTTYは、端末タイプとしてxtermをリモートホストに送信します。しかし、どこかで混乱し、正しい制御コードを送信しません Home、 End、... xtermから期待されること。または、xterm端末がそれらなどを送信することは期待されていません...(Del キーはxtermで機能しますが、ZSHで構成した場合)。また、テンキーのキーは、たとえばxtermターミナルを使用してVimでおかしな動作をすることに注意してください。

解決策は、別の端末タイプを送信するようにPuTTYを構成することです。 xterm-colorlinuxを試しました。 xterm-color修正 Home/End 問題がありましたが、テンキーはまだ面白かったです。 linuxに設定すると、両方の問題が修正されました。

PuTTYの[接続]-> [データ]で端末タイプを設定できます。 .zshrcexport TERM=linuxを使用して端末タイプを設定しようとしないでください。これは間違っています。ターミナルタイプは、ターミナルアプリで指定する必要があります。たとえば、MacボックスからMac SSHクライアントに接続する場合、独自の端末タイプを設定できます。

TERMは端末タイプを指定し、接続しているホストとは何の関係もないことに注意してください。 PuTTYで端末タイプをlinuxに設定し、FreeBSDサーバーに問題なく接続できます。

だから、これらの両方を修正すれば大丈夫です:)

65
hopla

PuTTY構成ダイアログで、接続->データに移動し、接続する前にターミナルタイプの文字列にlinuxと入力します。

15
Adam Pierce

これは私のために働いています

bindkey -v

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

PuTTYのようです。 Gnome-terminalはHomeとEndにそれぞれコード^[OH^[OFを送信し、PuTTYは^[[1~^[[4~を送信します。 PuTTYには、ホーム/終了キーを標準モードからrxvtモードに変更するオプションがあります。これにより、ホームキーは修正されるようですが、終了キーは修正されません(現在は^[Owを送信します)。どこかにバグレポートを提出する時が来たと思います... :-)

3
agnul

allディストリビューション(必ずしもすべてのバージョンのzshではありませんが、ここではymmv)間で移植可能である必要がある適切な答えは、zkbdのzkbdヘルパーユーティリティを使用することです。

キーボードの定義
キーボード、ワークステーション、端末、エミュレーター、およびウィンドウシステムの可能な組み合わせが多数あるため、zshがあらゆる状況に対応する組み込みのキーバインディングを持つことは不可能です。 Functions/Miscにあるzkbdユーティリティは、構成のキーバインディングをすばやく作成するのに役立ちます。

オートロードされた関数またはシェルスクリプトとしてzkbdを実行します。

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

Zkbdを実行すると、最初に端末タイプの入力を求められます。提供されるデフォルトが正しい場合は、Returnキーを押すだけです。次に、キーボードと端末の特性を判断するために、いくつかの異なるキーを押すように求められます。 zkbdは、^ Hも^?も送信しないDeleteキーなど、通常とは異なるものを検出した場合に警告します。

Zkbdによって読み取られたキーストロークは、keyという名前の連想配列の定義として記録され、HOMEまたはZDOTDIRディレクトリ内のサブディレクトリ.zkbd内のファイルに書き込まれます。ファイルの名前は、ハイフンで結合されたTERM、VENDOR、およびOSTYPEパラメーターで構成されます。

このファイルを.zshrcまたはsource' orを使用して別のスタートアップファイルに読み込むことができます。コマンドを実行し、次のように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.

「autoloadzkbd」が機能するためには、zkdbファイルがfpath配列で指定されたディレクトリの1つにある必要があることに注意してください(zshparam(1)を参照)。標準のzshがインストールされている場合、これはすでに当てはまるはずです。そうでない場合は、Functions/Misc/zkbdを適切なディレクトリにコピーします。

man -P "less -p 'keyboard definition'" zshcontribを参照するか、メタマンページzshallを検索してください

3
Josh McGee

これらのバインディングは、emacsモードで設定されたデフォルトのバインディングの一部ではないようです。

「bindkey-e」を実行した後、デフォルトのzshインストールで「where-isbeginning-of-line」を実行すると、^ aにのみバインドされていることが示されます。おそらく、zsh開発者に理由を尋ねる必要があります:-)

0
Sec