Zsh zle shift selection

Как использовать Shift для выделения части командной строки (как во многих текстовых редакторах)?


person log0    schedule 23.03.2011    source источник
comment
Какая ОС? Какой терминал? Кроме того, это может быть лучше спросить в SuperUser, поскольку это не связано с программированием (но я думаю, что программисты с большей вероятностью будут использовать CLI ;-)   -  person DarkDust    schedule 23.03.2011
comment
Надеюсь, я ищу ответ, не зависящий от платформы или терминала. Тогда вы правы для superUser, но ответ потенциально может быть zle-скриптом, так что ...   -  person log0    schedule 23.03.2011
comment
Понятия не имею, что такое zle, но в Unix выбор - это функция, реализованная каждым терминалом. Это не базовая функциональность, и, например, на реальных терминалах, таких как консоли с текстовым режимом или аппаратный терминал, нет поддержки выбора (насколько мне известно).   -  person DarkDust    schedule 23.03.2011
comment
В zsh выделение или отметки обрабатываются zle (редактор строки zsh), для чего я сейчас.   -  person log0    schedule 23.03.2011
comment
@Ugo Как вы делаете отбор? Я не знаю никаких виджетов по умолчанию ни для выбора, ни для отметок, поэтому, скорее всего, это обрабатывается терминалом.   -  person ZyX    schedule 23.03.2011
comment
@ZyX set-mark-command zsh.sourceforge.net/Doc /Release/Zsh-Line-Editor.html#SEC134   -  person log0    schedule 23.03.2011
comment
Фактически, вы можете выделить некоторый текст в своем терминале (с помощью мыши), но это отличается от выделения для редактирования командной строки.   -  person log0    schedule 23.03.2011
comment
@Ugo Я знал второй факт, но я не знал о set-mark-command, поэтому данные, которые я могу предоставить, не будут мне очень полезны. Под shift вы имели в виду комбинации <S-Right> и <S-Left>? Вы можете использовать <C-v>, чтобы узнать, какой именно терминал выдает, когда вы нажимаете <S-{Arrow}> и связываете это с чем-то, но это будет зависеть от терминала. Если вам нужен выделенный фрагмент, а он отсутствует (я точно не знаю), вам следует посмотреть на $zle_highlighting и xclip. Эмулировать выделение в zsh возможно, но я никогда не беспокоился об этом и не знаю никого, кто бы беспокоился.   -  person ZyX    schedule 23.03.2011


Ответы (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 последовательностей).

person Stephane Chazelas    schedule 30.08.2012

Расширяя отличный ответ Стефана почти 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.

person Jamie Treworgy    schedule 17.06.2015
comment
Где найти дополнительную документацию по shome, csleft и т. Д.? Google здесь не дружелюбен. - person Myer; 13.10.2015
comment
Как я могу заменить ctrl на alt здесь? Кроме того, как я могу сделать их совместимыми с ubuntu и xterm? - person Myer; 13.10.2015
comment
К сожалению, повторное связывание backspace таким образом прерывает набор backspace во время bck-i-search. - person Vladimir Panteleev; 11.10.2019
comment
@VladimirPanteleev Верно - я не могу найти хорошего обходного пути - похоже, у него особое поведение (например, backward-delete-char, который является привязкой по умолчанию для BS, не действует одинаково при вызове из функции в контексте bck-i-search). Вы по-прежнему можете использовать CTRL + H в качестве возврата; Думаю, нужно решить, должен ли ключ BS работать в этом контексте или в обычном CLI. - person Jamie Treworgy; 17.10.2019
comment
это помогает (почему это не по умолчанию?) Но наличие alt / option вместо ctrl поможет еще больше - person Havnar; 14.09.2020
comment
Как поместить выделение в буфер обмена (как обычный буфер обмена ctrl + shift + c)? - person Slim; 11.03.2021