Question

Comment utiliser Shift pour sélectionner une partie de la ligne de commande (comme dans de nombreux éditeurs de texte)?

Était-ce utile?

La solution

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

Qui suppose que votre terminal envoie une séquence d'évasion différente Arrivées de décalage de celui envoyé sur Flèche et que votre base de données Terminfo est correctement remplie avec les capacités KLFT et KRIT correspondantes, et que vous utilisez la liaison des clés de style EMACS.

Ou, pour factoriser un peu le code:

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
}

Ci-dessus, des séquences codées en dur pour les cas où la base de données Terminfo ne dispose pas d'informations (en utilisant des séquences xterm).

Autres conseils

En développant l'excellente réponse de Stephane à partir de près de 3 ans, j'ai ajouté quelques liaisons supplémentaires pour rendre le comportement (presque) entièrement cohérent avec tout le comportement du clavier standard de Windows:

  • La sélection est effacée lors de l'utilisation d'une clé de navigation (flèche, maison, fin) sans décalage
  • Backspace et Del Supprimer une sélection active
  • La sélection est étendue au mot suivant / précédent lors de l'utilisation Ctrl+Shift+Left/Ctrl+Shift+Right
  • Shift+Home et Shift+End Étendez respectivement la sélection au début et à la fin de la ligne. Ctrl+Shift+Home et Ctrl+Shift+End faire de même.

Deux choses qui ne sont pas exactement les mêmes:

  • L'extension d'une sélection au mot suivant comprend l'espace de fuite, contrairement aux fenêtres. Cela pourrait être corrigé, mais cela ne me dérange pas.
  • La saisie lorsqu'il y a une sélection active ne le supprimera pas et le remplacera par le caractère que vous avez tapé. Cela semblerait nécessiter beaucoup plus de travail pour remapper l'ensemble du clavier. Ne vaut pas la peine pour moi.

Notez que le comportement d'impression par défaut est de se lier Shift+End et Shift+Home Pour accéder au tampon arrière défile. Cela remplace la configuration ZSH; Les clés ne sont jamais passées. Pour que ceux-ci fonctionnent, vous devrez configurer une clé différente (ou désactiver le défilement vers l'arrière) /etc/minttyrc ou ~/.minttyrc. Voir "Modificateur pour le défilement" ici - La solution la plus simple est juste définie ScrollMod=2 pour le lier à Alt à la place de Shift.

Donc tout:

~ / .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
}

Cela couvre des keycodes à partir de plusieurs configurations de clavier différentes que j'ai utilisées.

Noter: Les valeurs de la colonne "clé" ne signifient rien, elles sont simplement utilisées pour construire une référence nommée pour ZLE. Ils pourraient être n'importe quoi. Ce qui est important, c'est le seq, mode et widget Colonnes.

Note 2: Vous pouvez lier à peu près toutes les clés souhaitées, vous avez juste besoin des codes de clés utilisés dans votre émulateur de console. Ouvrez une console régulière (sans courir ZSH) et type Ctrl + v Et puis la clé que vous voulez. Il devrait émettre le code. ^[ moyens \E.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top