// Fenrir console screen reader. // Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later // // This program 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 3 of the License, or (at your option) // any later version. // // This program 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 // this program. If not, see . package interaction import ( "git.stormux.org/storm/fenrir/internal/i18n" "strings" "unicode" ) func (s *Session) edit(control *Control, key Key) Result { runes := []rune(control.Text) if key.Ctrl { if strings.EqualFold(key.Text, "a") { s.selectAll = true return Result{Speech: i18n.T("selected") + " " + control.Text} } return Result{} } switch key.Name { case "enter": return Result{Action: control.Action} case "left": s.cursor = max(0, s.cursor-1) s.selectAll = false case "right": s.cursor = min(len(runes), s.cursor+1) s.selectAll = false case "home": s.cursor = 0 s.selectAll = false case "end": s.cursor = len(runes) s.selectAll = false case "backspace", "delete": if s.selectAll { runes = nil s.cursor = 0 } else if key.Name == "backspace" && s.cursor > 0 { runes = append(runes[:s.cursor-1], runes[s.cursor:]...) s.cursor-- } else if key.Name == "delete" && s.cursor < len(runes) { runes = append(runes[:s.cursor], runes[s.cursor+1:]...) } s.selectAll = false default: text := []rune(key.Text) if len(text) == 0 { return Result{} } for _, char := range text { if !unicode.IsPrint(char) { return Result{} } } length := len(runes) if s.selectAll { length = 0 } if length+len(text) > 4096 { return Result{} } if s.selectAll { runes = nil s.cursor = 0 } runes = append(runes[:s.cursor], append(text, runes[s.cursor:]...)...) s.cursor += len(text) s.selectAll = false } control.Text = string(runes) if (key.Name == "left" || key.Name == "right" || key.Name == "home" || key.Name == "end") && s.cursor < len(runes) { return Result{Speech: string(runes[s.cursor])} } return Result{Speech: s.Describe()} }