mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-30 21:59:46 +02:00
feat: source editor reveals and highlights lines
This commit is contained in:
parent
86f8fc0530
commit
b73a31f889
1 changed files with 36 additions and 1 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
import { useEffect, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
import { Spinner } from "@/components/ui/spinner";
|
import { Spinner } from "@/components/ui/spinner";
|
||||||
|
|
||||||
const MonacoEditor = dynamic(() => import("@monaco-editor/react"), {
|
const MonacoEditor = dynamic(() => import("@monaco-editor/react"), {
|
||||||
|
|
@ -17,6 +17,8 @@ interface SourceCodeEditorProps {
|
||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
onSave?: () => Promise<void> | void;
|
onSave?: () => Promise<void> | void;
|
||||||
|
/** 1-based inclusive line range to reveal and highlight (e.g. a citation). */
|
||||||
|
highlightLines?: { start: number; end: number } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SourceCodeEditor({
|
export function SourceCodeEditor({
|
||||||
|
|
@ -27,10 +29,40 @@ export function SourceCodeEditor({
|
||||||
readOnly = false,
|
readOnly = false,
|
||||||
fontSize = 12,
|
fontSize = 12,
|
||||||
onSave,
|
onSave,
|
||||||
|
highlightLines = null,
|
||||||
}: SourceCodeEditorProps) {
|
}: SourceCodeEditorProps) {
|
||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
const onSaveRef = useRef(onSave);
|
const onSaveRef = useRef(onSave);
|
||||||
const monacoRef = useRef<any>(null);
|
const monacoRef = useRef<any>(null);
|
||||||
|
const editorRef = useRef<any>(null);
|
||||||
|
const decorationsRef = useRef<any>(null);
|
||||||
|
const highlightLinesRef = useRef(highlightLines);
|
||||||
|
highlightLinesRef.current = highlightLines;
|
||||||
|
|
||||||
|
const applyHighlight = useCallback(() => {
|
||||||
|
const editor = editorRef.current;
|
||||||
|
const monaco = monacoRef.current;
|
||||||
|
if (!editor || !monaco) return;
|
||||||
|
if (decorationsRef.current) {
|
||||||
|
decorationsRef.current.clear();
|
||||||
|
decorationsRef.current = null;
|
||||||
|
}
|
||||||
|
const range = highlightLinesRef.current;
|
||||||
|
if (!range) return;
|
||||||
|
const start = Math.max(1, Math.floor(range.start));
|
||||||
|
const end = Math.max(start, Math.floor(range.end));
|
||||||
|
decorationsRef.current = editor.createDecorationsCollection([
|
||||||
|
{
|
||||||
|
range: new monaco.Range(start, 1, end, 1),
|
||||||
|
options: { isWholeLine: true, className: "citation-line-highlight" },
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
editor.revealLinesInCenter(start, end);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
applyHighlight();
|
||||||
|
}, [applyHighlight, highlightLines?.start, highlightLines?.end]);
|
||||||
const normalizedModelPath = (() => {
|
const normalizedModelPath = (() => {
|
||||||
const raw = (path || "local-file.txt").trim();
|
const raw = (path || "local-file.txt").trim();
|
||||||
const withLeadingSlash = raw.startsWith("/") ? raw : `/${raw}`;
|
const withLeadingSlash = raw.startsWith("/") ? raw : `/${raw}`;
|
||||||
|
|
@ -104,7 +136,10 @@ export function SourceCodeEditor({
|
||||||
}}
|
}}
|
||||||
onMount={(editor, monaco) => {
|
onMount={(editor, monaco) => {
|
||||||
monacoRef.current = monaco;
|
monacoRef.current = monaco;
|
||||||
|
editorRef.current = editor;
|
||||||
applySidebarTheme(monaco);
|
applySidebarTheme(monaco);
|
||||||
|
// Defer one frame so the model is laid out before revealing.
|
||||||
|
requestAnimationFrame(() => applyHighlight());
|
||||||
if (!isManualSaveEnabled) return;
|
if (!isManualSaveEnabled) return;
|
||||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
|
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
|
||||||
void onSaveRef.current?.();
|
void onSaveRef.current?.();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue