我正在从 bash 转到 zsh。在 bash 中,esc-del 删除路径名的一个组成部分;在 zsh 中,它会删除整个路径名。
也就是说,如果我输入:
cat /usr/local/bin/foobar
然后我按下 ESC-DEL,在 bash 中我得到了:
cat /usr/local/bin
使用 zsh 我最终得到:
cat
这不是我想要的!
我该如何改变这种行为?
答案1
我用这个功能
function kill-path-word()
{
local words word spaces
zle set-mark-command # save current cursor position ("mark")
while [[ $LBUFFER[-1] == "/" ]] {
(( CURSOR -= 1 )) # consume all trailing slashes
}
words=("${(s:/:)LBUFFER/\~/_}") # split command line at "/" after "~" is replaced by "_" to prevent FILENAME EXPANSION messing things up
word=$words[-1] # this is the portion from cursor back to previous "/"
(( CURSOR -= $#word )) # then, jump to the previous "/"
zle exchange-point-and-mark # swap "mark" and "cursor"
zle kill-region # delete marked region
}
zle -N kill-path-word
现在,你可以将此功能绑定到ESC+Del
例如
bindkey "^[^[[3~" kill-path-word
将两个代码片段放入你的~/.zshrc
文件中,然后重新启动嘚然后foo/bar/baz////
应缩短为foo/bar/
upon ESC+Del
。
如果您还想删除训练斜线(如您的示例所示),请while ...
在之前添加相同的循环zle exchange-point-and-mark
。
答案2
为了扩展 mpy 的答案,这是一个不会完全使用最后一个 'cat /usr' 的版本,而是先删除 '/usr',然后删除 'cat '。它用正则表达式拆分 $LBUFFER 变量,这比单个斜杠字符更灵活。
function kill-path-word()
{
local words word spaces
zle set-mark-command # save current cursor position ("mark")
words=($(grep -Eo '(/?[a-zA-Z1-9]+[\\ /]*)|([^a-zA-Z0-9])' <<< "$LBUFFER"))
word=$words[-1] # this is the portion from cursor back to previous "/"
while [[ $LBUFFER[-1] == " " ]] {
(( CURSOR -= 1 )) # consume all trailing spaces - they don't get into the $word variable
}
(( CURSOR -= $#word )) # then, jump to the previous "/"
zle exchange-point-and-mark # swap "mark" and "cursor"
zle kill-region # delete marked region
}
zle -N kill-path-word
bindkey "^[^?" kill-path-word