Conclusão para o primeiro argumento do CD OLD NEW

22

Em zsh, o cdcomando tem uma forma de dois argumentos: cd OLD NEWmuda para ${PWD/OLD/NEW}. Com o novo sistema de conclusão de estilo, o zsh é capaz de concluir NEW: o segundo argumento é concluído com base no que OLDpode ser substituído para obter um diretório existente. Mas o primeiro argumento é concluído apenas em diretórios existentes.

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

Por exemplo, se o diretório atual for /path/to/fooe também houver diretórios /also/to/fooe /path/to/foo/prime, em seguida, cd pTabconclua ppara prime. Se pretendo executar cd path also, gostaria que o zsh também oferecesse pathcomo conclusão. Quão?

Usar valores já digitados do segundo argumento para limitar as possibilidades do primeiro argumento seria uma vantagem, mas concluir o primeiro argumento de forma independente também seria bom.

Gilles 'SO- parar de ser mau'
fonte
Seu exemplo de conclusão com 2 argumentos seria:, cd p also <Tab>ou cd p also <left arrow x 5> <Tab>?
Jeff Schaller
@JeffSchaller O exemplo sensível ao segundo argumento seria cd p also<Left*5><Tab>: se eu pressionar <Tab>enquanto o cursor estiver also, espero alsoque seja concluído, não p.
Gilles 'SO- stop be evil'
Se você digitar cd t<tab>, ele deve oferecer th/to/foo/primee to/foo/prime? Ou deveria apenas limitar-se aos limites do diretório?
Barmar
@ Barmar Acho que limitar os limites do diretório seria o mais conveniente.
Gilles 'SO- stop be evil'
Pergunta interessante ... #
19417 wogsland

Respostas:

1

Eu acho que você pode adicionar os componentes de $PWDà cdlista de conclusão, embora isso pareça exigir mexer com _cd; ou seja, uma versão personalizada de _cddeve aparecer primeiro $fpath.

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

Em seguida, no topo de ~/zcomp/_cdadicionar uma função

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

e, logo antes da _alternativelinha, adicione 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 pwdcomponentes às cdconclusões:

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

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

Contudo! Isso sempre atrapalha a cdconclusão e exige que façamos um patch na _cdconclusão inicial. 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 PWDcomponentes para isso. Adicione isto a~/.zshrc

function cdsub { builtin cd "$@" }

E então uma _cd conclusão_cdsub estripada para ser colocada em algum lugar $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
agitar
fonte