| ... | @@ -292,6 +292,12 @@ const DEFAULT_RESOLVED_KEYBINDINGS = compileDefaultKeybindings(); | ... | @@ -292,6 +292,12 @@ const DEFAULT_RESOLVED_KEYBINDINGS = compileDefaultKeybindings(); |
| 292 | const KEYBINDINGS_CONFIG_PATH = path.join(".t3", "keybindings.json"); | 292 | const KEYBINDINGS_CONFIG_PATH = path.join(".t3", "keybindings.json"); |
| 293 | const MAX_KEYBINDINGS = 256; | 293 | const MAX_KEYBINDINGS = 256; |
| 294 | | 294 | |
| | 295 | class KeybindingsConfigParseError extends Error { |
| | 296 | constructor(configPath: string, detail: string, options?: { cause?: unknown }) { |
| | 297 | super(`Unable to parse keybindings config at ${configPath}: ${detail}`, options); |
| | 298 | } |
| | 299 | } |
| | 300 | |
| 295 | function resolveKeybindingsConfigPath(): string { | 301 | function resolveKeybindingsConfigPath(): string { |
| 296 | return path.join(os.homedir(), KEYBINDINGS_CONFIG_PATH); | 302 | return path.join(os.homedir(), KEYBINDINGS_CONFIG_PATH); |
| 297 | } | 303 | } |
| ... | @@ -308,7 +314,7 @@ function loadCustomKeybindingsConfig( | ... | @@ -308,7 +314,7 @@ function loadCustomKeybindingsConfig( |
| 308 | const parsed = JSON.parse(raw) as unknown; | 314 | const parsed = JSON.parse(raw) as unknown; |
| 309 | if (!Array.isArray(parsed)) { | 315 | if (!Array.isArray(parsed)) { |
| 310 | if (options?.throwOnUnreadableConfig) { | 316 | if (options?.throwOnUnreadableConfig) { |
| 311 | throw new Error(`Unable to parse keybindings config at ${configPath}: expected JSON array`); | 317 | throw new KeybindingsConfigParseError(configPath, "expected JSON array"); |
| 312 | } | 318 | } |
| 313 | logger.warn("ignoring keybindings config with unsupported format; expected array", { | 319 | logger.warn("ignoring keybindings config with unsupported format; expected array", { |
| 314 | path: configPath, | 320 | path: configPath, |
| ... | @@ -343,10 +349,12 @@ function loadCustomKeybindingsConfig( | ... | @@ -343,10 +349,12 @@ function loadCustomKeybindingsConfig( |
| 343 | return []; | 349 | return []; |
| 344 | } | 350 | } |
| 345 | if (options?.throwOnUnreadableConfig) { | 351 | if (options?.throwOnUnreadableConfig) { |
| 346 | throw new Error( | 352 | if (error instanceof KeybindingsConfigParseError) { |
| 347 | `Unable to parse keybindings config at ${configPath}: ${ | 353 | throw error; |
| 348 | error instanceof Error ? error.message : String(error) | 354 | } |
| 349 | }`, | 355 | throw new KeybindingsConfigParseError( |
| | 356 | configPath, |
| | 357 | error instanceof Error ? error.message : String(error), |
| 350 | { cause: error }, | 358 | { cause: error }, |
| 351 | ); | 359 | ); |
| 352 | } | 360 | } |