feat(query): show result source ranges
This commit is contained in:
5 files changed
+248
-26
No files matched your search
@@ -249,8 +249,10 @@ let codeMirrorInsertNewlineKeepIndent: typeof import("@codemirror/commands").ins
|
||||
let codeMirrorToggleLineComment: typeof import("@codemirror/commands").toggleLineComment | null = null;
|
||||
let setSqlDiagnosticsEffect: import("@codemirror/state").StateEffectType<SqlSemanticDiagnostic[]> | null = null;
|
||||
let setPreviewRangeEffect: import("@codemirror/state").StateEffectType<{ from: number; to: number } | null> | null = null;
|
||||
let setResultSourceRangeEffect: import("@codemirror/state").StateEffectType<{ from: number; to: number } | null> | null = null;
|
||||
let previewRangeComp: import("@codemirror/state").Compartment | null = null;
|
||||
let buildPreviewRangeExtension: (() => import("@codemirror/state").Extension) | null = null;
|
||||
let buildResultSourceRangeExtension: (() => import("@codemirror/state").Extension) | null = null;
|
||||
let buildRunStatementGutterExtension: (() => import("@codemirror/state").Extension) | null = null;
|
||||
let indentComp: import("@codemirror/state").Compartment | null = null;
|
||||
let codeMirrorIndentUnit: typeof import("@codemirror/language").indentUnit | null = null;
|
||||
@@ -491,6 +493,33 @@ function setPreviewRange(range: { from: number; to: number } | null) {
|
||||
});
|
||||
}
|
||||
|
||||
function setResultSourceRange(range: { from: number; to: number } | null) {
|
||||
if (!view.value || !setResultSourceRangeEffect) return;
|
||||
view.value.dispatch({
|
||||
effects: setResultSourceRangeEffect.of(range),
|
||||
});
|
||||
}
|
||||
|
||||
function previewStatementRange(range: { from: number; to: number } | null) {
|
||||
const currentView = view.value;
|
||||
if (!range || !currentView || !editorViewModule || !setResultSourceRangeEffect) {
|
||||
setResultSourceRange(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const from = Math.max(0, Math.min(range.from, currentView.state.doc.length));
|
||||
const to = Math.max(from, Math.min(range.to, currentView.state.doc.length));
|
||||
if (from === to) {
|
||||
setResultSourceRange(null);
|
||||
return;
|
||||
}
|
||||
|
||||
currentView.dispatch({
|
||||
selection: { anchor: from },
|
||||
effects: [setResultSourceRangeEffect.of({ from, to }), editorViewModule.EditorView.scrollIntoView(from, { y: "center" })],
|
||||
});
|
||||
}
|
||||
|
||||
function onPickerActiveIndexChange(index: number) {
|
||||
pickerActiveIndex.value = index;
|
||||
const candidate = pickerCandidates.value[index];
|
||||
@@ -2574,8 +2603,8 @@ onMounted(async () => {
|
||||
if (!editorRef.value) return;
|
||||
|
||||
const [
|
||||
{ EditorView, keymap, rectangularSelection, hoverTooltip, showTooltip, Decoration, tooltips, gutter, GutterMarker, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, crosshairCursor, ViewPlugin },
|
||||
{ EditorState, EditorSelection, Compartment, Prec, StateEffect, StateField },
|
||||
{ EditorView, keymap, rectangularSelection, hoverTooltip, showTooltip, Decoration, tooltips, gutter, GutterMarker, lineNumberMarkers, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, crosshairCursor, ViewPlugin },
|
||||
{ EditorState, EditorSelection, Compartment, Prec, RangeSet, StateEffect, StateField },
|
||||
langSql,
|
||||
{ autocompletion, startCompletion, acceptCompletion, closeBrackets, closeBracketsKeymap, snippetCompletion, completionStatus, completionKeymap, insertCompletionText, nextSnippetField },
|
||||
{ copyLineDown, copyLineUp, deleteLine, indentLess, indentMore, insertNewlineKeepIndent, moveLineDown, moveLineUp, redo, selectAll, undo, toggleLineComment, history, defaultKeymap, historyKeymap },
|
||||
@@ -2681,6 +2710,7 @@ onMounted(async () => {
|
||||
return Decoration.set([Decoration.mark({ class: "cm-db-execution-preview" }).range(range.from, range.to)]);
|
||||
}
|
||||
}
|
||||
if (transaction.docChanged || transaction.selection) return Decoration.none;
|
||||
return decorations;
|
||||
},
|
||||
provide: (f) => EditorView.decorations.from(f),
|
||||
@@ -2688,6 +2718,41 @@ onMounted(async () => {
|
||||
return field;
|
||||
};
|
||||
|
||||
class ResultSourceLineNumberMarker extends GutterMarker {
|
||||
elementClass = "cm-db-result-source-line-number";
|
||||
}
|
||||
|
||||
const resultSourceLineNumberMarker = new ResultSourceLineNumberMarker();
|
||||
setResultSourceRangeEffect = StateEffect.define<{ from: number; to: number } | null>();
|
||||
buildResultSourceRangeExtension = () => {
|
||||
const effectType = setResultSourceRangeEffect!;
|
||||
const markersForRange = (state: import("@codemirror/state").EditorState, range: { from: number; to: number }) => {
|
||||
const from = Math.max(0, Math.min(range.from, state.doc.length));
|
||||
const to = Math.max(from, Math.min(range.to, state.doc.length));
|
||||
const startLine = state.doc.lineAt(from);
|
||||
const endLine = state.doc.lineAt(Math.max(from, to - 1));
|
||||
const markers = Array.from({ length: endLine.number - startLine.number + 1 }, (_, index) => resultSourceLineNumberMarker.range(state.doc.line(startLine.number + index).from));
|
||||
return RangeSet.of(markers);
|
||||
};
|
||||
|
||||
const field = StateField.define({
|
||||
create() {
|
||||
return RangeSet.empty;
|
||||
},
|
||||
update(markers, transaction) {
|
||||
for (const effect of transaction.effects) {
|
||||
if (effect.is(effectType)) {
|
||||
return effect.value ? markersForRange(transaction.state, effect.value) : RangeSet.empty;
|
||||
}
|
||||
}
|
||||
if (transaction.docChanged || transaction.selection) return RangeSet.empty;
|
||||
return markers;
|
||||
},
|
||||
provide: (field) => lineNumberMarkers.from(field),
|
||||
});
|
||||
return field;
|
||||
};
|
||||
|
||||
buildSqlSignatureExtension = () =>
|
||||
showTooltip.compute(["doc", "selection"], (currentState) => {
|
||||
const signature = getSqlFunctionSignatureHelp(currentState.doc.toString(), currentState.selection.main.head);
|
||||
@@ -2878,6 +2943,7 @@ onMounted(async () => {
|
||||
requestTableColumns: requestInsertValueHintTableColumns,
|
||||
}),
|
||||
previewRangeComp.of(buildPreviewRangeExtension()),
|
||||
buildResultSourceRangeExtension(),
|
||||
Prec.highest(
|
||||
keymap.of([
|
||||
{ key: "'", run: handleSqlSingleQuote },
|
||||
@@ -3462,7 +3528,7 @@ function scrollCursorIntoView() {
|
||||
});
|
||||
}
|
||||
|
||||
defineExpose({ openSearch, openReplace, scrollCursorIntoView, requestExecute, pasteClipboardAsSqlInCondition });
|
||||
defineExpose({ openSearch, openReplace, scrollCursorIntoView, requestExecute, pasteClipboardAsSqlInCondition, previewStatementRange });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -3495,6 +3561,15 @@ defineExpose({ openSearch, openReplace, scrollCursorIntoView, requestExecute, pa
|
||||
background: var(--dbx-editor-selection-background, rgba(59, 130, 246, 0.35));
|
||||
}
|
||||
|
||||
:deep(.cm-lineNumbers .cm-db-result-source-line-number) {
|
||||
color: rgb(126 34 206) !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
:global(.dark) :deep(.cm-lineNumbers .cm-db-result-source-line-number) {
|
||||
color: rgb(216 180 254) !important;
|
||||
}
|
||||
|
||||
:deep(.cm-db-current-statement-line) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user