aboutsummaryrefslogtreecommitdiff
blob: 98c501178eef5466470d1a59f14b3424b5f12adb (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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# -*-eselect-*-  vim: ft=eselect
# Copyright (c) 2005-2012 Gentoo Foundation
#
# This file is part of the 'eselect' tools framework.
#
# eselect is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 2 of the License, or (at your option) any later
# version.
#
# eselect is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# eselect.  If not, see <http://www.gnu.org/licenses/>.

# Colours
colours() {
	COLOUR_NORMAL=$(tput sgr0)
	COLOUR_BOLD=$(tput bold)
	COLOUR_HI=$(tput setaf 4)${COLOUR_BOLD} # blue
	COLOUR_WARN=$(tput setaf 1)${COLOUR_BOLD} # red
	COLOUR_ERROR=${COLOUR_WARN}
	COLOUR_LIST_HEADER=$(tput setaf 2)${COLOUR_BOLD} # green
	COLOUR_LIST_LEFT=${COLOUR_BOLD}
	COLOUR_LIST_RIGHT=${COLOUR_NORMAL}
}

# disable all colours
nocolours() {
	COLOUR_NORMAL=""
	COLOUR_BOLD=""
	COLOUR_HI=""
	COLOUR_WARN=""
	COLOUR_ERROR=""
	COLOUR_LIST_HEADER=""
	COLOUR_LIST_LEFT=""
	COLOUR_LIST_RIGHT=""
}

# set output mode to $1
set_output_mode() {
	ESELECT_OUTPUT_MODE=${1}
}

# is_output_mode PUBLIC
# test if $1 is the current output mode
is_output_mode() {
	[[ ${ESELECT_OUTPUT_MODE} = ${1} ]]
}

# Determine width of terminal and set COLUMNS variable
init_columns() {
	[[ -n ${COLUMNS} ]] || COLUMNS=$(tput cols) || COLUMNS=80
}

# write_error_msg PUBLIC
# write an error
write_error_msg() {
	echo -e "${COLOUR_ERROR}!!! Error: ${COLOUR_NORMAL}${*}" 1>&2
}

# write_warning_msg PUBLIC
# write a warning
write_warning_msg() {
	echo -e "${COLOUR_WARN}!!! Warning: ${COLOUR_NORMAL}${*}" 1>&2
}

# write_list_start PUBLIC
# Write a list heading. Args may include text highlighting. If -p is passed,
# use 'plain' highlighting.
write_list_start() {
	is_output_mode brief && return
	local colour=${COLOUR_LIST_HEADER} normal=${COLOUR_NORMAL}
	if [[ ${1} == "-p" ]] ; then
		colour=; normal=
		shift
	fi
	echo -n -e "${colour}"
	echo -n -e "$(apply_text_highlights "${colour}" "$*")"
	echo -n -e "${normal}"
	echo
}

# write_kv_list_entry PUBLIC
# Write a key/value list entry with $1 on the left and $2 on the right.
# Args may include text highlighting. If -p is passed, use 'plain'
# highlighting rather than bold.
write_kv_list_entry() {
	local n text key val lindent rindent ifs_save=${IFS}
	local left=${COLOUR_LIST_LEFT} right=${COLOUR_LIST_RIGHT}
	local normal=${COLOUR_NORMAL}

	IFS=$' \t\n'

	if [[ ${1} == "-p" ]] ; then
		left=; right=; normal=
		shift
	fi

	lindent=${1%%[^[:space:]]*}
	rindent=${2%%[^[:space:]]*}
	key=${1##*([[:space:]])}
	val=${2##*([[:space:]])}

	echo -n -e "  ${lindent}${left}"
	echo -n -e "$(apply_text_highlights "${left}" "${key}")"
	echo -n -e "${normal}"

	text=${key//\%%%??%%%/}
	n=$(( 26 + ${#rindent} - ${#lindent} - ${#text} ))

	# if ${n} is less than or equal to zero then we have a long ${key}
	# that will mess up the formatting of ${val}, so end the line, indent
	# and let ${val} go on the next line.
	if [[ ${n} -le 0 ]] ; then
		echo
		n=$(( 28 + ${#rindent} ))
	fi

	space ${n}
	echo -n -e "${right}"
	n=$(( 28 + ${#rindent} ))

	local cols=${COLUMNS:-80}
	local cwords=$(apply_text_highlights "${right}" "${val}")

	text=${val//\%%%??%%%/}
	# only loop if it doesn't fit on the same line
	if [[ $(( ${n} + ${#text} )) -ge ${cols} ]] ; then
		local i=0 spc=""
		rindent=$(space ${n})
		cwords=( ${cwords} )
		for text in ${val} ; do
			text=${text//\%%%??%%%/}
			# put the word on the same line if it fits
			if [[ $(( ${n} + ${#spc} + ${#text} )) -lt ${cols} ]] ; then
				echo -n -e "${spc}${cwords[i]}"
				n=$(( ${n} + ${#spc} + ${#text} ))
			# otherwise, start a new line and indent
			else
				echo -n -e "\n${rindent}${cwords[i]}"
				n=$(( ${#rindent} + ${#text} ))
			fi
			i=$(( ${i} + 1 ))
			spc=" "
		done
	else
		echo -n -e "${cwords}"
	fi
	echo -e "${normal}"
	IFS=${ifs_save}
}

# write_numbered_list_entry PUBLIC
# Write out a numbered list entry with index $1 and text $2. Args may
# include text highlighting. If -p is passed, use 'plain' highlighting.
write_numbered_list_entry() {
	local left=${COLOUR_LIST_LEFT} right=${COLOUR_LIST_RIGHT}
	local normal=${COLOUR_NORMAL}

	if [[ ${1} == "-p" ]] ; then
		left=; right=; normal=
		shift
	fi

	if ! is_output_mode brief; then
		echo -n -e "  ${left}"
		echo -n -e "[$(apply_text_highlights "${left}" "$1")]"
		echo -n -e "${normal}"
		space $(( 4 - ${#1} ))
	fi

	echo -n -e "${right}"
	echo -n -e "$(apply_text_highlights "${right}" "$2")"
	echo -e "${normal}"
}

# write_numbered_list PUBLIC
# Write out a numbered list. Args may include text highlighting.
# If called with the -m option and an empty list, output a negative report.
write_numbered_list() {
	local n=1 m p
	while [[ $1 == -* ]]; do
		case $1 in
			"-m") shift; m=$1 ;;
			"-p") p="-p" ;;
			"--") shift; break ;;
		esac
		shift
	done

	if [[ $# -eq 0 && -n ${m} ]] && ! is_output_mode brief; then
		write_kv_list_entry ${p} "${m}" ""
	fi

	while [[ $# -gt 0 ]] ; do
		item=${1}
		shift
		if [[ ${item##*\\} == "" ]] ; then
			item="${item%\\} ${1}"
			shift
		fi
		write_numbered_list_entry ${p} "${n}" "${item}"
		n=$(( ${n} + 1 ))
	done
}

# apply_text_highlights INTERNAL
# Apply text highlights. First arg is the 'restore' colour, second arg
# is the text.
apply_text_highlights() {
	local restore=${1:-${COLOUR_NORMAL}} text=${2}
	text="${text//?%%HI%%%/${COLOUR_HI}}"
	text="${text//?%%WA%%%/${COLOUR_WARN}}"
	text="${text//?%%RE%%%/${restore}}"
	echo -n "${text}"
}

# highlight PUBLIC
# Highlight all arguments. Text highlighting function.
highlight() {
	echo -n "%%%HI%%%${*}%%%RE%%%"
}

# highlight_warning PUBLIC
# Highlight all arguments as a warning (red). Text highlighting function.
highlight_warning() {
	echo -n "%%%WA%%%${*}%%%RE%%%"
}

# highlight_marker PUBLIC
# Mark list entry $1 as active/selected by placing a highlighted star
# (or $2 if set) behind it.
highlight_marker() {
	local text=${1} mark=${2-*}
	echo -n "${text}"
	if [[ -n ${mark} ]] && ! is_output_mode brief; then
		echo -n " "
		highlight "${mark}"
	fi
}

# space PUBLIC
# Write $1 numbers of spaces
space() {
	local n ret=""
	for (( n = 1 ; n <= ${1} ; ++n )) ; do
		ret="${ret} "
	done
	echo -n "${ret}"
}