Skip to content

Commit

Permalink
add experiment statement gutter highlight
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal committed Aug 25, 2024
1 parent ba9d3b4 commit 86ac7a1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/components/gui/sql-editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { sqliteDialect } from "@/drivers/sqlite/sqlite-dialect";
import { functionTooltip } from "./function-tooltips";
import sqliteFunctionList from "@/drivers/sqlite/function-tooltip.json";
import { toast } from "sonner";
import SqlStatementHighlightPlugin from "./statement-highlight";

interface SqlEditorProps {
value: string;
Expand Down Expand Up @@ -58,6 +59,15 @@ const SqlEditor = forwardRef<ReactCodeMirrorRef, SqlEditorProps>(
return createSQLTableNameHighlightPlugin([]);
}, [schema]);

const baseTheme = useMemo(() => {
return EditorView.baseTheme({
"& .cm-line": {
borderLeft: "3px solid transparent",
paddingLeft: "10px",
},
});
}, []);

const keyExtensions = useMemo(() => {
return keymap.of([
{
Expand Down Expand Up @@ -138,6 +148,7 @@ const SqlEditor = forwardRef<ReactCodeMirrorRef, SqlEditorProps>(
height: "100%",
}}
extensions={[
baseTheme,
keyExtensions,
sql({
dialect: sqliteDialect,
Expand All @@ -152,6 +163,7 @@ const SqlEditor = forwardRef<ReactCodeMirrorRef, SqlEditorProps>(
const columnNumber = pos - line.from;
if (onCursorChange) onCursorChange(pos, lineNumber, columnNumber);
}),
SqlStatementHighlightPlugin,
]}
/>
);
Expand Down
69 changes: 69 additions & 0 deletions src/components/gui/sql-editor/statement-highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
Decoration,
EditorState,
EditorView,
StateField,
Range,
} from "@uiw/react-codemirror";
import { syntaxTree } from "@codemirror/language";
import { SyntaxNode } from "@lezer/common";

const statementLineHighlight = Decoration.line({
class: "cm-highlight-statement",
});

function resolveToNearestStatement(node: SyntaxNode, cursor: number) {
const statements = node.getChildren("Statement");
if (statements.length === 0) return null;

for (let i = 0; i < statements.length; i++) {
const statement = statements[i];
if (statement.to < cursor) continue;
return statement;
}

return statements[statements.length - 1];
}

function getDecorationFromState(state: EditorState) {
const tree = syntaxTree(state);
const node = resolveToNearestStatement(
tree.topNode,
state.selection.main.from
);

if (!node) return Decoration.none;

// Get the line of the node
const fromLineNumber = state.doc.lineAt(node.from).number;
const toLineNumber = state.doc.lineAt(node.to).number;

const d: Range<Decoration>[] = [];
for (let i = fromLineNumber; i <= toLineNumber; i++) {
d.push(statementLineHighlight.range(state.doc.line(i).from));
}

return Decoration.set(d);
}

const SqlStatementStateField = StateField.define({
create(state) {
return getDecorationFromState(state);
},

update(_, tr) {
return getDecorationFromState(tr.state);
},

provide: (f) => EditorView.decorations.from(f),
});

const SqlStatementTheme = EditorView.baseTheme({
".cm-highlight-statement": {
borderLeft: "3px solid #ff9ff3 !important",
},
});

const SqlStatementHighlightPlugin = [SqlStatementStateField, SqlStatementTheme];

export default SqlStatementHighlightPlugin;

0 comments on commit 86ac7a1

Please sign in to comment.