/ src / keybindings / template.ts
template.ts
 1  /**
 2   * Keybindings template generator.
 3   * Generates a well-documented template file for ~/.claude/keybindings.json
 4   */
 5  
 6  import { jsonStringify } from '../utils/slowOperations.js'
 7  import { DEFAULT_BINDINGS } from './defaultBindings.js'
 8  import {
 9    NON_REBINDABLE,
10    normalizeKeyForComparison,
11  } from './reservedShortcuts.js'
12  import type { KeybindingBlock } from './types.js'
13  
14  /**
15   * Filter out reserved shortcuts that cannot be rebound.
16   * These would cause /doctor to warn, so we exclude them from the template.
17   */
18  function filterReservedShortcuts(blocks: KeybindingBlock[]): KeybindingBlock[] {
19    const reservedKeys = new Set(
20      NON_REBINDABLE.map(r => normalizeKeyForComparison(r.key)),
21    )
22  
23    return blocks
24      .map(block => {
25        const filteredBindings: Record<string, string | null> = {}
26        for (const [key, action] of Object.entries(block.bindings)) {
27          if (!reservedKeys.has(normalizeKeyForComparison(key))) {
28            filteredBindings[key] = action
29          }
30        }
31        return { context: block.context, bindings: filteredBindings }
32      })
33      .filter(block => Object.keys(block.bindings).length > 0)
34  }
35  
36  /**
37   * Generate a template keybindings.json file content.
38   * Creates a fully valid JSON file with all default bindings that users can customize.
39   */
40  export function generateKeybindingsTemplate(): string {
41    // Filter out reserved shortcuts that cannot be rebound
42    const bindings = filterReservedShortcuts(DEFAULT_BINDINGS)
43  
44    // Format as object wrapper with bindings array
45    const config = {
46      $schema: 'https://www.schemastore.org/claude-code-keybindings.json',
47      $docs: 'https://code.claude.com/docs/en/keybindings',
48      bindings,
49    }
50  
51    return jsonStringify(config, null, 2) + '\n'
52  }