mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-12 01:01:50 +01:00
This change passes the file name to monaco, so it can use its own detection to determine highlighting of supported files. It also resolves some of the mimetypes with more common use cases for a terminal.
128 lines
3.8 KiB
TypeScript
128 lines
3.8 KiB
TypeScript
// Copyright 2024, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import "./codeedit.less";
|
|
|
|
import { globalStore } from "@/store/global";
|
|
import loader from "@monaco-editor/loader";
|
|
import { Editor, Monaco } from "@monaco-editor/react";
|
|
import * as jotai from "jotai";
|
|
import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
|
import * as React from "react";
|
|
|
|
// there is a global monaco variable (TODO get the correct TS type)
|
|
declare var monaco: Monaco;
|
|
let monacoLoadedAtom = jotai.atom(false);
|
|
|
|
function loadMonaco() {
|
|
loader.config({ paths: { vs: "./monaco" } });
|
|
loader
|
|
.init()
|
|
.then(() => {
|
|
monaco.editor.defineTheme("wave-theme-dark", {
|
|
base: "hc-black",
|
|
inherit: true,
|
|
rules: [],
|
|
colors: {
|
|
"editor.background": "#000000",
|
|
},
|
|
});
|
|
monaco.editor.defineTheme("wave-theme-light", {
|
|
base: "hc-light",
|
|
inherit: true,
|
|
rules: [],
|
|
colors: {
|
|
"editor.background": "#fefefe",
|
|
},
|
|
});
|
|
globalStore.set(monacoLoadedAtom, true);
|
|
console.log("monaco loaded", monaco);
|
|
})
|
|
.catch((e) => {
|
|
console.error("error loading monaco", e);
|
|
});
|
|
}
|
|
|
|
// TODO: need to update these on theme change (pull from CSS vars)
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
setTimeout(loadMonaco, 30);
|
|
});
|
|
|
|
function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions {
|
|
const opts: MonacoTypes.editor.IEditorOptions = {
|
|
scrollBeyondLastLine: false,
|
|
fontSize: 12,
|
|
fontFamily: "Hack",
|
|
};
|
|
return opts;
|
|
}
|
|
|
|
interface CodeEditProps {
|
|
readonly?: boolean;
|
|
text: string;
|
|
language?: string;
|
|
filename: string;
|
|
}
|
|
|
|
export function CodeEdit({ readonly = false, text, language, filename }: CodeEditProps) {
|
|
const divRef = React.useRef<HTMLDivElement>(null);
|
|
const monacoRef = React.useRef<MonacoTypes.editor.IStandaloneCodeEditor | null>(null);
|
|
const theme = "wave-theme-dark";
|
|
const [divDims, setDivDims] = React.useState(null);
|
|
const monacoLoaded = jotai.useAtomValue(monacoLoadedAtom);
|
|
|
|
React.useEffect(() => {
|
|
if (!divRef.current) {
|
|
return;
|
|
}
|
|
const height = divRef.current.clientHeight;
|
|
const width = divRef.current.clientWidth;
|
|
setDivDims({ height, width });
|
|
}, [divRef.current]);
|
|
|
|
function handleEditorMount(editor: MonacoTypes.editor.IStandaloneCodeEditor) {
|
|
monacoRef.current = editor;
|
|
const monacoModel = editor.getModel();
|
|
//monaco.editor.setModelLanguage(monacoModel, "text/markdown");
|
|
}
|
|
|
|
function handleEditorChange(newText: string, ev: MonacoTypes.editor.IModelContentChangedEvent) {
|
|
// TODO
|
|
}
|
|
|
|
const editorOpts = defaultEditorOptions();
|
|
editorOpts.readOnly = readonly;
|
|
|
|
return (
|
|
<div className="codeedit" ref={divRef}>
|
|
{divDims != null && monacoLoaded ? (
|
|
<Editor
|
|
theme={theme}
|
|
height={divDims.height}
|
|
value={text}
|
|
onMount={handleEditorMount}
|
|
options={editorOpts}
|
|
onChange={handleEditorChange}
|
|
path={filename}
|
|
language={language}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface CodeEditViewProps {
|
|
readonly?: boolean;
|
|
text: string;
|
|
language?: string;
|
|
filename?: string;
|
|
}
|
|
|
|
export function CodeEditView({ readonly, text, language, filename }: CodeEditViewProps) {
|
|
return (
|
|
<div className="view-codeedit">
|
|
<CodeEdit readonly={readonly} text={text} language={language} filename={filename} />
|
|
</div>
|
|
);
|
|
}
|