Make “.” and “source” default to ~/.zshrc

aliaszsh

I would like to source my ~/.zshrc by running . with no arguments. So this:

$ .

should do this:

$ . ~/.zshrc

I would like the normal functionality of . to remain unchanged. The only difference should be when . is invoked with no arguments.

Is this possible?

I have tried a few different approaches. Here is one of them:

dot_zshrc_or_args() {
    if [[ $# == 0 ]]; then
        \. ~/.zshrc
    else
        filename=$1
        shift
        \. $filename $@
    fi
}
alias .=dot_zshrc_or_args

Here is an example showing why it does not work:

$ echo 'echo $#' > count_args.sh
$ delegate() { . ./count_args.sh }
$ delegate foo bar baz

The last command should echo 3, but it echoes 0 if the above alias for . has been defined.

The fundamental problem seems to be that . is treated specially by the shell, allowing the script that it invokes to have access to all local variables including $1, $2, and so on. So if I try to wrap . in another function, I will lose that behavior (as in the example above).

The two approaches I was thinking of were:

  1. use an alias instead of a function
  2. make it so that . is only aliased in the interactive shell, as opposed to when it is run from another function.

I can't get it to work, though, no matter what I try. Is it possible? (If not, what are the closest alternatives I could use? My end goal is to be able to quickly source my ~/.zshrc from a shell, preferably in an intuitive and easy-to-remember way.)

Best Answer

This can potentially be done by doing horrible things with accept-line:

function _accept-line() {
    if [[ $BUFFER == "." ]]; then
        BUFFER="source ~/.zshrc"
    fi
    zle .accept-line
} 

zle -N accept-line _accept-line
Related Question