Completamento per il primo argomento di cd OLD NEW


22

In zsh, il cdcomando ha una forma a due argomenti: cd OLD NEWcambia in ${PWD/OLD/NEW}. Con il nuovo sistema di completamento, zsh è in grado di completarsi NEW: il secondo argomento viene completato in base a ciò che OLDpuò essere sostituito per ottenere una directory esistente. Ma il primo argomento è completato solo per le directory esistenti.

Come posso ottenere zsh per offrire completamenti che sono valori possibili per OLD, oltre a completare le directory esistenti?

Ad esempio, se la directory corrente è /path/to/fooe ci sono anche directory /also/to/fooe /path/to/foo/prime, quindi cd pTabcompleta pa prime. Se ho intenzione di correre, cd path alsovorrei che zsh offrisse anche pathcome completamento. Come?

Usare i valori già digitati del secondo argomento per limitare le possibilità per il primo argomento sarebbe un vantaggio, ma anche completare il primo argomento in modo indipendente andrebbe bene.


Il tuo esempio di completamento di 2 argomenti sarebbe:, cd p also <Tab>oppure cd p also <left arrow x 5> <Tab>?
Jeff Schaller

@JeffSchaller L'esempio sensibile al secondo argomento sarebbe cd p also<Left*5><Tab>: se premo <Tab>mentre il cursore è in also, mi aspetto alsodi essere completato, no p.
Gilles 'SO- smetti di essere malvagio'

Se si digita cd t<tab>dovrebbe offrire th/to/foo/primee to/foo/prime? O dovrebbe limitarsi ai limiti della directory?
Barmar,

@Barmar Penso che limitare i limiti della directory sia il più conveniente.
Gilles 'SO- smetti di essere malvagio'

Domanda interessante ...
wogsland

Risposte:


1

Immagino che si potrebbe aggiungere i componenti $PWDalla cdlista di completamento, anche se questo sembra richiedere giocherellare con _cd; cioè, una versione personalizzata di _cddeve apparire per prima in $fpath.

% cd && mkdir zcomp
% cp $fpath[-1]/_cd zcomp
% fpath=(~/zcomp $fapth)

Quindi in cima ~/zcomp/_cd aggiungi una funzione

_our_pwd() {
  _values ourpwd ${(ps:/:)PWD}
}

e poi poco prima del _alternative riga aggiungi ciò che ritorna all'elenco delle alternative

  ...
  alt=("$service-options:$service option:_cd_options" "$alt[@]")
fi

alt=(ourpwd:pwd:_our_pwd "$alt[@]")

_alternative "$alt[@]" && ret=0

return ret
...

sebbene questo aggiungerà sempre i pwdcomponenti ai cdcompletamenti:

% cd
Users    jdoe    Applications/  Desktop/  Documents/  Downloads/  Library/
...

con una logica aggiuntiva puoi solo aggiungere il file $PWD componenti solo quando è già presente un secondo argomento anziché sempre.

Tuttavia! Questo incasina sempre il cdcompletamento e richiede che eseguiamo la patch del _cdcompletamento a monte . Un'altra opzione sarebbe quella di creare un nuovo nome per la funzione fornita da two-arg cd, forse chiamato cdsub, e far PWDapparire solo il completamento dei componenti. Aggiungi questo a~/.zshrc

function cdsub { builtin cd "$@" }

E poi un _cd completamento_cdsub sventrato per essere posizionato da qualche parte in $fpath:

#compdef cdsub
#
# Modified version of _cd from ZSH 5.3.1 with specific support for the
# `cd old new` form whereby PWD elements are provided for completion.

_cd_options() {
  _arguments -s \
  '-q[quiet, no output or use of hooks]' \
  '-s[refuse to use paths with symlinks]' \
  '(-P)-L[retain symbolic links ignoring CHASE_LINKS]' \
  '(-L)-P[resolve symbolic links as CHASE_LINKS]'
}

setopt localoptions nonomatch

local expl ret=1 curarg
integer argstart=2 noopts

if (( CURRENT > 1 )); then
  # if not in command position, may have options.
  # Careful: -<-> is not an option.
  while [[ $words[$argstart] = -* && argstart -lt CURRENT ]]; do
    curarg=$words[$argstart]
    [[ $curarg = -<-> ]] && break
    (( argstart++ ))
    [[ $curarg = -- ]] && noopts=1 && break
  done
fi

if [[ CURRENT -eq $((argstart+1)) ]]; then
  # cd old new: look for old in $PWD and see what can replace it
  local rep
  # Get possible completions using word in position 2
  rep=(${~PWD/$words[$argstart]/*}~$PWD(-/))
  # Now remove all the common parts of $PWD and the completions from this
  rep=(${${rep#${PWD%%$words[$argstart]*}}%${PWD#*$words[$argstart]}})
  (( $#rep )) && _wanted -C replacement strings expl replacement compadd -a rep
else
  _values ourpwd ${(ps:/:)PWD} && ret=0
  return ret
fi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.