В bash поведение такое:
- Ctrl+ Wудаляет слово за курсором до следующего пробела
- Ctrl+ Alt+ Hудаляет слово за курсором до следующего разделительного символа, например
.
,,
, ,-
,/
и т. д.
В zsh
обоих случаях Ctrl+ Wи Ctrl+ Alt+ Hведут себя как последний в bash
.
Я бы хотел такого же поведения, как в bash
.
решение1
Это делает то, что вам нужно, независимо от того, что находится в $WORDCHARS
, и делает удаленные слова доступными для yank
:
# Create a new widget.
zle -N backward-kill-space-word
backward-kill-space-word() {
# Inform the line editor that this widget will kill text.
zle -f kill
# Set $WORDCHARS for this command only.
WORDCHARS='*?_-.[]~=/&;!#$%^(){}<>' zle .backward-kill-word
}
# See comments above.
zle -N backward-kill-bash-word
backward-kill-bash-word() {
zle -f kill
WORDCHARS='' zle .backward-kill-word
}
# Bind the widgets to keys.
bindkey '^W' backward-kill-space-word
bindkey '^[^H' backward-kill-bash-word
В качестве альтернативы я выпустилплагин называетсяzsh-edit
, который поставляется с более сложными версиями этих сочетаний клавиш.
решение2
Вы можете задать специальные символы, которые считаются частью слова с помощью переменной WORDCHARS
. Это влияет на то, как слова удаляются Ctrl + W
:
WORDCHARS='~!#$%^&*(){}[]<>?.+;-_/\|=@`'
Однако он также влияет на Ctrl + Alt + H
. Мы хотим, чтобы это поведение применялось только к Ctrl + W
. Но есть трюк, который мы можем сделать. Позвольте мне объяснить:
Вы можете переназначить комбинации клавиш на разные функции (см. man zshzle
). И есть 2 функции, которые на самом деле ведут себя одинаково:
- удалить-слово-назад
- слово-убить-назад
Вы также можете переопределить эти функции с помощью zle -N <func>
. Я не совсем уверен, как это работает, но вы получите представление, если прочитаете код, в любом случае, это делает свое дело.
По умолчанию Ctrl + W
и и Ctrl + Alt + H
сопоставлены с backward-kill-word
. Поэтому мы можем переопределить backward-delete-word
и затем связать это с Ctrl + W
:
# Make `Ctrl + W` behave like it does in Bash, deleting words separated by
# spaces. We do this by redefining the `backward-delete-word` function and bind
# that to `Ctrl + W`.
SPACE_WORDCHARS='~!#$%^&*(){}[]<>?.+;-_/\|=@`'
backward-delete-word() WORDCHARS=$SPACE_WORDCHARS zle .$WIDGET
zle -N backward-delete-word
bindkey "^W" backward-delete-word
Да, теперь Ctrl + W
удаляет слова большего размера, чем Ctrl + Alt + H
!
Редактировать:
Очень грустно, что теперь я обнаруживаю, что этот подход не имеет некоторой функциональности: когда вы удаляете слово, оно не копируется в буфер вставки (Ctrl + Y). Пока не нашел решения для этого..
решение3
В конечном итоге я нашел желаемое поведение с помощью этих привязок:
# Configures bindings for jumping/deleting full and sub-words, similar to
# the keybindings in bash.
# Jumping:
# Alt + B Backward sub-word
# Ctrl + Alt + B Backward full-word
# Alt + F Forward sub-word
# Ctrl + Alt + F Forward full-word
# Deleting:
# Ctrl + W Backward delete full-word
# Ctrl + Alt + H Backward delete sub-word
# Alt + D Forward delete sub-word
# Ctrl + Alt + D Forward delete full-word
# Which characters, besides letters and numbers, that are jumped over by a
# full-word jump:
FULLWORDCHARS="*?_-.,[]~=/&:;!#$%^(){}<>'\""
backward-full-word() { WORDCHARS=$FULLWORDCHARS zle .backward-word ; }
backward-sub-word() { WORDCHARS="" zle .backward-word ; }
forward-full-word() { WORDCHARS=$FULLWORDCHARS zle .forward-word ; }
backward-kill-full-word() { WORDCHARS=$FULLWORDCHARS zle .backward-kill-word ; }
backward-kill-sub-word() { WORDCHARS="" zle .backward-kill-word ; }
forward-kill-full-word() { WORDCHARS=$FULLWORDCHARS zle .kill-word ; }
forward-kill-sub-word() { WORDCHARS="" zle .kill-word ; }
zle -N backward-full-word
zle -N backward-sub-word
zle -N forward-full-word
zle -N backward-kill-full-word
zle -N backward-kill-sub-word
zle -N forward-kill-full-word
zle -N forward-kill-sub-word
# For `forward-sub-word` we use the built-in `emacs-forward-word` widget,
# because that simulates bash behavior.
zle -A emacs-forward-word forward-sub-word
bindkey "^[b" backward-sub-word
bindkey "^[^b" backward-full-word
bindkey "^[f" forward-sub-word
bindkey "^[^f" forward-full-word
bindkey "^[^h" backward-kill-sub-word
bindkey "^w" backward-kill-full-word
bindkey "^[d" forward-kill-sub-word
bindkey "^[^d" forward-kill-full-word