My dotfiles. Period.

main.bashrc 14KB

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