feat: search field in the applications list

This commit is contained in:
Felitendo committed 2026-09-24 10:23:59 +02:00
1 parent e5d2481d6d
commit e9311431f8
4 files changed
+81 -16

No files matched your search

+1 -1
View File
@@ -95,7 +95,7 @@ Press **1**. Autoscroll _✨just works✨_, like on Windows.
<details> <details>
<summary>Applications</summary> <summary>Applications</summary>
**3** lists every app it found. Space turns one on or off. **3** lists every app it found. Type to search, then Space turns one on or off.
<p align="center"> <p align="center">
<img src="res/screenshots/applications.png" alt="The applications list in Konsole, each with how it gets autoscroll" width="620"> <img src="res/screenshots/applications.png" alt="The applications list in Konsole, each with how it gets autoscroll" width="620">
+9
View File
@@ -149,6 +149,15 @@ msgstr "Autoscroll ist aus. Das hier wäre abgedeckt."
msgid "Up/Down: select, Space: turn on or off, q: back" msgid "Up/Down: select, Space: turn on or off, q: back"
msgstr "Hoch/Runter: wählen, Leertaste: ein- oder ausschalten, q: zurück" msgstr "Hoch/Runter: wählen, Leertaste: ein- oder ausschalten, q: zurück"
msgid "Search:"
msgstr "Suchen:"
msgid "Type to search, Down: go to the list, Esc: back"
msgstr "Tippen zum Suchen, Runter: zur Liste, Esc: zurück"
msgid "No matches."
msgstr "Keine Treffer."
#. Results #. Results
msgid "Autoscroll is on for %d applications." msgid "Autoscroll is on for %d applications."
msgstr "Autoscroll ist für %d Anwendungen an." msgstr "Autoscroll ist für %d Anwendungen an."
+9
View File
@@ -147,6 +147,15 @@ msgstr ""
msgid "Up/Down: select, Space: turn on or off, q: back" msgid "Up/Down: select, Space: turn on or off, q: back"
msgstr "" msgstr ""
msgid "Search:"
msgstr ""
msgid "Type to search, Down: go to the list, Esc: back"
msgstr ""
msgid "No matches."
msgstr ""
#. Results #. Results
msgid "Autoscroll is on for %d applications." msgid "Autoscroll is on for %d applications."
msgstr "" msgstr ""
+62 -15
View File
@@ -378,10 +378,13 @@ mca_ui_edit_text() {
# turned on, and where a single application gets left out without having to # turned on, and where a single application gets left out without having to
# switch off its whole category. # switch off its whole category.
# #
# The screen opens on a search field above the list, so typing filters it
# right away. The field is row -1: Down leaves it, Up from the top returns.
#
# Returns 0 when something was changed. # Returns 0 when something was changed.
mca_ui_apps() { mca_ui_apps() {
local count key frame row pad i cursor=0 dirty=1 touched=0 locale local count key frame row pad i idx cursor=-1 dirty=1 touched=0 locale query=''
local -a labels=() states=() local -a labels=() lower=() states=() matches=()
locale="$(mca_ui_locale)" locale="$(mca_ui_locale)"
@@ -389,6 +392,11 @@ mca_ui_apps() {
mca_msg_into "$locale" "Applications"; title="$MCA_MSG_RESULT" mca_msg_into "$locale" "Applications"; title="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Up/Down: select, Space: turn on or off, q: back" mca_msg_into "$locale" "Up/Down: select, Space: turn on or off, q: back"
hint="$MCA_MSG_RESULT" hint="$MCA_MSG_RESULT"
local l_search hint_search nomatch
mca_msg_into "$locale" "Search:"; l_search="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Type to search, Down: go to the list, Esc: back"
hint_search="$MCA_MSG_RESULT"
mca_msg_into "$locale" "No matches."; nomatch="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Anything not identified is left alone until it is turned on here." mca_msg_into "$locale" "Anything not identified is left alone until it is turned on here."
legend="$MCA_MSG_RESULT" legend="$MCA_MSG_RESULT"
mca_msg_into "$locale" "Autoscroll is off. This is what would be covered." mca_msg_into "$locale" "Autoscroll is off. This is what would be covered."
@@ -430,31 +438,44 @@ mca_ui_apps() {
if (( dirty )); then if (( dirty )); then
mca_config_load mca_config_load
mca_count_routes mca_count_routes
labels=(); states=() labels=(); lower=(); states=()
for i in "${!MCA_IDS[@]}"; do for i in "${!MCA_IDS[@]}"; do
labels+=("${MCA_NAMES[i]}") labels+=("${MCA_NAMES[i]}")
lower+=("${MCA_NAMES[i],,}")
states+=("${MCA_ROUTES[i]}") states+=("${MCA_ROUTES[i]}")
done done
dirty=0 dirty=0
fi fi
matches=()
for i in "${!labels[@]}"; do
[[ ${lower[i]} == *"${query,,}"* ]] && matches+=("$i")
done
count=${#matches[@]}
(( cursor >= count )) && cursor=$(( count - 1 ))
frame="$clearseq"$'\n'"${MCA_C_BOLD}${MCA_C_BLUE} ${title}${MCA_C_RESET}"$'\n\n' frame="$clearseq"$'\n'"${MCA_C_BOLD}${MCA_C_BLUE} ${title}${MCA_C_RESET}"$'\n\n'
local marker selected="${MCA_C_BLUE}▸${MCA_C_RESET} " shown local marker selected="${MCA_C_BLUE}▸${MCA_C_RESET} " shown
for i in "${!labels[@]}"; do if (( cursor < 0 )); then marker="$selected"; else marker=' '; fi
case "${states[i]}" in frame+=" ${marker}${l_search} ${query}"$'\n\n'
for i in "${!matches[@]}"; do
idx=${matches[i]}
case "${states[idx]}" in
off) shown="$s_off" ;; off) shown="$s_off" ;;
unknown) shown="$s_cannot" ;; unknown) shown="$s_cannot" ;;
steam) shown="$s_steam" ;; steam) shown="$s_steam" ;;
flags) shown="$s_flags" ;; flags) shown="$s_flags" ;;
*) shown="$s_desktop" ;; *) shown="$s_desktop" ;;
esac esac
pad=$(( 34 - ${#labels[i]} )) pad=$(( 34 - ${#labels[idx]} ))
(( pad < 0 )) && pad=0 (( pad < 0 )) && pad=0
if (( i == cursor )); then marker="$selected"; else marker=' '; fi if (( i == cursor )); then marker="$selected"; else marker=' '; fi
printf -v row ' %s%s%*s %s' "$marker" "${labels[i]}" "$pad" '' "$shown" printf -v row ' %s%s%*s %s' "$marker" "${labels[idx]}" "$pad" '' "$shown"
frame+="$row"$'\n' frame+="$row"$'\n'
done done
(( count )) || frame+=" ${MCA_C_DIM}${nomatch}${MCA_C_RESET}"$'\n'
frame+=$'\n' frame+=$'\n'
# Without this the list reads as a list of what is switched on, which # Without this the list reads as a list of what is switched on, which
@@ -463,23 +484,49 @@ mca_ui_apps() {
frame+=" ${MCA_C_YELLOW}${warn}${MCA_C_RESET}"$'\n' frame+=" ${MCA_C_YELLOW}${warn}${MCA_C_RESET}"$'\n'
fi fi
frame+=" ${MCA_C_DIM}${legend}${MCA_C_RESET}"$'\n' frame+=" ${MCA_C_DIM}${legend}${MCA_C_RESET}"$'\n'
frame+=" ${MCA_C_DIM}${hint}${MCA_C_RESET}"$'\n' if (( cursor < 0 )); then
frame+=" ${MCA_C_DIM}${hint_search}${MCA_C_RESET}"$'\n'
# Puts the terminal cursor at the end of the query (row 4).
printf -v row '\033[4;%dH' $(( 6 + ${#l_search} + ${#query} ))
frame+="$row"
else
frame+=" ${MCA_C_DIM}${hint}${MCA_C_RESET}"$'\n'
fi
printf '%s' "$frame" printf '%s' "$frame"
key="$(mca_read_key)" || return "$(( ! touched ))" key="$(mca_read_key)" || return "$(( ! touched ))"
# In the search field every key that can be typed goes into the query,
# q and the vi keys too.
if (( cursor < 0 )); then
case "$key" in
down|enter) (( count )) && cursor=0 ;;
up) cursor=$(( count - 1 )) ;;
backspace) query="${query%?}" ;;
space) query+=' ' ;;
escape)
[[ -z $query ]] && return "$(( ! touched ))"
query=''
;;
left|right) ;;
*) [[ $key == [[:print:]] ]] && query+="$key" ;;
esac
continue
fi
idx=${matches[cursor]}
case "$key" in case "$key" in
up|k) cursor=$(( (cursor - 1 + count) % count )) ;; up|k) cursor=$(( cursor - 1 )) ;;
down|j) cursor=$(( (cursor + 1) % count )) ;; down|j) cursor=$(( cursor + 1 < count ? cursor + 1 : -1 )) ;;
space|enter|right|left|l|h) space|enter|right|left|l|h)
case "${states[cursor]}" in case "${states[idx]}" in
off|unknown) off|unknown)
mca_config_list_del Skip "${MCA_IDS[cursor]}" mca_config_list_del Skip "${MCA_IDS[idx]}"
mca_config_list_add Include "${MCA_IDS[cursor]}" mca_config_list_add Include "${MCA_IDS[idx]}"
;; ;;
*) *)
mca_config_list_del Include "${MCA_IDS[cursor]}" mca_config_list_del Include "${MCA_IDS[idx]}"
mca_config_list_add Skip "${MCA_IDS[cursor]}" mca_config_list_add Skip "${MCA_IDS[idx]}"
;; ;;
esac esac
touched=1 touched=1