Domanda

Come utilizzare Shift per selezionare parte della linea di comando (come in molti redattori di testo)?

È stato utile?

Soluzione

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

Ciò presuppone che il tuo terminale invii una sequenza di fuga diversa Corri a turni da quello inviato Freccia e che il tuo database terminale è correttamente popolato con le corrispondenti funzionalità KLFT e KRIT e che stai utilizzando l'associazione dei tasti in stile EMACS.

Oppure, per consentire un po 'il codice:

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
}

Sopra, sequenze hardcoded per i casi in cui il database terminale non ha le informazioni (utilizzando sequenze XTERM).

Altri suggerimenti

Espandendosi sull'eccellente risposta di Stephane da quasi 3 anni fa, ho aggiunto alcuni più legami per rendere il comportamento (quasi) completamente coerente con tutto il comportamento standard della tastiera di Windows:

  • La selezione viene cancellata quando si utilizza una chiave di navigazione (freccia, casa, fine) senza turno
  • Backspace e Del Elimina una selezione attiva
  • La selezione viene estesa alla parola successiva/precedente quando si utilizza Ctrl+Shift+Left/Ctrl+Shift+Right
  • Shift+Home e Shift+End estendere la selezione rispettivamente all'inizio e alla fine della linea. Ctrl+Shift+Home e Ctrl+Shift+End Fai lo stesso.

Due cose che non sono esattamente le stesse:

  • L'estensione di una selezione alla parola successiva include lo spazio finale, a differenza delle finestre. Questo potrebbe essere risolto, ma non mi dà fastidio.
  • La digitazione in caso di selezione attiva non lo eliminerà e lo sostituirà con il carattere digitato. Ciò sembrerebbe richiedere molto più lavoro per rimodellare l'intera tastiera. Non ne vale la pena per me.

Si noti che il comportamento di zecca predefinito è legarsi Shift+End e Shift+Home Per accedere al buffer di scorrimento. Ciò supercedes la configurazione ZSH; Le chiavi non sono mai passate. Affinché questi funzionino, dovrai configurare una chiave diversa (o disabilitare la scorrimento) /etc/minttyrc o ~/.minttyrc. Vedi "Modificatore per lo scorrimento" qui - La soluzione più semplice è semplicemente impostata ScrollMod=2 per legarlo a Alt invece di Shift.

Quindi tutto:

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

Questo copre i codi chiave da diverse configurazioni di tastiera che ho usato.

Nota: I valori nella colonna "chiave" non significano nulla, sono usati solo per costruire un riferimento denominato per Zle. Potrebbero essere qualsiasi cosa. Ciò che è importante è il seq, mode e widget colonne.

Nota 2: Puoi legare praticamente tutte le chiavi che desideri, hai solo bisogno dei codici chiave utilizzati nell'emulatore della console. Apri una console normale (senza eseguire ZSH) e digita Ctrl+V. E poi la chiave che desideri. Dovrebbe emettere il codice. ^[ significa \E.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top