editor context menu, focus fix

This commit is contained in:
Jan Prochazka 2021-03-11 07:53:37 +01:00
parent 5f97f7d922
commit c193955fbe
6 changed files with 91 additions and 12 deletions

View File

@ -1,8 +1,8 @@
<script lang="ts">
<script lang="ts" context="module">
import { commands } from '../stores';
import { get } from 'svelte/store';
function handleKeyDown(e) {
export function handleCommandKeyDown(e) {
let keyText = '';
if (e.ctrlKey) keyText += 'Ctrl+';
if (e.shiftKey) keyText += 'Shift+';
@ -20,7 +20,13 @@
.toLowerCase()
.split('|')
.map(x => x.trim())
.includes(keyText.toLowerCase())
.includes(keyText.toLowerCase()) &&
(x.disableHandleKeyText == null ||
!x.disableHandleKeyText
.toLowerCase()
.split('|')
.map(x => x.trim())
.includes(keyText.toLowerCase()))
);
if (command) {
@ -30,4 +36,4 @@
}
</script>
<svelte:window on:keydown={handleKeyDown} />
<svelte:window on:keydown={handleCommandKeyDown} />

View File

@ -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),

View File

@ -20,6 +20,7 @@ export interface GlobalCommand {
showDisabled?: boolean;
toolbarName?: string;
toolbarOrder?: number;
disableHandleKeyText?: string;
}
export default function registerCommand(command: GlobalCommand) {

View File

@ -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() {

View File

@ -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(),
});
</script>
<script lang="ts">
import { get_current_component } from 'svelte/internal';
import { getContext } from 'svelte';
import sqlFormatter from 'sql-formatter';
import { writable, derived, get } from 'svelte/store';
import registerCommand from '../commands/registerCommand';
@ -144,6 +161,16 @@
return status;
}
export function toggleComment() {
domEditor.getEditor().execCommand('togglecomment');
}
export function formatCode() {
const editor = domEditor.getEditor();
editor.setValue(sqlFormatter.format(editor.getValue()));
editor.clearSelection();
}
const handleMesageClick = message => {
// console.log('EDITOR', editorRef.current.editor);
if (domEditor.getEditor()) {
@ -163,6 +190,10 @@
? () => applySqlTemplate(initialArgs.sqlTemplate, $extensions, $$props)
: null,
});
function createMenu() {
return [{ command: 'query.execute' }, { command: 'query.toggleComment' }, { command: 'query.formatCode' }];
}
</script>
<VerticalSplitter isSplitter={visibleResultTabs}>
@ -170,6 +201,7 @@
<SqlEditor
engine={$connection && $connection.engine}
value={$editorState.value || ''}
menu={createMenu()}
on:input={e => setEditorData(e.detail)}
on:focus={() => lastFocusedQuery.set(instance)}
bind:this={domEditor}

View File

@ -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);
},
});
</script>
<script lang="ts">
import _ from 'lodash';
import { derived, get } from 'svelte/store';
import registerCommand from '../commands/registerCommand';
import FontIcon from '../icons/FontIcon.svelte';
import { currentDatabase, openedTabs } from '../stores';