Achèvement pour le premier argument de cd OLD NEW


22

Dans zsh, la cdcommande a une forme à deux arguments: cd OLD NEWdevient ${PWD/OLD/NEW}. Avec le système d'achèvement de nouveau style, zsh est capable de terminer NEW: le deuxième argument est complété en fonction de ce qui OLDpeut être remplacé par pour obtenir un répertoire existant. Mais le premier argument n'est complété que pour les répertoires existants.

Comment puis-je demander à zsh de proposer des complétions qui sont des valeurs possibles pour OLD, en plus de compléter les répertoires existants?

Par exemple, si le répertoire actuel est /path/to/fooet qu'il existe également des répertoires /also/to/fooet /path/to/foo/prime, puis se cd pTabtermine ppar prime. Si j'ai l'intention de courir, cd path alsoj'aimerais que zsh propose également pathun achèvement. Comment?

L'utilisation de valeurs déjà saisies du deuxième argument pour limiter les possibilités du premier argument serait un plus, mais compléter le premier argument indépendamment serait également très bien.


Votre exemple de complétion à 2 arguments serait-il:, cd p also <Tab>ou cd p also <left arrow x 5> <Tab>?
Jeff Schaller

@JeffSchaller L'exemple sensible au second argument serait cd p also<Left*5><Tab>: si j'appuie <Tab>alors que le curseur est en place also, je m'attends alsoà ce que ce soit terminé p.
Gilles 'SO- arrête d'être méchant'

Si vous tapez cd t<tab>devrait-il offrir th/to/foo/primeet to/foo/prime? Ou devrait-il simplement se limiter aux limites des répertoires?
Barmar

@Barmar Je pense que limiter les limites des répertoires serait le plus pratique.
Gilles 'SO- arrête d'être méchant'

Question intéressante ...
Wogsland

Réponses:


1

Je suppose que vous pourriez ajouter les composants de $PWDà la cdliste d'achèvement, bien que cela semble nécessiter de jouer avec _cd; c'est-à-dire qu'une version personnalisée de _cddoit apparaître en premier dans $fpath.

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

Puis en haut de l' ~/zcomp/_cdajout d'une fonction

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

puis juste avant la _alternativeligne, ajoutez ce qui renvoie à la liste des alternatives

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

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

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

return ret
...

bien que cela ajoute toujours les pwdcomposants aux cdcompléments:

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

avec une logique supplémentaire, vous ne pouvez ajouter les $PWDcomposants que lorsqu'un deuxième argument est déjà présent au lieu de toujours.

Toutefois! Cela gâche toujours l' cdachèvement et nécessite que nous réparions l' _cdachèvement en amont . Une autre option serait de créer un nouveau nom pour la fonction fournie par le double argument cd, peut-être appelé cdsub, et de ne faire PWDapparaître que l'achèvement des composants pour cela. Ajoutez ceci à~/.zshrc

function cdsub { builtin cd "$@" }

Et puis un _cd achèvement_cdsub vidé pour être placé quelque part dans $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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.