summaryrefslogtreecommitdiffstats
path: root/.bashrc
blob: c96d63f7d3d4bab11302d8f3d7051e44c39fcf4c (plain)
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
# .bashrc

# Some minimal API expected by sourced files
# XXX: check for alias collision
_diralias () {
	local target=$(echo $* | sed -s "s| |/|g")
	test "$(pwd)" = "$(eval echo "$(dirs +1 2>/dev/null)")" && popd -n &>/dev/null
	test "${target}" = "$(eval echo "$(dirs +0)")" || pushd "${target}" >/dev/null
	pwd
}
diralias () {
	alias "$(basename "$1")=_diralias $1"
	# using loose depth from the beginning unnecessarily clutter the offer,
	# so this way, albeit complicated, convenient traversal is achieved
	# XXX could -G be used instead?
	complete -o nospace -C \
	  "f(){ test \"\$3\" != \"$(basename "$1")\" || \
	        find -L \"${1%%* }/\${2%\${2##*/}}\" \
	          -mindepth 1 -maxdepth 1 -type d  -name \"\${2##*/}*\" \
	          -printf \"\${2%\${2##*/}}%P\\n\"; }; f" \
	  "$(basename "$1")"
}

if test -n "${XAUTHORITY:-}"; then
	_linkalias () {
		gnome-open "$(printf "$1" "${@:2}")"
	}
else
	_linkalias () {
		elinks "$(printf "$1" "${@:2}")"
	}
fi
linkalias () { alias "$1=_linkalias $2"; }

# Source the other common definitions
for f in /etc/profile ~/.profile \
        $(find ~ -maxdepth 1 -name '.bashrc-*' \! -name '.bashrc-priv-*'); do
	test -f "${f}" && source "${f}" || :
done

# User specific aliases and functions

# set -o vi  # not as usable :-/
shopt -s histappend
HISTSIZE=60000
HISTCONTROL=ignoreboth

# SMART EXIT CODE INFO (by jpokorny)
#
# demo@system:~[0|..]$ true
# demo@system:~[0|00]$ 
# demo@system:~[0|..]$ false
# demo@system:~[0|01]$ 
# demo@system:~[0|..]$ ^C
# demo@system:~[0|..]$ trueue
# > bash: trueue: command not found
# demo@system:~[0|7f]$ kinit
# demo@system:~(0|00)$ 
#
# see XXX at preexec (tightly connected)
# XXX subshell to avoid triggering DEBUG? (src: http://stuff.lhunath.com/.bashrc)
#PROMPT_COMMAND='(trap - DEBUG; history -a)'
PROMPT_COMMAND='(history -a; [ ${_postexec_flag} -ne 0 ]) \
  && _postexec_flag_=${_postexec_flag} || _postexec_flag_=0'
_bash_tick="${XDG_RUNTIME_DIR:-${TMPDIR:-/var/run}}/_bash_tick.$$"
PS1='\[\033[01;34m\]\u@\h\[\033[00m\]:\[\033[01;36m\]\w\[\033[00m\]\[\033[$(
  _ps_ret=$?
  [ -n "${MC_SID}" ] && _ps_mc_char="#" || _ps_mc_char="|"
  klist -s && { _ps_lpar="("; _ps_rpar=")"; } || { _ps_lpar="["; _ps_rpar="]"; }
  git rev-parse --git-dir &>/dev/null \
    && { git diff-files --quiet \
         && { git diff-index --quiet --cached HEAD \
              && _ps_head=$(git rev-parse --abbrev-ref HEAD) \
	      || _ps_head=C; } \
	 || _ps_head=S; } \
    || _ps_head="$(($(dirs -p | head -n9 | wc -l) - 1))"
  _ps_head+="${_ps_mc_char}"
  [ -n "$(find "${_bash_tick}" -mmin -5 2>/dev/null)" ] \
    || { _ps_head+="$(date "+%H:%M")${_ps_mc_char}"; touch -- "${_bash_tick}"; }
  [ "${_postexec_flag_}" -eq 0 ] \
    && printf "0m\]${_ps_lpar}${_ps_head}..${_ps_rpar}" \
    || { [ ${_ps_ret} -eq 0 ] && printf "1;34m\]" || printf "1;35m\]"
         printf "${_ps_lpar}${_ps_head}%0.2x${_ps_rpar}" "${_ps_ret}"; }
)$\[\033[00m\] '

ACK=ack
test "$(ack --version | head -n1 | sed 's|^ack\s\([0-9]\+\).*|\1|')" -ge 2 \
  || ACK+=" -a"

# http://ruslanspivak.com/2010/11/25/bash-history-incremental-search-forward/
# ^X goes in to the way of vim's omnicompletion
stty stop ^G

# almost canonical aliases (man pages, etc.)
alias r="fc -s"

# op(t)inioned commands
alias tree='tree -a'
alias mc='LESS="-RSX" mc'
alias tmux='tmux -2'
alias acka='${ACK} --follow'
alias ackp='${ACK} *.patch --match'
alias fname='find -name'
alias mk='make -j$( \
              nproc --ignore=1 2>/dev/null \
              || sed "s|.*\([0-9]\+\)$|\1|" /sys/devices/system/cpu/online; )'
alias vimdiff='vimdiff -u NONE'

# internal, debug, etc.
alias hist-del-last='history -d $(history 1 | cut -d" " -f2)'  # historical NOOP
alias int-usage='echo "usage: $FUNCNAME "'

# dir aliases (use either as "gmy" or "cd $(gmy)" or, e.g., "gmy dotfiles")
diralias ~/wrkspc
for d in $(ls -1d ~/wrkspc/*/); do diralias "${d}"; done


# internal, debug, etc.

debug-argsep() { while [ $# -ne 0 ]; do echo $1; shift; done; }

# proper functions

cdup() {
	local up="."
	for i in $(seq 1 $1); do up+="/.."; done
	cd "${up}" 2>/dev/null && pwd || :
	unset up
}

cdmk() { cd "$1" 2>/dev/null || { mkdir "$1"; cd "$1";}; }

# Jim Meyring's take on "display the programs with W and X memory"
# http://lists.fedoraproject.org/pipermail/devel/2013-April/181747.html
sec-wx-mem() {
	grep -lE '^[0-9a-f-]+ .wx' /proc/*/maps 2>/dev/null \
	  | perl -ne 'm!^(/proc/(\d+))/.*! and printf qq(%5d %s\n), $2, `cat $1/cmdline`' \
	  | tr '\0' ' '
}

ack-intersection() {
	[ $# -ne 2 ] && int-usage "1st-regexp" "2nd-regexp" && return
	comm <(${ACK} -l --follow "$1" | sort) \
	     <(${ACK} -l --follow "$2" | sort) -12
}

hist-grep() {
	hist-del-last  # omit hist-grep invocation
	grep $* -- ~/.bash_history
}

img-diff() {
	[ $# -ne 2 ] && int-usage "1st-img" "2nd-img" && return
	#xloadimage <(gm compare "$1" "$2" -highlight-color red -highlight-style threshold -file -)
	#xloadimage <(compare "$1" "$2" -highlight-color violet -lowlight-color darkgray -compose threshold -)
	#xloadimage <(compare "$1" "$2" -highlight-color violet -lowlight-color darkgray \
	#             -compose threshold jpg:- | convert jpg:- -fuzz 2% -fill red -opaque '#915e99' png:-)
	xloadimage <(compare "$1" "$2" -highlight-color violet -lowlight-color darkgray -compose threshold -)
}

img-qr() {
	local title="Piped: "
	[ $# -ge 1 ] \
	  && { input="$1"; title="$1"; } \
	  || { input=$(</dev/stdin); title+="$(echo "${input}" | head -n1)"; }
	xloadimage -fit -shrink -title "${title}" <(qrencode -m0 -s40 -o- "${input}" )
}

pcalc() { python -c "print 0.0 + $*"; }

# prexec stuff

_preexec_flag=0
_postexec_flag=0
# idea is simple: auto-paginate output of selected commads that cannot do it
#                 on their own
# XXX: hacky, not exactly sure why this (and so far only this) works :)
# BUG: once something paginated, sole Enter will repeat last command
preexec() {
	_postexec_flag=0
	local cmd=${1%% *}
	#test ${_preexec_flag} -eq 0 && test ${BASH_SUBSHELL} -eq 0 \
	#  || { _preexec_flag=0; return 0; }
	test ${BASH_SUBSHELL} -eq 0 && [[ ! "${1}" =~ .*\|.* ]] \
	  || { _preexec_flag=0; return 0; }
	_postexec_flag=1
	case "$1" in
colordiff\ *|\
diff\ *|\
find\ *|\
git\ ls-files|\
rpm\ *|\
sdcv\ \ *|\
yum\ check-update*|\
yum\ list*|\
yum\ search*)
		_preexec_flag=1
		eval "${1} <&- 2>&1 | ${PAGER}"
		trap "_preexec_flag=0; trap - RETURN;" RETURN
		return 2
		;;
	esac
}

preexec_install