bash 中 emacs 樣式鍵綁定的令人困惑的行為
emacs-style keybindings
Bash為簡單的命令行編輯提供了許多有用的功能。例如,Ctrl+w
刪除(“殺死”)游標左側的單詞。另一個鍵綁定,
Alt+d
應該是第一個鍵的“鏡像”。它應該從游標中刪除一個單詞。但是,我注意到,這兩個鍵綁定並不完全對稱。而當做一個詞,
Ctrl+w
把它當成兩個詞foo.bar``Alt+d
更可氣的是,
# echo
是兩個字Ctrl+w
,卻是一個字Alt+d
。這有什麼邏輯嗎?他們為什麼不以同樣的方式對待單詞有什麼原因嗎?
我有什麼辦法可以改變這個嗎?
我正在使用 bash
Debian Wheezy
不同的 bash 命令使用不同的單詞概念。檢查手冊中每個命令的描述。
C-w
殺死前一個空格。M-DEL
(通常是Alt
+BackSpace
)殺死前一個單詞邊界,其中單詞僅包含字母和數字(與M-b
and相同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 中都會容易得多。