hacer que zsh ESC-Del elimine componentes de una ruta y no toda la ruta

hacer que zsh ESC-Del elimine componentes de una ruta y no toda la ruta

Me estoy moviendo de bash a zsh. En bash, esc-del eliminó un componente de una ruta de acceso; en zsh elimina el nombre de ruta completo.

Es decir, si he escrito:

cat /usr/local/bin/foobar

y presioné ESC-DEL, en bash terminé con:

cat /usr/local/bin

y con zsh termino con:

cat

¡que no es lo que quiero!

¿Cómo cambio este comportamiento?

Respuesta1

Yo uso esta función

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

Ahora, puede vincular esta función, por ejemplo, ESC+Delmediante

bindkey "^[^[[3~" kill-path-word

Coloque ambos fragmentos en su ~/.zshrcarchivo, reiniciezshy luego foo/bar/baz////debería acortarse a foo/bar/on ESC+Del.

Si también desea eliminar la barra diagonal de entrenamiento (como en su ejemplo), agregue el mismo while ...bucle antes zle exchange-point-and-mark.

Respuesta2

Para ampliar la respuesta de mpy, esta es una versión que no consume el último 'cat/usr' por completo, sino que elimina '/usr' y luego 'cat'. Divide la variable $LBUFFER mediante una expresión regular, que es más flexible que un solo carácter de barra.

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

información relacionada