# -*-eselect-*- vim: ft=eselect # Copyright (c) 2005-2025 Gentoo Authors # # 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 . colours() { if [[ $1 != n* ]]; then COLOUR_NORMAL=$(tput sgr0) COLOUR_BOLD=$(tput bold) COLOUR_HI=$(tput setaf 4)${COLOUR_BOLD} # blue COLOUR_WARN=$(tput setaf 3)${COLOUR_BOLD} # yellow COLOUR_ERROR=$(tput setaf 1)${COLOUR_BOLD} # red COLOUR_LIST_HEADER=$(tput setaf 2)${COLOUR_BOLD} # green COLOUR_LIST_LEFT=${COLOUR_BOLD} COLOUR_LIST_RIGHT=${COLOUR_NORMAL} else # disable all colours COLOUR_NORMAL="" COLOUR_BOLD="" COLOUR_HI="" COLOUR_WARN="" COLOUR_ERROR="" COLOUR_LIST_HEADER="" COLOUR_LIST_LEFT="" COLOUR_LIST_RIGHT="" fi } # 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 local text="$*" apply_text_highlights "${colour}" echo -e "${colour}${text}${normal}" } # 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 tlen key val lindent rindent local left=${COLOUR_LIST_LEFT} right=${COLOUR_LIST_RIGHT} local normal=${COLOUR_NORMAL} local cols=${COLUMNS:-80} local IFS=$' \t\n' if [[ $1 == "-p" ]]; then left=; right=; normal= shift fi lindent=${1%%[^[:space:]]*} rindent=${2%%[^[:space:]]*} key=${1##*([[:space:]])} val=${2##*([[:space:]])} tlen=${key//\%%%??%%%/} n=$(( 26 + ${#rindent} - ${#lindent} - ${#tlen} )) text=${key} apply_text_highlights "${left}" echo -n -e " ${lindent}${left}${text}${normal}" tlen=${val//\%%%??%%%/} if [[ -z ${tlen} ]]; then # empty ${val}: end the line and be done echo return fi # 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. Don't start a new line when # in brief output mode, in order to keep the output easily parsable. if [[ ${n} -le 0 ]]; then if is_output_mode brief; then n=1 else echo n=$(( 28 + ${#rindent} )) fi fi space ${n} echo -n -e "${right}" n=$(( 28 + ${#rindent} )) text=${val} apply_text_highlights "${right}" # only loop if it doesn't fit on the same line if [[ $(( ${n} + ${#tlen} )) -ge ${cols} ]] && ! is_output_mode brief; then local i spc="" nind=${n} words cwords read -r -d '' -a words <<< "${val}" read -r -d '' -a cwords <<< "${text}" for (( i = 0; i < ${#words[@]}; i++ )); do tlen=${words[i]//\%%%??%%%/} # put the word on the same line if it fits if [[ $(( ${n} + ${#spc} + ${#tlen} )) -lt ${cols} ]]; then echo -n -e "${spc}${cwords[i]}" n=$(( ${n} + ${#spc} + ${#tlen} )) # otherwise, start a new line and indent else echo space ${nind} echo -n -e "${cwords[i]}" n=$(( ${nind} + ${#tlen} )) fi spc=" " done else echo -n -e "${text}" fi echo -e "${normal}" } # 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 local text=$1 apply_text_highlights "${left}" echo -n -e " ${left}[${text}]${normal}" space $(( 4 - ${#1} )) fi local text=$2 apply_text_highlights "${right}" echo -e "${right}${text}${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. Arg is the "restore" colour; # variable "text" is modified by side effect. apply_text_highlights() { local restore=${1:-${COLOUR_NORMAL}} text="${text//?%%HI%%%/${COLOUR_HI}}" text="${text//?%%WA%%%/${COLOUR_WARN}}" text="${text//?%%RE%%%/${restore}}" } # 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() { printf "%${1}s" }