-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbashrc-setup.sh
More file actions
211 lines (182 loc) · 5.82 KB
/
Copy pathbashrc-setup.sh
File metadata and controls
211 lines (182 loc) · 5.82 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
#!/usr/bin/env bash
#
# bashrc-setup.sh -- install the WSL2 bash power-tools block into ~/.bashrc.
#
# Writes a marked block that initialises zoxide, direnv, atuin, thefuck, fzf and
# oh-my-posh, plus the eza/bat/lazygit aliases. Every line is guarded: a tool that
# is not installed contributes nothing, so the block never breaks a fresh shell.
#
# The block is delimited by markers, so re-running replaces it in place rather
# than appending a second copy. Anything outside the markers is left alone.
#
# Usage:
# ./bashrc-setup.sh # write the block into ~/.bashrc (backs up first)
# ./bashrc-setup.sh --dry-run # print the block that would be written, change nothing
# ./bashrc-setup.sh --remove # strip the block back out
# ./bashrc-setup.sh --file PATH # target a different rc file
#
# Env:
# OMP_THEME oh-my-posh theme name without .omp.json (default: jandedobbeleer)
set -euo pipefail
BEGIN_MARK='# >>> apsolut cli: bash power tools >>>'
END_MARK='# <<< apsolut cli: bash power tools <<<'
rc_file="${HOME}/.bashrc"
dry_run=0
remove=0
omp_theme="${OMP_THEME:-jandedobbeleer}"
usage() { sed -n '3,20p' "$0" | sed 's/^# \{0,1\}//'; }
while [ $# -gt 0 ]; do
case "$1" in
--dry-run|-n) dry_run=1 ;;
--remove) remove=1 ;;
--file) shift; rc_file="${1:-}"; [ -n "$rc_file" ] || { echo "--file needs a path" >&2; exit 2; } ;;
--help|-h) usage; exit 0 ;;
*) echo "unknown option: $1 (try --help)" >&2; exit 2 ;;
esac
shift
done
have() { command -v "$1" >/dev/null 2>&1; }
# ---------------------------------------------------------------- build block
block=""
add() { block="${block}$1
"; }
skipped=""
skip() { skipped="${skipped} - $1
"; }
add "$BEGIN_MARK"
add "# Generated by apsolut/cli bin/bashrc-setup.sh -- edit the script, not this block."
if have oh-my-posh; then
add ""
add "# Oh My Posh"
add "eval \"\$(oh-my-posh init bash --config \$(oh-my-posh get themes-path)/${omp_theme}.omp.json)\""
else
skip "oh-my-posh"
fi
if have zoxide; then
add ""
add "# zoxide -- z / zi"
add 'eval "$(zoxide init bash)"'
else
skip "zoxide"
fi
if have direnv; then
add ""
add "# direnv -- per-project .envrc"
add 'eval "$(direnv hook bash)"'
else
skip "direnv"
fi
# atuin installs to ~/.atuin/bin when using the official installer rather than a package.
if have atuin || [ -x "${HOME}/.atuin/bin/atuin" ]; then
add ""
add "# atuin -- shell history (Ctrl+R)"
[ -x "${HOME}/.atuin/bin/atuin" ] && add 'export PATH="$HOME/.atuin/bin:$PATH"'
add 'eval "$(atuin init bash)"'
else
skip "atuin"
fi
if have thefuck; then
add ""
add "# thefuck -- correct the last command"
add 'eval "$(thefuck --alias)"'
else
skip "thefuck"
fi
# fzf >= 0.48 ships `fzf --bash`, which supersedes sourcing key-bindings.bash by hand.
# Older builds need the file, and its location differs per distro -- so probe.
if have fzf; then
add ""
add "# fzf -- Ctrl+R history, Ctrl+T files, Alt+C cd"
if fzf --bash >/dev/null 2>&1; then
add 'eval "$(fzf --bash)"'
else
fzf_kb=""
for candidate in \
/usr/share/doc/fzf/examples/key-bindings.bash \
/usr/share/fzf/key-bindings.bash \
/usr/share/bash-completion/completions/fzf \
"${HOME}/.fzf/shell/key-bindings.bash"
do
[ -f "$candidate" ] && { fzf_kb="$candidate"; break; }
done
if [ -n "$fzf_kb" ]; then
add "[ -f ${fzf_kb} ] && source ${fzf_kb}"
else
add "# key-bindings.bash not found -- install fzf's shell integration to get Ctrl+R"
fi
fi
else
skip "fzf"
fi
# Debian/Ubuntu ship these under different binary names than upstream.
ls_bin=""
have eza && ls_bin="eza"
[ -z "$ls_bin" ] && have exa && ls_bin="exa"
cat_bin=""
have bat && cat_bin="bat"
[ -z "$cat_bin" ] && have batcat && cat_bin="batcat"
if [ -n "$ls_bin" ] || [ -n "$cat_bin" ] || have lazygit; then
add ""
add "# aliases"
if [ -n "$ls_bin" ]; then
add "alias ls='${ls_bin} --icons --group-directories-first'"
add "alias ll='${ls_bin} --icons --group-directories-first -la'"
add "alias lt='${ls_bin} --icons --tree --level=2'"
else
skip "eza (no ls/ll/lt aliases)"
fi
[ -n "$cat_bin" ] && add "alias cat='${cat_bin}'" || skip "bat (no cat alias)"
have lazygit && add "alias lg='lazygit'" || skip "lazygit (no lg alias)"
else
skip "eza"; skip "bat"; skip "lazygit"
fi
add "$END_MARK"
# ---------------------------------------------------------------------- apply
strip_block() {
# Drop everything between the markers, inclusive. Leaves the rest byte-identical.
awk -v b="$BEGIN_MARK" -v e="$END_MARK" '
$0 == b { inblock = 1; next }
$0 == e { inblock = 0; next }
!inblock { print }
' "$1"
}
if [ "$remove" -eq 1 ]; then
[ -f "$rc_file" ] || { echo "no such file: $rc_file" >&2; exit 1; }
if ! grep -Fqx "$BEGIN_MARK" "$rc_file"; then
echo "No apsolut block found in $rc_file -- nothing to remove."
exit 0
fi
if [ "$dry_run" -eq 1 ]; then
echo "[dry-run] would remove the apsolut block from $rc_file"
exit 0
fi
cp "$rc_file" "${rc_file}.bak"
strip_block "$rc_file" > "${rc_file}.tmp"
mv "${rc_file}.tmp" "$rc_file"
echo "Removed the apsolut block from $rc_file (backup: ${rc_file}.bak)"
exit 0
fi
if [ "$dry_run" -eq 1 ]; then
printf '%s' "$block"
[ -n "$skipped" ] && printf '\n# not installed, so omitted:\n%s' "$skipped"
exit 0
fi
[ -f "$rc_file" ] || : > "$rc_file"
cp "$rc_file" "${rc_file}.bak"
had_block=0
grep -Fqx "$BEGIN_MARK" "$rc_file" && had_block=1
{
strip_block "$rc_file"
printf '%s' "$block"
} > "${rc_file}.tmp"
mv "${rc_file}.tmp" "$rc_file"
if [ "$had_block" -eq 1 ]; then
echo "Updated the apsolut block in $rc_file (backup: ${rc_file}.bak)"
else
echo "Added the apsolut block to $rc_file (backup: ${rc_file}.bak)"
fi
if [ -n "$skipped" ]; then
echo "Skipped -- not installed:"
printf '%s' "$skipped"
fi
echo "Run: source $rc_file"