Pregunta
¿Cómo usar Shift para seleccionar parte de la línea de comandos (como en muchos editores de texto)?
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
yDel
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
yShift+End
Extienda la selección al principio y al final de la línea respectivamente.Ctrl+Shift+Home
yCtrl+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
.