61 lines
1.6 KiB
Go
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]}
|
|
}
|