forked from bcyran/fancy-motd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
framework.sh
executable file
·190 lines (173 loc) · 5.42 KB
/
framework.sh
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
# shellcheck shell=bash
# Source the config
# shellcheck source=config.sh.example
source "${CONFIG_PATH}"
# Provide default values for obligatory settings
# Colors
CA="${CA:-\e[34m}" # Accent
CO="${CO:-\e[32m}" # Ok
CW="${CW:-\e[33m}" # Warning
CE="${CE:-\e[31m}" # Error
CN="${CN:-\e[0m}" # None
# Max width used for components in second column
WIDTH="${WIDTH:-50}"
# Prints given blocks of text side by side
# $1 - left column
# $2 - right column
print_columns() {
[[ -z $2 ]] && return
paste <(echo -e "${CA}$1${1:+:}${CN}") <(echo -e "$2")
}
# Prints given text n times
# $1 - text to print
# $2 - how many times to print
print_n() {
local out=""
for ((i = 0; i < $2; i++)); do
out+="$1"
done
echo "${out}"
}
# Prints bar divided in two parts by given percentage
# $1 - bar width
# $2 - percentage
print_bar() {
local bar_width=$(($1 - 2))
local used_width=$(($2 * bar_width / 100))
local free_width=$((bar_width - used_width))
local out=""
out+="["
out+="${CE}"
out+=$(print_n "—" ${used_width})
out+="${CO}"
out+=$(print_n "—" ${free_width})
out+="${CN}"
out+="]"
echo "${out}"
}
# Prints text with color according to given value and two thresholds
# $1 - text to print
# $2 - current value
# $3 - warning threshold
# $4 - error threshold
print_color() {
local out=""
if (($(bc -l <<< "$2 < $3"))); then
out+="${CO}"
elif (($(bc -l <<< "$2 >= $3 && $2 < $4"))); then
out+="${CW}"
else
out+="${CE}"
fi
out+="$1${CN}"
echo "${out}"
}
# Prints text as either acitve or inactive
# $1 - text to print
# $2 - literal "active" or "inactive"
print_status() {
local out=""
if [[ $2 == "active" ]]; then
out+="${CO}▲${CN}"
else
out+="${CE}▼${CN}"
fi
out+=" $1${CN}"
echo "${out}"
}
# Prints comma-separated arguments wrapped to the given width
# $1 - width to wrap to
# $2, $3, ... - values to print
print_wrap() {
local width=$1
shift
local out=""
local line_length=0
for element in "$@"; do
element="${element},"
local visible_elelement future_length
visible_elelement=$(strip_ansi "${element}")
future_length=$((line_length + ${#visible_elelement}))
if [[ ${line_length} -ne 0 && ${future_length} -gt ${width} ]]; then
out+="\n"
line_length=0
fi
out+="${element} "
line_length=$((line_length + ${#visible_elelement}))
done
[[ -n "${out}" ]] && echo "${out::-2}"
}
# Prints some text justified to left and some justified to right
# $1 - total width
# $2 - left text
# $3 - right text
print_split() {
local visible_first visible_second invisible_first_width invisible_second_width total_width \
first_half_width second_half_width format_string
visible_first=$(strip_ansi "$2")
visible_second=$(strip_ansi "$3")
invisible_first_width=$((${#2} - ${#visible_first}))
invisible_second_width=$((${#3} - ${#visible_second}))
total_width=$(($1 + invisible_first_width + invisible_second_width))
if ((${#visible_first} + ${#visible_second} < $1)); then
first_half_width=${#2}
else
first_half_width=$(($1 / 2))
fi
second_half_width=$((total_width - first_half_width))
format_string="%-${first_half_width}s%${second_half_width}s"
# shellcheck disable=SC2059
printf "${format_string}" "${2:0:${first_half_width}}" "${3:0:${second_half_width}}"
}
# Prints one line of text, truncates it at specified width and add ellipsis.
# Truncation can occur either at the start or at the end of the string.
# $1 - line to print
# $2 - width limit
# $3 - "start" or "end", default "end"
print_truncate() {
local out
local new_length=$(($2 - 1))
# Just echo the string if it's shorter than the limit
if [[ ${#1} -le "$2" ]]; then
out="$1"
elif [[ -z "$3" || "$3" == "end" ]]; then
out="${1::${new_length}}…"
else
out="…${1: -${new_length}}"
fi
echo "${out}"
}
# Strips ANSI color codes from given string
# $1 - text to strip
strip_ansi() {
echo -e "$1" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
}
# Following is basically simple `column` reimplementation because it doesn't work consistently.
# I fucked way too long with this.
# $1 - text to columnize
# $2 - column separator
# $3 - row separator
columnize() {
local left_lines left_widths right_lines max_left_width left right visible_left \
padding_width padding
left_lines=() # Lines in left column
left_widths=() # Numbers of visible chars in left lines
right_lines=() # Lines in right column
max_left_width=0 # Max width of left column line
# Iterate over lines and populate above variables
while IFS="$3" read -r line; do
left="$(echo -e "${line}" | cut -d "$2" -f 1)"
right="$(echo -e "${line}" | cut -d "$2" -f 2)"
left_lines+=("${left}")
right_lines+=("${right}")
visible_left=$(strip_ansi "${left}")
left_widths+=(${#visible_left})
[[ ${#visible_left} -gt ${max_left_width} ]] && max_left_width=${#visible_left}
done <<< "$1"
# Iterate over lines and print them while padding left column with spaces
for ((i = 0; i < ${#left_lines[@]} - 1; i++)); do
padding_width=$((max_left_width - left_widths[i]))
padding=$(print_n " " ${padding_width})
echo -e "${left_lines[${i}]}${padding} ${right_lines[${i}]}"
done
}