mirror of
https://github.com/massbug/judge4c.git
synced 2025-05-17 23:12:23 +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 { useProblem } from "@/hooks/use-problem";
|
||||
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";
|
||||
|
||||
// Dynamically import Monaco Editor with SSR disabled
|
||||
@ -25,14 +28,81 @@ const Editor = dynamic(
|
||||
);
|
||||
|
||||
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) => {
|
||||
shikiToMonaco(highlighter, monaco);
|
||||
};
|
||||
|
||||
const handleOnMount = (editor: editor.IStandaloneCodeEditor) => {
|
||||
const handleOnMount = async (editor: editor.IStandaloneCodeEditor) => {
|
||||
setEditor(editor);
|
||||
await connectLSP();
|
||||
};
|
||||
|
||||
const handleOnChange = (value: string | undefined) => {
|
||||
|
Loading…
Reference in New Issue
Block a user