Pregunta

¿Cómo usar Shift para seleccionar parte de la línea de comandos (como en muchos editores de texto)?

¿Fue útil?

Solución

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

Eso supone que su terminal envía una secuencia de escape diferente a Flujo de turno Del uno enviado Flecha y que su base de datos Terminfo está poblada correctamente con las capacidades de KLFT y KRIT correspondientes, y que está utilizando la vinculación de teclas de estilo EMACS.

O, para factorizar un poco el código:

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
}

Arriba, las secuencias codificadas para los casos en que la base de datos TermInfo no tiene la información (usando secuencias Xterm).

Otros consejos

En expansión de la excelente respuesta de Stephane de hace casi 3 años, agregué algunas ataduras más para que el comportamiento (casi) sea completamente consistente con todo el comportamiento estándar del teclado de Windows:

  • La selección se borra cuando se usa una clave de navegación (flecha, inicio, final) sin turno
  • Backspace y Del Eliminar una selección activa
  • La selección se extiende a la siguiente/palabra anterior cuando se usa Ctrl+Shift+Left/Ctrl+Shift+Right
  • Shift+Home y Shift+End Extienda la selección al principio y al final de la línea respectivamente. Ctrl+Shift+Home y Ctrl+Shift+End hacer lo mismo.

Dos cosas que no son exactamente las mismas:

  • Extender una selección a la siguiente palabra incluye espacio para arrastre, a diferencia de Windows. Esto podría arreglarse, pero no me molesta.
  • Escribir cuando hay una selección activa no la eliminará y la reemplazará con el personaje que escribió. Esto parece requerir mucho más trabajo para reasignar todo el teclado. No vale la pena para mí.

Tenga en cuenta que el comportamiento de menta predeterminado es unir Shift+End y Shift+Home Para acceder al búfer de desplazamiento. Esto reemplaza a la configuración ZSH; Las llaves nunca se pasan. Para que estos funcionen, deberá configurar una clave diferente (o deshabilitar el desplazamiento hacia atrás) en /etc/minttyrc o ~/.minttyrc. Ver "Modificador para desplazarse" aquí - La solución más simple está configurada ScrollMod=2 para atarlo a Alt en vez de Shift.

Entonces todo:

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

Esto cubre códigos de teclas de varias configuraciones de teclado diferentes que he usado.

Nota: Los valores en la columna "clave" no significan nada, solo se usan para construir una referencia nombrada para ZLE. Podrían ser cualquier cosa. Lo importante es el seq, mode y widget columnas.

Nota 2: Puede unir casi cualquier tecla que desee, solo necesita los códigos de clave utilizados en el emulador de su consola. Abra una consola regular (sin ejecutar ZSH) y escriba CTRL+V Y luego la clave que deseas. Debería emitir el código. ^[ medio \E.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top