(path string, node any)
| 80 | } |
| 81 | |
| 82 | func validateKeybindingsRecurse(path string, node any) error { |
| 83 | value := reflect.ValueOf(node) |
| 84 | if value.Kind() == reflect.Struct { |
| 85 | for _, field := range reflect.VisibleFields(reflect.TypeOf(node)) { |
| 86 | var newPath string |
| 87 | if len(path) == 0 { |
| 88 | newPath = field.Name |
| 89 | } else { |
| 90 | newPath = fmt.Sprintf("%s.%s", path, field.Name) |
| 91 | } |
| 92 | if err := validateKeybindingsRecurse(newPath, |
| 93 | value.FieldByName(field.Name).Interface()); err != nil { |
| 94 | return err |
| 95 | } |
| 96 | } |
| 97 | } else if value.Kind() == reflect.Slice { |
| 98 | for i := range value.Len() { |
| 99 | if err := validateKeybindingsRecurse( |
| 100 | fmt.Sprintf("%s[%d]", path, i), value.Index(i).Interface()); err != nil { |
| 101 | return err |
| 102 | } |
| 103 | } |
| 104 | } else if value.Kind() == reflect.String { |
| 105 | key := node.(string) |
| 106 | if !isValidKeybindingKey(key) { |
| 107 | return fmt.Errorf("Unrecognized key '%s' for keybinding '%s'. For permitted values see %s", |
| 108 | key, path, constants.Links.Docs.CustomKeybindings) |
| 109 | } |
| 110 | } else { |
| 111 | log.Fatalf("Unexpected type for property '%s': %s", path, value.Kind()) |
| 112 | } |
| 113 | return nil |
| 114 | } |
| 115 | |
| 116 | func validateKeybindings(keybindingConfig KeybindingConfig) error { |
| 117 | if err := validateKeybindingsRecurse("", keybindingConfig); err != nil { |
no test coverage detected