Files

61 lines
1.6 KiB
Go

// Fenrir console screen reader.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package interaction
import (
"strings"
"unicode"
"git.stormux.org/storm/fenrir/internal/i18n"
)
// Lists use Text as a prefix search without filtering or activating items.
func (s *Session) list(control *Control, key Key) Result {
if key.Ctrl && key.Name != "backspace" {
return Result{}
}
if key.Name == "backspace" || (key.Name == "" || key.Name == "space") && key.Text != "" && !key.Ctrl {
prefix := []rune(control.Text)
if key.Name == "backspace" {
if key.Ctrl {
prefix = nil
} else if len(prefix) > 0 {
prefix = prefix[:len(prefix)-1]
}
} else {
for _, char := range key.Text {
if !unicode.IsPrint(char) {
return Result{}
}
}
if len(prefix)+len([]rune(key.Text)) > 4096 {
return Result{}
}
prefix = append(prefix, []rune(key.Text)...)
}
query := strings.ToLower(string(prefix))
for index, item := range control.Items {
if strings.HasPrefix(strings.ToLower(item), query) {
control.Text, control.Selected = string(prefix), index
return Result{Speech: item}
}
}
// Reject unmatched input so a typo leaves the last valid search intact.
return Result{Speech: i18n.T("No matches")}
}
switch key.Name {
case "up":
control.Selected = (control.Selected + len(control.Items) - 1) % len(control.Items)
case "down":
control.Selected = (control.Selected + 1) % len(control.Items)
case "enter":
return Result{Action: control.Action}
default:
return Result{}
}
control.Text = ""
return Result{Speech: control.Items[control.Selected]}
}