NixOS/nixos — pull request #138 by MarcWeber (2013-04-11 14:43:22+00:00)
Title: Step towards supporting multiple shells

Please note that I'd like to push this for discussion - it doesn't mean you have to merge it right now.

bash setup changes:

- new option environment.bashFeatures modularizing bash setup
implementations based on previous code: prompt, completion, aliases, other
-> See examples below

- provide /etc/bash/setup-all shell scripts setting those features up
You can opt out by defining keys in DID_NIX_BASH_FEATURES, use declare -A
first (see comment)

- provide /etc/skel/.bashrc which by default sources setup-all
This way users can opt-out. Mind that I wrote a [shadow patch] so that user-add
creates ~/.bashrc as file, not as symlink

[shadow patch]: https://github.com/NixOS/nixpkgs/pull/459

- support XML_CATALOG_FILES, so that you can use xmllint like tools without
having them download dts easily

- introduce nix-bash-lib which provides some helper functions.
It is sourced as needed.

- export __ETC_PROFILE_DONE, so that profile isn't setup twice

zsh:
implement the very same.
Please note that the zshrc hack found in nixpkgs is obsolete then.

Thus a typical .bashrc/ .zshrc of a user looks like this after this patch:

# opt-out from the completion feature:

declare -A DID_NIX_BASH_FEATURES
DID_NIX_BASH_FEATURES["completion"]=1

# but load everything else the system administrator thinks is useful on
# this machine:
source /etc/bash/setup-all

# custom setup of the user
....

Example features zsh:
Note that interactive_code is only loaded for interactive shells whereas
env_code is loaded always

zsh.availableFeatures = {
# simple xpath like navigation for the filesystem. Eg open /etc/nixos/configuration.nix by
# E /enc
pathSelector.interactive_code = let ps = "${pkgs.misc.pathSelector}/bin/path-selector"; in ''
autoload -Uz _path_selector
bindkey '^g' _path_selector
zle -N _path_selector
fpath=(${pkgs.misc.pathSelector}/fpath $fpath)

C() { cd $(${ps} "$@"); }
E() { $EDITOR $(${ps} "$@"); }
MDC() { mdc $(${ps} "$@"); }
alias F=${ps}'';

# setup vi keybindings for zsh, but keep useful mappings like ctrl-a ctrl-e (move to start/end of line)
vi_setup.interactive_code = ''
# vi keys
bindkey -v
bindkey "^a" beginning-of-line
bindkey "^e" end-of-line
bindkey "^p" up-line-or-history
bindkey "^r" history-incremental-search-backward
'';

# provide a function which can be used to install Vim plugin vim-addon-manager
vam.env_code = ''
vim-install-vam(){
mkdir -p ~/.vim/vim-addons \
&& git clone --depth=1 git://github.com/MarcWeber/vim-addon-manager.git ~/.vim/vim-addons/vim-addon-manager \
&& cat >> ~/.vimrc << EOF
set nocompatible
filetype indent plugin on | syn on
fun ActivateAddons()
let g:vim_addon_manager = {}
let g:vim_addon_manager.log_to_buf =1
set runtimepath+=~/.vim/vim-addons/vim-addon-manager
call vam#ActivateAddons([])
endf
call ActivateAddons()
" experimental: run after gui has been started [3]
" option1: au VimEnter * call Activate()
" option2: au GUIEnter * call Activate()
EOF
}
'';
};

TODO: provide other implementations (fish etc)

Signed-off-by: Marc Weber