My dotfiles. Period.

main.bashrc 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. #!/bin/bash
  2. ## hack to workaround Fedora/Red Hat bug 878428
  3. #shellcheck disable=SC1091
  4. test -f /usr/share/git-core/contrib/completion/git-prompt.sh \
  5. && . /usr/share/git-core/contrib/completion/git-prompt.sh
  6. #######################################################
  7. ### things to do BEFORE host/user-specific settings ###
  8. #######################################################
  9. ### .... ###
  10. ### SUBZ ###
  11. ### '''' ###
  12. bb() {
  13. #
  14. # Ring the bell
  15. #
  16. local stime=${1:-0}
  17. sleep "$stime"
  18. printf '\a'
  19. }
  20. nn() {
  21. #
  22. # Ring the bell and send notification $1
  23. #
  24. local msg=${1:-this is done}
  25. bb
  26. echo -e "hey, \033[1;31m$msg\033[1;0m!"
  27. notify-send -a 'nn()' "hey, $msg"
  28. }
  29. dt() {
  30. #
  31. # Open $1 new terminals
  32. #
  33. __bashum_run_n "${1:-1}" urxvt
  34. }
  35. dT() {
  36. #
  37. # Open $1 new alterminals
  38. #
  39. __bashum_run_n "${1:-1}" xfce4-terminal
  40. }
  41. hr() {
  42. #
  43. # Make horizontal ruler
  44. #
  45. local i
  46. local line
  47. for i in $(seq 1 "$COLUMNS"); do
  48. case $((i%10)) in
  49. 0) line+='#' ;;
  50. *) line+='-' ;;
  51. esac
  52. done
  53. echo "$line"
  54. echo "$line"
  55. echo "$line"
  56. }
  57. __bashum_run_n() {
  58. #
  59. # Run $2 in background $1 times
  60. #
  61. local n=${1:-1}
  62. while test "$n" -gt 0;
  63. do
  64. "$2" &
  65. ((n--))
  66. done
  67. }
  68. twice() {
  69. #
  70. # Run $@ two times
  71. #
  72. "$@"
  73. "$@"
  74. }
  75. ckyaml() {
  76. #
  77. # Check if YAML file $1 is loadable
  78. #
  79. local yfile=$1
  80. python -c 'import yaml; import sys; print(yaml.load(sys.stdin)["this"])' <"$yfile"
  81. }
  82. git() {
  83. #
  84. # /usr/bin/git wrapper just to disable dangerous commands
  85. #
  86. # In particular, `git-am` is a a close typo of my favorite
  87. # aliases `ap` (`git-add --patch`) and `cm` (`git-commit`)
  88. # but it's dangerous to call by accident as it destroys
  89. # workdir changes.
  90. #
  91. if grep -Fwqse "$1" "$GIT_DISABLED_COMMANDS"; then
  92. echo "You don't want this." >&2
  93. return 1
  94. else
  95. command git "$@"
  96. fi
  97. }
  98. grepcl() {
  99. #
  100. # Grep in common chat log files
  101. #
  102. # The order is from older apps to newer as I was moving towards
  103. # weechat.
  104. #
  105. grep "$@" -R \
  106. "$HOME/.config/xchat2/xchatlogs" \
  107. "$HOME/.config/xchat2/scrollback" \
  108. "$HOME/.config/hexchat/logs" \
  109. "$HOME/.config/hexchat/scrollback" \
  110. "$HOME/.local/share/weechat/logs.old" \
  111. "$HOME/.local/share/weechat/logs"
  112. }
  113. grepfx() {
  114. #
  115. # Grep recursively for technical debt
  116. #
  117. # '[F]' hack to avoid matching self
  118. #
  119. grep --color -n \
  120. --exclude-dir 'utils' \
  121. --exclude-dir '.git' \
  122. -o '#[F]IXME:.*' -R "$@"
  123. }
  124. grepr() {
  125. #
  126. # Grep recursively, keeping numbers and ignoring common dirs
  127. #
  128. # Number one tool for refactoring!
  129. #
  130. local p=$1; shift
  131. grep --color -n --exclude-dir=".git" -e "$p" -R "$@"
  132. }
  133. grepr1() {
  134. #
  135. # Like grepr() but only list matching items in this directory
  136. #
  137. # Ie. list only files in current directory or names of subdirectories
  138. # where matches were found "somewhere".
  139. #
  140. grepr "$@" -l | cut -d/ -f1 | uniq
  141. }
  142. greph() {
  143. #
  144. # Grep through bash history
  145. #
  146. history | sed 's/^ *//; s/ / /' | cut -d' ' -f2- | grep "$@"
  147. }
  148. gitcd() {
  149. #
  150. # Deep in git repo, cd to the git root
  151. #
  152. cd "$(git rev-parse --show-toplevel)" || return 1
  153. }
  154. clsz() {
  155. #
  156. # Clear screen and move the prompt to bottom
  157. #
  158. tput clear; tput cup "$(tput lines)" 0
  159. }
  160. bcdiff() {
  161. #
  162. # Call bcompare only if objects actually differ
  163. #
  164. test $# -eq 2 && diff "$@" >/dev/null && return
  165. bcompare "$@" &
  166. }
  167. strip_colors() {
  168. #
  169. # Strip color codes from stdin
  170. #
  171. # Stolen from http://unix.stackexchange.com/a/4533/9365
  172. #
  173. sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g'
  174. }
  175. vims() {
  176. #
  177. # List Vim .swp files in a nice table
  178. #
  179. # **Note:** For this ro work, you need to set up Vim to
  180. # use same swap directory as assigned below. this can
  181. # be achieved by addoing section such as this to your
  182. # .vimrc:
  183. #
  184. # if isdirectory($HOME . '/.local/share/vim') == 0
  185. # :silent !mkdir -p ~/.vim/swap >/dev/null 2>&1
  186. # endif
  187. # set directory=./.vim-swap//
  188. # set directory+=~/.local/share/vim/swap//
  189. # set directory+=~/tmp//
  190. # set directory+=.
  191. #
  192. # Call this after crash or poweroff to remind yourself what
  193. # files you were editing before fact. Example:
  194. #
  195. # 2015-07-10 06:10:48.603953758 +0200 ~/TODO.todo
  196. #
  197. # This should make it easier to recover after a little
  198. # disaster.
  199. #
  200. local swap="$HOME/.local/share/vim/swap"
  201. #shellcheck disable=SC1117
  202. find "$swap" -type f -print0 \
  203. | xargs -0 -r stat -c "%y %n" \
  204. | sed "
  205. s| $swap/| |
  206. s|%|/|g
  207. s|.swp$||
  208. s| $HOME| ~|
  209. s| \(..:..\):[^ ]* +.... | \\1 |
  210. " \
  211. | sort \
  212. | tac
  213. }
  214. fixnl() {
  215. #
  216. # Fix newlines in stdin and pass to stdout
  217. #
  218. # Note: We need to read whole stdin; this cannot work
  219. # for infinite stream.
  220. #
  221. # Fix annoying cases:
  222. #
  223. # * If multi-line text is missing newline at the
  224. # end---add the missing newline.
  225. #
  226. # * If -c is passed, and single-line text does have
  227. # a newline at the end, remove it.
  228. #
  229. # This will not touch properly terminated multi-line texts,
  230. # or zero-line texts (ie. oly chars with no newline at all).
  231. #
  232. local arg=$1 # argument passed
  233. local cache # cache to keep stream in
  234. local nlcount # count of newlines in the stream
  235. local lastchr # hex dump (2-digit, lowercase) of last char
  236. local single=keep # single-line streams:
  237. # keep: do nothing
  238. # chop: drop last char if it's a LF
  239. case $arg in
  240. -c|--chop-single) single=chop ;;
  241. esac
  242. cache="$(mktemp -t fixnl.XXXXXXXX)"
  243. cat >"$cache"
  244. nlcount=$(<"$cache" wc -l)
  245. lastchr=$(<"$cache" tail -c1 | hexdump -e '"%02x"')
  246. case $nlcount:$lastchr:$single in
  247. 0:??:*) cat "$cache" ;; # 'abc' => keep as is
  248. 1:0a:chop) head -c -1 "$cache" ;; # 'abc\n' => -c passed: chop!
  249. 1:0a:keep) cat "$cache" ;; # 'abc\n' => keep as is
  250. *:0a:*) cat "$cache" ;; # 'a\nb\nc\n' => keep as is
  251. *:??:*) cat "$cache"; echo ;; # 'a\nb\nc' => add the missing NL
  252. esac
  253. rm "$cache"
  254. }
  255. nlfor() {
  256. #
  257. # Replace $1 (or blank space) with newlines and fix final newline
  258. #
  259. # Shorthand for commonly used tr syntax. Example:
  260. #
  261. # $ echo "$PATH" | nlat :
  262. # /foo
  263. # /bar
  264. # $
  265. #
  266. # is almost like `tr : '\n'` except that it is a bit easier
  267. # to type and fixes the annoying problem with missing
  268. # newline at the end of the replaced string.
  269. #
  270. local char=$1
  271. test -n "$char" || char='[:blank:]'
  272. tr "$char" '\n' \
  273. | fixnl
  274. }
  275. nljoin() {
  276. #
  277. # Join lines with $1 (or space)
  278. #
  279. # Shorthand for commonly used tr syntax. Example:
  280. #
  281. # $ { echo foo; echo bar; } | nljoin :
  282. #
  283. # is almost like `tr '\n' :` except that it is a bit easier
  284. # to type and fixes the annoying problem with extraneous
  285. # newline/colon at the end of final string.
  286. #
  287. local char=$1
  288. test -n "$char" || char=' '
  289. tr '\n' "$char" \
  290. | sed "s/$char*$//" \
  291. | fixnl -c
  292. }
  293. qpr() {
  294. #
  295. # Encode or decode (if $1 is '-d') message on stdin as Quoted Printable
  296. #
  297. local fn=encode
  298. case $1 in
  299. -d) fn=decode ;;
  300. -*) echo 'usage: qpr [-d] <text' >&2; return 2 ;;
  301. esac
  302. perl -MMIME::QuotedPrint -pe "\$_=MIME::QuotedPrint::$fn(\$_);"
  303. }
  304. xop() {
  305. #
  306. # Common clipboard operations with fixnl() on top
  307. #
  308. local op=$1
  309. local file=${2:-/dev/stdin}
  310. case $op in
  311. oo) xclip -selection clipboard -o | fixnl ;;
  312. o) xclip -o | fixnl ;;
  313. ii) fixnl -c | xclip -selection clipboard -i ;;
  314. i) fixnl -c | xclip -i ;;
  315. esac <"$file"
  316. }
  317. xod() {
  318. #
  319. # Like mktemp but get the content from clipboard
  320. #
  321. # Dump xo in a file named $1 somewhere in /tmp; echo the path
  322. # usage: scp $(xod useful_name.txt) eg:some/shared/place
  323. # instead of:
  324. #
  325. # xo > useful_name.txt
  326. # scp useful_name.txt eg:some/shared/place
  327. # rm useful_name.txt
  328. #
  329. local name="${1:-clipboard_dump.txt}"
  330. local tmp
  331. tmp=$(mktemp -d -t "xod.XXXXXXXX")
  332. xclip -o > "$tmp/$name"
  333. echo "$tmp/$name"
  334. }
  335. xood() {
  336. #
  337. # Just like xod() but using xoo (i.e. 'clipboard' clipboard)
  338. #
  339. local name="${1:-clipboard_dump.txt}"
  340. local tmp
  341. tmp=$(mktemp -d -t "xood.XXXXXXXX")
  342. xclip -selection clipboard -o > "$tmp/$name"
  343. echo "$tmp/$name"
  344. }
  345. xvxx() {
  346. #
  347. # Edit text in primary clipboard and save it to C-C clipboard
  348. #
  349. # Ideal for editing snippets in browser-based editors: during editing,
  350. # select the text, open terminal, call `xvx`, edit the text, move
  351. # back to the browser and paste it over the old (still selected) text.
  352. # That's it, no need to make up and save temporary files.
  353. #
  354. # If you quickly realize you need to re-edit the text, use xvvx().
  355. #
  356. xop o | vipe | xop ii
  357. }
  358. vx() {
  359. #
  360. # Edit stdin and save it to primary clipboard
  361. #
  362. # Ideal for selecting snippets of output of arbitrary commands.
  363. # select the text, open terminal, call `xvx`, edit the text, move
  364. # back to the browser and paste it over the old (still selected) text.
  365. # That's it, no need to make up and save temporary files.
  366. #
  367. vipe | xop i
  368. }
  369. xxvxx() {
  370. #
  371. # Edit text in C-C clipboard and save it back
  372. #
  373. xop oo | vipe | xop ii
  374. }
  375. yt2ogg() {
  376. #
  377. # Download YouTube video as vorbis audio
  378. #
  379. local url=$1
  380. youtube-dl -x --audio-format vorbis "$url"
  381. }
  382. yum_hasbin() {
  383. #
  384. # Ask yum who has bin $1 (and make the output actually readable)
  385. #
  386. local bname
  387. for bname in "$@";
  388. do
  389. case $bname in
  390. */*) dnf provides "$bname" ;;
  391. *) dnf provides "*/bin/$bname" ;;
  392. esac \
  393. | grep '^.' \
  394. | grep -E '^[[:alnum:]_:.-]+ :'
  395. done
  396. }
  397. cal() {
  398. #
  399. # cal with the proper version pick
  400. #
  401. local cal_v
  402. local cal_es
  403. cal_v=$(command cal -V 2>/dev/null); cal_es=$?
  404. case $cal_es:$cal_v in
  405. 0:cal\ from\ util-linux\ 2.32.1)
  406. command cal --color=always --monday --week "$@"
  407. ;;
  408. 64:*)
  409. command cal -M "$@"
  410. ;;
  411. esac
  412. }
  413. ### .... ###
  414. ### BASH ###
  415. ### '''' ###
  416. HISTCONTROL=ignoredups:erasedups
  417. shopt -s histappend
  418. PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
  419. HISTIGNORE="$HISTIGNORE:ls:ll:la:cd"
  420. HISTIGNORE="$HISTIGNORE:git dc:git st"
  421. HISTIGNORE="$HISTIGNORE:reset"
  422. HISTIGNORE="$HISTIGNORE:se *:sc *"
  423. HISTSIZE=-1
  424. HISTFILESIZE=100000
  425. HISTTIMEFORMAT='%F %T '
  426. GLOBIGNORE=.:..
  427. shopt -s histverify
  428. # some more aliases
  429. alias cls='clear'
  430. alias czkrates='czkrates -v'
  431. alias ll='ls -lh'
  432. alias lla='ls -lha'
  433. alias open='gnome-open'
  434. alias diff='colordiff -u'
  435. alias dmesg='dmesg --time-format iso'
  436. alias pad4='sed -e "/./s/^/ /"'
  437. alias mkittool='mkittool -v'
  438. alias grep='grep --color'
  439. alias sc='se --direction=encz.cz'
  440. alias taskm='task modify'
  441. alias tasks='task rc.context:none'
  442. alias ts='ts "%F %T"'
  443. alias lsblk='lsblk -o +UUID,LABEL'
  444. alias pstree='pstree -h'
  445. alias virsh='virsh --connect qemu:///system'
  446. alias wttr='curl -s "wttr.in/?1&n&q"'
  447. alias xaa='xclip -o | audit2allow'
  448. alias xi='xop i'
  449. alias xii='xop ii'
  450. alias xo='xop o'
  451. alias xoo='xop oo'
  452. alias reboot="echo -n . ; sync ; echo -n . ; sync ; echo -n . ; systemctl reboot"
  453. alias poweroff="echo -n . ; sync ; echo -n . ; sync ; echo -n . ; systemctl poweroff"
  454. x4x() {
  455. #
  456. # Pad text from primary clipboard with 4 spaces; save to C-C clipboard
  457. #
  458. # ...that is, for inclusion as Markdown verbatim text.
  459. #
  460. xo | pad4 | xii
  461. }
  462. RV_TMP="/tmp/bash-rv"
  463. mkdir -p "$RV_TMP"
  464. ### ...... ###
  465. ### OTHERS ###
  466. ### '''''' ###
  467. export LC_COLLATE=C # make sort upper first
  468. export EDITOR=vim
  469. export LESSOPEN="| /usr/bin/src-hilite-lesspipe.sh %s"
  470. export LESS=' -R '
  471. export PRETTY=color
  472. export PRETTY_DEBUG_EXCLUDE=inigrep
  473. export MDVIMB__CONVERTER=commonmark
  474. export MDVIMB__STYLE=darkzen # pergamen
  475. #shellcheck disable=SC2034
  476. {
  477. GIT_PS1_SHOWDIRTYSTATE=true
  478. GIT_PS1_SHOWUNTRACKEDFILES=true
  479. __SATURNIN_COMPLETE_DEBUG=true
  480. GIT_DISABLED_COMMANDS="$HOME/.gittum/disabled-commands"
  481. }
  482. export GIT_PAGER='less -S'
  483. # disable mounting things like SFTP to ~/.gvfs when accessed
  484. # via GIO (used by nautilus etc.)
  485. export GVFS_DISABLE_FUSE=1
  486. # disable the terrible beep sound (only for X; for tty?, blacklist pcspkr)
  487. xhost >& /dev/null && xset b off
  488. # get rid of those .pyc files once and for all
  489. export PYTHONDONTWRITEBYTECODE=1
  490. ssh-add -l >& /dev/null || ssh-add