BashでのEmacsスタイルのキーバインディングの混乱した動作

BashでのEmacsスタイルのキーバインディングの混乱した動作

emacs-style keybindingsBashには便利でシンプルなコマンドライン編集機能がたくさんあります。たとえば、Ctrl+wカーソルの左側にある単語を削除(「kill」)します。

他のキーバインディングは、Alt+d最初のキーバインディングの「ミラー」でなければなりません。カーソルから単語を削除する必要があります。

しかし、私はこれら2つのキーバインディングの動作が完全に対称的ではないことを発見しました。 1つの単語Ctrl+wとして扱うのではなく、2つの単語として扱います。foo.barAlt+d

もっと迷惑なのは# echo二つの単語なのにCtrl+w一つの単語という点だAlt+d

これにロジックはありますか?彼らが言葉を同じように扱わない理由はありますか?

これを変える方法はありますか?

バッシュを使っていますDebian Wheezy

ベストアンサー1

異なるbashコマンドは異なる単語の概念を使用します。コマンドの各コマンドの説明を表示する手動

C-w古い空白を殺します。M-DEL(通常Alt+)単語に文字と数字のみが含まれている前の単語の境界(と同じBackSpace)を削除し、同様に前に削除します。M-bM-fM-d

BashはReadlineライブラリを使用してユーザー入力を処理し、次の方法で設定できます。~/.inputrcまたは経由bind内蔵されています~/.bashrc。あるキーを別のキーにバインドできます。ラインコマンドの読み出しあなたがしたい場合。キーを変更された変数bind -xにバインドするbash関数を使用することもできます。READLINE_LINE

M-dたとえば、Kill 単語をシェル単語にするには、次のようにバインドします。shell-kill-wordあなたの.bashrc

bind '"\M-d": shell-kill-word'

スペースで区切られた単語を削除するには組み込みM-d関数がないため、マクロまたはシェル関数を作成する必要があります。スペースで区切られた単語からなる移動コマンドがないため、少なくともその部分には機能が必要です。

delete_whitespace_word () {
  local suffix="${READLINE_LINE:$READLINE_POINT}"
  if [[ $suffix =~ ^[[:space:]]*[^[:space:]]+ ]]; then
    local -i s=READLINE_POINT+${#BASH_REMATCH[0]}
    READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}${READLINE_LINE:$s}"
  fi
}
bind -x '"\ed": delete_whitespace_word'

M-d私が知っている限り、bashコードからkillループにアクセスする方法がないので、killをスペースで区切られた単語にするのはより複雑です。そのためには、削除するセクションの終わりを見つける関数と実際の削除に続くマクロが必要です。

forward_whitespace_word () {
  local suffix="${READLINE_LINE:$READLINE_POINT}" 
  if [[ $suffix =~ ^[[:space:]]*[^[:space:]]+ ]]; then
    ((READLINE_POINT += ${#BASH_REMATCH[0]}))
  else
    READLINE_POINT=${#READLINE_LINE}
  fi
}
bind -x '"\C-xF": forward_whitespace_word'
bind '"\C-x\C-w": kill-region'
bind '"\ed": "\e \C-xF\C-x\C-w"'

これらすべてがzshでははるかに簡単です。

おすすめ記事