Conclusão do primeiro argumento do cd OLD NEW

22

Em zsh , o comando cd tem um formulário de dois argumentos: cd OLD NEW muda para ${PWD/OLD/NEW} . Com o novo sistema de completação, zsh é capaz de completar NEW : o segundo argumento é completado com base no que OLD pode ser substituído para obter um diretório existente. Mas o primeiro argumento só é completado para diretórios existentes.

Como posso fazer com que o zsh ofereça conclusões que sejam valores possíveis para OLD , além de completar os diretórios existentes?

Por exemplo, se o diretório atual for /path/to/foo e também houver diretórios /also/to/foo e /path/to/foo/prime , então cd p Guia concluirá p to prime . Se eu pretendo executar cd path also , gostaria que o zsh também oferecesse path como conclusão. Como?

Usar valores já digitados do segundo argumento para limitar as possibilidades do primeiro argumento seria um plus, mas completar o primeiro argumento independentemente também seria bom.

    
por Gilles 11.05.2016 / 02:12

1 resposta

2

Acho que você poderia adicionar os componentes de $PWD à lista cd de conclusão, embora isso pareça exigir mexer com _cd ; ou seja, uma versão personalizada de _cd deve aparecer primeiro em $fpath .

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

Em seguida, na parte superior de ~/zcomp/_cd , adicione uma função

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

e logo antes da linha _alternative adicionar o que retorna à lista de alternativas

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

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

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

return ret
...

embora isso sempre adicione os componentes pwd a cd completions:

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

com lógica adicional, você só pode adicionar os componentes $PWD quando já houver um segundo argumento em vez de sempre.

No entanto! Isso sempre atrapalha a conclusão de cd e exige que nós atualizemos o coeficiente de upstream _cd completion. Outra opção seria criar um novo nome para a função fornecida pelo two-arg cd , talvez chamado cdsub , e ter apenas a conclusão dos componentes PWD para isso. Adicione isto a ~/.zshrc

function cdsub { builtin cd "$@" }

E, em seguida, uma conclusão evasiva do _cd _cdsub para ser colocada em algum lugar na $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
    
por 16.05.2017 / 21:11