package input import ( "errors" "strings" ) const ( InterruptAllKeys = "all" InterruptCommonKeys = "common" InterruptCustomKeys = "custom" MaxInterruptionKeys = 64 ) // InterruptionSettings selects individual keys, independently of key echo and // command bindings. Reader commands retain their own explicit cancellation. type InterruptionSettings struct { Mode string `toml:"mode"` Keys []string `toml:"keys"` } func (settings InterruptionSettings) Validate() error { switch settings.Mode { case InterruptAllKeys, InterruptCommonKeys, InterruptCustomKeys: default: return errors.New("choose a valid speech interruption mode") } if len(settings.Keys) > MaxInterruptionKeys { return errors.New("too many speech interruption keys") } if settings.Mode == InterruptCustomKeys && len(settings.Keys) == 0 { return errors.New("record at least one speech interruption key") } seen := make(map[string]bool, len(settings.Keys)) for _, name := range settings.Keys { key := strings.ToLower(name) if name == "" || len(name) > 128 || seen[key] { return errors.New("speech interruption keys must have unique, valid key names") } for _, character := range name { if character != '_' && !(character >= 'a' && character <= 'z') && !(character >= 'A' && character <= 'Z') && !(character >= '0' && character <= '9') { return errors.New("invalid speech interruption key name") } } seen[key] = true } return nil } func (settings InterruptionSettings) ShouldInterrupt(event Event) bool { if !event.Pressed { return false } switch settings.Mode { case InterruptCommonKeys: switch event.Name { case "Control_L", "Control_R", "Return", "KP_Enter", "space", "KP_Space", "Escape": return true } return false case InterruptCustomKeys: for _, name := range settings.Keys { if strings.EqualFold(name, event.Name) || name == "Tab" && event.Name == "ISO_Left_Tab" { return true } } return false default: return true } }