-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy path.bashrc
More file actions
277 lines (232 loc) · 9.59 KB
/
.bashrc
File metadata and controls
277 lines (232 loc) · 9.59 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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# shellcheck shell=bash disable=SC1091,SC2016,SC2028,SC2034,SC2059,SC2139
# If not running interactively, don't do anything
if [[ $- != *i* ]]; then
return
fi
## show greeter
# -----------------------------------------------------------------------------
# if not in vim or ranger show reminders for today
if [[ -z $NVIM && -z $RANGER_LEVEL && -n $(type -t when) ]]; then
when --noheader --styled_output_if_not_tty w | sed 's/^/│ /' |
xargs -r0 printf "┌─[ Reminders ]\\n%s└$(printf '%0.s─' {0..22})\\n"
fi
## build prompt
# -----------------------------------------------------------------------------
function __start_ps1(){
local fmt args time=$((SECONDS-START_TIME)) exit_code=$?
local white='\[\e[37m\]' ylw='\[\e[33m\]' reset='\[\e[m\]'
local boldred='\[\e[1;31m\]' boldblue='\[\e[1;34m\]'
if [[ -v REPORT_STATUS && $exit_code -ne 0 ]]; then
# display exit code of previous command if it is nonzero
__printf "%s " "$boldred$exit_code"
fi
if [[ $EUID -eq 0 ]]; then
__printf "%s" "$boldred\u$reset"
else
__printf "%s" "$boldblue\u$reset"
fi
__printf "@%s %s" "\h" "$white\w$reset"
if [[ -v REPORT_STATUS ]]; then
local -x TZ=UTC0 # interpret $time as unix epoch time
# ring bell and show execution time of previous command if above threshold
if ((time >= 10)); then
__printf "\[\a\]"
if ((time >= 86400)); then
__printf " (%s%d-%(%T)T%s)" "$ylw" "$((time/86400))" "$time" "$reset"
elif ((time >= 3600)); then
__printf " (%s%(%-H:%M:%S)T%s)" "$ylw" "$time" "$reset"
else
__printf " (%s%(%-M:%S)T%s)" "$ylw" "$time" "$reset"
fi
fi
fi
printf -v START_PS1 "$fmt" "${args[@]}"
}
function __end_ps1(){
local fmt args jobs purple='\[\e[35m\]' aqua='\[\e[36m\]' reset='\[\e[m\]'
if [[ -n "$VIRTUAL_ENV" ]]; then
__printf " (%s)" "$purple${VIRTUAL_ENV##*/}$reset"
fi
# -V flag is new in bash 5.3. Be backwards compatible.
compgen -jV jobs || readarray jobs < <(compgen -j)
if (( jobs=${#jobs[@]}, jobs )); then
__printf " (%s%d job%.*s%s)" "${aqua}" $jobs $((jobs>1)) s "${reset}"
fi
printf -v END_PS1 "$fmt%s>%s " "${args[@]}" "\n" "$reset"
} 2> /dev/null
function __printf(){
fmt+="$1" args+=("${@:2}")
}
# integrate git into prompt via PROMPT_COMMAND
if [[ -r /usr/share/git/git-prompt.sh ]]; then
source /usr/share/git/git-prompt.sh
GIT_PS1_SHOWCOLORHINTS=yes GIT_PS1_SHOWCONFLICTSTATE=yes
PROMPT_COMMAND=(__start_ps1 __end_ps1 '__git_ps1 "$START_PS1" "$END_PS1"')
else
PROMPT_COMMAND=(__start_ps1 __end_ps1 'PS1="$START_PS1$END_PS1"')
fi
# whenever PS0 is evaluated (non-empty command) set status flag and timestamp
PS0='\[${PS0:$((START_TIME=$SECONDS, REPORT_STATUS=yes, 0)):0}\]'
PROMPT_COMMAND+=("unset START_TIME REPORT_STATUS START_PS1 END_PS1")
PROMPT_DIRTRIM=3
PS2="» "
## general shell behavior
# -----------------------------------------------------------------------------
shopt -s histappend # append history on exit, don't overwrite
shopt -s lithist # Save multi-line cmd with embedded newline
shopt -s checkwinsize # Update col/lines after commands
shopt -s checkjobs # defer exit if jobs are running
shopt -s autocd # Can change dir without `cd`
shopt -s cdspell # Fixes minor spelling errors in cd paths
shopt -s no_empty_cmd_completion # Stops empty line tab comp
shopt -s dirspell # Tab comp can fix dir name typos
shopt -s globstar # pattern ** also searches subdirectories
shopt -s extglob # enable extended pattern matching features
# reset cursor shape before executing a command (see .config/readline/inputrc)
if [[ $TERM = linux ]]; then
PS0+='\[\e[?8c\]'
else
PS0+='\[\e[2 q\]'
fi
# bash history stuff
HISTSIZE=10000
HISTFILESIZE=inf
HISTTIMEFORMAT="%d/%m/%y %T "
HISTCONTROL=ignoreboth:erasedups
# don't append wifi passwords to history file
HISTIGNORE="nmcli d* w* [ch]* * password *"
PROMPT_COMMAND+=("history -a")
## Aliases
# -----------------------------------------------------------------------------
# bring color to the terminal
alias ls='ls --color=auto -v'
alias la='ls --color=auto -vla'
alias ll='ls --color=auto -vl'
alias lh='ls --color=auto -vhAl'
alias diff='diff --color=auto'
alias grep='grep --color=auto'
alias ip='ip -color=auto'
alias info="info --vi-keys -v match-style=underline,bold,nocolor \
-v link-style=yellow -v active-link-style=yellow,bold"
# other useful aliases
alias pac='pacman'
alias spac='sudo pacman'
alias apac='yay --aur --editmenu --removemake'
alias pacli='pacman -Q | wc -l'
alias pacro='pacman -Qtd > /dev/null && sudo pacman -Rns $(pacman -Qtdq)'
alias calc='ptpython -i <(echo "from math import *; from statistics import *")'
alias todo='$EDITOR +sil\ /^##\ $(date +%A) +noh +norm\ zz ~/Documents/TODO.md'
alias {vim,nvim}="$EDITOR"
alias bell="printf '\a'"
alias nmcli='nmcli --ask --pretty'
alias server='python3 -m http.server 9999'
alias {dotfiles,dofi}='git --git-dir=$HOME/.dotfiles --work-tree=$HOME'
alias rec='ffmpeg -f x11grab -i $DISPLAY -f pulse -i default -y'
alias backup="sudo snap-sync --config home --noconfirm --UUID \
\"\$(lsblk -no UUID /dev/disk/by-label/backup)\""
# fun stuff
alias starwars='telnet towel.blinkenlights.nl'
alias maps='telnet mapscii.me'
alias 2048='ssh play@ascii.town'
alias tron='ssh sshtron.zachlatta.com'
alias chat='ssh -o StrictHostKeyChecking=no -o LogLevel=QUIET ch.at'
alias nyancat="mpv --no-terminal --no-video --loop ytdl://QH2-TGUlwu4 & \
telnet rainbowcat.acc.umu.se; kill %%"
## Bash-completions
# -----------------------------------------------------------------------------
if [[ -r /usr/share/bash-completion/bash_completion ]]; then
source /usr/share/bash-completion/bash_completion
fi
# sourcing order is important, see
# https://github.com/cykerway/complete-alias/issues/46
if [[ -n $(type -t fzf) ]]; then
eval "$(fzf --bash)"
fi
# external alias completion, progcomp_alias shopt builtin sadly doesn't work
# https://github.com/scop/bash-completion/issues/383
if [[ -r /usr/share/bash-complete-alias/complete_alias ]]; then
COMPAL_AUTO_UNMASK=1
source /usr/share/bash-complete-alias/complete_alias
complete -F _complete_alias "${!BASH_ALIASES[@]}"
fi
## FZF config for interactive use
# -----------------------------------------------------------------------------
if [[ -n $(type -t fzf) ]]; then
# syntax highlight matches and preview directories
FZF_COMPLETION_OPTS="--preview '{ pygmentize -f terminal {} || cat {} ||
tree -C {}; } 2> /dev/null | head -200'"
# To apply the command to CTRL-T as well
FZF_CTRL_T_OPTS="$FZF_COMPLETION_OPTS"
# Preview directories with tree
FZF_ALT_C_OPTS="--preview 'tree -C {} | head -200'"
# preview long commands with "?"
FZF_CTRL_R_OPTS="--preview 'echo {}' --preview-window down:3:hidden:wrap \
--bind '?:toggle-preview'"
# https://github.com/junegunn/fzf/blob/master/ADVANCED.md#ripgrep-integration
function lgrep(){
rm -f /tmp/rg-fzf-{r,f}
local rg_prefix="rg --column --line-number --no-heading --color=always"
rg_prefix+=" --smart-case --hidden --glob '!{.git,node_modules,.venv}'"
local switch='%s(change)+change-prompt(%s> )+%s+transform-query:"'
switch+='echo \{q} > /tmp/rg-fzf-%s; cat /tmp/rg-fzf-%s\n'
fzf --ansi --multi --disabled --query "${*:-}" \
--bind "start:reload:$rg_prefix {q} || true" \
--bind "change:reload:sleep 0.1; $rg_prefix {q} || true" \
--bind "ctrl-g:transform:[[ ! \$FZF_PROMPT =~ regex ]] &&
printf ${switch@Q} rebind regex disable-search f r ||
printf ${switch@Q} unbind fuzzy enable-search r f" \
--color "hl:-1:underline,hl+:-1:underline:reverse" \
--prompt 'regex> ' \
--delimiter : \
--header 'ctrl-g to switch between fuzzy/regex search' \
--preview "pygmentize -f terminal {1} || cat {1}" \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
--bind "enter:become($EDITOR +{2} {1})"
}
fi
## Functions
# -----------------------------------------------------------------------------
# report disk usage of directory and sort files by size
function dusort(){
find "$@" -mindepth 1 -maxdepth 1 -exec du -sch {} + | sort -h
}
# tldr version of man pages
function tldr(){
local IFS=-
curl cheat.sh/"$*"
}
# list package which owns command
function whoowns(){
pacman -Qo "$@" 2> /dev/null || pacman -F "$@"
}
# list commands which are provided by package
function listprogs(){
pacman -Qlq "$@" | grep -F "${PATH//:/$'\n'}" | sed -rn 's|.*/([^/]+)$|\1|p'
}
# find fonts which contain character(s)
function findfonts(){
fc-list ":charset=$(printf "%x " "${@/#/\'}")" family style
}
# fetch current weather report, with location as optional parameter
function weather(){
local request="wttr.in/${*^}?Fm"
if [[ "$(tput cols)" -lt 125 ]]; then
request+='n'
fi
curl -H "Accept-Language: ${LANG%_*}" --compressed "${request// /+}"
}
# Conveniently copy files to NAS
function ncp(){
rsync --info=progress2 --recursive --protect-args --times --perms \
--chmod=D775,F664 "${1%/}" "${2:+NAS:/media/storage/$2}"
}
## window title and current working directory
# -----------------------------------------------------------------------------
# advise the terminal of the current working directory
PROMPT_COMMAND+=('printf "\e]7;file://%s%s\e\\" "$HOSTNAME" "$PWD"')
# aerc's terminal doesn't like this
if [[ $(< /proc/$PPID/comm) != aerc ]]; then
# set window title to currently running command or current working directory
PROMPT_COMMAND+=('[ -n "$BASH_COMMAND" ] && printf "\e]0;%s\a" "$PWD"')
trap 'printf "\e]0;%s\a" "${BASH_COMMAND//[^[:print:]]/}"' DEBUG
fi