yaml syntax highligting

This commit is contained in:
Nate Kelley 2025-01-14 12:37:59 -07:00
parent d893eee231
commit 3104cace3c
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
8 changed files with 997 additions and 32 deletions

900
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -66,6 +66,7 @@
"material-symbols": "^0.27.2",
"monaco-sql-languages": "^0.12.2",
"monaco-themes": "^0.4.4",
"monaco-yaml": "^5.2.3",
"next": "14.2.22",
"next-themes": "^0.4.4",
"next-transpile-modules": "^10.0.1",
@ -119,6 +120,7 @@
"eslint-config-next": "14.2.3",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"monaco-editor-webpack-plugin": "^7.1.0",
"postcss": "~8",
"sass": "^1.83.1",
"tailwindcss": "^3.4.17",

View File

@ -1,4 +1,3 @@
import { BusterDataset } from '@/api/busterv2/datasets';
import { AppCodeEditor } from '@/components/inputs/AppCodeEditor';
import { createStyles } from 'antd-style';
import React from 'react';
@ -11,7 +10,12 @@ export const MetadataContainer: React.FC<{
return (
<div className={cx(styles.container, 'flex h-full w-full flex-col overflow-hidden')}>
<AppCodeEditor className="overflow-hidden" value={ymlFile} onChange={setYmlFile} />
<AppCodeEditor
language="yaml"
className="overflow-hidden"
value={ymlFile}
onChange={setYmlFile}
/>
</div>
);
});

View File

@ -12,6 +12,9 @@ import { createStyles } from 'antd-style';
import { motion } from 'framer-motion';
import { useMemoizedFn } from 'ahooks';
import './MonacoWebWorker';
import { configureMonacoToUseYaml } from './yamlHelper';
//import GithubLightTheme from 'monaco-themes/themes/Github Light.json';
//import NightOwnTheme from 'monaco-themes/themes/Night Owl.json';
//https://github.com/brijeshb42/monaco-ace-tokenizer
@ -120,8 +123,15 @@ export const AppCodeEditor = forwardRef<AppCodeEditorHandle, AppCodeEditorProps>
(await import('./Github_light')).default,
(await import('./Tomorrow-Night')).default
]);
monaco.editor.defineTheme('github-light', GithubLightTheme as any);
monaco.editor.defineTheme('night-owl', NightOwlTheme as any);
if (language === 'yaml') {
console.log('loading yaml');
await configureMonacoToUseYaml(monaco);
console.log('yaml loaded');
}
monaco.editor.defineTheme('github-light', GithubLightTheme);
monaco.editor.defineTheme('night-owl', NightOwlTheme);
editor.updateOptions({
theme: useDarkMode ? 'night-owl' : 'github-light'
});
@ -139,6 +149,14 @@ export const AppCodeEditor = forwardRef<AppCodeEditorHandle, AppCodeEditorProps>
setIsLoading(false);
hasLoadedDynamicEditor = true;
// Add this to see how Monaco is tokenizing the text
editor.onDidChangeModelContent(() => {
const model = editor.getModel();
if (model) {
console.log(monaco.editor.tokenize(model.getValue(), 'yaml'));
}
});
}
);

View File

@ -1,9 +1,10 @@
import tailwind from '../../../../tailwind.config';
import type { editor } from 'monaco-editor';
const colors = tailwind.theme.extend.colors;
const editorBackground = '#ffffff';
const theme = {
const theme: editor.IStandaloneThemeData = {
base: 'vs',
inherit: true,
rules: [
@ -336,7 +337,14 @@ const theme = {
foreground: '032f62',
fontStyle: 'underline',
token: 'string.other.link'
}
},
{
foreground: '24292e',
token: 'string.yaml'
},
{ foreground: colors.buster.primary, token: 'type' },
{ foreground: '24292e', token: 'keyword.yaml' }, //booleans
{ foreground: 'b31d28', token: 'number.yaml' }
],
colors: {
'editor.foreground': '#24292e',

View File

@ -0,0 +1,37 @@
import { isServer } from '@tanstack/react-query';
if (!isServer && typeof window !== 'undefined') {
window.MonacoEnvironment = {
getWorker(moduleId, label) {
switch (label) {
case 'editorWorkerService':
return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url));
case 'css':
case 'less':
case 'scss':
return new Worker(
new URL('monaco-editor/esm/vs/language/css/css.worker', import.meta.url)
);
case 'handlebars':
case 'html':
case 'razor':
return new Worker(
new URL('monaco-editor/esm/vs/language/html/html.worker', import.meta.url)
);
case 'json':
return new Worker(
new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url)
);
case 'javascript':
case 'typescript':
return new Worker(
new URL('monaco-editor/esm/vs/language/typescript/ts.worker', import.meta.url)
);
case 'yaml':
return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url));
default:
throw new Error(`Unknown label ${label}`);
}
}
};
}

View File

@ -1,4 +1,6 @@
const theme = {
import type { editor } from 'monaco-editor';
const theme: editor.IStandaloneThemeData = {
inherit: true,
base: 'vs-dark',
rules: [
@ -339,6 +341,12 @@ const theme = {
token: 'storage'
}
],
colors: {
'editor.foreground': '#DCDCAA',
'editor.background': '#1E1E1E',
'editorCursor.foreground': '#DCDCAA',
'editorWhitespace.foreground': '#DCDCAA'
},
encodedTokensColors: []
};

View File

@ -0,0 +1,38 @@
export const configureMonacoToUseYaml = async (monaco: typeof import('monaco-editor')) => {
const { configureMonacoYaml } = await import('monaco-yaml');
configureMonacoYaml(monaco, {
enableSchemaRequest: true,
schemas: [
{
// If YAML file is opened matching this glob
fileMatch: ['**/.prettierrc.*'],
// Then this schema will be downloaded from the internet and used.
uri: 'https://json.schemastore.org/prettierrc.json'
},
{
// If YAML file is opened matching this glob
fileMatch: ['**/person.yaml'],
// The following schema will be applied
schema: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'The persons display name'
},
age: {
type: 'integer',
description: 'How old is the person in years?'
},
occupation: {
enum: ['Delivery person', 'Software engineer', 'Astronaut']
}
}
},
// And the URI will be linked to as the source.
uri: 'https://github.com/remcohaszing/monaco-yaml#usage'
}
]
});
};