Bash

bash 中 emacs 樣式鍵綁定的令人困惑的行為

  • June 25, 2015

emacs-style keybindingsBash為簡單的命令行編輯提供了許多有用的功能。例如,Ctrl+w刪除(“殺死”)游標左側的單詞。

另一個鍵綁定,Alt+d應該是第一個鍵的“鏡像”。它應該從游標中刪除一個單詞。

但是,我注意到,這兩個鍵綁定並不完全對稱。而當做一個詞,Ctrl+w把它當成兩個詞foo.bar``Alt+d

更可氣的是,# echo是兩個字Ctrl+w,卻是一個字Alt+d

這有什麼邏輯嗎?他們為什麼不以同樣的方式對待單詞有什麼原因嗎?

我有什麼辦法可以改變這個嗎?

我正在使用 bashDebian Wheezy

不同的 bash 命令使用不同的單詞概念。檢查手冊中每個命令的描述。

C-w殺死前一個空格。M-DEL(通常是Alt+ BackSpace)殺死前一個單詞邊界,其中單詞僅包含字母和數字(與M-band相同M-f),並且M-d類似地向前殺死。

Bash 使用 Readline 庫來處理使用者輸入,並且可以通過~/.inputrc或通過bind內置的~/.bashrc. 如果您願意,可以將鍵綁定到不同的readline 命令。您還可以使用bind -x將鍵綁定到修改READLINE_LINE變數的 bash 函式。

例如,要M-d殺死一個 shell 詞,請將其綁定到shell-kill-word您的.bashrc:

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

M-d刪除以空格分隔的單詞,沒有內置函式,因此您需要編寫宏或 shell 函式。由於沒有以空格分隔的單詞的運動命令,因此您至少需要一個函式用於該部分。

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 ring。所以這需要一個函式來找到要殺死的部分的結尾,以及一個宏來跟隨這個實際的殺死。

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 中都會容易得多。

引用自:https://unix.stackexchange.com/questions/150578