Directory specific shell configuration with Zsh
Now being an official Debian developer I’ve the possibility to use $DEBEMAIL=mika@debian.org for my Debian packages. But whereas I want to use that for all my official Debian packages I still want to use $DEBEMAIL=mika@grml.org for my grml related packages. I’m a lazy sysadmin and don’t want to manually adjust my changelogs depending on the type of package (especially since this might be error-prone) so I needed a generic solution. Grml’s Zsh configuration (Debian package grml-etc-core >=0.3.71) provides a solution for Zsh (version 4.3.3 or later): based on directories you can set your own profiles. Demonstration:
% cd /grml/git-grml chpwd(): Switching to profile: grml % echo $DEBEMAIL mika@grml.org % cd /grml/git-debian chpwd(): Switching to profile: debian % echo $DEBEMAIL mika@debian.org
The configuration is pretty simple:
# define profiles based on directories: zstyle ':chpwd:profiles:/grml/git-grml(|/|/*)' profile grml zstyle ':chpwd:profiles:/grml/git-debian(|/|/*)' profile debian zstyle ':chpwd:profiles:/home/mika/Customers(|/|/*)' profile customers # configuration for profile 'grml': chpwd_profile_grml() { [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1 print "chpwd(): Switching to profile: $profile" export DEBEMAIL=mika@grml.org export GIT_AUTHOR_EMAIL="mika@grml.org" export GIT_COMMITTER_EMAIL="mika@grml.org" } # configuration for profile 'debian': chpwd_profile_debian() { [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1 print "chpwd(): Switching to profile: $profile" export DEBEMAIL=mika@debian.org export GIT_AUTHOR_EMAIL="mika@debian.org" export GIT_COMMITTER_EMAIL="mika@debian.org" } # configuration for profile 'customers': chpwd_profile_customers() { [[ ${profile} == ${CHPWD_PROFILE} ]] && return 1 print "chpwd(): Switching to profile: $profile" export TELEPHONE=[...] export MAIL=[...] }
Kudos to Frank for implementing this lovely feature in grml’s zshrc. Look for chpwd_profiles() in grml’s zsh config for further documentation on this feature.
May 31st, 2009 at 08:10
You can do something similar in bash:
set-git-email-address () {
case "$PWD" in (/home/pabs/devel/debian/*)
export GIT_AUTHOR_EMAIL=pabs@debian.org
export GIT_COMMITTER_EMAIL=pabs@debian.org
;;
(*)
unset GIT_AUTHOR_EMAIL
unset GIT_COMMITTER_EMAIL
;;
esac
}
export PROMPT_COMMAND="set-git-email-address"
May 31st, 2009 at 23:45
Wow, amazing zsh feature I never knew about… definitely a +1 for reasons to switch to zsh.
pabs: do you know how much slower setting PROMPT_COMMAND would be for bash?
June 1st, 2009 at 23:29
@Samat: well, zsh doesn’t quite ship that feature, but it makes it possible
to implement it in a few lines of code, like we did.
About PROMPT_COMMAND: Yeah, you can do that. But PROMPT_COMMAND is far less
suitable for that kind of action. The point of implementing this via zstyle
based setup is, that we could provide a basic functionality that people can
easily build the exact features they need on.
And finally, a note about the version requirement, mika mentioned: That’s true
for our setup. In order to keep our code structured, I decided to use the
$chpwd_functions[] array – and that makes the code require zsh 4.3.3 or newer.
If someone wants that feature in her/his zsh setup, you can just make
chpwd_profiles() to your chpwd() function. When you do that, the code should
work with zsh version 3.1.7 and newer (because of zstyle and ‘local -x’).