-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdot_bashrc.tmpl
More file actions
246 lines (224 loc) · 10.8 KB
/
Copy pathdot_bashrc.tmpl
File metadata and controls
246 lines (224 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# ~/.bashrc - Interactive bash configuration. Managed by chezmoi.
#
# Init order (load-bearing — see docs/shells/bash.md):
# 1. Early-return guard (non-interactive shells)
# 2. /etc/bashrc source (RHEL families)
# 3. ble.sh --attach=none ← BEFORE bash-preexec / starship
# 4. XDG dirs + Homebrew shellenv (mac)
# 5. Bash-specific config files (history / completion / vi-mode / aliases)
# 6. oh-my-bash source (after ble.sh so OMB's bash-preexec install no-ops)
# 7. Shared modular layer (starship / mise / zoxide / direnv / thefuck)
# 8. atuin init bash --disable-up-arrow (ble.sh handles up-arrow history)
# 9. Secrets
# 10. ble-attach ← absorbs all precmd/preexec stacks accumulated above
# 11. ~/.bash_aliases (Debian/Ubuntu) + ~/.bashrc.d/* (RHEL family)
# — backward-compat with distro skel conventions
# 12. .bashrc.adhoc tail (chezmoi-ignored; highest-priority user override)
#
# The ble.sh / oh-my-bash / atuin steps are presence-gated and no-op
# silently when the artefact isn't installed (e.g. fresh host before
# `chezmoi apply` finishes the externals + run-onchange-after_install).
# Plain bash without ble.sh + OMB still gets a fully working starship
# prompt + the shared layer + bash-completion v2.
# 1. ============================================================
# Non-interactive shells (SSH commands, cron, scp) bail out here.
# Anything below this guard runs only in interactive bash.
# Mirrors /etc/skel/.bashrc convention on Debian/Ubuntu.
case $- in
*i*) ;;
*) return ;;
esac
# 2. ============================================================
# /etc/bashrc on RHEL families carries the protective `rm -i`
# aliases, the Modules system init, and umask defaults. Source it
# first so we don't lose those — and so anything we set below can
# override (we set HISTSIZE etc. larger than RHEL's defaults).
# Debian/Ubuntu has no /etc/bashrc, so this is a no-op there.
[ -r /etc/bashrc ] && . /etc/bashrc
# 3. ============================================================
# ble.sh --attach=none lets us chain starship/atuin between this
# point and `ble-attach` at the end. Sourcing ble.sh AFTER
# bash-preexec (which starship installs) is the #1 ble.sh footgun
# documented at https://github.com/akinomyoga/ble.sh/wiki/
# So we source it FIRST, with --attach=none, then call ble-attach
# only at the very end. Presence-gated for hosts where
# .chezmoiscripts/global/run_onchange_after_NN_install_blesh.sh
# hasn't completed yet.
if [[ $- == *i* ]] && [ -r "$HOME/.local/share/blesh/ble.sh" ]; then
# shellcheck disable=SC1091
source "$HOME/.local/share/blesh/ble.sh" --attach=none --noattach
fi
# 4. ============================================================
# XDG Base Directory Specification (mirrors dot_zshrc.tmpl)
export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}"
export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
# Modular config directories
export BASH_CONFIG_DIR="$XDG_CONFIG_HOME/bash"
{{ if eq .chezmoi.os "darwin" -}}
# Homebrew (macOS) — must run before shared layer so bash-completion v2's
# $HOMEBREW_PREFIX detection works.
if [[ -f /opt/homebrew/bin/brew ]]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
elif [[ -f /usr/local/bin/brew ]]; then
eval "$(/usr/local/bin/brew shellenv)"
fi
{{ end -}}
# 5. ============================================================
# Modular Configuration Loader (sister of dot_zshrc.tmpl's loader,
# shares the same name + signature). Globs $dir/*.<ext> and sources
# each file in alphabetical order.
load_modular_dir() {
local dir="$1"
local ext="${2:-bash}"
[[ -d "$dir" ]] || return 0
local _had_nullglob; _had_nullglob=$(shopt -p nullglob)
shopt -s nullglob
local f
for f in "$dir"/*."$ext"; do
[[ -r "$f" ]] && source "$f"
done
eval "$_had_nullglob"
}
# Bash-specific config (history / completion / vi-mode / aliases).
# Loaded BEFORE oh-my-bash so ~/.config/bash/01_omb_plugins.bash can
# set the `plugins=()` array that oh-my-bash.sh then consumes.
load_modular_dir "$BASH_CONFIG_DIR" bash
# 6. ============================================================
# oh-my-bash. Theme MUST be empty so starship owns the prompt.
# OMB's autosuggestions / syntax-highlighting / history-substring-search
# plugins are excluded in dot_config/bash/01_omb_plugins.bash because
# ble.sh provides better native versions.
# Presence-gated so plain-bash (no OMB installed) still works.
if [ -r "$HOME/.oh-my-bash/oh-my-bash.sh" ]; then
export OSH="$HOME/.oh-my-bash"
: "${OSH_THEME:=""}" # empty = no OMB theme; starship takes over
# shellcheck disable=SC1091
source "$OSH/oh-my-bash.sh"
fi
# 7. ============================================================
# Shared POSIX layer — env vars (PATH, GFW mirrors, GOPATH, BUN_INSTALL,
# PNPM_HOME), tool init wrappers (starship/mise/zoxide/direnv/thefuck),
# POSIX aliases. Same dir is sourced by ~/.zshrc.
# starship init bash is here, AFTER ble.sh source but BEFORE ble-attach.
load_modular_dir "$XDG_CONFIG_HOME/shell" sh
# 8. ============================================================
# atuin (history sync) — `--disable-up-arrow` is mandatory when
# ble.sh is loaded; ble.sh's history navigation owns the up arrow.
# Ctrl+R still opens atuin's TUI (no conflict).
# Alt+R is also bound to atuin via dot_config/shell/15_atuin.sh
# (cross-shell parity with zsh; deferred-bind via PROMPT_COMMAND
# because __atuin_history is defined by THIS init below, after
# 15_atuin.sh has already been sourced by load_modular_dir).
if command -v atuin >/dev/null 2>&1; then
eval "$(atuin init bash --disable-up-arrow)"
fi
# 9. ============================================================
# Load secrets (not tracked by chezmoi). Two-layer pattern mirrors zsh:
# 9a. ~/.shellrc.secrets — shared POSIX layer, sourced by BOTH shells.
# Canonical home for API keys / tokens that both shells need.
# 9b. ~/.config/bash/secrets.sh — bash-only secrets, layered on top so
# it can use bash-only syntax and overrides shared on conflict.
# Both run BEFORE ble-attach so vars are available to ble.sh / starship.
# Full design: docs/shells/adhoc-and-secrets.md
[ -r "$HOME/.shellrc.secrets" ] && . "$HOME/.shellrc.secrets"
[ -r "$BASH_CONFIG_DIR/secrets.sh" ] && . "$BASH_CONFIG_DIR/secrets.sh"
# 10. ===========================================================
# ble-attach: now that bash-preexec / starship / atuin / OMB have all
# registered their precmd / preexec hooks, hand control over to ble.sh.
# Presence-gated to match the source guard above.
if [[ -n $BLE_VERSION ]]; then
ble-attach
fi
# 11. ===========================================================
# Backward-compat with distro-specific user-customisation conventions:
#
# - ~/.bash_aliases (Ubuntu/Debian skel sources this)
# - ~/.bashrc.d/* (RHEL/Rocky/Alma/Fedora skel loops
# over this dir — verified in Rocky 9)
#
# Without these sources, our managed bashrc would silently strip user
# content that other dotfiles / distro defaults accumulated — hard to
# debug, hostile UX.
#
# Sourced AFTER ble-attach so any `bind -x` / `ble-bind -x` calls take
# effect. Sourced BEFORE `.bashrc.adhoc` (step 12) so the chezmoi-
# ignored adhoc tail wins on conflict.
# Convention: long-lived stuff goes here (or migrate to
# dot_config/bash/10_aliases.bash); machine-local experiments go in
# .bashrc.adhoc.
[ -r "$HOME/.bash_aliases" ] && . "$HOME/.bash_aliases"
if [ -d "$HOME/.bashrc.d" ]; then
for _rc_file in "$HOME"/.bashrc.d/*; do
[ -r "$_rc_file" ] && . "$_rc_file"
done
unset _rc_file
fi
# 12. ===========================================================
# Adhoc Configuration (not tracked by chezmoi). Two-layer pattern:
# 12a. ~/.shellrc.adhoc — shared POSIX layer, sourced by BOTH shells.
# Use this for anything portable so you don't duplicate it in
# ~/.zshrc.adhoc and ~/.bashrc.adhoc.
# 12b. ~/.bashrc.adhoc — bash-only adhoc; can use `bind -x` / `ble-bind`,
# OMB plugin tweaks, `shopt`. Layered on top — wins on conflict.
# Both run AFTER ble-attach + after ~/.bash_aliases / ~/.bashrc.d/*, so
# ble-bind / readline `bind -x` in either file takes effect.
# Full design: docs/shells/adhoc-and-secrets.md
# 12a. Create shared adhoc file if it doesn't exist (sourced by both zsh+bash).
if [[ ! -f "$HOME/.shellrc.adhoc" ]]; then
cat > "$HOME/.shellrc.adhoc" << 'SHELLRC_ADHOC_EOF'
# ~/.shellrc.adhoc - Personal SHARED shell customizations (not tracked by chezmoi)
#
# This file is sourced by BOTH ~/.zshrc AND ~/.bashrc. Put anything POSIX-
# portable here so you don't have to duplicate it in ~/.zshrc.adhoc and
# ~/.bashrc.adhoc.
#
# HARD RULE: POSIX-only.
# - No zsh-isms: no `setopt`, `compdef`, ZLE widgets, `read -q`, `${m:t}`,
# glob qualifiers, `bindkey`. Put those in ~/.zshrc.adhoc instead.
# - No bash-isms: no `bind -x`, `ble-bind`, `shopt`, `complete -F`. Put
# those in ~/.bashrc.adhoc instead.
# - If you need shell-specific logic, dispatch via $ZSH_VERSION /
# $BASH_VERSION (same convention as ~/.config/shell/*.sh):
# if [ -n "$ZSH_VERSION" ]; then ...
# elif [ -n "$BASH_VERSION" ]; then ...
# fi
#
# Sourced AFTER ~/.shellrc.secrets, BEFORE the per-shell ~/.{zsh,bash}rc.adhoc
# (per-shell wins on conflict). See docs/shells/adhoc-and-secrets.md.
#
# Example:
# export MY_SHARED_VAR="hello from both shells"
# alias ll='ls -lah'
SHELLRC_ADHOC_EOF
fi
# Source shared adhoc (POSIX, both shells).
[ -r "$HOME/.shellrc.adhoc" ] && . "$HOME/.shellrc.adhoc"
# 12b. Create bash-only adhoc file if it doesn't exist.
if [[ ! -f "$HOME/.bashrc.adhoc" ]]; then
cat > "$HOME/.bashrc.adhoc" << 'ADHOC_EOF'
# ~/.bashrc.adhoc - Personal BASH-ONLY shell customizations (not tracked by chezmoi)
#
# Use this file for:
# - Quick experiments with bash-only constructs (`bind -x`, `ble-bind`,
# `shopt`, `complete -F`, OMB plugin tweaks)
# - Machine-specific bash-only configurations
# - Testing before adding to chezmoi-managed configs
#
# For anything POSIX-portable that should also affect zsh, prefer
# ~/.shellrc.adhoc instead. See docs/shells/adhoc-and-secrets.md.
#
# This file is sourced at the end of ~/.bashrc (AFTER ble-attach + after
# ~/.bash_aliases + AFTER ~/.shellrc.adhoc), so ble-bind / readline
# `bind -x` calls here will take effect, and anything you set here
# overrides the shared ~/.shellrc.adhoc on conflict.
# Changes here apply to new shell sessions (or run: source ~/.bashrc.adhoc)
# Example:
# alias myalias='echo "Hello from adhoc!"'
# export MY_VAR="my_value"
# To enable ble.sh's pacman-style auto-suggestion mode:
# bleopt complete_auto_complete=1
ADHOC_EOF
fi
# Source bash-only adhoc (per-shell wins over ~/.shellrc.adhoc on conflict).
[ -r "$HOME/.bashrc.adhoc" ] && . "$HOME/.bashrc.adhoc"