add shiki for playground highlighting
This commit is contained in:
parent
48a450c2fb
commit
d5e9ec7dfc
|
@ -18,13 +18,16 @@
|
||||||
"@monaco-editor/react": "^4.6.0",
|
"@monaco-editor/react": "^4.6.0",
|
||||||
"@mui/icons-material": "^5.15.20",
|
"@mui/icons-material": "^5.15.20",
|
||||||
"@mui/material": "^5.15.20",
|
"@mui/material": "^5.15.20",
|
||||||
|
"@shikijs/monaco": "^1.7.0",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"astro": "^4.10.2",
|
"astro": "^4.10.2",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
|
"shiki": "^1.7.0",
|
||||||
"starlight-links-validator": "^0.7.1",
|
"starlight-links-validator": "^0.7.1",
|
||||||
|
"tm-themes": "^1.4.3",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -29,6 +29,9 @@ dependencies:
|
||||||
'@mui/material':
|
'@mui/material':
|
||||||
specifier: ^5.15.20
|
specifier: ^5.15.20
|
||||||
version: 5.15.20(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
|
version: 5.15.20(@emotion/react@11.11.4)(@emotion/styled@11.11.5)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@shikijs/monaco':
|
||||||
|
specifier: ^1.7.0
|
||||||
|
version: 1.7.0
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^18.3.3
|
specifier: ^18.3.3
|
||||||
version: 18.3.3
|
version: 18.3.3
|
||||||
|
@ -47,9 +50,15 @@ dependencies:
|
||||||
sharp:
|
sharp:
|
||||||
specifier: ^0.32.6
|
specifier: ^0.32.6
|
||||||
version: 0.32.6
|
version: 0.32.6
|
||||||
|
shiki:
|
||||||
|
specifier: ^1.7.0
|
||||||
|
version: 1.7.0
|
||||||
starlight-links-validator:
|
starlight-links-validator:
|
||||||
specifier: ^0.7.1
|
specifier: ^0.7.1
|
||||||
version: 0.7.1(@astrojs/starlight@0.24.2)(astro@4.10.2)
|
version: 0.7.1(@astrojs/starlight@0.24.2)(astro@4.10.2)
|
||||||
|
tm-themes:
|
||||||
|
specifier: ^1.4.3
|
||||||
|
version: 1.4.3
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.4.5
|
specifier: ^5.4.5
|
||||||
version: 5.4.5
|
version: 5.4.5
|
||||||
|
@ -141,7 +150,7 @@ packages:
|
||||||
remark-parse: 11.0.0
|
remark-parse: 11.0.0
|
||||||
remark-rehype: 11.1.0
|
remark-rehype: 11.1.0
|
||||||
remark-smartypants: 2.1.0
|
remark-smartypants: 2.1.0
|
||||||
shiki: 1.6.4
|
shiki: 1.7.0
|
||||||
unified: 11.0.4
|
unified: 11.0.4
|
||||||
unist-util-remove-position: 5.0.0
|
unist-util-remove-position: 5.0.0
|
||||||
unist-util-visit: 5.0.0
|
unist-util-visit: 5.0.0
|
||||||
|
@ -1131,7 +1140,7 @@ packages:
|
||||||
resolution: {integrity: sha512-aFQBPepv0zhVXqJFAvfQ4vXYv/meJKiqmEEKSxdjAfwXllIV49PDlnGEXmbGYjR4hUQQjbfDgzAbrbfePc3YVQ==}
|
resolution: {integrity: sha512-aFQBPepv0zhVXqJFAvfQ4vXYv/meJKiqmEEKSxdjAfwXllIV49PDlnGEXmbGYjR4hUQQjbfDgzAbrbfePc3YVQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@expressive-code/core': 0.35.3
|
'@expressive-code/core': 0.35.3
|
||||||
shiki: 1.6.4
|
shiki: 1.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@expressive-code/plugin-text-markers@0.35.3:
|
/@expressive-code/plugin-text-markers@0.35.3:
|
||||||
|
@ -1822,8 +1831,14 @@ packages:
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@shikijs/core@1.6.4:
|
/@shikijs/core@1.7.0:
|
||||||
resolution: {integrity: sha512-WTU9rzZae1p2v6LOxMf6LhtmZOkIHYYW160IuahUyJy7YXPPjyWZLR1ag+SgD22ZMxZtz1gfU6Tccc8t0Il/XA==}
|
resolution: {integrity: sha512-O6j27b7dGmJbR3mjwh/aHH8Ld+GQvA0OQsNO43wKWnqbAae3AYXrhFyScHGX8hXZD6vX2ngjzDFkZY5srtIJbQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@shikijs/monaco@1.7.0:
|
||||||
|
resolution: {integrity: sha512-7wLuwcMhxYShdSOJ0c8z3puiwi0j9EFzCsIDWo8Q4wWc1sX2XrsGg/e4LyydwwydY4Kwc40KDgXBsX/0A211mg==}
|
||||||
|
dependencies:
|
||||||
|
'@shikijs/core': 1.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@types/acorn@4.0.6:
|
/@types/acorn@4.0.6:
|
||||||
|
@ -2210,7 +2225,7 @@ packages:
|
||||||
rehype: 13.0.1
|
rehype: 13.0.1
|
||||||
resolve: 1.22.8
|
resolve: 1.22.8
|
||||||
semver: 7.6.2
|
semver: 7.6.2
|
||||||
shiki: 1.6.4
|
shiki: 1.7.0
|
||||||
string-width: 7.1.0
|
string-width: 7.1.0
|
||||||
strip-ansi: 7.1.0
|
strip-ansi: 7.1.0
|
||||||
tsconfck: 3.1.0(typescript@5.4.5)
|
tsconfck: 3.1.0(typescript@5.4.5)
|
||||||
|
@ -4989,10 +5004,10 @@ packages:
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/shiki@1.6.4:
|
/shiki@1.7.0:
|
||||||
resolution: {integrity: sha512-X88chM7w8jnadoZtjPTi5ahCJx9pc9f8GfEkZAEYUTlcUZIEw2D/RY86HI/LkkE7Nj8TQWkiBfaFTJ3VJT6ESg==}
|
resolution: {integrity: sha512-H5pMn4JA7ayx8H0qOz1k2qANq6mZVCMl1gKLK6kWIrv1s2Ial4EmD4s4jE8QB5Dw03d/oCQUxc24sotuyR5byA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@shikijs/core': 1.6.4
|
'@shikijs/core': 1.7.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/signal-exit@3.0.7:
|
/signal-exit@3.0.7:
|
||||||
|
@ -5246,6 +5261,10 @@ packages:
|
||||||
b4a: 1.6.6
|
b4a: 1.6.6
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/tm-themes@1.4.3:
|
||||||
|
resolution: {integrity: sha512-nsUGwktLaWFMyKw2e/hNyDmcTIO+ue6Q2Mvb8L7WQkKSCflOm2TjGSspcJw6q7hi4QxQQNTuGICyvQN1UqtunQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/to-fast-properties@2.0.0:
|
/to-fast-properties@2.0.0:
|
||||||
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
[pack]
|
||||||
|
name = "my-shulkerscript-pack"
|
||||||
|
description = "A Minecraft datapack created with shulkerscript"
|
||||||
|
format = 48
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[compiler]
|
||||||
|
# assets = "./assets"
|
|
@ -1,10 +1,13 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Editor, { useMonaco, type Monaco } from "@monaco-editor/react";
|
import { useMonaco, type Monaco } from "@monaco-editor/react";
|
||||||
import FileView from "./playground/FileView";
|
import FileView from "./playground/FileView";
|
||||||
|
import Editor from "./playground/Editor";
|
||||||
|
|
||||||
import "@styles/playground.scss";
|
import "@styles/playground.scss";
|
||||||
|
|
||||||
import mainFileContent from "@assets/playground/main.shu?raw";
|
import mainFileContent from "@assets/playground/main.shu?raw";
|
||||||
|
import packTomlContent from "@assets/playground/pack.toml?raw";
|
||||||
|
|
||||||
import Header from "./playground/Header";
|
import Header from "./playground/Header";
|
||||||
|
|
||||||
export type File = {
|
export type File = {
|
||||||
|
@ -24,13 +27,22 @@ export default function Playground() {
|
||||||
files: {
|
files: {
|
||||||
"main.shu": {
|
"main.shu": {
|
||||||
content: mainFileContent,
|
content: mainFileContent,
|
||||||
|
language: "shulkerscript",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
"test.mcfunction": {
|
||||||
|
content: "",
|
||||||
|
language: "mcfunction",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
files: {
|
files: {
|
||||||
"pack.toml": {
|
"pack.toml": {
|
||||||
content: "pack.toml content",
|
content: packTomlContent,
|
||||||
language: "toml",
|
language: "toml",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -63,15 +75,7 @@ export default function Playground() {
|
||||||
fileName={fileName}
|
fileName={fileName}
|
||||||
setSelectedFileName={setFileName}
|
setSelectedFileName={setFileName}
|
||||||
/>
|
/>
|
||||||
<div className="editor">
|
<Editor fileName={fileName} file={file} />
|
||||||
<Editor
|
|
||||||
height="60vh"
|
|
||||||
theme="vs-dark"
|
|
||||||
path={fileName}
|
|
||||||
defaultLanguage={file.language}
|
|
||||||
defaultValue={file.content}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import type { File } from "@components/Playground";
|
||||||
|
import MonacoEditor, { useMonaco } from "@monaco-editor/react";
|
||||||
|
import { getHighlighter, type Highlighter } from "shiki";
|
||||||
|
import { shikiToMonaco } from "@shikijs/monaco";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import darkPlus from "tm-themes/themes/dark-plus.json";
|
||||||
|
|
||||||
|
import { shulkerscriptGrammar } from "@utils/shulkerscript-grammar";
|
||||||
|
import { mcfunctionGrammar } from "@utils/mcfunction-grammar";
|
||||||
|
|
||||||
|
export default function Editor({
|
||||||
|
fileName,
|
||||||
|
file,
|
||||||
|
}: {
|
||||||
|
fileName: string;
|
||||||
|
file: File;
|
||||||
|
}) {
|
||||||
|
const [highlighter, setHighlighter] = useState<Highlighter | null>(null);
|
||||||
|
|
||||||
|
const monaco = useMonaco();
|
||||||
|
useEffect(() => {
|
||||||
|
if (monaco) {
|
||||||
|
if (highlighter == null) {
|
||||||
|
getHighlighter({
|
||||||
|
themes: [darkPlus as any],
|
||||||
|
langs: ["toml", shulkerscriptGrammar, mcfunctionGrammar],
|
||||||
|
}).then((highlighter) => {
|
||||||
|
setHighlighter(highlighter);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
shikiToMonaco(highlighter, monaco);
|
||||||
|
}
|
||||||
|
|
||||||
|
monaco.languages.register({ id: "toml" });
|
||||||
|
monaco.languages.register({ id: "shulkerscript" });
|
||||||
|
monaco.languages.register({ id: "mcfunction" });
|
||||||
|
}
|
||||||
|
}, [monaco]);
|
||||||
|
useEffect(() => {
|
||||||
|
if (highlighter != null) {
|
||||||
|
shikiToMonaco(highlighter, monaco);
|
||||||
|
}
|
||||||
|
}, [highlighter]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="editor">
|
||||||
|
<MonacoEditor
|
||||||
|
height="70vh"
|
||||||
|
theme="vs-dark"
|
||||||
|
path={fileName}
|
||||||
|
defaultLanguage={file.language}
|
||||||
|
defaultValue={file.content}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -90,11 +90,11 @@ function DirElement({
|
||||||
([dirname, dir]) => {
|
([dirname, dir]) => {
|
||||||
return (
|
return (
|
||||||
<DirElement
|
<DirElement
|
||||||
key={name}
|
key={dirname}
|
||||||
name={name}
|
name={dirname}
|
||||||
dir={dir}
|
dir={dir}
|
||||||
fileName={fileName.slice(
|
fileName={fileName.slice(
|
||||||
name.length + 1
|
dirname.length + 1
|
||||||
)}
|
)}
|
||||||
setSelectedFileName={
|
setSelectedFileName={
|
||||||
modSetSelectedFileName
|
modSetSelectedFileName
|
||||||
|
@ -107,8 +107,8 @@ function DirElement({
|
||||||
([currentName, _]) => {
|
([currentName, _]) => {
|
||||||
return (
|
return (
|
||||||
<FileElement
|
<FileElement
|
||||||
key={name}
|
key={currentName}
|
||||||
name={name}
|
name={currentName}
|
||||||
disabled={fileName == currentName}
|
disabled={fileName == currentName}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
modSetSelectedFileName(currentName)
|
modSetSelectedFileName(currentName)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.playground {
|
.playground {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 4fr;
|
grid-template-columns: clamp(100px, 15%, 400px) auto;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"header header"
|
"header header"
|
||||||
"files editor";
|
"files editor";
|
||||||
|
|
|
@ -15,4 +15,17 @@ export const customTheme = createTheme({
|
||||||
contrastText: '#000',
|
contrastText: '#000',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
typography: {
|
||||||
|
fontFamily: [
|
||||||
|
'-apple-system',
|
||||||
|
'BlinkMacSystemFont',
|
||||||
|
'"Segoe UI"',
|
||||||
|
'"Helvetica Neue"',
|
||||||
|
'Arial',
|
||||||
|
'sans-serif',
|
||||||
|
'"Apple Color Emoji"',
|
||||||
|
'"Segoe UI Emoji"',
|
||||||
|
'"Segoe UI Symbol"',
|
||||||
|
].join(','),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,11 @@
|
||||||
import type { PluginShikiOptions } from "@astrojs/starlight/expressive-code";
|
import type { PluginShikiOptions } from "@astrojs/starlight/expressive-code";
|
||||||
import { shulkerscriptGrammar } from "./shulkerscript-grammar";
|
import { shulkerscriptGrammar } from "./shulkerscript-grammar";
|
||||||
|
import { mcfunctionGrammar } from "./mcfunction-grammar";
|
||||||
|
|
||||||
const config: PluginShikiOptions = {
|
const config: PluginShikiOptions = {
|
||||||
langs: [
|
langs: [
|
||||||
shulkerscriptGrammar,
|
shulkerscriptGrammar,
|
||||||
|
mcfunctionGrammar,
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
import type { LanguageInput } from "shiki";
|
||||||
|
|
||||||
export const shulkerscriptGrammar = {
|
export const shulkerscriptGrammar: LanguageInput = {
|
||||||
name: "shulkerscript",
|
name: "shulkerscript",
|
||||||
aliases: ["shu"],
|
aliases: ["shu"],
|
||||||
displayName: "ShulkerScript",
|
displayName: "ShulkerScript",
|
||||||
|
@ -23,6 +24,8 @@ export const shulkerscriptGrammar = {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
repository: {
|
repository: {
|
||||||
|
"$base": {},
|
||||||
|
"$self": {},
|
||||||
// Groupings
|
// Groupings
|
||||||
functionContents: {
|
functionContents: {
|
||||||
patterns: [
|
patterns: [
|
||||||
|
|
Loading…
Reference in New Issue