Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: How do *you* sync your zsh config files?



Timothy J Luoma (tjlists@xxxxxxxxxxx) wrote:
> Does anyone else have advice on trying to keep these 4 separate accounts  
> somewhat in sync, so I don't have to re-write every new function over and  
> over again?

Keep everything as portable as possible.  Error-check as much as
possible, and make as few assumptions as possible - for example, if a
function you use for a particular completion runs a program in order
to calculate possible completions, check that that program is actually
installed on the current system, and if not, try to write some
fall-back code.  Use ~ and $USER instead of the values they expand to.
Use that switch-on-zsh-version technique mentioned elsewhere in this
thread.

> I once tried a 'zlocal' file that I would keep all my local configurations,  
> and keep everything else current, but that didn't work.

Why not?  I have this at the end of ~/.zshenv:

if [[ -r $HOME/.zshenv.local ]]; then
    . $HOME/.zshenv.local
fi

if [[ -r $HOME/.zshenv.${HOST%%.*} ]]; then
	. $HOME/.zshenv.${HOST%%.*}
fi

and similarly for .zshrc.  Thus the main bulk of my setup is in
.zshrc, but any tweaks specific to a particular host can go in the
much smaller .zshrc.host, and any tweaks specific to a particular
group of hosts which NFS-share my home directory go in .zshrc.local. 

> I'm getting to the point of dumping everything in one big .zshenv
> (global config files are empty in most of these cases) but that's
> not really what I'd prefer... I like having my
> aliases/bindkeys/completions/etc all in different files, in case of
> an editing mistake in one file it is easier to locate and fix.

Why's that?  zsh usually tells me a line number if I mess things up
badly.

Here's how I've recently re-implemented my rc file syncing across
different hosts:

rc_home='adam@xxxxxxxxxxxxxxxxxxxxxx:'

zsh_rcfiles=( ~/.zsh{rc,env}(N:s#$HOME/##) )

emacs_rcfiles=( \
                ~/.[e]macs(N:s#$HOME/##) \
                ~/lib/emacs/init/**/*.el(N:s#$HOME/##) \
              )

misc_rcfiles=( \
               ~/.{bash,complete,ex,lftp,lynx,shell,ytalk}rc(N:s#$HOME/##) \
             )

all_rcfiles=( $zsh_rcfiles $emacs_rcfiles $misc_rcfiles )

function sendhome {
    if [[ $#* -eq 0 ]]; then
        echo 'Usage: sendhome <files>'
        return 1
    fi

    if [[ "`which rsync`" != "rsync not found" ]]; then
        pushd ~ >/dev/null
        rsync -aHRuvz -e ssh $* $rc_home
        if [[ $OLDPWD != $PWD ]] popd >/dev/null
    else
        echo rsync not found and no other transfer method implemented yet
    fi
}

function gethome {
    if [[ $#* -eq 0 ]]; then
        echo 'Usage: gethome <files>'
        return 1
    fi

    if [[ "`which rsync`" != "rsync not found" ]]; then
        rsync -aHRuvz -e ssh $rc_home"$^^*" ~
    else
        echo rsync not found and no other transfer method implemented yet
    fi
}

Constructive criticism very welcome.

Of course, there are drawbacks to this system of having one central
repository.  I keep a `history' section in the comments at the top of
my bigger rc files, so that I can confirm which is the newer of two
versions; however an automated alternative to this would be great.  I
considered using cvs a while back and decided against it, although I
suspect that I rejected on the grounds that you had to use rsh which
is insecure (of course, I have since discovered that you can easily
tunnel cvs through ssh instead!)  At the end of the day, my main goal
was to produce as simple a design as possible, so that if I suddenly
found myself in an environment without cvs, ssh, or any other nice
tools, I could still pluck one magic .zshrc (or whatever) from my host
and get a workable environment quickly.

Incidentally, if anyone can explain why this works

zsh_rcfiles=( ~/.[z]sh{rc,env}(N:s#$HOME#\\\\\~#) )

but with any less backslashes it doesn't work, I'd be very interested
to hear, not to mention extremely impressed!  Also, I didn't think
$variable interpolation was even supposed to occur within s///
modifiers (from zshexpn: ``The left-hand side of substitutions are not
regular expressions, but character strings.'')  I guess this must be
something to do with the expansion order.

In the course of experimenting with globbing in conjuction with the
s/// modifier inside arrays, I experienced some strange things, which
got me so confused that I couldn't decide whether they were the
correct behaviour or not, even after careful reading of the man
pages... I would try to be more descriptive and helpful in case any
zsh-workers are listening, but I don't really have time right now.
Thought I'd mention it anyway.  Sorry -- maybe another time!

P.S. Is this excessive, or fairly standard amongst zsh hackers?

adam@omni ~ % wc .zsh{rc,env}*~(*~|*.flc)
   1345    5211   35741 .zshrc
      7       5      51 .zshrc.local
      7       9     109 .zshrc.prophet5
    117     319    2301 .zshenv
      9      11     156 .zshenv.local
   1485    5555   38358 total


-- 
Adam Spiers  -=-  music student @ RAM.ac.uk  -=-  Perl/Linux/security hacker
e-mail: adam@xxxxxxxxxx            PGP & WWW: http://www.new.ox.ac.uk/~adam/



Messages sorted by: Reverse Date, Date, Thread, Author