讓 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/on 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

相關內容