Как использовать Shift для выделения части командной строки (как во многих текстовых редакторах)?
Zsh zle shift selection
Ответы (2)
shift-arrow() {
((REGION_ACTIVE)) || zle set-mark-command
zle $1
}
shift-left() shift-arrow backward-char
shift-right() shift-arrow forward-char
shift-up() shift-arrow up-line-or-history
shift-down() shift-arrow down-line-or-history
zle -N shift-left
zle -N shift-right
zle -N shift-up
zle -N shift-down
bindkey $terminfo[kLFT] shift-left
bindkey $terminfo[kRIT] shift-right
bindkey $terminfo[kri] shift-up
bindkey $terminfo[kind] shift-down
Это предполагает, что ваш терминал отправляет другую escape-последовательность при Shift-Arrow, отличную от той, которая была отправлена на Arrow, и что ваша база данных terminfo правильно заполнена соответствующими возможностями kLFT и kRIT, и что вы используете привязку клавиш в стиле emacs.
Или, чтобы немного разложить код:
shift-arrow() {
((REGION_ACTIVE)) || zle set-mark-command
zle $1
}
for key kcap seq widget (
left LFT $'\e[1;2D' backward-char
right RIT $'\e[1;2C' forward-char
up ri $'\e[1;2A' up-line-or-history
down ind $'\e[1;2B' down-line-or-history
) {
functions[shift-$key]="shift-arrow $widget"
zle -N shift-$key
bindkey ${terminfo[k$kcap]-$seq} shift-$key
}
Выше жестко запрограммированные последовательности для случаев, когда в базе данных terminfo нет информации (с использованием xterm
последовательностей).
Расширяя отличный ответ Стефана почти 3 года назад, я добавил еще несколько привязок, чтобы сделать поведение (почти) полностью совместимым со всем стандартным поведением клавиатуры Windows:
- Выбор очищается при использовании навигационной клавиши (стрелка, начало, конец) БЕЗ сдвига
Backspace
иDel
удаляют активный выбор- При использовании _3 _ / _ 4_ выделение расширяется до следующего / предыдущего слова
Shift+Home
иShift+End
расширяют выделение до начала и конца строки соответственно.Ctrl+Shift+Home
иCtrl+Shift+End
делают то же самое.
Две вещи, которые не совсем совпадают:
- Расширение выделения до следующего слова включает в себя конечный пробел, в отличие от окон. Это можно исправить, но меня это не беспокоит.
- Ввод, когда есть активный выбор, не удалит его и не заменит на набранный вами символ. Казалось бы, потребуется гораздо больше работы, чтобы переназначить всю клавиатуру. Для меня это не стоит того.
Обратите внимание, что поведение mintty по умолчанию заключается в связывании Shift+End
и Shift+Home
для доступа к буферу обратной прокрутки. Это заменяет конфигурацию zsh; ключи никогда не проходят. Чтобы они работали, вам нужно будет настроить другую клавишу (или отключить прокрутку назад) в /etc/minttyrc
или ~/.minttyrc
. См. «Модификатор для прокрутки» здесь - простейшее решение - просто установить ScrollMod=2
, чтобы привязать его к Alt
вместо Shift
.
Итак все:
~ / .minttyrc
ScrollMod=2
~ / .zshrc
r-delregion() {
if ((REGION_ACTIVE)) then
zle kill-region
else
local widget_name=$1
shift
zle $widget_name -- $@
fi
}
r-deselect() {
((REGION_ACTIVE = 0))
local widget_name=$1
shift
zle $widget_name -- $@
}
r-select() {
((REGION_ACTIVE)) || zle set-mark-command
local widget_name=$1
shift
zle $widget_name -- $@
}
for key kcap seq mode widget (
sleft kLFT $'\e[1;2D' select backward-char
sright kRIT $'\e[1;2C' select forward-char
sup kri $'\e[1;2A' select up-line-or-history
sdown kind $'\e[1;2B' select down-line-or-history
send kEND $'\E[1;2F' select end-of-line
send2 x $'\E[4;2~' select end-of-line
shome kHOM $'\E[1;2H' select beginning-of-line
shome2 x $'\E[1;2~' select beginning-of-line
left kcub1 $'\EOD' deselect backward-char
right kcuf1 $'\EOC' deselect forward-char
end kend $'\EOF' deselect end-of-line
end2 x $'\E4~' deselect end-of-line
home khome $'\EOH' deselect beginning-of-line
home2 x $'\E1~' deselect beginning-of-line
csleft x $'\E[1;6D' select backward-word
csright x $'\E[1;6C' select forward-word
csend x $'\E[1;6F' select end-of-line
cshome x $'\E[1;6H' select beginning-of-line
cleft x $'\E[1;5D' deselect backward-word
cright x $'\E[1;5C' deselect forward-word
del kdch1 $'\E[3~' delregion delete-char
bs x $'^?' delregion backward-delete-char
) {
eval "key-$key() {
r-$mode $widget \$@
}"
zle -N key-$key
bindkey ${terminfo[$kcap]-$seq} key-$key
}
Это касается кодов клавиш от нескольких различных конфигураций клавиатуры, которые я использовал.
Примечание. значения в столбце «ключ» ничего не значат, они просто используются для создания именованной ссылки для zle. Они могли быть кем угодно. Важны столбцы seq
, mode
и widget
.
Примечание 2: вы можете привязать практически любые клавиши, которые захотите, вам просто нужны коды клавиш, используемые в эмуляторе консоли. Откройте обычную консоль (без запуска zsh) и введите Ctrl + V, а затем нужный ключ. Он должен выдать код. ^[
означает \E
.
shome
, csleft
и т. Д.? Google здесь не дружелюбен.
- person Myer; 13.10.2015
bck-i-search
.
- person Vladimir Panteleev; 11.10.2019
backward-delete-char
, который является привязкой по умолчанию для BS, не действует одинаково при вызове из функции в контексте bck-i-search
). Вы по-прежнему можете использовать CTRL + H в качестве возврата; Думаю, нужно решить, должен ли ключ BS работать в этом контексте или в обычном CLI.
- person Jamie Treworgy; 17.10.2019
set-mark-command
, поэтому данные, которые я могу предоставить, не будут мне очень полезны. Подshift
вы имели в виду комбинации<S-Right>
и<S-Left>
? Вы можете использовать<C-v>
, чтобы узнать, какой именно терминал выдает, когда вы нажимаете<S-{Arrow}>
и связываете это с чем-то, но это будет зависеть от терминала. Если вам нужен выделенный фрагмент, а он отсутствует (я точно не знаю), вам следует посмотреть на$zle_highlighting
иxclip
. Эмулировать выделение в zsh возможно, но я никогда не беспокоился об этом и не знаю никого, кто бы беспокоился. - person ZyX   schedule 23.03.2011