MCPcopy Create free account
hub / github.com/AnukarOP/claude-code-leaked / useKeybindings

Function useKeybindings

source code/keybindings/useKeybinding.ts:115–198  ·  view source on GitHub ↗
(
  // Handler returning `false` means "not consumed" — the event propagates
  // to later useInput/useKeybindings handlers. Useful for fall-through:
  // e.g. ScrollKeybindingHandler's scroll:line* returns false when the
  // ScrollBox content fits (scroll is a no-op), letting a child component's
  // handler take the wheel event for list navigation instead. Promise<void>
  // is allowed for fire-and-forget async handlers (the `!== false` check
  // only skips propagation for a sync `false`, not a pending Promise).
  handlers: Record<string, () => void | false | Promise<void>>,
  options: Options = {},
)

Source from the content-addressed store, hash-verified

113 * ```
114 */
115export function useKeybindings(
116 // Handler returning `false` means "not consumed" — the event propagates
117 // to later useInput/useKeybindings handlers. Useful for fall-through:
118 // e.g. ScrollKeybindingHandler's scroll:line* returns false when the
119 // ScrollBox content fits (scroll is a no-op), letting a child component's
120 // handler take the wheel event for list navigation instead. Promise<void>
121 // is allowed for fire-and-forget async handlers (the `!== false` check
122 // only skips propagation for a sync `false`, not a pending Promise).
123 handlers: Record<string, () => void | false | Promise<void>>,
124 options: Options = {},
125): void {
126 const { context = 'Global', isActive = true } = options
127 const keybindingContext = useOptionalKeybindingContext()
128
129 // Register all handlers with the context for ChordInterceptor to invoke
130 useEffect(() => {
131 if (!keybindingContext || !isActive) return
132
133 const unregisterFns: Array<() => void> = []
134 for (const [action, handler] of Object.entries(handlers)) {
135 unregisterFns.push(
136 keybindingContext.registerHandler({ action, context, handler }),
137 )
138 }
139
140 return () => {
141 for (const unregister of unregisterFns) {
142 unregister()
143 }
144 }
145 }, [context, handlers, keybindingContext, isActive])
146
147 const handleInput = useCallback(
148 (input: string, key: Key, event: InputEvent) => {
149 // If no keybinding context available, skip resolution
150 if (!keybindingContext) return
151
152 // Build context list: registered active contexts + this context + Global
153 // More specific contexts (registered ones) take precedence over Global
154 const contextsToCheck: KeybindingContextName[] = [
155 ...keybindingContext.activeContexts,
156 context,
157 'Global',
158 ]
159 // Deduplicate while preserving order (first occurrence wins for priority)
160 const uniqueContexts = [...new Set(contextsToCheck)]
161
162 const result = keybindingContext.resolve(input, key, uniqueContexts)
163
164 switch (result.type) {
165 case 'match':
166 // Chord completed (if any) - clear pending state
167 keybindingContext.setPendingChord(null)
168 if (result.action in handlers) {
169 const handler = handlers[result.action]
170 if (handler && handler() !== false) {
171 event.stopImmediatePropagation()
172 }

Callers 15

ModelPickerFunction · 0.85
MessageSelectorFunction · 0.85
ScrollKeybindingHandlerFunction · 0.85
BridgeDialogFunction · 0.85
OnboardingFunction · 0.85
IdeOnboardingDialogFunction · 0.85
TabsFunction · 0.85
PermissionPromptFunction · 0.85
PreviewQuestionViewFunction · 0.85
useFilePermissionDialogFunction · 0.85

Calls 5

useInputFunction · 0.85
entriesMethod · 0.80
resolveMethod · 0.80

Tested by

no test coverage detected