feat(editor): optional space completion confirmation for SQL Server
This commit is contained in:
24 files changed
+202
-2
No files matched your search
@@ -253,6 +253,7 @@ import {
|
||||
import { applyEditorSettingsDraftToRefs, type EditorSettingsDraftRefMap } from "@/lib/settings/applyEditorSettingsDraft";
|
||||
import { serializeSettingsTransfer, sortTransferCategories, transferCategoryForKey, type SettingsTransferCategoryId } from "@/lib/settings/settingsTransfer";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { effectiveDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { useSavedSqlStore } from "@/stores/savedSqlStore";
|
||||
import { usePromptTemplateStore } from "@/stores/promptTemplateStore";
|
||||
import { useTunnelProfileStore } from "@/stores/tunnelProfileStore";
|
||||
@@ -291,6 +292,7 @@ const { t, locale } = useI18n();
|
||||
const { toast } = useToast();
|
||||
const settingsStore = useSettingsStore();
|
||||
const connectionStore = useConnectionStore();
|
||||
const hasSqlServerConnection = computed(() => connectionStore.connections.some((connection) => effectiveDatabaseTypeForConnection(connection) === "sqlserver"));
|
||||
const savedSqlStore = useSavedSqlStore();
|
||||
const promptTemplateStore = usePromptTemplateStore();
|
||||
const tunnelProfileStore = useTunnelProfileStore();
|
||||
@@ -568,6 +570,8 @@ const editShowCurrentStatementFrame = ref(settingsStore.editorSettings.showCurre
|
||||
const editShowInsertValueHints = ref(settingsStore.editorSettings.showInsertValueHints);
|
||||
const editAutoAliasTables = ref(settingsStore.editorSettings.autoAliasTables);
|
||||
const editInsertSpaceAfterCompletion = ref(settingsStore.editorSettings.insertSpaceAfterCompletion);
|
||||
const editSqlServerSpaceConfirmsCompletion = ref(settingsStore.editorSettings.sqlServerSpaceConfirmsCompletion);
|
||||
const showSqlServerSpaceConfirmsCompletion = computed(() => hasSqlServerConnection.value || settingsStore.editorSettings.sqlServerSpaceConfirmsCompletion || editSqlServerSpaceConfirmsCompletion.value);
|
||||
const editSortCompletionColumnsAlphabetically = ref(settingsStore.editorSettings.sortCompletionColumnsAlphabetically);
|
||||
const editSelectFirstCompletionOnOpen = ref(settingsStore.editorSettings.selectFirstCompletionOnOpen);
|
||||
const editCompletionTriggerMode = ref<SqlCompletionTriggerMode>(settingsStore.editorSettings.completionTriggerMode);
|
||||
@@ -904,6 +908,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
|
||||
showInsertValueHints: editShowInsertValueHints.value,
|
||||
autoAliasTables: editAutoAliasTables.value,
|
||||
insertSpaceAfterCompletion: editInsertSpaceAfterCompletion.value,
|
||||
sqlServerSpaceConfirmsCompletion: editSqlServerSpaceConfirmsCompletion.value,
|
||||
sortCompletionColumnsAlphabetically: editSortCompletionColumnsAlphabetically.value,
|
||||
selectFirstCompletionOnOpen: editSelectFirstCompletionOnOpen.value,
|
||||
completionTriggerMode: editCompletionTriggerMode.value,
|
||||
@@ -1541,6 +1546,7 @@ function syncEditorSettingsDraftFromStore() {
|
||||
editShowInsertValueHints.value = settingsStore.editorSettings.showInsertValueHints;
|
||||
editAutoAliasTables.value = settingsStore.editorSettings.autoAliasTables;
|
||||
editInsertSpaceAfterCompletion.value = settingsStore.editorSettings.insertSpaceAfterCompletion;
|
||||
editSqlServerSpaceConfirmsCompletion.value = settingsStore.editorSettings.sqlServerSpaceConfirmsCompletion;
|
||||
editSortCompletionColumnsAlphabetically.value = settingsStore.editorSettings.sortCompletionColumnsAlphabetically;
|
||||
editSelectFirstCompletionOnOpen.value = settingsStore.editorSettings.selectFirstCompletionOnOpen;
|
||||
editCompletionTriggerMode.value = settingsStore.editorSettings.completionTriggerMode;
|
||||
@@ -1671,6 +1677,7 @@ const editorSettingsDraftRefs: EditorSettingsDraftRefMap = {
|
||||
showInsertValueHints: editShowInsertValueHints,
|
||||
autoAliasTables: editAutoAliasTables,
|
||||
insertSpaceAfterCompletion: editInsertSpaceAfterCompletion,
|
||||
sqlServerSpaceConfirmsCompletion: editSqlServerSpaceConfirmsCompletion,
|
||||
sortCompletionColumnsAlphabetically: editSortCompletionColumnsAlphabetically,
|
||||
selectFirstCompletionOnOpen: editSelectFirstCompletionOnOpen,
|
||||
wordWrap: editWordWrap,
|
||||
@@ -2114,6 +2121,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
||||
editShowInsertValueHints.value = DEFAULT_EDITOR_SETTINGS.showInsertValueHints;
|
||||
editAutoAliasTables.value = DEFAULT_EDITOR_SETTINGS.autoAliasTables;
|
||||
editInsertSpaceAfterCompletion.value = DEFAULT_EDITOR_SETTINGS.insertSpaceAfterCompletion;
|
||||
editSqlServerSpaceConfirmsCompletion.value = DEFAULT_EDITOR_SETTINGS.sqlServerSpaceConfirmsCompletion;
|
||||
editSortCompletionColumnsAlphabetically.value = DEFAULT_EDITOR_SETTINGS.sortCompletionColumnsAlphabetically;
|
||||
editSelectFirstCompletionOnOpen.value = DEFAULT_EDITOR_SETTINGS.selectFirstCompletionOnOpen;
|
||||
editCompletionTriggerMode.value = DEFAULT_EDITOR_SETTINGS.completionTriggerMode;
|
||||
@@ -2259,6 +2267,7 @@ function resetAllDefaults() {
|
||||
editShowInsertValueHints.value = DEFAULT_EDITOR_SETTINGS.showInsertValueHints;
|
||||
editAutoAliasTables.value = DEFAULT_EDITOR_SETTINGS.autoAliasTables;
|
||||
editInsertSpaceAfterCompletion.value = DEFAULT_EDITOR_SETTINGS.insertSpaceAfterCompletion;
|
||||
editSqlServerSpaceConfirmsCompletion.value = DEFAULT_EDITOR_SETTINGS.sqlServerSpaceConfirmsCompletion;
|
||||
editSortCompletionColumnsAlphabetically.value = DEFAULT_EDITOR_SETTINGS.sortCompletionColumnsAlphabetically;
|
||||
editSelectFirstCompletionOnOpen.value = DEFAULT_EDITOR_SETTINGS.selectFirstCompletionOnOpen;
|
||||
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
|
||||
@@ -2792,6 +2801,8 @@ const settingsSearchEntries = computed(() =>
|
||||
[...SETTINGS_SEARCH_DEFINITIONS, ...createShortcutSettingsSearchDefinitions(SHORTCUT_DEFINITIONS)],
|
||||
{
|
||||
isWeb,
|
||||
hasSqlServerConnection: hasSqlServerConnection.value,
|
||||
sqlServerSpaceConfirmsCompletionEnabled: settingsStore.editorSettings.sqlServerSpaceConfirmsCompletion || editSqlServerSpaceConfirmsCompletion.value,
|
||||
visibleCategories: new Set(settingsCategoryNav.value.map((category) => category.value)),
|
||||
},
|
||||
translateWithExecuteShortcut,
|
||||
@@ -6044,6 +6055,16 @@ onUnmounted(() => {
|
||||
<Switch id="editor-insert-space-after-completion" v-model="editInsertSpaceAfterCompletion" class="mt-0.5" />
|
||||
</div>
|
||||
|
||||
<div v-if="showSqlServerSpaceConfirmsCompletion" class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="editor-sqlserver-space-confirms-completion">{{ t("settings.sqlServerSpaceConfirmsCompletion") }}</Label>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t("settings.sqlServerSpaceConfirmsCompletionDescription") }}
|
||||
</p>
|
||||
</div>
|
||||
<Switch id="editor-sqlserver-space-confirms-completion" v-model="editSqlServerSpaceConfirmsCompletion" class="mt-0.5" />
|
||||
</div>
|
||||
|
||||
<div class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="editor-sort-completion-columns-alphabetically">{{ t("settings.sortCompletionColumnsAlphabetically") }}</Label>
|
||||
|
||||
@@ -2705,6 +2705,38 @@ function acceptCompletionOrNextSnippetField(view: EditorViewType): boolean {
|
||||
return codeMirrorNextSnippetField?.(view) ?? false;
|
||||
}
|
||||
|
||||
function acceptSqlServerCompletionOnSpace(view: EditorViewType): boolean {
|
||||
if (isEditorComposing(view)) return false;
|
||||
if (props.databaseType !== "sqlserver" || !settingsStore.editorSettings.sqlServerSpaceConfirmsCompletion) return false;
|
||||
if (codeMirrorCompletionStatus?.(view.state) !== "active") return false;
|
||||
// A non-empty selection belongs to block editing, not word completion.
|
||||
if (!view.state.selection.main.empty) return false;
|
||||
const selected = codeMirrorSelectedCompletion?.(view.state) as QueryCompletionOption | null | undefined;
|
||||
const completionType = selected?.type;
|
||||
if (completionType !== "keyword" && completionType !== "table" && completionType !== "column") return false;
|
||||
// Batch-selection rows own Space for checkbox toggling; this Prec.highest binding outranks their keymap.
|
||||
if (selected?.dbxBatchColumnSelection || selected?.dbxBatchColumnSelectionAction) return false;
|
||||
if (!(codeMirrorAcceptCompletion?.(view) ?? false)) return false;
|
||||
|
||||
const selection = view.state.selection.main;
|
||||
if (!selection.empty) return true;
|
||||
const cursor = selection.head;
|
||||
const previousCharacter = cursor > 0 ? view.state.sliceDoc(cursor - 1, cursor) : "";
|
||||
if (/\s/.test(previousCharacter)) return true;
|
||||
|
||||
const nextCharacter = view.state.sliceDoc(cursor, cursor + 1);
|
||||
if (/\s/.test(nextCharacter)) {
|
||||
view.dispatch({ selection: { anchor: cursor + 1 }, scrollIntoView: true });
|
||||
} else {
|
||||
view.dispatch({
|
||||
changes: { from: cursor, insert: " " },
|
||||
selection: { anchor: cursor + 1 },
|
||||
scrollIntoView: true,
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function clearPendingCompletionTab() {
|
||||
if (pendingCompletionTabTimer === null) return;
|
||||
clearTimeout(pendingCompletionTabTimer);
|
||||
@@ -6942,6 +6974,7 @@ onMounted(async () => {
|
||||
vimModeComp.of(vimModeExtension(initialSettings.vimModeEnabled)),
|
||||
defaultKeymapComp.of(defaultKeymapExtension()),
|
||||
keymap.of([...searchKeymapWithoutModD(searchKeymap), ...historyKeymap, ...foldKeymap, ...completionKeymap]),
|
||||
Prec.highest(keymap.of([{ key: "Space", run: acceptSqlServerCompletionOnSpace }])),
|
||||
sqlLanguageComp.of(buildSqlLanguageExtension()),
|
||||
sqlSemanticHighlightComp.of(buildSqlSemanticHighlightExtension()),
|
||||
tooltips({ parent: tooltipParent }),
|
||||
|
||||
Reference in new issue
Block a user