I have a function to run a single command in a different category. cd1 SOMEDIR MYCOMMAND ARG…
is equivalent to (cd SOMEDIR && MYCOMMAND ARG…)
, with two advantages. It's slightly easier to type (and when you're a command line junkie, every key press matters), and (mostly), it lets me do completion relative to SOMEDIR
.
That is, it lets me define a completion function for cd1
. How do I arrange to complete relative to SOMEDIR
?
The following methods don't work without modification:
- Making ad hoc calls to
_files
with a modified argument for the arguments of the command is no good here (unlike there) because I want all the usual context-sensitive completion to apply. (cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal)
would do the right thing if completion worked in a subshell, but it doesn't.cd $words[2] && shift 2 words && ((CURRENT-=2)) && _normal; cd $OLDPWD
works in nominal cases but breaks and leaves me inSOMEDIR
in some cases, such as if I press Ctrl+C to cancel a completion that takes too long.
Here's the definition of cd1
. It supports aliases and expands wildcards relative to the target directory (on the other hand, command substitutions and the like will still run in the original directory).
cd1_glob () {
if (($# <= 1)); then
cd -- "$1"
elif (($+aliases[$2])); then
( cd -- $1 && eval $2 '$~@[3,$#]' )
else
( cd -- $1 && $~@[2,$#] )
fi
}
alias cd1='noglob cd1_glob'
(I don't call this function cd
. If you do, change the calls to cd
inside the functions to builtin cd
.)