mirror of
https://github.com/Kong/insomnia.git
synced 2026-06-03 21:55:53 -04:00
Move insomnia-data models, services, database code, and common utilities into a dedicated workspace package. Update consumers to import from the new package entrypoints and declare workspace dependencies for the extracted package.
343 lines
13 KiB
TypeScript
343 lines
13 KiB
TypeScript
import { keyboardKeys } from './keyboard-keys';
|
|
import { isMac, isWindows } from './platform';
|
|
import type { HotKeyRegistry, KeyboardShortcut, KeyCombination, PlatformKeyCombinations } from './settings';
|
|
import { strings } from './strings';
|
|
|
|
/**
|
|
* The collection of available hotkeys' and their descriptions.
|
|
* @IMPORTANT Not using dot, because NeDB prohibits field names to contain dots.
|
|
*/
|
|
export const keyboardShortcutDescriptions: Record<KeyboardShortcut, string> = {
|
|
workspace_showSettings: `Show ${strings.document.singular} / ${strings.collection.singular} Settings`,
|
|
request_showSettings: 'Show Request Settings',
|
|
preferences_showKeyboardShortcuts: 'Show Keyboard Shortcuts',
|
|
preferences_showGeneral: 'Show App Preferences',
|
|
request_quickSwitch: 'Quick search',
|
|
plugin_reload: 'Reload Plugins',
|
|
showAutocomplete: 'Show Autocomplete',
|
|
request_send: 'Send Request',
|
|
request_showOptions: 'Send Request (Options)',
|
|
environment_showEditor: 'Show Environment Editor',
|
|
environment_showSwitchMenu: 'Switch Environments',
|
|
request_toggleHttpMethodMenu: 'Change HTTP Method',
|
|
request_toggleHistory: 'Show Request History',
|
|
request_focusUrl: 'Focus URL',
|
|
request_showGenerateCodeEditor: 'Generate Code',
|
|
sidebar_focusFilter: 'Filter Sidebar',
|
|
sidebar_toggle: 'Toggle Sidebar',
|
|
response_focus: 'Focus Response',
|
|
showCookiesEditor: 'Edit Cookies',
|
|
request_createHTTP: 'Create HTTP Request',
|
|
request_showDelete: 'Delete Request',
|
|
request_showCreateFolder: 'Create Folder',
|
|
request_showDuplicate: 'Duplicate Request',
|
|
request_togglePin: 'Pin/Unpin Request',
|
|
environment_showVariableSourceAndValue: 'Show variable source and value',
|
|
beautifyRequestBody: 'Beautify Active Code Editors',
|
|
graphql_explorer_focus_filter: 'Focus GraphQL Explorer Filter',
|
|
close_tab: 'Close Tab',
|
|
tab_nextTab: 'Next Tab',
|
|
tab_previousTab: 'Previous Tab',
|
|
tab_reopenClosedTab: 'Reopen Closed Tab',
|
|
request_openInNewTab: 'Open Request in New Tab',
|
|
};
|
|
|
|
/**
|
|
* The default key bindings values of all available hotkeys.
|
|
*/
|
|
const defaultRegistry: HotKeyRegistry = {
|
|
workspace_showSettings: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
},
|
|
request_showSettings: {
|
|
macKeys: [{ alt: true, shift: true, meta: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, alt: true, shift: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
},
|
|
preferences_showKeyboardShortcuts: {
|
|
macKeys: [{ ctrl: true, shift: true, meta: true, keyCode: keyboardKeys.forwardslash.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.forwardslash.keyCode }],
|
|
},
|
|
preferences_showGeneral: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.comma.keyCode }],
|
|
},
|
|
request_quickSwitch: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.p.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.p.keyCode }],
|
|
},
|
|
plugin_reload: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.r.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.r.keyCode }],
|
|
},
|
|
showAutocomplete: {
|
|
macKeys: [{ ctrl: true, keyCode: keyboardKeys.space.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.space.keyCode }],
|
|
},
|
|
request_send: {
|
|
macKeys: [
|
|
{ meta: true, keyCode: keyboardKeys.enter.keyCode },
|
|
{ meta: true, keyCode: keyboardKeys.r.keyCode },
|
|
{ keyCode: keyboardKeys.f5.keyCode },
|
|
],
|
|
winLinuxKeys: [
|
|
{ ctrl: true, keyCode: keyboardKeys.enter.keyCode },
|
|
{ ctrl: true, keyCode: keyboardKeys.r.keyCode },
|
|
{ keyCode: keyboardKeys.f5.keyCode },
|
|
],
|
|
},
|
|
request_showOptions: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.enter.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.enter.keyCode }],
|
|
},
|
|
environment_showEditor: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.e.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.e.keyCode }],
|
|
},
|
|
environment_showSwitchMenu: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.e.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.e.keyCode }],
|
|
},
|
|
request_toggleHttpMethodMenu: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.l.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.l.keyCode }],
|
|
},
|
|
request_toggleHistory: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.h.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.h.keyCode }],
|
|
},
|
|
request_focusUrl: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.l.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.l.keyCode }],
|
|
},
|
|
request_showGenerateCodeEditor: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.g.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.g.keyCode }],
|
|
},
|
|
sidebar_focusFilter: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.f.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.f.keyCode }],
|
|
},
|
|
sidebar_toggle: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.backslash.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.backslash.keyCode }],
|
|
},
|
|
response_focus: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.singlequote.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.singlequote.keyCode }],
|
|
},
|
|
showCookiesEditor: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.k.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.k.keyCode }],
|
|
},
|
|
request_createHTTP: {
|
|
macKeys: [
|
|
{ meta: true, keyCode: keyboardKeys.n.keyCode },
|
|
{ alt: true, meta: true, keyCode: keyboardKeys.n.keyCode },
|
|
],
|
|
winLinuxKeys: [
|
|
{ ctrl: true, keyCode: keyboardKeys.n.keyCode },
|
|
{ ctrl: true, alt: true, keyCode: keyboardKeys.n.keyCode },
|
|
],
|
|
},
|
|
request_showDelete: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.backspace.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.backspace.keyCode }],
|
|
},
|
|
request_showCreateFolder: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.n.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.n.keyCode }],
|
|
},
|
|
request_showDuplicate: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.d.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.d.keyCode }],
|
|
},
|
|
request_togglePin: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.p.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.p.keyCode }],
|
|
},
|
|
environment_showVariableSourceAndValue: {
|
|
macKeys: [{ alt: true, shift: true, keyCode: keyboardKeys.u.keyCode }],
|
|
winLinuxKeys: [{ alt: true, shift: true, keyCode: keyboardKeys.u.keyCode }],
|
|
},
|
|
beautifyRequestBody: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.f.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.f.keyCode }],
|
|
},
|
|
graphql_explorer_focus_filter: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.i.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.i.keyCode }],
|
|
},
|
|
close_tab: {
|
|
macKeys: [{ meta: true, keyCode: keyboardKeys.w.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.w.keyCode }],
|
|
},
|
|
tab_nextTab: {
|
|
macKeys: [{ alt: true, meta: true, keyCode: keyboardKeys.rightarrow.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, keyCode: keyboardKeys.tab.keyCode }],
|
|
},
|
|
tab_previousTab: {
|
|
macKeys: [{ alt: true, meta: true, keyCode: keyboardKeys.leftarrow.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.tab.keyCode }],
|
|
},
|
|
tab_reopenClosedTab: {
|
|
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.t.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.t.keyCode }],
|
|
},
|
|
request_openInNewTab: {
|
|
macKeys: [{ meta: true, shift: true, keyCode: keyboardKeys.o.keyCode }],
|
|
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.o.keyCode }],
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Get a new copy of hotkey registry with default values.
|
|
*/
|
|
export function newDefaultRegistry(): HotKeyRegistry {
|
|
return structuredClone(defaultRegistry);
|
|
}
|
|
|
|
/**
|
|
* Get the key combinations based on the current platform.
|
|
*/
|
|
export function getPlatformKeyCombinations(bindings: PlatformKeyCombinations): KeyCombination[] {
|
|
if (isMac) {
|
|
return bindings.macKeys;
|
|
}
|
|
|
|
return bindings.winLinuxKeys;
|
|
}
|
|
|
|
/**
|
|
* Determine whether two key combinations are the same by comparing each of their keys.
|
|
*/
|
|
export function areSameKeyCombinations(keyComb1: KeyCombination, keyComb2: KeyCombination) {
|
|
return (
|
|
keyComb1.keyCode === keyComb2.keyCode &&
|
|
Boolean(keyComb1.alt) === Boolean(keyComb2.alt) &&
|
|
Boolean(keyComb1.shift) === Boolean(keyComb2.shift) &&
|
|
Boolean(keyComb1.ctrl) === Boolean(keyComb2.ctrl) &&
|
|
Boolean(keyComb1.meta) === Boolean(keyComb2.meta)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets the displayed text of a key code.
|
|
*/
|
|
export function getChar(keyCode: number) {
|
|
let char;
|
|
const key = Object.keys(keyboardKeys).find(k => keyboardKeys[k].keyCode === keyCode);
|
|
|
|
if (!key) {
|
|
console.error('Invalid key code', keyCode);
|
|
} else {
|
|
char = keyboardKeys[key].label;
|
|
}
|
|
|
|
return char || 'unknown';
|
|
}
|
|
|
|
function joinHotKeys(mustUsePlus: boolean, keys: string[]) {
|
|
if (!mustUsePlus && isMac) {
|
|
return keys.join(' ');
|
|
}
|
|
|
|
return keys.join(' + ');
|
|
}
|
|
|
|
/**
|
|
* Check whether key code is a modifier key, i.e., alt, shift, ctrl, or meta.
|
|
*/
|
|
export function isModifierKeyCode(keyCode: number): boolean {
|
|
return (
|
|
keyCode === keyboardKeys.alt.keyCode ||
|
|
keyCode === keyboardKeys.shift.keyCode ||
|
|
keyCode === keyboardKeys.ctrl.keyCode ||
|
|
// Meta keys.
|
|
keyCode === keyboardKeys.leftwindowkey.keyCode ||
|
|
keyCode === keyboardKeys.rightwindowkey.keyCode ||
|
|
keyCode === keyboardKeys.selectkey.keyCode
|
|
);
|
|
}
|
|
|
|
export const displayModifierKey = (key: keyof Omit<KeyCombination, 'keyCode'>) => {
|
|
const mac = isMac;
|
|
switch (key) {
|
|
case 'ctrl': {
|
|
return mac ? '⌃' : 'Ctrl';
|
|
}
|
|
|
|
case 'alt': {
|
|
return mac ? '⌥' : 'Alt';
|
|
}
|
|
|
|
case 'shift': {
|
|
return mac ? '⇧' : 'Shift';
|
|
}
|
|
|
|
case 'meta': {
|
|
if (mac) {
|
|
return '⌘';
|
|
}
|
|
|
|
if (isWindows) {
|
|
// Note: Although this unicode character for the Windows doesn't exist, the Unicode character U+229E ⊞ SQUARED PLUS is very commonly used for this purpose. For example, Wikipedia uses it as a simulation of the windows logo. Though, Windows itself uses `Windows` or `Win`, so we'll go with `Win` here.
|
|
// see: https://en.wikipedia.org/wiki/Windows_key
|
|
return 'Win';
|
|
}
|
|
|
|
// Note: To avoid using a Microsoft trademark, much Linux documentation refers to the key as "Super". This can confuse some users who still consider it a "Windows key". In KDE Plasma documentation it is called the Meta key even though the X11 "Super" shift bit is used.
|
|
// see: https://en.wikipedia.org/wiki/Super_key_(keyboard_button)
|
|
return 'Super';
|
|
}
|
|
|
|
default: {
|
|
throw new Error(key + 'unrecognized key');
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Construct the display string of a key combination based on platform.
|
|
* For example, the display of alt in Windows or Linux would be "Alt";
|
|
* while in Mac would be "⌥".
|
|
* @param mustUsePlus if true will join the characters with " + " for all platforms;
|
|
* otherwise if the platform is Mac, the characters will be next to each other.
|
|
* @returns the constructed string, if keyCode is null and the characters are joined with " + ",
|
|
* it will have a dangling "+" as the last character, e.g., "Alt + Ctrl +".
|
|
*/
|
|
export function constructKeyCombinationDisplay(keyComb: KeyCombination, mustUsePlus: boolean) {
|
|
const { keyCode } = keyComb;
|
|
const chars: string[] = [];
|
|
|
|
const addModifierKeys = (keys: (keyof Omit<KeyCombination, 'keyCode'>)[]) => {
|
|
keys.forEach(key => {
|
|
if (keyComb[key]) {
|
|
chars.push(displayModifierKey(key));
|
|
}
|
|
});
|
|
};
|
|
|
|
if (isMac) {
|
|
// Note: on Mac the canonical order is Control, Option (i.e. Alt), Shift, Command (i.e. Meta)
|
|
// see: https://developer.apple.com/design/human-interface-guidelines/macos/user-interaction/keyboard
|
|
addModifierKeys(['ctrl', 'alt', 'shift', 'meta']);
|
|
} else {
|
|
// Note: on Windows the observed oreder (as in, if you just try to make a shortcut with all modifiers) is Windows (i.e. Super/Meta), Ctrl, Alt, Shift.
|
|
// No such standard really exists, but at least on Ubuntu it follows the Windows ordering.
|
|
addModifierKeys(['meta', 'ctrl', 'alt', 'shift']);
|
|
}
|
|
|
|
if (keyCode != null && !isModifierKeyCode(keyCode)) {
|
|
chars.push(getChar(keyCode));
|
|
}
|
|
|
|
let joint = joinHotKeys(mustUsePlus, chars);
|
|
|
|
if (mustUsePlus && isModifierKeyCode(keyCode)) {
|
|
joint += ' +';
|
|
}
|
|
|
|
return joint;
|
|
}
|