mirror of
https://github.com/massbug/judge4c.git
synced 2025-05-18 07:16:34 +00:00
feat(problem-editor): add LSP support and language client connection
This commit is contained in:
parent
becb48f4d7
commit
4842c9302c
@ -7,6 +7,9 @@ import { Loading } from "@/components/loading";
|
|||||||
import { shikiToMonaco } from "@shikijs/monaco";
|
import { shikiToMonaco } from "@shikijs/monaco";
|
||||||
import { useProblem } from "@/hooks/use-problem";
|
import { useProblem } from "@/hooks/use-problem";
|
||||||
import type { Monaco } from "@monaco-editor/react";
|
import type { Monaco } from "@monaco-editor/react";
|
||||||
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
|
import { connectToLanguageServer } from "@/lib/language-server";
|
||||||
|
import type { MonacoLanguageClient } from "monaco-languageclient";
|
||||||
import { DefaultEditorOptionConfig } from "@/config/editor-option";
|
import { DefaultEditorOptionConfig } from "@/config/editor-option";
|
||||||
|
|
||||||
// Dynamically import Monaco Editor with SSR disabled
|
// Dynamically import Monaco Editor with SSR disabled
|
||||||
@ -25,14 +28,81 @@ const Editor = dynamic(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export function CodeEditor() {
|
export function CodeEditor() {
|
||||||
const { setEditor, currentLang, currentPath, currentTheme, currentValue, changeValue } = useProblem();
|
const {
|
||||||
|
hydrated,
|
||||||
|
editor,
|
||||||
|
setEditor,
|
||||||
|
setMonacoLanguageClient,
|
||||||
|
currentLang,
|
||||||
|
currentPath,
|
||||||
|
currentTheme,
|
||||||
|
currentValue,
|
||||||
|
changeValue,
|
||||||
|
currentEditorLanguageConfig,
|
||||||
|
currentLanguageServerConfig,
|
||||||
|
} = useProblem();
|
||||||
|
|
||||||
|
const monacoLanguageClientRef = useRef<MonacoLanguageClient | null>(null);
|
||||||
|
|
||||||
|
// Connect to LSP only if enabled
|
||||||
|
const connectLSP = useCallback(async () => {
|
||||||
|
if (!(currentLang && editor)) return;
|
||||||
|
|
||||||
|
// If there's an existing language client, stop it first
|
||||||
|
if (monacoLanguageClientRef.current) {
|
||||||
|
monacoLanguageClientRef.current.stop();
|
||||||
|
monacoLanguageClientRef.current = null;
|
||||||
|
setMonacoLanguageClient(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentEditorLanguageConfig || !currentLanguageServerConfig) return;
|
||||||
|
|
||||||
|
// Create a new language client
|
||||||
|
try {
|
||||||
|
const monacoLanguageClient = await connectToLanguageServer(
|
||||||
|
currentEditorLanguageConfig,
|
||||||
|
currentLanguageServerConfig,
|
||||||
|
);
|
||||||
|
monacoLanguageClientRef.current = monacoLanguageClient;
|
||||||
|
setMonacoLanguageClient(monacoLanguageClient);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to connect to LSP:", error);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
currentEditorLanguageConfig,
|
||||||
|
currentLang,
|
||||||
|
currentLanguageServerConfig,
|
||||||
|
editor,
|
||||||
|
setMonacoLanguageClient,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Reconnect to the LSP whenever language or lspConfig changes
|
||||||
|
useEffect(() => {
|
||||||
|
connectLSP();
|
||||||
|
}, [connectLSP]);
|
||||||
|
|
||||||
|
// Cleanup the LSP connection when the component unmounts
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (monacoLanguageClientRef.current) {
|
||||||
|
monacoLanguageClientRef.current.stop();
|
||||||
|
monacoLanguageClientRef.current = null;
|
||||||
|
setMonacoLanguageClient(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [setMonacoLanguageClient]);
|
||||||
|
|
||||||
|
if (!hydrated) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
|
||||||
const handleBeforeMount = (monaco: Monaco) => {
|
const handleBeforeMount = (monaco: Monaco) => {
|
||||||
shikiToMonaco(highlighter, monaco);
|
shikiToMonaco(highlighter, monaco);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnMount = (editor: editor.IStandaloneCodeEditor) => {
|
const handleOnMount = async (editor: editor.IStandaloneCodeEditor) => {
|
||||||
setEditor(editor);
|
setEditor(editor);
|
||||||
|
await connectLSP();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnChange = (value: string | undefined) => {
|
const handleOnChange = (value: string | undefined) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user