Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Add customizable keybind for closing modals #142

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/insomnia/src/common/hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { strings } from './strings';
export const keyboardShortcutDescriptions: Record<KeyboardShortcut, string> = {
'workspace_showSettings': `Show ${strings.document.singular} / ${strings.collection.singular} Settings`,
'request_showSettings': 'Show Request Settings',
'workspace_closeModal': 'Close Modal Dialog',
'preferences_showKeyboardShortcuts': 'Show Keyboard Shortcuts',
'preferences_showGeneral': 'Show App Preferences',
'request_quickSwitch': 'Switch Requests',
Expand Down Expand Up @@ -47,6 +48,10 @@ const defaultRegistry: HotKeyRegistry = {
macKeys: [{ shift: true, meta: true, keyCode: keyboardKeys.comma.keyCode }],
winLinuxKeys: [{ ctrl: true, shift: true, keyCode: keyboardKeys.comma.keyCode }],
},
workspace_closeModal: {
macKeys: [{ keyCode: keyboardKeys.esc.keyCode }],
winLinuxKeys: [{ keyCode: keyboardKeys.esc.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 }],
Expand Down
3 changes: 2 additions & 1 deletion packages/insomnia/src/common/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export type KeyboardShortcut =
| 'request_togglePin'
| 'environment_showVariableSourceAndValue'
| 'beautifyRequestBody'
| 'graphql_explorer_focus_filter';
| 'graphql_explorer_focus_filter'
| 'workspace_closeModal';

/**
* The collection of defined hotkeys.
Expand Down
1 change: 1 addition & 0 deletions packages/insomnia/src/ui/components/base/editable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const Editable: FC<Props> = ({

const handleKeyDown = createKeybindingsHandler({
'Enter': handleEditEnd,
// TODO: is this also broken for vim mode?
'Escape': () => {
if (inputRef.current) {
// Set the input to the original value
Expand Down
14 changes: 3 additions & 11 deletions packages/insomnia/src/ui/components/base/modal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classnames from 'classnames';
import React, { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';

import { createKeybindingsHandler } from '../keydown-binder';
import { useDocBodyKeyboardShortcuts } from '../keydown-binder';
// Keep global z-index reference so that every modal will
// appear over top of an existing one.
let globalZIndex = 1000;
Expand Down Expand Up @@ -79,23 +79,15 @@ export const Modal = forwardRef<ModalHandle, ModalProps>(({
}
}, [hide, open]);

const handleKeydown = createKeybindingsHandler({
'Escape': () => {
useDocBodyKeyboardShortcuts({
workspace_closeModal: () => {
hide();
},
});
useEffect(() => {
document.body.addEventListener('keydown', handleKeydown);

return () => {
document.body.removeEventListener('keydown', handleKeydown);
};
}, [handleKeydown]);

return (open ?
<div
ref={containerRef}
onKeyDown={handleKeydown}
tabIndex={-1}
className={classes}
style={{ zIndex }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,12 @@ export const CodeEditor = forwardRef<CodeEditorHandle, CodeEditorProps>(({
'showAutocomplete': settings.hotKeyRegistry.showAutocomplete,
});
// Stop the editor from handling global keyboard shortcuts except for the autocomplete binding
// This includes the shortcut for closing modals, which defaults to Escape
const isShortcutButNotAutocomplete = isUserDefinedKeyboardShortcut && !isAutoCompleteBinding;
// Should not capture escape in order to exit modals
const isEscapeKey = event.code === 'Escape';
if (isShortcutButNotAutocomplete) {
// @ts-expect-error -- unsound property assignment
event.codemirrorIgnore = true;
// Stop the editor from handling the escape key
} else if (isEscapeKey) {
// @ts-expect-error -- unsound property assignment
event.codemirrorIgnore = true;
} else {
event.stopPropagation();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ CodeMirror.defineOption('environmentAutocomplete', null, (cm: CodeMirror.Editor,

let keydownTimeoutHandle: NodeJS.Timeout | null = null;
cm.on('keydown', (cm: CodeMirror.Editor, event) => {
// Close autocomplete on Escape if it's open
// Close autocomplete on Escape if it's open. In vim mode, this will require
// a second keypress to leave insert mode.
if (cm.isHintDropdownActive() && event.key === 'Escape') {
if (!cm.state.completionActive) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,11 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, OneLineEditorProps>
'showAutocomplete': settings.hotKeyRegistry.showAutocomplete,
});
// Stop the editor from handling global keyboard shortcuts except for the autocomplete binding
// This includes the shortcut for closing modals, which is Escape by default
const isShortcutButNotAutocomplete = isUserDefinedKeyboardShortcut && !isAutoCompleteBinding;
// Should not capture escape in order to exit modals
const isEscapeKey = event.code === 'Escape';
if (isShortcutButNotAutocomplete) {
// @ts-expect-error -- unsound property assignment
event.codemirrorIgnore = true;
// Stop the editor from handling the escape key
} else if (isEscapeKey) {
// @ts-expect-error -- unsound property assignment
event.codemirrorIgnore = true;
} else {
event.stopPropagation();
}
Expand Down
13 changes: 10 additions & 3 deletions packages/insomnia/src/ui/components/settings/general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,17 @@ export const General: FC = () => {
<EnumSetting<EditorKeyMap>
label="Text Editor Key Map"
setting="editorKeyMap"
help={isMac() && settings.editorKeyMap === EditorKeyMap.vim && (
help={settings.editorKeyMap === EditorKeyMap.vim && (
<Fragment>
To enable key-repeating with Vim on macOS, see <Link href={docsKeyMaps}>
documentation <i className="fa fa-external-link-square" /></Link>
To prevent the Escape key from closing modals, you can set a custom
keyboard shortcut for 'Close Modal Dialog'.
{isMac() && (
<Fragment>
<br /><br />
To enable key-repeating with Vim on macOS, see <Link href={docsKeyMaps}>
documentation <i className="fa fa-external-link-square" /></Link>
</Fragment>
)}
</Fragment>
)}
values={[
Expand Down