Skip to content

feat(shell): share env/aliases/functions between zsh and bash#1892

Merged
fredclausen merged 1 commit into
mainfrom
share-shell-config-bash-zsh
Jun 28, 2026
Merged

feat(shell): share env/aliases/functions between zsh and bash#1892
fredclausen merged 1 commit into
mainfrom
share-shell-config-bash-zsh

Conversation

@fredclausen

Copy link
Copy Markdown
Member

Summary

Make bash behave like zsh by sharing a single source of truth for the portable shell config, with no duplicated code maintained in two places.

Shared config (dotfiles/shell/, installed at ~/.config/shell)

Portable (POSIX/bash) files sourced by both shells:

  • 00-env.sh -- env vars, paths, ogcat, WEZTERM_HOSTNAME guard
  • 10-aliases.sh -- all aliases
  • 40-functions.sh -- all functions
  • 90-final.sh -- fastfetch

zsh wiring

The .oh-my-zsh/custom/{00-env,10-aliases,40-functions,90-final}.zsh files
become thin wrappers that source the shared files. The zsh-only
20-zle.zsh and 30-fzf.zsh are left untouched (bash has no ZLE/fzf-zsh
equivalent and does not need one).

bash wiring

features/shell/bash/default.nix sources the shared files via
programs.bash.initExtra in the same order zsh uses (env -> bind ->
aliases -> functions -> final), and enables completion + history.

20-bind.bash is the bash-only readline equivalent of the zsh ZLE
keybindings (Home/End, Up/Down prefix history search, Ctrl-L
clear+scrollback), guarded so it does not call the bind builtin in
non-TTY shells.

Portability changes to functions

  • The two setopt localoptions nounset pipefail calls become paired
    _shell_func_opts_on/_shell_func_opts_off helpers.
  • [[ "$HOME" == /home/* ]] style tests become POSIX prefix tests.

Verification

  • nix eval of impacted hosts (desktops + servers) and their
    home-manager activation packages: clean.
  • shellcheck passes on every shared file.
  • Interactive bash confirmed: type nr -> aliased to updatenix,
    updatenix resolves as a function.

Extract the portable parts of the zsh oh-my-zsh custom config into a
shell-agnostic dotfiles/shell/ tree (00-env.sh, 10-aliases.sh,
40-functions.sh, 90-final.sh) installed at ~/.config/shell and sourced
by both shells. The zsh custom files become thin wrappers that source
these shared files, and bash sources them via programs.bash.initExtra
in the right order. zsh-only bits (20-zle.zsh, 30-fzf.zsh) stay in zsh.

Add a bash-only 20-bind.bash with the readline equivalent of the zsh
ZLE keybindings (Home/End, Up/Down prefix history search, Ctrl-L
clear+scrollback), guarded so it does not call the bind builtin in
non-TTY shells.

Functions are made bash-portable: the two setopt localoptions nounset
pipefail calls become paired _shell_func_opts_on/off helpers, and
[[ ... == /home/* ]] style tests become POSIX prefix tests.
@fredclausen fredclausen enabled auto-merge June 28, 2026 08:33
@fredclausen fredclausen added this pull request to the merge queue Jun 28, 2026
Merged via the queue into main with commit 3d410ea Jun 28, 2026
21 checks passed
@fredclausen fredclausen deleted the share-shell-config-bash-zsh branch June 28, 2026 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant