| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 | #!/bin/bash
## hack to workaround Fedora/Red Hat bug 878428
test -f /usr/share/git-core/contrib/completion/git-prompt.sh \
 && . /usr/share/git-core/contrib/completion/git-prompt.sh
#######################################################
### things to do BEFORE host/user-specific settings ###
#######################################################
### .... ###
### SUBZ ###
### '''' ###
bb() {
    #
    # Ring the bell
    #
    printf '\a'
}
dt() {
    #
    # Open $1 new terminals
    #
    __bashum_run_n "${1:-1}" urxvt
}
dT() {
    #
    # Open $1 new alterminals
    #
    __bashum_run_n "${1:-1}" xfce4-terminal
}
__bashum_run_n() {
    #
    # Run $2 in background $1 times
    #
    local n=${1:-1}
    while test "$n" -gt 0;
    do
        "$2" &
        ((n--))
    done
}
twice() {
    #
    # Run $@ two times
    #
    "$@"
    "$@"
}
git() {
    #
    # /usr/bin/git wrapper just to disable dangerous commands
    #
    # In particular, `git-am` is a a close typo of my favorite
    # aliases `ap` (`git-add --patch`) and `cm` (`git-commit`)
    # but it's dangerous to call by accident as it destroys
    # workdir changes.
    #
    if grep -Fwqse "$1" "$GIT_DISABLED_COMMANDS"; then
        echo "You don't want this." >&2
        return 1
    else
        command git "$@"
    fi
}
grepcl() {
    #
    # Grep in common chat log files
    #
    # The order is from older apps to newer as I was moving towards
    # weechat.
    #
    grep "$@" -r \
        "$HOME/.config/xchat2/xchatlogs" \
        "$HOME/.config/xchat2/scrollback" \
        "$HOME/.config/hexchat/logs" \
        "$HOME/.config/hexchat/scrollback" \
        "$HOME/.local/share/weechat/logs.old" \
        "$HOME/.local/share/weechat/logs"
}
grepfx() {
    #
    # Grep recursively for technical debt
    #
    # '[F]' hack to avoid matching self
    #
    grep --color -n \
        --exclude-dir 'utils' \
        --exclude-dir '.git' \
        -o '#[F]IXME:.*' -r "$@"
}
grepr() {
    #
    # Grep recursively, keeping numbers and ignoring common dirs
    #
    # Number one tool for refactoring!
    #
    local p=$1; shift
    grep --color -n --exclude-dir=".git" -e "$p" -r "$@"
}
grepr1() {
    #
    # Like grepr() but only list matching items in this directory
    #
    # Ie. list only files in current directory or names of subdirectories
    # where matches were found "somewhere".
    #
    grepr "$@" -l | cut -d/ -f1 | uniq
}
greph() {
    #
    # Grep through bash history
    #
    history | sed 's/^  *//; s/  / /' | cut -d' ' -f2- | grep "$@"
}
gitcd() {
    #
    # Deep in git repo, cd to the git root
    #
    cd "$(git rev-parse --show-toplevel)"
}
clsz() {
    #
    # Clear screen and move the prompt to bottom
    #
    tput clear; tput cup "$(tput lines)" 0
}
bcdiff() {
    #
    # Call bcompare only if objects actually differ
    #
    test $# -eq 2 && diff "$@" >/dev/null && return
    bcompare "$@" &
}
strip_colors() {
    #
    # Strip color codes from stdin
    #
    # Stolen from http://unix.stackexchange.com/a/4533/9365
    #
    sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
}
vims() {
    #
    # List Vim .swp files in a nice table
    #
    # **Note:** For this ro work, you need to set up Vim to
    # use same swap directory as assigned below.  this can
    # be achieved by addoing section such as this to your
    # .vimrc:
    #
    #     if isdirectory($HOME . '/.local/share/vim') == 0
    #       :silent !mkdir -p ~/.vim/swap >/dev/null 2>&1
    #     endif
    #     set directory=./.vim-swap//
    #     set directory+=~/.local/share/vim/swap//
    #     set directory+=~/tmp//
    #     set directory+=.
    #
    # Call this after crash or poweroff to remind yourself what
    # files you were editing before fact.  Example:
    #
    #     2015-07-10 06:10:48.603953758 +0200 ~/TODO.todo
    #
    # This should make it easier to recover after a little
    # disaster.
    #
    local swap="$HOME/.local/share/vim/swap"
    find "$swap" -type f -print0 \
      | xargs -0 -r stat -c "%y %n" \
      | sed "
            s| $swap/| |
            s|%|/|g
            s|.swp$||
            s| $HOME| ~|
            s| \(..:..\):[^ ]* +.... | \\1 |
        " \
      | sort \
      | tac
}
fixnl() {
    #
    # Fix newlines in stdin and pass to stdout
    #
    # Note: We need to read whole stdin; this cannot work
    # for infinite stream.
    #
    # Fix annoying cases:
    #
    #  *  If multi-line text is missing newline at the
    #     end---add the missing newline.
    #
    #  *  If -c is passed, and single-line text does have
    #     a newline at the end, remove it.
    #
    # This will not touch properly terminated multi-line texts,
    # or zero-line texts (ie. oly chars with no newline at all).
    #
    local arg=$1        # argument passed
    local cache         # cache to keep stream in
    local nlcount       # count of newlines in the stream
    local lastchr       # hex dump (2-digit, lowercase) of last char
    local single=keep   # single-line streams:
                        #   keep: do nothing
                        #   chop: drop last char if it's a LF
    case $arg in
        -c|--chop-single) single=chop ;;
    esac
    cache="$(mktemp -t fixnl.XXXXXXXX)"
    cat >"$cache"
    nlcount=$(<"$cache" wc -l)
    lastchr=$(<"$cache" tail -c1 | hexdump -e '"%02x"')
    case $nlcount:$lastchr:$single in
        0:??:*)     cat "$cache"        ;;  # 'abc'       => keep as is
        1:0a:chop)  head -c -1 "$cache" ;;  # 'abc\n'     => -c passed: chop!
        1:0a:keep)  cat "$cache"        ;;  # 'abc\n'     => keep as is
        *:0a:*)     cat "$cache"        ;;  # 'a\nb\nc\n' => keep as is
        *:??:*)     cat "$cache";  echo ;;  # 'a\nb\nc'   => add the missing NL
    esac
    rm "$cache"
}
mdvimb() {
    #
    # Open Markdown file in Vimb (no junk)
    #
    local file=$1
    <"$file" Markdown | vimb -
}
nlfor() {
    #
    # Replace $1 (or blank space) with newlines and fix final newline
    #
    # Shorthand for commonly used tr syntax.  Example:
    #
    #     $ echo "$PATH" | nlat :
    #     /foo
    #     /bar
    #     $
    #
    # is almost like `tr : '\n'` except that it is a bit easier
    # to type and fixes the annoying problem with missing
    # newline at the end of the replaced string.
    #
    local char=$1
    test -n "$char" || char='[:blank:]'
    tr "$char" '\n' \
      | fixnl
}
nljoin() {
    #
    # Join lines with $1 (or space)
    #
    # Shorthand for commonly used tr syntax.  Example:
    #
    #     $ { echo foo; echo bar; } | nljoin :
    #
    # is almost like `tr '\n' :` except that it is a bit easier
    # to type and fixes the annoying problem with extraneous
    # newline/colon at the end of final string.
    #
    local char=$1
    test -n "$char" || char=' '
    tr '\n' "$char" \
      | sed "s/$char*$//" \
      | fixnl -c
}
qpr() {
    #
    # Encode or decode (if $1 is '-d') message on stdin as Quoted Printable
    #
    local fn=encode
    case $1 in
        -d) fn=decode ;;
        -*) echo 'usage: qpr [-d] <text' >&2; return 2 ;;
    esac
    perl -MMIME::QuotedPrint -pe "\$_=MIME::QuotedPrint::$fn(\$_);"
}
xop() {
    #
    # Common clipboard operations with fixnl() on top
    #
    local op=$1
    local file=${2:-/dev/stdin}
    case $op in
        oo) xclip -selection clipboard -o    | fixnl ;;
        o)  xclip -o                         | fixnl ;;
        ii) fixnl -c | xclip -selection clipboard -i ;;
        i)  fixnl -c | xclip -i                      ;;
    esac <"$file"
}
xod() {
    #
    # Like mktemp but get the content from clipboard
    #
    # Dump xo in a file named $1 somewhere in /tmp; echo the path
    # usage: scp $(xod useful_name.txt) eg:some/shared/place
    # instead of:
    #
    #     xo > useful_name.txt
    #     scp useful_name.txt eg:some/shared/place
    #     rm useful_name.txt
    #
    local name="${1:-clipboard_dump.txt}"
    local tmp=$(mktemp -d -t "xod.XXXXXXXX")
    xclip -o > "$tmp/$name"
    echo "$tmp/$name"
}
xood() {
    #
    # Just like xod() but using xoo (i.e. 'clipboard' clipboard)
    #
    local name="${1:-clipboard_dump.txt}"
    local tmp=$(mktemp -d -t "xood.XXXXXXXX")
    xclip -selection clipboard -o > "$tmp/$name"
    echo "$tmp/$name"
}
xvxx() {
    #
    # Edit text in primary clipboard and save it to C-C clipboard
    #
    # Ideal for editing snippets in browser-based editors: during editing,
    # select the text, open terminal, call `xvx`, edit the text, move
    # back to the browser and paste it over the old (still selected) text.
    # That's it, no need to make up and save temporary files.
    #
    # If you quickly realize you need to re-edit the text, use xvvx().
    #
    xop o | vipe | xop ii
}
vx() {
    #
    # Edit stdin and save it to primary clipboard
    #
    # Ideal for selecting snippets of output of arbitrary commands.
    # select the text, open terminal, call `xvx`, edit the text, move
    # back to the browser and paste it over the old (still selected) text.
    # That's it, no need to make up and save temporary files.
    #
    vipe | xop i
}
xxvxx() {
    #
    # Edit text in C-C clipboard and save it back
    #
    xop oo | vipe | xop ii
}
yt2ogg() {
    #
    # Download YouTube video as vorbis audio
    #
    local url=$1
    youtube-dl -x --audio-format vorbis "$url"
}
yum_hasbin() {
    #
    # Ask yum who has bin $1 (and make the output actually readable)
    #
    local bname
    for bname in "$@";
    do
        case $bname in
            */*)    dnf provides "$bname" ;;
            *)      dnf provides "*/bin/$bname" ;;
        esac \
          | grep '^.' \
          | grep -E '^[[:alnum:]_:.-]+ :'
    done
}
### .... ###
### BASH ###
### '''' ###
HISTCONTROL=ignoredups:erasedups
shopt -s histappend
PROMPT_COMMAND="history -n; history -w; history -c; history -r; $PROMPT_COMMAND"
HISTIGNORE="$HISTIGNORE:ls:ll:la:cd"
HISTIGNORE="$HISTIGNORE:git dc:git st"
HISTIGNORE="$HISTIGNORE:reset"
HISTIGNORE="$HISTIGNORE:se *:sc *"
HISTSIZE=-1
HISTFILESIZE=100000
GLOBIGNORE=.:..
shopt -s histverify
# some more aliases
alias cal='cal -m'
alias cls='clear'
alias czkrates='czkrates -v'
alias ll='ls -lh'
alias lla='ls -lha'
alias open='gnome-open'
alias diff='colordiff -u'
alias dmesg='dmesg --time-format iso'
alias pad4='sed -e "/./s/^/    /"'
alias grep='grep --color'
alias sc='se --direction=encz.cz'
alias taskm='task modify'
alias tasks='task rc.context:none'
alias ts='ts "%F %T"'
alias lsblk='lsblk -o +UUID,LABEL'
alias virsh='virsh --connect qemu:///system'
alias wttr='curl -s "wttr.in/?1&n&q"'
alias xaa='xclip -o | audit2allow'
alias xi='xop i'
alias xii='xop ii'
alias xo='xop o'
alias xoo='xop oo'
alias reboot="echo -n . ; sync ; echo -n . ; sync ; echo -n . ; systemctl reboot"
alias poweroff="echo -n . ; sync ; echo -n . ; sync ; echo -n . ; systemctl poweroff"
x4x() {
    #
    # Pad text from primary clipboard with 4 spaces; save to C-C clipboard
    #
    # ...that is, for inclusion as Markdown verbatim text.
    #
    xo | pad4 | xii
}
RV_TMP="/tmp/bash-rv"
mkdir -p "$RV_TMP"
### ...... ###
### OTHERS ###
### '''''' ###
export LC_COLLATE=C     # make sort upper first
export EDITOR=vim
export LESSOPEN="| /usr/bin/src-hilite-lesspipe.sh %s"
export LESS=' -R '
export PRETTY=color
export PRETTY_DEBUG_EXCLUDE=inigrep
# make green git bash trinket even cooler
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_DISABLED_COMMANDS="$HOME/.gittum/disabled-commands"
export GIT_PAGER='less -S'
# disable mounting things like SFTP to ~/.gvfs when accessed
# via GIO (used by nautilus etc.)
export GVFS_DISABLE_FUSE=1
# disable the terrible beep sound (only for X; for tty?, blacklist pcspkr)
xhost >& /dev/null && xset b off
# get rid of those .pyc files once and for all
export PYTHONDONTWRITEBYTECODE=1
ssh-add -l >& /dev/null || ssh-add
 |