Skip to main content

Format

Format key binding strings for display with platform-aware modifier labels.

import { formatForDisplay, formatWithLabels, SYMBOL_MAP, LABEL_MAP } from '@gentleduck/vim/format'
import type { FormatOptions } from '@gentleduck/vim/format'
import { formatForDisplay, formatWithLabels, SYMBOL_MAP, LABEL_MAP } from '@gentleduck/vim/format'
import type { FormatOptions } from '@gentleduck/vim/format'

Types

FormatOptions

interface FormatOptions {
  platform?: Platform  // Override auto-detection
  separator?: string   // Separator between parts. Default: '+'
}
interface FormatOptions {
  platform?: Platform  // Override auto-detection
  separator?: string   // Separator between parts. Default: '+'
}

Functions

formatForDisplay(binding, options?)

Formats a binding for UI display using platform-specific modifier names. Uses ASCII labels (no Unicode symbols).

function formatForDisplay(binding: string, options?: FormatOptions): string
function formatForDisplay(binding: string, options?: FormatOptions): string

Examples by platform:

BindingMacWindowsLinux
Mod+SCmd+SCtrl+SCtrl+S
Mod+Shift+ZCmd+Shift+ZCtrl+Shift+ZCtrl+Shift+Z
alt+kOpt+KAlt+KAlt+K
meta+enterCmd+EnterWin+EnterSuper+Enter
formatForDisplay('Mod+S', { platform: 'mac' })     // 'Cmd+S'
formatForDisplay('Mod+S', { platform: 'windows' })  // 'Ctrl+S'
formatForDisplay('Mod+S', { platform: 'linux' })    // 'Ctrl+S'
 
// Custom separator
formatForDisplay('ctrl+shift+k', { separator: ' ' }) // 'Ctrl Shift K'
formatForDisplay('Mod+S', { platform: 'mac' })     // 'Cmd+S'
formatForDisplay('Mod+S', { platform: 'windows' })  // 'Ctrl+S'
formatForDisplay('Mod+S', { platform: 'linux' })    // 'Ctrl+S'
 
// Custom separator
formatForDisplay('ctrl+shift+k', { separator: ' ' }) // 'Ctrl Shift K'

formatWithLabels(binding, options?)

Similar to formatForDisplay but uses a wider separator (' + ' by default) and maps special keys to human-readable names.

function formatWithLabels(binding: string, options?: FormatOptions): string
function formatWithLabels(binding: string, options?: FormatOptions): string

Examples:

formatWithLabels('Mod+Shift+S', { platform: 'linux' })
// 'Ctrl + Shift + S'
 
formatWithLabels('ctrl+backspace')
// 'Ctrl + Backspace'
 
formatWithLabels('alt+arrowup')
// 'Alt + Up'
formatWithLabels('Mod+Shift+S', { platform: 'linux' })
// 'Ctrl + Shift + S'
 
formatWithLabels('ctrl+backspace')
// 'Ctrl + Backspace'
 
formatWithLabels('alt+arrowup')
// 'Alt + Up'

Constants

SYMBOL_MAP

Platform-specific display names for modifiers.

const SYMBOL_MAP: Record<Platform, Record<string, string>> = {
  mac: { meta: 'Cmd', ctrl: 'Ctrl', alt: 'Opt', shift: 'Shift' },
  windows: { meta: 'Win', ctrl: 'Ctrl', alt: 'Alt', shift: 'Shift' },
  linux: { meta: 'Super', ctrl: 'Ctrl', alt: 'Alt', shift: 'Shift' },
}
const SYMBOL_MAP: Record<Platform, Record<string, string>> = {
  mac: { meta: 'Cmd', ctrl: 'Ctrl', alt: 'Opt', shift: 'Shift' },
  windows: { meta: 'Win', ctrl: 'Ctrl', alt: 'Alt', shift: 'Shift' },
  linux: { meta: 'Super', ctrl: 'Ctrl', alt: 'Alt', shift: 'Shift' },
}

LABEL_MAP

Human-readable names for special keys.

const LABEL_MAP: Record<string, string> = {
  space: 'Space',
  esc: 'Escape',
  enter: 'Enter',
  tab: 'Tab',
  backspace: 'Backspace',
  delete: 'Delete',
  arrowup: 'Up',
  arrowdown: 'Down',
  arrowleft: 'Left',
  arrowright: 'Right',
  pageup: 'PageUp',
  pagedown: 'PageDown',
  home: 'Home',
  end: 'End',
  insert: 'Insert',
}
const LABEL_MAP: Record<string, string> = {
  space: 'Space',
  esc: 'Escape',
  enter: 'Enter',
  tab: 'Tab',
  backspace: 'Backspace',
  delete: 'Delete',
  arrowup: 'Up',
  arrowdown: 'Down',
  arrowleft: 'Left',
  arrowright: 'Right',
  pageup: 'PageUp',
  pagedown: 'PageDown',
  home: 'Home',
  end: 'End',
  insert: 'Insert',
}

Rendering in React

A common pattern is to render formatted shortcuts inside a <kbd> element:

import { formatForDisplay } from '@gentleduck/vim/format'
 
function Shortcut({ binding }: { binding: string }) {
  const parts = formatForDisplay(binding).split('+')
 
  return (
    <span className="flex items-center gap-1">
      {parts.map((part, i) => (
        <kbd key={i} className="px-1.5 py-0.5 text-xs bg-gray-100 rounded border">
          {part}
        </kbd>
      ))}
    </span>
  )
}
 
// Usage: <Shortcut binding="Mod+Shift+K" />
import { formatForDisplay } from '@gentleduck/vim/format'
 
function Shortcut({ binding }: { binding: string }) {
  const parts = formatForDisplay(binding).split('+')
 
  return (
    <span className="flex items-center gap-1">
      {parts.map((part, i) => (
        <kbd key={i} className="px-1.5 py-0.5 text-xs bg-gray-100 rounded border">
          {part}
        </kbd>
      ))}
    </span>
  )
}
 
// Usage: <Shortcut binding="Mod+Shift+K" />