How to expand all variables at the command line in Zsh

command lineenvironment-variablesvariablezsh

In an earlier question, specific to bash, I asked How can I expand a relative path at the command line, with tab completion?

I liked @Mikel's answer that mentioned using Ctrl+Alt+e to expand all variables and I used that a lot.

Since then I've switched to zsh and while I can type $PWD and press Tab to expand the current directory's path, if I type something like $PWD/.profile and press Tab it does not get expanded.

I have read up on similar questions and have seen answers on expanding aliases as well as how to expand variables by typing them and pressing Tab but nothing that was the same as pressing Ctrl+Alt+e in bash.

Is there some way to allow an escape sequence such as Ctrl+Alt+e to expand all variables in the command line that is being typed in zsh ?

Best Answer

You can set up compinit to expand parameters in your ~/.zshrc:

zstyle ':completion:*' completer _expand _complete
autoload -Uz compinit
compinit

This is a minimal setting, if you have compinit already enabled, it should be sufficient to add _expand to the settings of completer

There is also the expand-word widget that is by default bound to ^X* (Ctrl+x *) that essentially does the same as the same binding in bash.

Note: Both methods only work on the current word.


As an alternative, in zsh you can actually do what you asked for in your original question: turn a relative path into an absolute path. Here is a slightly modified example from the zshcontrib(1) manpage:

# load necessary utility function
autoload -Uz modify-current-argument

# define helper function for actual work
expand-and-abspath () {
    # expand the path (for example `~` -> `/home/youruser`)
    REPLY=${~1}
    # transform into absolute path (use `:A` if you want to resolve symlinks)
    REPLY=${REPLY:a}
}

# actual widget function
abspath-word() {
    # use helper function on current word
    modify-current-argument expand-and-abspath
}

# create zle widget `abspath-word` (with function of the same name)
zle -N abspath-word

# bind widget to "Ctrl+x p"
bindkey '^Xp' abspath-word

This defines the abspath-word widget, which replaces the current word with an absolute path representation and binds it to Ctrl+xp.