Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fa830284e |
No files matched your search
@@ -8,7 +8,7 @@
|
||||
# Overridable so a packager can pass the version it is actually building
|
||||
# (`make VERSION=$pkgver`). The literal below is the fallback for builds
|
||||
# straight from a checkout, and is what a release tag has to carry.
|
||||
VERSION ?= 1.1.0
|
||||
VERSION ?= 1.1.1
|
||||
|
||||
PREFIX ?= /usr
|
||||
DESTDIR ?=
|
||||
|
||||
@@ -75,6 +75,27 @@ cau_msg() {
|
||||
cau_msg_in "$(cau_ui_locale)" "$@"
|
||||
}
|
||||
|
||||
# cau_msg_into <locale> <msgid>
|
||||
# Plain lookup with the result in CAU_MSG_RESULT and no printf formatting.
|
||||
# For callers that redraw many labels per keypress, where wrapping cau_msg in a
|
||||
# command substitution would cost a fork per label.
|
||||
CAU_MSG_RESULT=''
|
||||
|
||||
cau_msg_into() {
|
||||
local locale="$1" msgid="$2" cachekey
|
||||
cachekey="${locale}"$'\x1f'"${msgid}"
|
||||
|
||||
if [[ -n ${CAU_MSG_CACHE[$cachekey]+set} ]]; then
|
||||
CAU_MSG_RESULT="${CAU_MSG_CACHE[$cachekey]}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
CAU_MSG_RESULT="$(LC_ALL="$locale" LANGUAGE="${locale%%.*}" gettext -- "$msgid" 2>/dev/null)"
|
||||
[[ -n $CAU_MSG_RESULT ]] || CAU_MSG_RESULT="$msgid"
|
||||
CAU_MSG_CACHE[$cachekey]="$CAU_MSG_RESULT"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Translations are memoized. Every gettext lookup is a fork, and the settings
|
||||
# screen redraws forty-odd labels per keypress; without this the redraw takes
|
||||
# long enough that a keystroke arriving during it is lost when the terminal
|
||||
|
||||
+17
-8
@@ -20,11 +20,17 @@ _cau_config_slurp() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# cau_config_get <Key> [default]
|
||||
cau_config_get() {
|
||||
# _cau_config_lookup <Key> [default]
|
||||
# Result in CAU_CONFIG_VALUE. Assigning rather than printing matters on the
|
||||
# settings screen, which reads every key on every frame: a command substitution
|
||||
# there is a fork, and forks were the entire cost of a redraw.
|
||||
CAU_CONFIG_VALUE=''
|
||||
|
||||
_cau_config_lookup() {
|
||||
local key="$1" default="${2:-}" val='' line
|
||||
|
||||
[[ -r $CAU_CONFIG ]] || { printf '%s\n' "$default"; return; }
|
||||
CAU_CONFIG_VALUE="$default"
|
||||
[[ -r $CAU_CONFIG ]] || return 0
|
||||
_cau_config_slurp
|
||||
|
||||
# last assignment wins, matching the previous sed|tail behaviour
|
||||
@@ -41,11 +47,14 @@ cau_config_get() {
|
||||
val="${val%\"}"
|
||||
val="${val#\"}"
|
||||
|
||||
if [[ -n $val ]]; then
|
||||
printf '%s\n' "$val"
|
||||
else
|
||||
printf '%s\n' "$default"
|
||||
fi
|
||||
[[ -n $val ]] && CAU_CONFIG_VALUE="$val"
|
||||
return 0
|
||||
}
|
||||
|
||||
# cau_config_get <Key> [default]
|
||||
cau_config_get() {
|
||||
_cau_config_lookup "$@"
|
||||
printf '%s\n' "$CAU_CONFIG_VALUE"
|
||||
}
|
||||
|
||||
# cau_config_bool <Key> <default: yes|no>
|
||||
|
||||
+72
-34
@@ -156,25 +156,33 @@ _cau_is_true() {
|
||||
}
|
||||
|
||||
# _cau_setting_display <type> <value>
|
||||
# Result in CAU_SETTING_SHOWN. The three constant strings are resolved once by
|
||||
# the caller into CAU_LBL_*; looking them up here would put a translation call
|
||||
# on the per-line path.
|
||||
CAU_SETTING_SHOWN=''
|
||||
CAU_LBL_ON=''
|
||||
CAU_LBL_OFF=''
|
||||
CAU_LBL_NONE=''
|
||||
|
||||
_cau_setting_display() {
|
||||
local type="$1" value="$2"
|
||||
|
||||
case "$type" in
|
||||
bool)
|
||||
if _cau_is_true "$value"; then
|
||||
printf '%s%s%s' "$CAU_C_GREEN" "$(cau_msg "ON")" "$CAU_C_RESET"
|
||||
CAU_SETTING_SHOWN="${CAU_C_GREEN}${CAU_LBL_ON}${CAU_C_RESET}"
|
||||
else
|
||||
printf '%s%s%s' "$CAU_C_DIM" "$(cau_msg "OFF")" "$CAU_C_RESET"
|
||||
CAU_SETTING_SHOWN="${CAU_C_DIM}${CAU_LBL_OFF}${CAU_C_RESET}"
|
||||
fi
|
||||
;;
|
||||
text)
|
||||
if [[ -n $value ]]; then
|
||||
printf '%s' "$value"
|
||||
CAU_SETTING_SHOWN="$value"
|
||||
else
|
||||
printf '%s%s%s' "$CAU_C_DIM" "$(cau_msg "(none)")" "$CAU_C_RESET"
|
||||
CAU_SETTING_SHOWN="${CAU_C_DIM}${CAU_LBL_NONE}${CAU_C_RESET}"
|
||||
fi
|
||||
;;
|
||||
*) printf '%s' "$value" ;;
|
||||
*) CAU_SETTING_SHOWN="$value" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -205,58 +213,88 @@ _cau_setting_cycle() {
|
||||
# cau_ui_settings
|
||||
# A cursor list rather than a numbered menu: there are eighteen settings, and
|
||||
# numbering them would run out of digits and force paging.
|
||||
#
|
||||
# The frame is assembled in memory and written once. Everything constant - the
|
||||
# specs, the translated labels, the clear sequence - is resolved before the
|
||||
# loop, and the values are re-read only after something actually changes.
|
||||
# Drawing the naive way cost a command substitution per label per frame, which
|
||||
# measured 435 ms per keypress: arrow keys felt like the console was reloading,
|
||||
# because in effect it was.
|
||||
cau_ui_settings() {
|
||||
local cursor=0 key spec name type default label value line pad
|
||||
local count=${#CAU_SETTINGS[@]}
|
||||
local -a names=() types=() defaults=() labels=()
|
||||
local -a values=()
|
||||
local spec name type default label locale i key frame row pad dirty=1 cursor=0
|
||||
|
||||
while true; do
|
||||
clear 2>/dev/null || true
|
||||
cau_head " $(cau_msg "Settings")"
|
||||
locale="$(cau_ui_locale)"
|
||||
cau_msg_into "$locale" "ON"; CAU_LBL_ON="$CAU_MSG_RESULT"
|
||||
cau_msg_into "$locale" "OFF"; CAU_LBL_OFF="$CAU_MSG_RESULT"
|
||||
cau_msg_into "$locale" "(none)"; CAU_LBL_NONE="$CAU_MSG_RESULT"
|
||||
|
||||
local i=0
|
||||
for spec in "${CAU_SETTINGS[@]}"; do
|
||||
IFS='|' read -r name type default label <<< "$spec"
|
||||
value="$(cau_config_get "$name" "$default")"
|
||||
|
||||
if (( i == cursor )); then
|
||||
line="${CAU_C_BLUE}▸${CAU_C_RESET} "
|
||||
else
|
||||
line=" "
|
||||
fi
|
||||
|
||||
local text
|
||||
text="$(cau_msg "$label")"
|
||||
pad=$(( 42 - ${#text} ))
|
||||
(( pad < 0 )) && pad=0
|
||||
|
||||
printf ' %s%s%*s %s\n' "$line" "$text" "$pad" '' \
|
||||
"$(_cau_setting_display "$type" "$value")"
|
||||
i=$(( i + 1 ))
|
||||
names+=("$name"); types+=("$type"); defaults+=("$default")
|
||||
cau_msg_into "$locale" "$label"
|
||||
labels+=("$CAU_MSG_RESULT")
|
||||
done
|
||||
|
||||
printf '\n %s%s%s\n' "$CAU_C_DIM" \
|
||||
"$(cau_msg "Up/Down select - Space or Right changes - q goes back")" "$CAU_C_RESET"
|
||||
local title hint
|
||||
cau_msg_into "$locale" "Settings"; title="$CAU_MSG_RESULT"
|
||||
cau_msg_into "$locale" "Up/Down select - Space or Right changes - q goes back"
|
||||
hint="$CAU_MSG_RESULT"
|
||||
|
||||
# the terminfo clear string, fetched once instead of forking per frame
|
||||
local clearseq
|
||||
clearseq="$(clear 2>/dev/null)" || clearseq=$'\033[H\033[2J'
|
||||
|
||||
while true; do
|
||||
if (( dirty )); then
|
||||
for i in "${!names[@]}"; do
|
||||
_cau_config_lookup "${names[i]}" "${defaults[i]}"
|
||||
values[i]="$CAU_CONFIG_VALUE"
|
||||
done
|
||||
dirty=0
|
||||
fi
|
||||
|
||||
frame="$clearseq"$'\n'"${CAU_C_BOLD}${CAU_C_BLUE} ${title}${CAU_C_RESET}"$'\n\n'
|
||||
|
||||
local marker selected="${CAU_C_BLUE}▸${CAU_C_RESET} "
|
||||
for i in "${!names[@]}"; do
|
||||
_cau_setting_display "${types[i]}" "${values[i]}"
|
||||
pad=$(( 42 - ${#labels[i]} ))
|
||||
(( pad < 0 )) && pad=0
|
||||
if (( i == cursor )); then marker="$selected"; else marker=' '; fi
|
||||
printf -v row ' %s%s%*s %s' \
|
||||
"$marker" "${labels[i]}" "$pad" '' "$CAU_SETTING_SHOWN"
|
||||
frame+="$row"$'\n'
|
||||
done
|
||||
|
||||
frame+=$'\n'" ${CAU_C_DIM}${hint}${CAU_C_RESET}"$'\n'
|
||||
printf '%s' "$frame"
|
||||
|
||||
key="$(cau_read_key)" || return 0
|
||||
|
||||
IFS='|' read -r name type default label <<< "${CAU_SETTINGS[cursor]}"
|
||||
value="$(cau_config_get "$name" "$default")"
|
||||
type="${types[cursor]}"
|
||||
name="${names[cursor]}"
|
||||
|
||||
case "$key" in
|
||||
up|k) cursor=$(( (cursor - 1 + count) % count )) ;;
|
||||
down|j) cursor=$(( (cursor + 1) % count )) ;;
|
||||
space|enter|right|l)
|
||||
if [[ $type == text ]]; then
|
||||
cau_ui_edit_text "$name" "$value"
|
||||
cau_ui_edit_text "$name" "${values[cursor]}"
|
||||
else
|
||||
cau_config_set "$name" "$(_cau_setting_cycle "$type" "$value" 1)" \
|
||||
cau_config_set "$name" "$(_cau_setting_cycle "$type" "${values[cursor]}" 1)" \
|
||||
|| { cau_bad "$(cau_msg "Could not write the configuration file.")"; cau_pause; }
|
||||
fi
|
||||
dirty=1
|
||||
;;
|
||||
left|h)
|
||||
[[ $type == text ]] || cau_config_set "$name" \
|
||||
"$(_cau_setting_cycle "$type" "$value" -1)" \
|
||||
if [[ $type != text ]]; then
|
||||
cau_config_set "$name" "$(_cau_setting_cycle "$type" "${values[cursor]}" -1)" \
|
||||
|| { cau_bad "$(cau_msg "Could not write the configuration file.")"; cau_pause; }
|
||||
dirty=1
|
||||
fi
|
||||
;;
|
||||
q|Q|escape) return 0 ;;
|
||||
*) ;;
|
||||
|
||||
Reference in new issue
Block a user