mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-05 22:48:48 +00:00
Fix Monaco editor syntax highlighting in Preview block (#2459)
The Preview block's CodeEditPreview component was not passing file information to Monaco editor, preventing automatic language detection from file extensions. Changes: - Add fileName prop to CodeEditor component - Pass actual file path to Monaco with fallback to random UUID Fixes syntax highlighting for all text files opened in Preview blocks while maintaining backward compatibility with existing CodeEditor usage. --------- Co-authored-by: sawka
This commit is contained in:
parent
ae42e2ccce
commit
6bfb9e650a
4 changed files with 66 additions and 6 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2025, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { useCallback, useLayoutEffect, useState } from "react";
|
||||
import { useCallback, useLayoutEffect, useRef, useState } from "react";
|
||||
import { FakeBlock } from "./onboarding-layout";
|
||||
import waveLogo from "/logos/wave-logo.png";
|
||||
|
||||
|
|
@ -114,6 +114,7 @@ export const ViewLogoCommand = ({ onComplete }: { onComplete?: () => void }) =>
|
|||
};
|
||||
|
||||
export const EditBashrcCommand = ({ onComplete }: { onComplete?: () => void }) => {
|
||||
const fileNameRef = useRef(`${crypto.randomUUID()}/.bashrc`);
|
||||
const bashrcContent = `# Aliases
|
||||
alias ll="ls -lah"
|
||||
alias gst="git status"
|
||||
|
|
@ -127,7 +128,13 @@ export PATH="$HOME/.local/bin:$PATH"`;
|
|||
|
||||
return (
|
||||
<FakeCommand command="wsh edit ~/.bashrc" onComplete={onComplete}>
|
||||
<FakeBlock icon="file-lines" name=".bashrc" editorText={bashrcContent} />
|
||||
<FakeBlock
|
||||
icon="file-lines"
|
||||
name=".bashrc"
|
||||
editorText={bashrcContent}
|
||||
editorFileName={fileNameRef.current}
|
||||
editorLanguage="shell"
|
||||
/>
|
||||
</FakeCommand>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,9 +15,21 @@ export type FakeBlockProps = {
|
|||
markdown?: string;
|
||||
imgsrc?: string;
|
||||
editorText?: string;
|
||||
editorFileName?: string;
|
||||
editorLanguage?: string;
|
||||
};
|
||||
|
||||
export const FakeBlock = ({ icon, name, highlighted, className, markdown, imgsrc, editorText }: FakeBlockProps) => {
|
||||
export const FakeBlock = ({
|
||||
icon,
|
||||
name,
|
||||
highlighted,
|
||||
className,
|
||||
markdown,
|
||||
imgsrc,
|
||||
editorText,
|
||||
editorFileName,
|
||||
editorLanguage,
|
||||
}: FakeBlockProps) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
|
|
@ -37,7 +49,13 @@ export const FakeBlock = ({ icon, name, highlighted, className, markdown, imgsrc
|
|||
<div className="flex-1 flex items-center justify-center overflow-auto p-4">
|
||||
{editorText ? (
|
||||
<div className="w-full h-full">
|
||||
<CodeEditor blockId="fake-block" text={editorText} readonly={true} language="shell" />
|
||||
<CodeEditor
|
||||
blockId="fake-block"
|
||||
text={editorText}
|
||||
readonly={true}
|
||||
fileName={editorFileName}
|
||||
language={editorLanguage ?? "shell"}
|
||||
/>
|
||||
</div>
|
||||
) : imgsrc ? (
|
||||
<img src={imgsrc} alt={name} className="max-w-full max-h-full object-contain" />
|
||||
|
|
|
|||
|
|
@ -108,11 +108,12 @@ interface CodeEditorProps {
|
|||
text: string;
|
||||
readonly: boolean;
|
||||
language?: string;
|
||||
fileName?: string;
|
||||
onChange?: (text: string) => void;
|
||||
onMount?: (monacoPtr: MonacoTypes.editor.IStandaloneCodeEditor, monaco: Monaco) => () => void;
|
||||
}
|
||||
|
||||
export function CodeEditor({ blockId, text, language, readonly, onChange, onMount }: CodeEditorProps) {
|
||||
export function CodeEditor({ blockId, text, language, fileName, readonly, onChange, onMount }: CodeEditorProps) {
|
||||
const divRef = useRef<HTMLDivElement>(null);
|
||||
const unmountRef = useRef<() => void>(null);
|
||||
const minimapEnabled = useOverrideConfigAtom(blockId, "editor:minimapenabled") ?? false;
|
||||
|
|
@ -120,7 +121,14 @@ export function CodeEditor({ blockId, text, language, readonly, onChange, onMoun
|
|||
const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false;
|
||||
const fontSize = boundNumber(useOverrideConfigAtom(blockId, "editor:fontsize"), 6, 64);
|
||||
const theme = "wave-theme-dark";
|
||||
const editorPath = useRef(crypto.randomUUID()).current;
|
||||
const uuidRef = useRef(crypto.randomUUID()).current;
|
||||
let editorPath: string;
|
||||
if (fileName) {
|
||||
const separator = fileName.startsWith("/") ? "" : "/";
|
||||
editorPath = blockId + separator + fileName;
|
||||
} else {
|
||||
editorPath = uuidRef;
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
|
|
|
|||
|
|
@ -12,10 +12,35 @@ import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
|||
import { useEffect } from "react";
|
||||
import type { SpecializedViewProps } from "./preview";
|
||||
|
||||
export const shellFileMap: Record<string, string> = {
|
||||
".bashrc": "shell",
|
||||
".bash_profile": "shell",
|
||||
".bash_login": "shell",
|
||||
".bash_logout": "shell",
|
||||
".profile": "shell",
|
||||
".zshrc": "shell",
|
||||
".zprofile": "shell",
|
||||
".zlogin": "shell",
|
||||
".zlogout": "shell",
|
||||
".kshrc": "shell",
|
||||
".cshrc": "shell",
|
||||
".tcshrc": "shell",
|
||||
".xonshrc": "python",
|
||||
".shrc": "shell",
|
||||
".aliases": "shell",
|
||||
".functions": "shell",
|
||||
".exports": "shell",
|
||||
".direnvrc": "shell",
|
||||
};
|
||||
|
||||
function CodeEditPreview({ model }: SpecializedViewProps) {
|
||||
const fileContent = useAtomValue(model.fileContent);
|
||||
const setNewFileContent = useSetAtom(model.newFileContent);
|
||||
const fileInfo = useAtomValue(model.statFile);
|
||||
const fileName = fileInfo?.path || fileInfo?.name;
|
||||
|
||||
const baseName = fileName ? fileName.split("/").pop() : null;
|
||||
const language = baseName && shellFileMap[baseName] ? shellFileMap[baseName] : undefined;
|
||||
|
||||
function codeEditKeyDownHandler(e: WaveKeyboardEvent): boolean {
|
||||
if (checkKeyPressed(e, "Cmd:e")) {
|
||||
|
|
@ -65,6 +90,8 @@ function CodeEditPreview({ model }: SpecializedViewProps) {
|
|||
<CodeEditor
|
||||
blockId={model.blockId}
|
||||
text={fileContent}
|
||||
fileName={fileName}
|
||||
language={language}
|
||||
readonly={fileInfo.readonly}
|
||||
onChange={(text) => setNewFileContent(text)}
|
||||
onMount={onMount}
|
||||
|
|
|
|||
Loading…
Reference in a new issue