112 lines
3.3 KiB
JavaScript
112 lines
3.3 KiB
JavaScript
import MonacoEditor from "@monaco-editor/react";
|
|
import {
|
|
createConnection,
|
|
MonacoLanguageClient,
|
|
MonacoServices,
|
|
Services,
|
|
} from "monaco-languageclient";
|
|
import React from "react";
|
|
import { createMessageConnection } from "vscode-jsonrpc";
|
|
import RijuMessageReader from "../services/RijuMessageReader";
|
|
import RijuMessageWriter from "../services/RijuMessageWriter";
|
|
import { EventEmitter } from "../utils/EventEmitter";
|
|
|
|
let clientDisposable = null;
|
|
let servicesDisposable = null;
|
|
|
|
const RijuEditor = (props) => {
|
|
const { onEditorValueChange, config, splitType, onEditorMount } = props;
|
|
const editorRef = React.useRef();
|
|
const monacoRef = React.useRef();
|
|
|
|
React.useEffect(() => {
|
|
EventEmitter.subscribe("lspStarted", (data) => {
|
|
const { message, socket } = data;
|
|
initLSP(socket, message, monacoRef.current, editorRef.current);
|
|
});
|
|
EventEmitter.subscribe("lspStopped", () => {
|
|
if (clientDisposable) {
|
|
clientDisposable.dispose();
|
|
clientDisposable = null;
|
|
}
|
|
if (servicesDisposable) {
|
|
servicesDisposable.dispose();
|
|
servicesDisposable = null;
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
const initLSP = (socket, message, monaco, editor) => {
|
|
const services = MonacoServices.create(editor, {
|
|
rootUri: `file://${message.root}`,
|
|
});
|
|
servicesDisposable = Services.install(services);
|
|
const newURI = `file://${message.root}/${config.main}`;
|
|
const oldModel = editor.getModel();
|
|
if (oldModel.uri.toString() !== newURI) {
|
|
// This code is likely to be buggy as it will probably
|
|
// never run and has thus never been tested.
|
|
editor.setModel(
|
|
monaco.editor.createModel(
|
|
oldModel.getValue(),
|
|
undefined,
|
|
monaco.Uri.parse(newURI)
|
|
)
|
|
);
|
|
oldModel.dispose();
|
|
}
|
|
|
|
const connection = createMessageConnection(
|
|
new RijuMessageReader(socket),
|
|
new RijuMessageWriter(socket, config)
|
|
);
|
|
const client = new MonacoLanguageClient({
|
|
name: "Riju",
|
|
clientOptions: {
|
|
documentSelector: [{ pattern: "**" }],
|
|
middleware: {
|
|
workspace: {
|
|
configuration: (params, token, configuration) => {
|
|
return Array(configuration(params, token).length).fill(
|
|
config.lsp.config !== undefined ? config.lsp.config : {}
|
|
);
|
|
},
|
|
},
|
|
},
|
|
initializationOptions: config.lsp.init || {},
|
|
},
|
|
connectionProvider: {
|
|
get: (errorHandler, closeHandler) =>
|
|
Promise.resolve(
|
|
createConnection(connection, errorHandler, closeHandler)
|
|
),
|
|
},
|
|
});
|
|
clientDisposable = client.start();
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<MonacoEditor
|
|
wrapperClassName={"rijuEditor"}
|
|
onChange={onEditorValueChange}
|
|
language={config.monacoLang || "plaintext"}
|
|
value={config.template + "\n"}
|
|
options={{
|
|
minimap: { enabled: splitType == "horizontal" ? false : true },
|
|
scrollbar: { verticalScrollbarSize: 0 },
|
|
fontLigatures: true,
|
|
fontFamily: "Fira Code",
|
|
}}
|
|
onMount={(editor, monaco) => {
|
|
editorRef.current = editor;
|
|
monacoRef.current = monaco;
|
|
if (onEditorMount) onEditorMount(editor, monaco);
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default RijuEditor;
|