π File detail
keybindings/shortcutFormat.ts
π― Use case
This file lives under βkeybindings/β, which covers keyboard shortcuts and binding tables. On the API surface it exposes getShortcutDisplay β mainly functions, hooks, or classes. It composes internal code from services, loadUserBindings, resolver, and types (relative imports). What the file header says: TODO(keybindings-migration): Remove fallback parameter after migration is complete and we've confirmed no 'keybinding_fallback_used' events are being logged. The fallback exists as a safety net during migration - if bindings fail to load or an action isn't found, we fall back to.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
TODO(keybindings-migration): Remove fallback parameter after migration is complete and we've confirmed no 'keybinding_fallback_used' events are being logged. The fallback exists as a safety net during migration - if bindings fail to load or an action isn't found, we fall back to hardcoded values.
π€ Exports (heuristic)
getShortcutDisplay
π₯οΈ Source preview
import {
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
logEvent,
} from '../services/analytics/index.js'
import { loadKeybindingsSync } from './loadUserBindings.js'
import { getBindingDisplayText } from './resolver.js'
import type { KeybindingContextName } from './types.js'
// TODO(keybindings-migration): Remove fallback parameter after migration is
// complete and we've confirmed no 'keybinding_fallback_used' events are being
// logged. The fallback exists as a safety net during migration - if bindings
// fail to load or an action isn't found, we fall back to hardcoded values.
// Once stable, callers should be able to trust that getBindingDisplayText
// always returns a value for known actions, and we can remove this defensive
// pattern.
// Track which action+context pairs have already logged a fallback event
// to avoid duplicate events from repeated calls in non-React contexts.
const LOGGED_FALLBACKS = new Set<string>()
/**
* Get the display text for a configured shortcut without React hooks.
* Use this in non-React contexts (commands, services, etc.).
*
* This lives in its own module (not useShortcutDisplay.ts) so that
* non-React callers like query/stopHooks.ts don't pull React into their
* module graph via the sibling hook.
*
* @param action - The action name (e.g., 'app:toggleTranscript')
* @param context - The keybinding context (e.g., 'Global')
* @param fallback - Fallback text if binding not found
* @returns The configured shortcut display text
*
* @example
* const expandShortcut = getShortcutDisplay('app:toggleTranscript', 'Global', 'ctrl+o')
* // Returns the user's configured binding, or 'ctrl+o' as default
*/
export function getShortcutDisplay(
action: string,
context: KeybindingContextName,
fallback: string,
): string {
const bindings = loadKeybindingsSync()
const resolved = getBindingDisplayText(action, context, bindings)
if (resolved === undefined) {
const key = `${action}:${context}`
if (!LOGGED_FALLBACKS.has(key)) {
LOGGED_FALLBACKS.add(key)
logEvent('tengu_keybinding_fallback_used', {
action:
action as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
context:
context as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
fallback:
fallback as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
reason:
'action_not_found' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
})
}
return fallback
}
return resolved
}