zsh ESC-Del löscht Komponenten eines Pfades und nicht den gesamten Pfad

zsh ESC-Del löscht Komponenten eines Pfades und nicht den gesamten Pfad

Ich wechsle von Bash zu Zsh. In Bash löscht Esc-Entf eine Komponente eines Pfadnamens; in Zsh löscht es den gesamten Pfadnamen.

Das heißt, wenn ich Folgendes eingegeben habe:

cat /usr/local/bin/foobar

und ich drückte ESC-ENTF. In Bash endete das Ergebnis mit:

cat /usr/local/bin

und mit zsh erhalte ich:

cat

und das ist nicht das, was ich will!

Wie ändere ich dieses Verhalten?

Antwort1

Ich benutze diese Funktion

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

Nun können Sie diese Funktion binden an zB ESC+Deldurch

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

Fügen Sie beide Snippets in Ihre ~/.zshrcDatei ein und starten Sie neuzshfoo/bar/baz////und sollte dann zu foo/bar/„upon“ gekürzt werden ESC+Del.

Wenn Sie auch den Trainingsschrägstrich entfernen möchten (wie in Ihrem Beispiel), fügen Sie while ...davor dieselbe Schleife hinzu zle exchange-point-and-mark.

Antwort2

Um die Antwort von mpy zu erweitern: Dies ist eine Version, die das letzte 'cat /usr' nicht komplett verbraucht, sondern '/usr' und dann 'cat' löscht. Sie teilt die Variable $LBUFFER durch einen regulären Ausdruck auf, der flexibler ist als ein einzelner Schrägstrich.

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

verwandte Informationen