Zsh zle shift выбор - PullRequest
       27

Zsh zle shift выбор

7 голосов
/ 23 марта 2011

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

Ответы [ 2 ]

11 голосов
/ 17 июня 2015

В продолжение превосходного ответа Стефана почти 3 года назад, я добавил еще несколько привязок, чтобы поведение (почти) полностью соответствовало стандартному поведению клавиатуры Windows:

  • Выбор очищается при использовании навигационной клавиши (стрелка, дом, конец) БЕЗ сдвига
  • Backspace и Del удалить активный выбор
  • Выбор распространяется на следующее / предыдущее слово при использовании Ctrl+Shift+Left / Ctrl+Shift+Right
  • 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.

11 голосов
/ 30 августа 2012
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-Arrows от той, которая отправлена ​​на 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 последовательности).

...