# Implementing keyboard shortcuts We use [Mousetrap](https://craig.is/killing/mice) to implement keyboard shortcuts in GitLab. Mousetrap provides an API that allows keyboard shortcut strings (like `mod+shift+p` or `p b`) to be bound to a JavaScript handler: ```javascript // Don't do this; see note below Mousetrap.bind('p b', togglePerformanceBar) ``` However, associating a hard-coded key sequence to a handler (as shown above) prevents these keyboard shortcuts from being customized or disabled by users. To allow keyboard shortcuts to be customized, commands are defined in `~/behaviors/shortcuts/keybindings.js`. The `keysFor` method is responsible for returning the correct key sequence for the provided command: ```javascript import { keysFor, TOGGLE_PERFORMANCE_BAR } from '~/behaviors/shortcuts/keybindings' Mousetrap.bind(keysFor(TOGGLE_PERFORMANCE_BAR), togglePerformanceBar); ``` ## Shortcut customization `keybindings.js` stores keyboard shortcut customizations as a JSON string in `localStorage`. When `keybindings.js` is first imported, it fetches any customizations from `localStorage` and merges these customizations into the default set of keybindings. There is no UI to edit these customizations. ## Adding new shortcuts Because keyboard shortcuts can be customized or disabled by end users, developers are encouraged to build _lots_ of keyboard shortcuts into GitLab. Shortcuts that are less likely to be used should be [disabled](#disabling-shortcuts) by default. To add a new shortcut, define and export a new command string in `keybindings.js`: ```javascript export const MAKE_COFFEE = 'foodAndBeverage.makeCoffee'; ``` Next, add a new command definition under the appropriate group in the `keybindingGroups` array: ```javascript { description: s__('KeyboardShortcuts|Make coffee'), command: MAKE_COFFEE, defaultKeys: ['mod+shift+c'], customKeys: customizations[MAKE_COFFEE], } ``` Finally, in the application code, import the `keysFor` function and the new command and bind the shortcut to the handler using Mousetrap: ```javascript import { keysFor, MAKE_COFFEE } from '~/behaviors/shortcuts/keybindings' Mousetrap.bind(keysFor(MAKE_COFFEE), makeCoffee); ``` See the existing the command definitions in `keybindings.js` for more examples. ## Disabling shortcuts A shortcut can be disabled, also known as _unassigned_, by assigning the shortcut to an empty array `[]`. For example, to introduce a new shortcut that is disabled by default, a command can be defined like this: ```javascript export const MAKE_MOCHA = 'foodAndBeverage.makeMocha'; { description: s__('KeyboardShortcuts|Make a mocha'), command: MAKE_MOCHA, defaultKeys: [], customKeys: customizations[MAKE_MOCHA], } ``` ## Make cross-platform shortcuts It's difficult to make shortcuts that work well in all platforms and browsers. This is one of the reasons that being able to customize and disable shortcuts is so important. One important way to make keyboard shortcuts more portable is to use the `mod` shortcut string, which resolves to `command` on Mac and `ctrl` otherwise. See [Mousetrap's documentation](https://craig.is/killing/mice#api.bind.combo) for more information.