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
_fileswith 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 $OLDPWDworks in nominal cases but breaks and leaves me inSOMEDIRin 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.)