diff --git a/packages/web/src/commands/CommandListener.svelte b/packages/web/src/commands/CommandListener.svelte
index 8b311ef99..8b75bec91 100644
--- a/packages/web/src/commands/CommandListener.svelte
+++ b/packages/web/src/commands/CommandListener.svelte
@@ -1,8 +1,8 @@
-
-
+
diff --git a/packages/web/src/commands/CommandPalette.svelte b/packages/web/src/commands/CommandPalette.svelte
index 8589ba08a..e0ee22d85 100644
--- a/packages/web/src/commands/CommandPalette.svelte
+++ b/packages/web/src/commands/CommandPalette.svelte
@@ -31,7 +31,13 @@
$: selectedIndex = true ? 0 : filter;
- onMount(() => domInput.focus());
+ onMount(() => {
+ const oldFocus = document.activeElement;
+ domInput.focus();
+ return () => {
+ if (oldFocus) oldFocus.focus();
+ };
+ });
$: sortedComands = _.sortBy(
Object.values($commands).filter(x => x.enabled),
diff --git a/packages/web/src/commands/registerCommand.ts b/packages/web/src/commands/registerCommand.ts
index 7d3c99909..26547034c 100644
--- a/packages/web/src/commands/registerCommand.ts
+++ b/packages/web/src/commands/registerCommand.ts
@@ -20,6 +20,7 @@ export interface GlobalCommand {
showDisabled?: boolean;
toolbarName?: string;
toolbarOrder?: number;
+ disableHandleKeyText?: string;
}
export default function registerCommand(command: GlobalCommand) {
diff --git a/packages/web/src/query/AceEditor.svelte b/packages/web/src/query/AceEditor.svelte
index 4b37d3c59..e02757136 100644
--- a/packages/web/src/query/AceEditor.svelte
+++ b/packages/web/src/query/AceEditor.svelte
@@ -15,6 +15,9 @@
import 'ace-builds/src-noconflict/theme-twilight';
import 'ace-builds/src-noconflict/ext-searchbox';
import 'ace-builds/src-noconflict/ext-language_tools';
+ import { currentDropDownMenu } from '../stores';
+ import _ from 'lodash';
+ import { handleCommandKeyDown } from '../commands/CommandListener.svelte';
const EDITOR_ID = `svelte-ace-editor-div:${Math.floor(Math.random() * 10000000000)}`;
const dispatch = createEventDispatcher<{
@@ -40,6 +43,7 @@
export let mode: string = 'text'; // String
export let theme: string = 'github'; // String
export let options: any = {}; // Object
+ export let menu;
let editor: ace.Editor;
let contentBackup: string = '';
@@ -54,13 +58,6 @@
const requireEditorPlugins = () => {};
requireEditorPlugins();
- onDestroy(() => {
- if (editor) {
- editor.destroy();
- editor.container.remove();
- }
- });
-
$: watchValue(value);
function watchValue(val: string) {
if (contentBackup !== val && editor && typeof val === 'string') {
@@ -101,6 +98,17 @@
resizeOnNextTick();
}
+ const handleContextMenu = e => {
+ e.preventDefault();
+ const left = e.pageX;
+ const top = e.pageY;
+ currentDropDownMenu.set({ left, top, items: _.isFunction(menu) ? menu() : menu });
+ };
+
+ const handleKeyDown = (data, hash, keyString, keyCode, event) => {
+ handleCommandKeyDown(event);
+ };
+
onMount(() => {
editor = ace.edit(EDITOR_ID);
@@ -115,6 +123,18 @@
if (options) {
editor.setOptions(options);
}
+
+ editor.container.addEventListener('contextmenu', handleContextMenu);
+ editor.keyBinding.addKeyboardHandler(handleKeyDown);
+ });
+
+ onDestroy(() => {
+ if (editor) {
+ editor.container.removeEventListener('contextmenu', handleContextMenu);
+ editor.keyBinding.removeKeyboardHandler(handleKeyDown);
+ editor.destroy();
+ editor.container.remove();
+ }
});
function setEventCallBacks() {
diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte
index a4c53912a..a0fd3aa2e 100644
--- a/packages/web/src/tabs/QueryTab.svelte
+++ b/packages/web/src/tabs/QueryTab.svelte
@@ -30,11 +30,28 @@
),
onClick: () => get(currentQuery).kill(),
});
+ registerCommand({
+ id: 'query.toggleComment',
+ category: 'Query',
+ name: 'Toggle comment',
+ keyText: 'Ctrl+/',
+ disableHandleKeyText: 'Ctrl+/',
+ enabledStore: derived(currentQuery, query => query != null),
+ onClick: () => get(currentQuery).toggleComment(),
+ });
+ registerCommand({
+ id: 'query.formatCode',
+ category: 'Query',
+ name: 'Format code',
+ enabledStore: derived(currentQuery, query => query != null),
+ onClick: () => get(currentQuery).formatCode(),
+ });
@@ -170,6 +201,7 @@
setEditorData(e.detail)}
on:focus={() => lastFocusedQuery.set(instance)}
bind:this={domEditor}
diff --git a/packages/web/src/widgets/TabsPanel.svelte b/packages/web/src/widgets/TabsPanel.svelte
index 705b02bd2..d43e40cf0 100644
--- a/packages/web/src/widgets/TabsPanel.svelte
+++ b/packages/web/src/widgets/TabsPanel.svelte
@@ -17,10 +17,24 @@
if (key.startsWith('archive://')) return 'icon archive';
return 'icon file';
}
+
+ registerCommand({
+ id: 'tabs.nextTab',
+ category: 'Tabs',
+ name: 'Next tab',
+ keyText: 'Ctrl+Tab',
+ enabledStore: derived(openedTabs, tabs => tabs.filter(x => !x.closedTime).length >= 2),
+ onClick: () => {
+ const tabs = get(openedTabs).filter(x => x.closedTime == null);
+ if (tabs.length >= 2) setSelectedTab(tabs[tabs.length - 2].tabid);
+ },
+ });