заставить 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

Связанный контент