让 zsh ESC-Del 删除路径的一部分而不是整个路径

让 zsh ESC-Del 删除路径的一部分而不是整个路径

我正在从 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

相关内容