playground: Add AST/Tokens/Formatter panels (#5859)

This commit is contained in:
Micha Reiser 2023-07-19 16:46:08 +02:00 committed by GitHub
parent 9ed7ceeb0a
commit 46a17d11f3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 1343 additions and 780 deletions

1
Cargo.lock generated
View file

@ -2252,6 +2252,7 @@ dependencies = [
"ruff",
"ruff_diagnostics",
"ruff_python_ast",
"ruff_python_formatter",
"ruff_rustpython",
"rustpython-parser",
"serde",

View file

@ -38,7 +38,7 @@ mod source_code;
use crate::formatter::Formatter;
use crate::group_id::UniqueGroupIdBuilder;
use crate::prelude::TagKind;
use std::fmt::Debug;
use std::fmt::{Debug, Display};
use std::marker::PhantomData;
use crate::format_element::document::Document;
@ -331,6 +331,16 @@ where
Ok(printed)
}
}
impl<Context> Display for Formatted<Context>
where
Context: FormatContext,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.document.display(self.context.source_code()), f)
}
}
pub type PrintResult<T> = Result<T, PrintError>;
#[derive(Debug, Clone, Eq, PartialEq)]

View file

@ -21,6 +21,7 @@ default = ["console_error_panic_hook"]
ruff = { path = "../ruff" }
ruff_diagnostics = { path = "../ruff_diagnostics" }
ruff_python_ast = { path = "../ruff_python_ast" }
ruff_python_formatter = { path = "../ruff_python_formatter" }
ruff_rustpython = { path = "../ruff_rustpython" }
console_error_panic_hook = { version = "0.1.7", optional = true }
@ -30,7 +31,7 @@ rustpython-parser = { workspace = true }
serde = { workspace = true }
serde-wasm-bindgen = { version = "0.5.0" }
wasm-bindgen = { version = "0.2.84" }
js-sys = { version = "0.3.61" }
[dev-dependencies]
js-sys = { version = "0.3.61" }
wasm-bindgen-test = { version = "0.3.34" }

View file

@ -1,6 +1,9 @@
use std::path::Path;
use js_sys::Error;
use rustpython_parser::lexer::LexResult;
use rustpython_parser::{parse_tokens, Mode};
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
@ -18,7 +21,10 @@ use ruff::rules::{
use ruff::settings::configuration::Configuration;
use ruff::settings::options::Options;
use ruff::settings::{defaults, flags, Settings};
use ruff_python_ast::source_code::{Indexer, Locator, SourceLocation, Stylist};
use ruff_python_ast::source_code::{
CommentRangesBuilder, Indexer, Locator, SourceLocation, Stylist,
};
use ruff_python_formatter::{format_module, format_node, PyFormatOptions};
#[wasm_bindgen(typescript_custom_section)]
const TYPES: &'static str = r#"
@ -89,157 +95,213 @@ pub fn run() {
}
#[wasm_bindgen]
#[allow(non_snake_case)]
pub fn currentVersion() -> JsValue {
JsValue::from(ruff::VERSION)
pub struct Workspace {
settings: Settings,
}
#[wasm_bindgen]
#[allow(non_snake_case)]
pub fn defaultSettings() -> Result<JsValue, JsValue> {
Ok(serde_wasm_bindgen::to_value(&Options {
// Propagate defaults.
allowed_confusables: Some(Vec::default()),
builtins: Some(Vec::default()),
dummy_variable_rgx: Some(defaults::DUMMY_VARIABLE_RGX.as_str().to_string()),
extend_fixable: Some(Vec::default()),
extend_ignore: Some(Vec::default()),
extend_select: Some(Vec::default()),
extend_unfixable: Some(Vec::default()),
external: Some(Vec::default()),
ignore: Some(Vec::default()),
line_length: Some(LineLength::default()),
tab_size: Some(TabSize::default()),
select: Some(defaults::PREFIXES.to_vec()),
target_version: Some(defaults::TARGET_VERSION),
// Ignore a bunch of options that don't make sense in a single-file editor.
cache_dir: None,
exclude: None,
extend: None,
extend_exclude: None,
extend_include: None,
extend_per_file_ignores: None,
fix: None,
fix_only: None,
fixable: None,
force_exclude: None,
format: None,
include: None,
ignore_init_module_imports: None,
namespace_packages: None,
per_file_ignores: None,
required_version: None,
respect_gitignore: None,
show_fixes: None,
show_source: None,
src: None,
task_tags: None,
typing_modules: None,
unfixable: None,
// Use default options for all plugins.
flake8_annotations: Some(flake8_annotations::settings::Settings::default().into()),
flake8_bandit: Some(flake8_bandit::settings::Settings::default().into()),
flake8_bugbear: Some(flake8_bugbear::settings::Settings::default().into()),
flake8_builtins: Some(flake8_builtins::settings::Settings::default().into()),
flake8_comprehensions: Some(flake8_comprehensions::settings::Settings::default().into()),
flake8_copyright: Some(flake8_copyright::settings::Settings::default().into()),
flake8_errmsg: Some(flake8_errmsg::settings::Settings::default().into()),
flake8_gettext: Some(flake8_gettext::settings::Settings::default().into()),
flake8_implicit_str_concat: Some(
flake8_implicit_str_concat::settings::Settings::default().into(),
),
flake8_import_conventions: Some(
flake8_import_conventions::settings::Settings::default().into(),
),
flake8_pytest_style: Some(flake8_pytest_style::settings::Settings::default().into()),
flake8_quotes: Some(flake8_quotes::settings::Settings::default().into()),
flake8_self: Some(flake8_self::settings::Settings::default().into()),
flake8_tidy_imports: Some(flake8_tidy_imports::settings::Settings::default().into()),
flake8_type_checking: Some(flake8_type_checking::settings::Settings::default().into()),
flake8_unused_arguments: Some(
flake8_unused_arguments::settings::Settings::default().into(),
),
isort: Some(isort::settings::Settings::default().into()),
mccabe: Some(mccabe::settings::Settings::default().into()),
pep8_naming: Some(pep8_naming::settings::Settings::default().into()),
pycodestyle: Some(pycodestyle::settings::Settings::default().into()),
pydocstyle: Some(pydocstyle::settings::Settings::default().into()),
pyflakes: Some(pyflakes::settings::Settings::default().into()),
pylint: Some(pylint::settings::Settings::default().into()),
pyupgrade: Some(pyupgrade::settings::Settings::default().into()),
})?)
}
impl Workspace {
pub fn version() -> String {
ruff::VERSION.to_string()
}
#[wasm_bindgen]
#[allow(non_snake_case)]
pub fn check(contents: &str, options: JsValue) -> Result<JsValue, JsValue> {
let options: Options = serde_wasm_bindgen::from_value(options).map_err(|e| e.to_string())?;
let configuration =
Configuration::from_options(options, Path::new(".")).map_err(|e| e.to_string())?;
let settings =
Settings::from_configuration(configuration, Path::new(".")).map_err(|e| e.to_string())?;
#[wasm_bindgen(constructor)]
pub fn new(options: JsValue) -> Result<Workspace, Error> {
let options: Options = serde_wasm_bindgen::from_value(options).map_err(into_error)?;
let configuration =
Configuration::from_options(options, Path::new(".")).map_err(into_error)?;
let settings =
Settings::from_configuration(configuration, Path::new(".")).map_err(into_error)?;
// Tokenize once.
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
Ok(Workspace { settings })
}
// Map row and column locations to byte slices (lazily).
let locator = Locator::new(contents);
// Detect the current code style (lazily).
let stylist = Stylist::from_tokens(&tokens, &locator);
// Extra indices from the code.
let indexer = Indexer::from_tokens(&tokens, &locator);
// Extract the `# noqa` and `# isort: skip` directives from the source.
let directives =
directives::extract_directives(&tokens, directives::Flags::empty(), &locator, &indexer);
// Generate checks.
let LinterResult {
data: (diagnostics, _imports),
..
} = check_path(
Path::new("<filename>"),
None,
tokens,
&locator,
&stylist,
&indexer,
&directives,
&settings,
flags::Noqa::Enabled,
None,
);
let source_code = locator.to_source_code();
let messages: Vec<ExpandedMessage> = diagnostics
.into_iter()
.map(|message| {
let start_location = source_code.source_location(message.start());
let end_location = source_code.source_location(message.end());
ExpandedMessage {
code: message.kind.rule().noqa_code().to_string(),
message: message.kind.body,
location: start_location,
end_location,
fix: message.fix.map(|fix| ExpandedFix {
message: message.kind.suggestion,
edits: fix
.into_edits()
.into_iter()
.map(|edit| ExpandedEdit {
location: source_code.source_location(edit.start()),
end_location: source_code.source_location(edit.end()),
content: edit.content().map(ToString::to_string),
})
.collect(),
}),
}
#[wasm_bindgen(js_name=defaultSettings)]
pub fn default_settings() -> Result<JsValue, Error> {
serde_wasm_bindgen::to_value(&Options {
// Propagate defaults.
allowed_confusables: Some(Vec::default()),
builtins: Some(Vec::default()),
dummy_variable_rgx: Some(defaults::DUMMY_VARIABLE_RGX.as_str().to_string()),
extend_fixable: Some(Vec::default()),
extend_ignore: Some(Vec::default()),
extend_select: Some(Vec::default()),
extend_unfixable: Some(Vec::default()),
external: Some(Vec::default()),
ignore: Some(Vec::default()),
line_length: Some(LineLength::default()),
tab_size: Some(TabSize::default()),
select: Some(defaults::PREFIXES.to_vec()),
target_version: Some(defaults::TARGET_VERSION),
// Ignore a bunch of options that don't make sense in a single-file editor.
cache_dir: None,
exclude: None,
extend: None,
extend_exclude: None,
extend_include: None,
extend_per_file_ignores: None,
fix: None,
fix_only: None,
fixable: None,
force_exclude: None,
format: None,
include: None,
ignore_init_module_imports: None,
namespace_packages: None,
per_file_ignores: None,
required_version: None,
respect_gitignore: None,
show_fixes: None,
show_source: None,
src: None,
task_tags: None,
typing_modules: None,
unfixable: None,
// Use default options for all plugins.
flake8_annotations: Some(flake8_annotations::settings::Settings::default().into()),
flake8_bandit: Some(flake8_bandit::settings::Settings::default().into()),
flake8_bugbear: Some(flake8_bugbear::settings::Settings::default().into()),
flake8_builtins: Some(flake8_builtins::settings::Settings::default().into()),
flake8_comprehensions: Some(
flake8_comprehensions::settings::Settings::default().into(),
),
flake8_copyright: Some(flake8_copyright::settings::Settings::default().into()),
flake8_errmsg: Some(flake8_errmsg::settings::Settings::default().into()),
flake8_gettext: Some(flake8_gettext::settings::Settings::default().into()),
flake8_implicit_str_concat: Some(
flake8_implicit_str_concat::settings::Settings::default().into(),
),
flake8_import_conventions: Some(
flake8_import_conventions::settings::Settings::default().into(),
),
flake8_pytest_style: Some(flake8_pytest_style::settings::Settings::default().into()),
flake8_quotes: Some(flake8_quotes::settings::Settings::default().into()),
flake8_self: Some(flake8_self::settings::Settings::default().into()),
flake8_tidy_imports: Some(flake8_tidy_imports::settings::Settings::default().into()),
flake8_type_checking: Some(flake8_type_checking::settings::Settings::default().into()),
flake8_unused_arguments: Some(
flake8_unused_arguments::settings::Settings::default().into(),
),
isort: Some(isort::settings::Settings::default().into()),
mccabe: Some(mccabe::settings::Settings::default().into()),
pep8_naming: Some(pep8_naming::settings::Settings::default().into()),
pycodestyle: Some(pycodestyle::settings::Settings::default().into()),
pydocstyle: Some(pydocstyle::settings::Settings::default().into()),
pyflakes: Some(pyflakes::settings::Settings::default().into()),
pylint: Some(pylint::settings::Settings::default().into()),
pyupgrade: Some(pyupgrade::settings::Settings::default().into()),
})
.collect();
.map_err(into_error)
}
Ok(serde_wasm_bindgen::to_value(&messages)?)
pub fn check(&self, contents: &str) -> Result<JsValue, Error> {
// Tokenize once.
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
// Map row and column locations to byte slices (lazily).
let locator = Locator::new(contents);
// Detect the current code style (lazily).
let stylist = Stylist::from_tokens(&tokens, &locator);
// Extra indices from the code.
let indexer = Indexer::from_tokens(&tokens, &locator);
// Extract the `# noqa` and `# isort: skip` directives from the source.
let directives =
directives::extract_directives(&tokens, directives::Flags::empty(), &locator, &indexer);
// Generate checks.
let LinterResult {
data: (diagnostics, _imports),
..
} = check_path(
Path::new("<filename>"),
None,
tokens,
&locator,
&stylist,
&indexer,
&directives,
&self.settings,
flags::Noqa::Enabled,
None,
);
let source_code = locator.to_source_code();
let messages: Vec<ExpandedMessage> = diagnostics
.into_iter()
.map(|message| {
let start_location = source_code.source_location(message.start());
let end_location = source_code.source_location(message.end());
ExpandedMessage {
code: message.kind.rule().noqa_code().to_string(),
message: message.kind.body,
location: start_location,
end_location,
fix: message.fix.map(|fix| ExpandedFix {
message: message.kind.suggestion,
edits: fix
.into_edits()
.into_iter()
.map(|edit| ExpandedEdit {
location: source_code.source_location(edit.start()),
end_location: source_code.source_location(edit.end()),
content: edit.content().map(ToString::to_string),
})
.collect(),
}),
}
})
.collect();
serde_wasm_bindgen::to_value(&messages).map_err(into_error)
}
pub fn format(&self, contents: &str) -> Result<String, Error> {
let printed = format_module(contents, PyFormatOptions::default()).map_err(into_error)?;
Ok(printed.into_code())
}
pub fn format_ir(&self, contents: &str) -> Result<String, Error> {
let tokens: Vec<_> = rustpython_parser::lexer::lex(contents, Mode::Module).collect();
let mut comment_ranges = CommentRangesBuilder::default();
for (token, range) in tokens.iter().flatten() {
comment_ranges.visit_token(token, *range);
}
let comment_ranges = comment_ranges.finish();
let module = parse_tokens(tokens, Mode::Module, ".").map_err(into_error)?;
let formatted = format_node(
&module,
&comment_ranges,
contents,
PyFormatOptions::default(),
)
.map_err(into_error)?;
Ok(format!("{formatted}"))
}
/// Parses the content and returns its AST
pub fn parse(&self, contents: &str) -> Result<String, Error> {
let parsed = rustpython_parser::parse(contents, Mode::Module, ".").map_err(into_error)?;
Ok(format!("{parsed:#?}"))
}
pub fn tokens(&self, contents: &str) -> Result<String, Error> {
let tokens: Vec<_> = rustpython_parser::lexer::lex(contents, Mode::Module).collect();
Ok(format!("{tokens:#?}"))
}
}
pub(crate) fn into_error<E: std::fmt::Display>(err: E) -> Error {
Error::new(&err.to_string())
}

View file

@ -4,12 +4,12 @@ use wasm_bindgen_test::wasm_bindgen_test;
use ruff::registry::Rule;
use ruff_python_ast::source_code::{OneIndexed, SourceLocation};
use ruff_wasm::{check, ExpandedMessage};
use ruff_wasm::{ExpandedMessage, Workspace};
macro_rules! check {
($source:expr, $config:expr, $expected:expr) => {{
let foo = js_sys::JSON::parse($config).unwrap();
match check($source, foo) {
let config = js_sys::JSON::parse($config).unwrap();
match Workspace::new(config).unwrap().check($source) {
Ok(output) => {
let result: Vec<ExpandedMessage> = serde_wasm_bindgen::from_value(output).unwrap();
assert_eq!(result, $expected);

View file

@ -13,7 +13,8 @@
"lz-string": "^1.4.4",
"monaco-editor": "^0.40.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-resizable-panels": "^0.0.54"
},
"devDependencies": {
"@types/react": "^18.0.26",
@ -3964,6 +3965,15 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true
},
"node_modules/react-resizable-panels": {
"version": "0.0.54",
"resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-0.0.54.tgz",
"integrity": "sha512-f8hHdQrqvXoiZGdRNuoOi/C2cdYT2nEpaOb1KIWVWorSTPZmnE+ZQiamGeu+AMx3iZ/tqBtlAkBOpKXzTnDCoA==",
"peerDependencies": {
"react": "^16.14.0 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",

View file

@ -20,7 +20,8 @@
"lz-string": "^1.4.4",
"monaco-editor": "^0.40.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-resizable-panels": "^0.0.54"
},
"devDependencies": {
"@types/react": "^18.0.26",

View file

@ -1,19 +1,26 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import {
useCallback,
useDeferredValue,
useEffect,
useMemo,
useState,
} from "react";
import { DEFAULT_PYTHON_SOURCE } from "../constants";
import init, {
check,
Diagnostic,
currentVersion,
defaultSettings,
} from "../pkg";
import init, { Diagnostic, Workspace } from "../pkg";
import { ErrorMessage } from "./ErrorMessage";
import Header from "./Header";
import { useTheme } from "./theme";
import { persist, restore, stringify } from "./settings";
import SettingsEditor from "./SettingsEditor";
import SourceEditor from "./SourceEditor";
import MonacoThemes from "./MonacoThemes";
import SideBar from "./SideBar";
import { Panel, PanelGroup } from "react-resizable-panels";
import PrimarySideBar from "./PrimarySideBar";
import SecondarySideBar from "./SecondarySideBar";
import { HorizontalResizeHandle } from "./ResizeHandle";
import SecondaryPanel, {
SecondaryPanelResult,
SecondaryTool,
} from "./SecondaryPanel";
type Tab = "Source" | "Settings";
@ -26,6 +33,7 @@ interface Source {
interface CheckResult {
diagnostics: Diagnostic[];
error: string | null;
secondary: SecondaryPanelResult;
}
export default function Editor() {
@ -33,6 +41,7 @@ export default function Editor() {
const [checkResult, setCheckResult] = useState<CheckResult>({
diagnostics: [],
error: null,
secondary: null,
});
const [source, setSource] = useState<Source>({
pythonSource: "",
@ -42,15 +51,18 @@ export default function Editor() {
const [tab, setTab] = useState<Tab>("Source");
const [theme, setTheme] = useTheme();
const [secondaryTool, setSecondaryTool] = useState<SecondaryTool | null>(
null,
);
const initialized = ruffVersion != null;
useEffect(() => {
init().then(() => {
setRuffVersion(currentVersion());
setRuffVersion(Workspace.version());
const [settingsSource, pythonSource] = restore() ?? [
stringify(defaultSettings()),
stringify(Workspace.defaultSettings()),
DEFAULT_PYTHON_SOURCE,
];
@ -62,28 +74,72 @@ export default function Editor() {
});
}, []);
const deferredSource = useDeferredValue(source);
useEffect(() => {
if (!initialized) {
return;
}
const { settingsSource, pythonSource } = source;
const { settingsSource, pythonSource } = deferredSource;
try {
const config = JSON.parse(settingsSource);
const diagnostics = check(pythonSource, config);
const workspace = new Workspace(config);
const diagnostics = workspace.check(pythonSource);
let secondary: SecondaryPanelResult = null;
try {
switch (secondaryTool) {
case "AST":
secondary = {
status: "ok",
content: workspace.parse(pythonSource),
};
break;
case "Format":
secondary = {
status: "ok",
content: workspace.format(pythonSource),
};
break;
case "FIR":
secondary = {
status: "ok",
content: workspace.format_ir(pythonSource),
};
break;
case "Tokens":
secondary = {
status: "ok",
content: workspace.tokens(pythonSource),
};
break;
}
} catch (error: unknown) {
secondary = {
status: "error",
error: error instanceof Error ? error.message : error + "",
};
}
setCheckResult({
diagnostics,
error: null,
secondary,
});
} catch (e) {
setCheckResult({
diagnostics: [],
error: (e as Error).message,
secondary: null,
});
}
}, [initialized, source]);
}, [initialized, deferredSource, secondaryTool]);
const handleShare = useMemo(() => {
if (!initialized) {
@ -111,6 +167,8 @@ export default function Editor() {
}));
}, []);
// useMonacoTheme();
return (
<main className="flex flex-col h-full bg-ayu-background dark:bg-ayu-background-dark">
<Header
@ -121,26 +179,51 @@ export default function Editor() {
onShare={handleShare}
/>
<MonacoThemes />
<div className="flex flex-grow">
{initialized ? (
<>
<SideBar onSelectTool={(tool) => setTab(tool)} selected={tab} />
<SourceEditor
visible={tab === "Source"}
source={source.pythonSource}
theme={theme}
diagnostics={checkResult.diagnostics}
onChange={handlePythonSourceChange}
<PanelGroup direction="horizontal" autoSaveId="main">
<PrimarySideBar
onSelectTool={(tool) => setTab(tool)}
selected={tab}
/>
<SettingsEditor
visible={tab === "Settings"}
source={source.settingsSource}
theme={theme}
onChange={handleSettingsSourceChange}
<Panel id="main" order={0} className="my-2">
<SourceEditor
visible={tab === "Source"}
source={source.pythonSource}
theme={theme}
diagnostics={checkResult.diagnostics}
onChange={handlePythonSourceChange}
/>
<SettingsEditor
visible={tab === "Settings"}
source={source.settingsSource}
theme={theme}
onChange={handleSettingsSourceChange}
/>
</Panel>
{secondaryTool != null && (
<>
<HorizontalResizeHandle />
<Panel id="secondary-panel" order={1} className={"my-2"}>
<SecondaryPanel
theme={theme}
tool={secondaryTool}
result={checkResult.secondary}
/>
</Panel>
</>
)}
<SecondarySideBar
selected={secondaryTool}
onSelected={(tool) => {
if (secondaryTool === tool) {
setSecondaryTool(null);
} else {
setSecondaryTool(tool);
}
}}
/>
</>
</PanelGroup>
) : null}
</div>
{checkResult.error && tab === "Source" ? (

View file

@ -25,8 +25,17 @@
export function FileIcon() {
return (
<svg width="24" height="24" viewBox="0 0 24 24">
<path d="M17.5 0H8.5L7 1.5V6H2.5L1 7.5V22.5699L2.5 24H14.5699L16 22.5699V18H20.7L22 16.5699V4.5L17.5 0ZM17.5 2.12L19.88 4.5H17.5V2.12ZM14.5 22.5H2.5V7.5H7V16.5699L8.5 18H14.5V22.5ZM20.5 16.5H8.5V1.5H16V6H20.5V16.5Z" />
<svg
width="24"
height="24"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.57 1.14L13.85 4.44L14 4.8V14.5L13.5 15H2.5L2 14.5V1.5L2.5 1H10.22L10.57 1.14ZM10 5H13L10 2V5ZM3 2V14H13V6H9.5L9 5.5V2H3ZM5.062 9.533L6.879 7.705L6.17 7L4 9.179V9.886L6.171 12.06L6.878 11.353L5.062 9.533ZM8.8 7.714L9.5 7.005L11.689 9.18V9.889L9.5 12.062L8.795 11.353L10.626 9.533L8.8 7.714Z"
/>
</svg>
);
}
@ -47,3 +56,54 @@ export function SettingsIcon() {
</svg>
);
}
export function StructureIcon() {
return (
<svg
width="24"
height="24"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2 2L1 3V6L2 7H14L15 6V3L14 2H2ZM2 3H3H13H14V4V5V6H13H3H2V5V4V3ZM1 10L2 9H5L6 10V13L5 14H2L1 13V10ZM3 10H2V11V12V13H3H4H5V12V11V10H4H3ZM10 10L11 9H14L15 10V13L14 14H11L10 13V10ZM12 10H11V11V12V13H12H13H14V12V11V10H13H12Z"
/>
</svg>
);
}
export function FormatIcon() {
return (
<svg
width="24"
height="24"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6 2.98361V2.97184V2H5.91083C5.59743 2 5.29407 2.06161 5.00128 2.18473C4.70818 2.30798 4.44942 2.48474 4.22578 2.71498C4.00311 2.94422 3.83792 3.19498 3.73282 3.46766L3.73233 3.46898C3.63382 3.7352 3.56814 4.01201 3.53533 4.29917L3.53519 4.30053C3.50678 4.5805 3.4987 4.86844 3.51084 5.16428C3.52272 5.45379 3.52866 5.74329 3.52866 6.03279C3.52866 6.23556 3.48974 6.42594 3.412 6.60507L3.4116 6.60601C3.33687 6.78296 3.23423 6.93866 3.10317 7.07359C2.97644 7.20405 2.82466 7.31055 2.64672 7.3925C2.4706 7.46954 2.28497 7.5082 2.08917 7.5082H2V7.6V8.4V8.4918H2.08917C2.28465 8.4918 2.47001 8.53238 2.64601 8.61334L2.64742 8.61396C2.82457 8.69157 2.97577 8.79762 3.10221 8.93161L3.10412 8.93352C3.23428 9.0637 3.33659 9.21871 3.41129 9.39942L3.41201 9.40108C3.48986 9.58047 3.52866 9.76883 3.52866 9.96721C3.52866 10.2567 3.52272 10.5462 3.51084 10.8357C3.4987 11.1316 3.50677 11.4215 3.53516 11.7055L3.53535 11.7072C3.56819 11.9903 3.63387 12.265 3.73232 12.531L3.73283 12.5323C3.83793 12.805 4.00311 13.0558 4.22578 13.285C4.44942 13.5153 4.70818 13.692 5.00128 13.8153C5.29407 13.9384 5.59743 14 5.91083 14H6V13.2V13.0164H5.91083C5.71095 13.0164 5.52346 12.9777 5.34763 12.9008C5.17396 12.8191 5.02194 12.7126 4.89086 12.5818C4.76386 12.4469 4.66104 12.2911 4.58223 12.1137C4.50838 11.9346 4.47134 11.744 4.47134 11.541C4.47134 11.3127 4.4753 11.0885 4.48321 10.8686C4.49125 10.6411 4.49127 10.4195 4.48324 10.2039C4.47914 9.98246 4.46084 9.76883 4.42823 9.56312C4.39513 9.35024 4.33921 9.14757 4.26039 8.95536C4.18091 8.76157 4.07258 8.57746 3.93616 8.40298C3.82345 8.25881 3.68538 8.12462 3.52283 8C3.68538 7.87538 3.82345 7.74119 3.93616 7.59702C4.07258 7.42254 4.18091 7.23843 4.26039 7.04464C4.33913 6.85263 4.39513 6.65175 4.42826 6.44285C4.46082 6.2333 4.47914 6.01973 4.48324 5.80219C4.49127 5.58262 4.49125 5.36105 4.48321 5.13749C4.4753 4.9134 4.47134 4.68725 4.47134 4.45902C4.47134 4.26019 4.50833 4.07152 4.58238 3.89205C4.66135 3.71034 4.76421 3.55475 4.89086 3.42437C5.02193 3.28942 5.17461 3.18275 5.34802 3.10513C5.5238 3.02427 5.71113 2.98361 5.91083 2.98361H6ZM10 13.0164V13.0282V14H10.0892C10.4026 14 10.7059 13.9384 10.9987 13.8153C11.2918 13.692 11.5506 13.5153 11.7742 13.285C11.9969 13.0558 12.1621 12.805 12.2672 12.5323L12.2677 12.531C12.3662 12.2648 12.4319 11.988 12.4647 11.7008L12.4648 11.6995C12.4932 11.4195 12.5013 11.1316 12.4892 10.8357C12.4773 10.5462 12.4713 10.2567 12.4713 9.96721C12.4713 9.76444 12.5103 9.57406 12.588 9.39493L12.5884 9.39399C12.6631 9.21704 12.7658 9.06134 12.8968 8.92642C13.0236 8.79595 13.1753 8.68945 13.3533 8.6075C13.5294 8.53046 13.715 8.4918 13.9108 8.4918H14V8.4V7.6V7.5082H13.9108C13.7153 7.5082 13.53 7.46762 13.354 7.38666L13.3526 7.38604C13.1754 7.30844 13.0242 7.20238 12.8978 7.06839L12.8959 7.06648C12.7657 6.9363 12.6634 6.78129 12.5887 6.60058L12.588 6.59892C12.5101 6.41953 12.4713 6.23117 12.4713 6.03279C12.4713 5.74329 12.4773 5.45379 12.4892 5.16428C12.5013 4.86842 12.4932 4.57848 12.4648 4.29454L12.4646 4.29285C12.4318 4.00971 12.3661 3.73502 12.2677 3.46897L12.2672 3.46766C12.1621 3.19499 11.9969 2.94422 11.7742 2.71498C11.5506 2.48474 11.2918 2.30798 10.9987 2.18473C10.7059 2.06161 10.4026 2 10.0892 2H10V2.8V2.98361H10.0892C10.2891 2.98361 10.4765 3.0223 10.6524 3.09917C10.826 3.18092 10.9781 3.28736 11.1091 3.41823C11.2361 3.55305 11.339 3.70889 11.4178 3.88628C11.4916 4.0654 11.5287 4.25596 11.5287 4.45902C11.5287 4.68727 11.5247 4.91145 11.5168 5.13142C11.5088 5.35894 11.5087 5.58049 11.5168 5.79605C11.5209 6.01754 11.5392 6.23117 11.5718 6.43688C11.6049 6.64976 11.6608 6.85243 11.7396 7.04464C11.8191 7.23843 11.9274 7.42254 12.0638 7.59702C12.1765 7.74119 12.3146 7.87538 12.4772 8C12.3146 8.12462 12.1765 8.25881 12.0638 8.40298C11.9274 8.57746 11.8191 8.76157 11.7396 8.95536C11.6609 9.14737 11.6049 9.34825 11.5717 9.55715C11.5392 9.7667 11.5209 9.98027 11.5168 10.1978C11.5087 10.4174 11.5087 10.6389 11.5168 10.8625C11.5247 11.0866 11.5287 11.3128 11.5287 11.541C11.5287 11.7398 11.4917 11.9285 11.4176 12.1079C11.3386 12.2897 11.2358 12.4452 11.1091 12.5756C10.9781 12.7106 10.8254 12.8173 10.652 12.8949C10.4762 12.9757 10.2889 13.0164 10.0892 13.0164H10Z"
/>
</svg>
);
}
export function TokensIcon() {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.5 0V1.5L21 3V22.5L19.5 24H4.5L3 22.5V3L4.5 1.5V0H6V1.5H9V0H10.5V1.5H13.5V0H15V1.5H18V0H19.5ZM4.5 22.5H19.5V3H4.5V22.5ZM7.5 6H16.5V7.5H7.5V6ZM16.5 12H7.5V13.5H16.5V12ZM7.5 18H16.5V19.5H7.5V18Z"
/>
</svg>
);
}

View file

@ -1,565 +0,0 @@
/**
* Non-rendering component that loads the Monaco editor themes.
*/
import { useMonaco } from "@monaco-editor/react";
import { useEffect } from "react";
export const WHITE = "#ffffff";
export const RADIATE = "#d7ff64";
export const FLARE = "#6340ac";
export const ROCK = "#78876e";
export const GALAXY = "#261230";
export const SPACE = "#30173d";
export const COMET = "#6f5d6f";
export const COSMIC = "#de5fe9";
export const SUN = "#ffac2f";
export const ELECTRON = "#46ebe1";
export const AURORA = "#46eb74";
export const CONSTELLATION = "#5f6de9";
export const NEUTRON = "#cff3cf";
export const PROTON = "#f6afbc";
export const NEBULA = "#cdcbfb";
export const SUPERNOVA = "#f1aff6";
export const STARLIGHT = "#f4f4f1";
export const LUNAR = "#fbf2fc";
export const ASTEROID = "#e3cee3";
export const CRATER = "#f0dfdf";
export default function MonacoThemes() {
const monaco = useMonaco();
useEffect(() => {
// Generated via `monaco-vscode-textmate-theme-converter`.
// See: https://github.com/ayu-theme/vscode-ayu/blob/91839e8a9dfa78d61e58dbcf9b52272a01fee66a/ayu-light.json.
monaco?.editor.defineTheme("Ayu-Light", {
inherit: false,
base: "vs-dark",
colors: {
focusBorder: "#ffaa33b3",
foreground: "#8a9199",
"widget.shadow": "#00000026",
"selection.background": "#035bd626",
"icon.foreground": "#8a9199",
errorForeground: "#e65050",
descriptionForeground: "#8a9199",
"textBlockQuote.background": "#f3f4f5",
"textLink.foreground": "#ffaa33",
"textLink.activeForeground": "#ffaa33",
"textPreformat.foreground": "#5c6166",
"button.background": "#ffaa33",
"button.foreground": "#f8f9fa",
"button.hoverBackground": "#f9a52e",
"button.secondaryBackground": "#8a919933",
"button.secondaryForeground": "#5c6166",
"button.secondaryHoverBackground": "#8a919980",
"dropdown.background": "#fcfcfc",
"dropdown.foreground": "#8a9199",
"dropdown.border": "#8a919945",
"input.background": "#fcfcfc",
"input.border": "#8a919945",
"input.foreground": "#5c6166",
"input.placeholderForeground": "#8a919980",
"inputOption.activeBorder": "#f4a0284d",
"inputOption.activeBackground": "#ffaa3333",
"inputOption.activeForeground": "#f4a028",
"inputValidation.errorBackground": "#fcfcfc",
"inputValidation.errorBorder": "#e65050",
"inputValidation.infoBackground": "#f8f9fa",
"inputValidation.infoBorder": "#55b4d4",
"inputValidation.warningBackground": "#f8f9fa",
"inputValidation.warningBorder": "#f2ae49",
"scrollbar.shadow": "#6b7d8f00",
"scrollbarSlider.background": "#8a919966",
"scrollbarSlider.hoverBackground": "#8a919999",
"scrollbarSlider.activeBackground": "#8a9199b3",
"badge.background": "#ffaa3333",
"badge.foreground": "#f4a028",
"progressBar.background": "#ffaa33",
"list.activeSelectionBackground": "#56728f1f",
"list.activeSelectionForeground": "#5c6166",
"list.focusBackground": "#56728f1f",
"list.focusForeground": "#5c6166",
"list.focusOutline": "#56728f1f",
"list.highlightForeground": "#ffaa33",
"list.deemphasizedForeground": "#e65050",
"list.hoverBackground": "#56728f1f",
"list.inactiveSelectionBackground": "#6b7d8f1f",
"list.inactiveSelectionForeground": "#8a9199",
"list.invalidItemForeground": "#8a91994d",
"list.errorForeground": "#e65050",
"tree.indentGuidesStroke": "#8a919959",
"listFilterWidget.background": "#f3f4f5",
"listFilterWidget.outline": "#ffaa33",
"listFilterWidget.noMatchesOutline": "#e65050",
"list.filterMatchBackground": "#8f30efcc",
"list.filterMatchBorder": "#9f40ffcc",
"activityBar.background": "#f8f9fa",
"activityBar.foreground": "#8a9199cc",
"activityBar.inactiveForeground": "#8a919999",
"activityBar.border": "#f8f9fa",
"activityBar.activeBorder": "#ffaa33b3",
"activityBarBadge.background": "#ffaa33",
"activityBarBadge.foreground": "#f8f9fa",
"sideBar.background": "#f8f9fa",
"sideBar.border": "#f8f9fa",
"sideBarTitle.foreground": "#8a9199",
"sideBarSectionHeader.background": "#f8f9fa",
"sideBarSectionHeader.foreground": "#8a9199",
"sideBarSectionHeader.border": "#f8f9fa",
"minimap.background": "#f8f9fa",
"minimap.selectionHighlight": "#035bd626",
"minimap.errorHighlight": "#e65050",
"minimap.findMatchHighlight": "#9f40ff2b",
"minimapGutter.addedBackground": "#6cbf43",
"minimapGutter.modifiedBackground": "#478acc",
"minimapGutter.deletedBackground": "#ff7383",
"editorGroup.border": "#6b7d8f1f",
"editorGroup.background": "#f3f4f5",
"editorGroupHeader.noTabsBackground": "#f8f9fa",
"editorGroupHeader.tabsBackground": "#f8f9fa",
"editorGroupHeader.tabsBorder": "#f8f9fa",
"tab.activeBackground": "#f8f9fa",
"tab.activeForeground": "#5c6166",
"tab.border": "#f8f9fa",
"tab.activeBorder": "#ffaa33",
"tab.unfocusedActiveBorder": "#8a9199",
"tab.inactiveBackground": "#f8f9fa",
"tab.inactiveForeground": "#8a9199",
"tab.unfocusedActiveForeground": "#8a9199",
"tab.unfocusedInactiveForeground": "#8a9199",
"editor.background": "#f8f9fa",
"editor.foreground": "#5c6166",
"editorLineNumber.foreground": "#8a919966",
"editorLineNumber.activeForeground": "#8a9199cc",
"editorCursor.foreground": "#ffaa33",
"editor.inactiveSelectionBackground": "#035bd612",
"editor.selectionBackground": "#035bd626",
"editor.selectionHighlightBackground": "#6cbf4326",
"editor.selectionHighlightBorder": "#6cbf4300",
"editor.wordHighlightBackground": "#478acc14",
"editor.wordHighlightStrongBackground": "#6cbf4314",
"editor.wordHighlightBorder": "#478acc80",
"editor.wordHighlightStrongBorder": "#6cbf4380",
"editor.findMatchBackground": "#9f40ff2b",
"editor.findMatchBorder": "#9f40ff2b",
"editor.findMatchHighlightBackground": "#9f40ffcc",
"editor.findMatchHighlightBorder": "#8f30efcc",
"editor.findRangeHighlightBackground": "#9f40ff40",
"editor.rangeHighlightBackground": "#9f40ff33",
"editor.lineHighlightBackground": "#8a91991a",
"editorLink.activeForeground": "#ffaa33",
"editorWhitespace.foreground": "#8a919966",
"editorIndentGuide.background": "#8a91992e",
"editorIndentGuide.activeBackground": "#8a919959",
"editorRuler.foreground": "#8a91992e",
"editorCodeLens.foreground": "#787b8099",
"editorBracketMatch.background": "#8a91994d",
"editorBracketMatch.border": "#8a91994d",
"editor.snippetTabstopHighlightBackground": "#6cbf4333",
"editorOverviewRuler.border": "#6b7d8f1f",
"editorOverviewRuler.modifiedForeground": "#478acc",
"editorOverviewRuler.addedForeground": "#6cbf43",
"editorOverviewRuler.deletedForeground": "#ff7383",
"editorOverviewRuler.errorForeground": "#e65050",
"editorOverviewRuler.warningForeground": "#ffaa33",
"editorOverviewRuler.bracketMatchForeground": "#8a9199b3",
"editorOverviewRuler.wordHighlightForeground": "#478acc66",
"editorOverviewRuler.wordHighlightStrongForeground": "#6cbf4366",
"editorOverviewRuler.findMatchForeground": "#9f40ff2b",
"editorError.foreground": "#e65050",
"editorWarning.foreground": "#ffaa33",
"editorGutter.modifiedBackground": "#478acccc",
"editorGutter.addedBackground": "#6cbf43cc",
"editorGutter.deletedBackground": "#ff7383cc",
"diffEditor.insertedTextBackground": "#6cbf431f",
"diffEditor.removedTextBackground": "#ff73831f",
"diffEditor.diagonalFill": "#6b7d8f1f",
"editorWidget.background": "#f3f4f5",
"editorWidget.border": "#6b7d8f1f",
"editorHoverWidget.background": "#f3f4f5",
"editorHoverWidget.border": "#6b7d8f1f",
"editorSuggestWidget.background": "#f3f4f5",
"editorSuggestWidget.border": "#6b7d8f1f",
"editorSuggestWidget.highlightForeground": "#ffaa33",
"editorSuggestWidget.selectedBackground": "#56728f1f",
"debugExceptionWidget.border": "#6b7d8f1f",
"debugExceptionWidget.background": "#f3f4f5",
"editorMarkerNavigation.background": "#f3f4f5",
"peekView.border": "#56728f1f",
"peekViewTitle.background": "#56728f1f",
"peekViewTitleDescription.foreground": "#8a9199",
"peekViewTitleLabel.foreground": "#5c6166",
"peekViewEditor.background": "#f3f4f5",
"peekViewEditor.matchHighlightBackground": "#9f40ffcc",
"peekViewEditor.matchHighlightBorder": "#8f30efcc",
"peekViewResult.background": "#f3f4f5",
"peekViewResult.fileForeground": "#5c6166",
"peekViewResult.lineForeground": "#8a9199",
"peekViewResult.matchHighlightBackground": "#9f40ffcc",
"peekViewResult.selectionBackground": "#56728f1f",
"panel.background": "#f8f9fa",
"panel.border": "#6b7d8f1f",
"panelTitle.activeBorder": "#ffaa33",
"panelTitle.activeForeground": "#5c6166",
"panelTitle.inactiveForeground": "#8a9199",
"statusBar.background": "#f8f9fa",
"statusBar.foreground": "#8a9199",
"statusBar.border": "#f8f9fa",
"statusBar.debuggingBackground": "#ed9366",
"statusBar.debuggingForeground": "#fcfcfc",
"statusBar.noFolderBackground": "#f3f4f5",
"statusBarItem.activeBackground": "#8a919933",
"statusBarItem.hoverBackground": "#8a919933",
"statusBarItem.prominentBackground": "#6b7d8f1f",
"statusBarItem.prominentHoverBackground": "#00000030",
"statusBarItem.remoteBackground": "#ffaa33",
"statusBarItem.remoteForeground": "#fcfcfc",
"titleBar.activeBackground": "#f8f9fa",
"titleBar.activeForeground": "#5c6166",
"titleBar.inactiveBackground": "#f8f9fa",
"titleBar.inactiveForeground": "#8a9199",
"titleBar.border": "#f8f9fa",
"extensionButton.prominentForeground": "#fcfcfc",
"extensionButton.prominentBackground": "#ffaa33",
"extensionButton.prominentHoverBackground": "#f9a52e",
"pickerGroup.border": "#6b7d8f1f",
"pickerGroup.foreground": "#8a919980",
"debugToolBar.background": "#f3f4f5",
"debugIcon.breakpointForeground": "#ed9366",
"debugIcon.breakpointDisabledForeground": "#ed936680",
"debugConsoleInputIcon.foreground": "#ffaa33",
"welcomePage.tileBackground": "#f8f9fa",
"welcomePage.tileShadow": "#00000026",
"welcomePage.progress.background": "#8a91991a",
"welcomePage.buttonBackground": "#ffaa3366",
"walkThrough.embeddedEditorBackground": "#f3f4f5",
"gitDecoration.modifiedResourceForeground": "#478accb3",
"gitDecoration.deletedResourceForeground": "#ff7383b3",
"gitDecoration.untrackedResourceForeground": "#6cbf43b3",
"gitDecoration.ignoredResourceForeground": "#8a919980",
"gitDecoration.conflictingResourceForeground": "",
"gitDecoration.submoduleResourceForeground": "#a37accb3",
"settings.headerForeground": "#5c6166",
"settings.modifiedItemIndicator": "#478acc",
"keybindingLabel.background": "#8a91991a",
"keybindingLabel.foreground": "#5c6166",
"keybindingLabel.border": "#5c61661a",
"keybindingLabel.bottomBorder": "#5c61661a",
"terminal.background": "#f8f9fa",
"terminal.foreground": "#5c6166",
"terminal.ansiBlack": "#000000",
"terminal.ansiRed": "#ea6c6d",
"terminal.ansiGreen": "#6cbf43",
"terminal.ansiYellow": "#eca944",
"terminal.ansiBlue": "#3199e1",
"terminal.ansiMagenta": "#9e75c7",
"terminal.ansiCyan": "#46ba94",
"terminal.ansiWhite": "#c7c7c7",
"terminal.ansiBrightBlack": "#686868",
"terminal.ansiBrightRed": "#f07171",
"terminal.ansiBrightGreen": "#86b300",
"terminal.ansiBrightYellow": "#f2ae49",
"terminal.ansiBrightBlue": "#399ee6",
"terminal.ansiBrightMagenta": "#a37acc",
"terminal.ansiBrightCyan": "#4cbf99",
"terminal.ansiBrightWhite": "#d1d1d1",
},
rules: [
{
fontStyle: "italic",
foreground: "#787b8099",
token: "comment",
},
{
foreground: ROCK,
token: "string",
},
{
foreground: SUN,
token: "keyword",
},
{
foreground: CONSTELLATION,
token: "number",
},
{
token: "tag",
foreground: ROCK,
},
],
encodedTokensColors: [],
});
// Generated via `monaco-vscode-textmate-theme-converter`.
// See: https://github.com/ayu-theme/vscode-ayu/blob/91839e8a9dfa78d61e58dbcf9b52272a01fee66a/ayu-dark.json.
monaco?.editor.defineTheme("Ayu-Dark", {
inherit: false,
base: "vs-dark",
colors: {
focusBorder: "#e6b450b3",
foreground: "#565b66",
"widget.shadow": "#00000080",
"selection.background": "#409fff4d",
"icon.foreground": "#565b66",
errorForeground: "#d95757",
descriptionForeground: "#565b66",
"textBlockQuote.background": "#0f131a",
"textLink.foreground": "#e6b450",
"textLink.activeForeground": "#e6b450",
"textPreformat.foreground": "#bfbdb6",
"button.background": "#e6b450",
"button.foreground": "#0b0e14",
"button.hoverBackground": "#e1af4b",
"button.secondaryBackground": "#565b6633",
"button.secondaryForeground": "#bfbdb6",
"button.secondaryHoverBackground": "#565b6680",
"dropdown.background": "#0d1017",
"dropdown.foreground": "#565b66",
"dropdown.border": "#565b6645",
"input.background": "#0d1017",
"input.border": "#565b6645",
"input.foreground": "#bfbdb6",
"input.placeholderForeground": "#565b6680",
"inputOption.activeBorder": "#e6b4504d",
"inputOption.activeBackground": "#e6b45033",
"inputOption.activeForeground": "#e6b450",
"inputValidation.errorBackground": "#0d1017",
"inputValidation.errorBorder": "#d95757",
"inputValidation.infoBackground": "#0b0e14",
"inputValidation.infoBorder": "#39bae6",
"inputValidation.warningBackground": "#0b0e14",
"inputValidation.warningBorder": "#ffb454",
"scrollbar.shadow": "#11151c00",
"scrollbarSlider.background": "#565b6666",
"scrollbarSlider.hoverBackground": "#565b6699",
"scrollbarSlider.activeBackground": "#565b66b3",
"badge.background": "#e6b45033",
"badge.foreground": "#e6b450",
"progressBar.background": "#e6b450",
"list.activeSelectionBackground": "#47526640",
"list.activeSelectionForeground": "#bfbdb6",
"list.focusBackground": "#47526640",
"list.focusForeground": "#bfbdb6",
"list.focusOutline": "#47526640",
"list.highlightForeground": "#e6b450",
"list.deemphasizedForeground": "#d95757",
"list.hoverBackground": "#47526640",
"list.inactiveSelectionBackground": "#47526633",
"list.inactiveSelectionForeground": "#565b66",
"list.invalidItemForeground": "#565b664d",
"list.errorForeground": "#d95757",
"tree.indentGuidesStroke": "#6c738080",
"listFilterWidget.background": "#0f131a",
"listFilterWidget.outline": "#e6b450",
"listFilterWidget.noMatchesOutline": "#d95757",
"list.filterMatchBackground": "#5f4c7266",
"list.filterMatchBorder": "#6c598066",
"activityBar.background": "#0b0e14",
"activityBar.foreground": "#565b66cc",
"activityBar.inactiveForeground": "#565b6699",
"activityBar.border": "#0b0e14",
"activityBar.activeBorder": "#e6b450b3",
"activityBarBadge.background": "#e6b450",
"activityBarBadge.foreground": "#0b0e14",
"sideBar.background": "#0b0e14",
"sideBar.border": "#0b0e14",
"sideBarTitle.foreground": "#565b66",
"sideBarSectionHeader.background": "#0b0e14",
"sideBarSectionHeader.foreground": "#565b66",
"sideBarSectionHeader.border": "#0b0e14",
"minimap.background": "#0b0e14",
"minimap.selectionHighlight": "#409fff4d",
"minimap.errorHighlight": "#d95757",
"minimap.findMatchHighlight": "#6c5980",
"minimapGutter.addedBackground": "#7fd962",
"minimapGutter.modifiedBackground": "#73b8ff",
"minimapGutter.deletedBackground": "#f26d78",
"editorGroup.border": "#11151c",
"editorGroup.background": "#0f131a",
"editorGroupHeader.noTabsBackground": "#0b0e14",
"editorGroupHeader.tabsBackground": "#0b0e14",
"editorGroupHeader.tabsBorder": "#0b0e14",
"tab.activeBackground": "#0b0e14",
"tab.activeForeground": "#bfbdb6",
"tab.border": "#0b0e14",
"tab.activeBorder": "#e6b450",
"tab.unfocusedActiveBorder": "#565b66",
"tab.inactiveBackground": "#0b0e14",
"tab.inactiveForeground": "#565b66",
"tab.unfocusedActiveForeground": "#565b66",
"tab.unfocusedInactiveForeground": "#565b66",
"editor.background": "#0b0e14",
"editor.foreground": "#bfbdb6",
"editorLineNumber.foreground": "#6c738099",
"editorLineNumber.activeForeground": "#6c7380e6",
"editorCursor.foreground": "#e6b450",
"editor.inactiveSelectionBackground": "#409fff21",
"editor.selectionBackground": "#409fff4d",
"editor.selectionHighlightBackground": "#7fd96226",
"editor.selectionHighlightBorder": "#7fd96200",
"editor.wordHighlightBackground": "#73b8ff14",
"editor.wordHighlightStrongBackground": "#7fd96214",
"editor.wordHighlightBorder": "#73b8ff80",
"editor.wordHighlightStrongBorder": "#7fd96280",
"editor.findMatchBackground": "#6c5980",
"editor.findMatchBorder": "#6c5980",
"editor.findMatchHighlightBackground": "#6c598066",
"editor.findMatchHighlightBorder": "#5f4c7266",
"editor.findRangeHighlightBackground": "#6c598040",
"editor.rangeHighlightBackground": "#6c598033",
"editor.lineHighlightBackground": "#131721",
"editorLink.activeForeground": "#e6b450",
"editorWhitespace.foreground": "#6c738099",
"editorIndentGuide.background": "#6c738033",
"editorIndentGuide.activeBackground": "#6c738080",
"editorRuler.foreground": "#6c738033",
"editorCodeLens.foreground": "#acb6bf8c",
"editorBracketMatch.background": "#6c73804d",
"editorBracketMatch.border": "#6c73804d",
"editor.snippetTabstopHighlightBackground": "#7fd96233",
"editorOverviewRuler.border": "#11151c",
"editorOverviewRuler.modifiedForeground": "#73b8ff",
"editorOverviewRuler.addedForeground": "#7fd962",
"editorOverviewRuler.deletedForeground": "#f26d78",
"editorOverviewRuler.errorForeground": "#d95757",
"editorOverviewRuler.warningForeground": "#e6b450",
"editorOverviewRuler.bracketMatchForeground": "#6c7380b3",
"editorOverviewRuler.wordHighlightForeground": "#73b8ff66",
"editorOverviewRuler.wordHighlightStrongForeground": "#7fd96266",
"editorOverviewRuler.findMatchForeground": "#6c5980",
"editorError.foreground": "#d95757",
"editorWarning.foreground": "#e6b450",
"editorGutter.modifiedBackground": "#73b8ffcc",
"editorGutter.addedBackground": "#7fd962cc",
"editorGutter.deletedBackground": "#f26d78cc",
"diffEditor.insertedTextBackground": "#7fd9621f",
"diffEditor.removedTextBackground": "#f26d781f",
"diffEditor.diagonalFill": "#11151c",
"editorWidget.background": "#0f131a",
"editorWidget.border": "#11151c",
"editorHoverWidget.background": "#0f131a",
"editorHoverWidget.border": "#11151c",
"editorSuggestWidget.background": "#0f131a",
"editorSuggestWidget.border": "#11151c",
"editorSuggestWidget.highlightForeground": "#e6b450",
"editorSuggestWidget.selectedBackground": "#47526640",
"debugExceptionWidget.border": "#11151c",
"debugExceptionWidget.background": "#0f131a",
"editorMarkerNavigation.background": "#0f131a",
"peekView.border": "#47526640",
"peekViewTitle.background": "#47526640",
"peekViewTitleDescription.foreground": "#565b66",
"peekViewTitleLabel.foreground": "#bfbdb6",
"peekViewEditor.background": "#0f131a",
"peekViewEditor.matchHighlightBackground": "#6c598066",
"peekViewEditor.matchHighlightBorder": "#5f4c7266",
"peekViewResult.background": "#0f131a",
"peekViewResult.fileForeground": "#bfbdb6",
"peekViewResult.lineForeground": "#565b66",
"peekViewResult.matchHighlightBackground": "#6c598066",
"peekViewResult.selectionBackground": "#47526640",
"panel.background": "#0b0e14",
"panel.border": "#11151c",
"panelTitle.activeBorder": "#e6b450",
"panelTitle.activeForeground": "#bfbdb6",
"panelTitle.inactiveForeground": "#565b66",
"statusBar.background": "#0b0e14",
"statusBar.foreground": "#565b66",
"statusBar.border": "#0b0e14",
"statusBar.debuggingBackground": "#f29668",
"statusBar.debuggingForeground": "#0d1017",
"statusBar.noFolderBackground": "#0f131a",
"statusBarItem.activeBackground": "#565b6633",
"statusBarItem.hoverBackground": "#565b6633",
"statusBarItem.prominentBackground": "#11151c",
"statusBarItem.prominentHoverBackground": "#00000030",
"statusBarItem.remoteBackground": "#e6b450",
"statusBarItem.remoteForeground": "#0d1017",
"titleBar.activeBackground": "#0b0e14",
"titleBar.activeForeground": "#bfbdb6",
"titleBar.inactiveBackground": "#0b0e14",
"titleBar.inactiveForeground": "#565b66",
"titleBar.border": "#0b0e14",
"extensionButton.prominentForeground": "#0d1017",
"extensionButton.prominentBackground": "#e6b450",
"extensionButton.prominentHoverBackground": "#e1af4b",
"pickerGroup.border": "#11151c",
"pickerGroup.foreground": "#565b6680",
"debugToolBar.background": "#0f131a",
"debugIcon.breakpointForeground": "#f29668",
"debugIcon.breakpointDisabledForeground": "#f2966880",
"debugConsoleInputIcon.foreground": "#e6b450",
"welcomePage.tileBackground": "#0b0e14",
"welcomePage.tileShadow": "#00000080",
"welcomePage.progress.background": "#131721",
"welcomePage.buttonBackground": "#e6b45066",
"walkThrough.embeddedEditorBackground": "#0f131a",
"gitDecoration.modifiedResourceForeground": "#73b8ffb3",
"gitDecoration.deletedResourceForeground": "#f26d78b3",
"gitDecoration.untrackedResourceForeground": "#7fd962b3",
"gitDecoration.ignoredResourceForeground": "#565b6680",
"gitDecoration.conflictingResourceForeground": "",
"gitDecoration.submoduleResourceForeground": "#d2a6ffb3",
"settings.headerForeground": "#bfbdb6",
"settings.modifiedItemIndicator": "#73b8ff",
"keybindingLabel.background": "#565b661a",
"keybindingLabel.foreground": "#bfbdb6",
"keybindingLabel.border": "#bfbdb61a",
"keybindingLabel.bottomBorder": "#bfbdb61a",
"terminal.background": "#0b0e14",
"terminal.foreground": "#bfbdb6",
"terminal.ansiBlack": "#11151c",
"terminal.ansiRed": "#ea6c73",
"terminal.ansiGreen": "#7fd962",
"terminal.ansiYellow": "#f9af4f",
"terminal.ansiBlue": "#53bdfa",
"terminal.ansiMagenta": "#cda1fa",
"terminal.ansiCyan": "#90e1c6",
"terminal.ansiWhite": "#c7c7c7",
"terminal.ansiBrightBlack": "#686868",
"terminal.ansiBrightRed": "#f07178",
"terminal.ansiBrightGreen": "#aad94c",
"terminal.ansiBrightYellow": "#ffb454",
"terminal.ansiBrightBlue": "#59c2ff",
"terminal.ansiBrightMagenta": "#d2a6ff",
"terminal.ansiBrightCyan": "#95e6cb",
"terminal.ansiBrightWhite": "#ffffff",
},
rules: [
{
fontStyle: "italic",
foreground: "#acb6bf8c",
token: "comment",
},
{
foreground: RADIATE,
token: "string",
},
{
foreground: ELECTRON,
token: "number",
},
{
foreground: STARLIGHT,
token: "identifier",
},
{
foreground: SUN,
token: "keyword",
},
{
foreground: PROTON,
token: "tag",
},
{
foreground: ASTEROID,
token: "delimiter",
},
],
encodedTokensColors: [],
});
}, [monaco]);
return null;
}

View file

@ -0,0 +1,34 @@
import { FileIcon, SettingsIcon } from "./Icons";
import SideBar, { SideBarEntry } from "./SideBar";
type Tool = "Settings" | "Source";
type SideBarProps = {
selected: Tool;
onSelectTool(tool: Tool): void;
};
export default function PrimarySideBar({
selected,
onSelectTool,
}: SideBarProps) {
return (
<SideBar position="left">
<SideBarEntry
title="Source"
onClick={() => onSelectTool("Source")}
selected={selected == "Source"}
>
<FileIcon />
</SideBarEntry>
<SideBarEntry
title="Settings"
onClick={() => onSelectTool("Settings")}
selected={selected == "Settings"}
>
<SettingsIcon />
</SideBarEntry>
</SideBar>
);
}

View file

@ -0,0 +1,13 @@
import { PanelResizeHandle } from "react-resizable-panels";
export function HorizontalResizeHandle() {
return (
<PanelResizeHandle className="cursor-ew-resize w-0.5 bg-gray-200 hover:bg-gray-300"></PanelResizeHandle>
);
}
export function VerticalResizeHandle() {
return (
<PanelResizeHandle className="cursor-eh-resize h-0.5 bg-gray-200 hover:bg-gray-300"></PanelResizeHandle>
);
}

View file

@ -0,0 +1,83 @@
import Editor from "@monaco-editor/react";
import { Theme } from "./theme";
export type SecondaryTool = "Format" | "AST" | "Tokens" | "FIR";
export type SecondaryPanelResult =
| null
| { status: "ok"; content: string }
| { status: "error"; error: string };
export type SecondaryPanelProps = {
tool: SecondaryTool;
result: SecondaryPanelResult;
theme: Theme;
};
export default function SecondaryPanel({
tool,
result,
theme,
}: SecondaryPanelProps) {
return (
<div className="flex flex-col h-full">
<div className="flex-grow">
<Content tool={tool} result={result} theme={theme} />
</div>
</div>
);
}
function Content({
tool,
result,
theme,
}: {
tool: SecondaryTool;
result: SecondaryPanelResult;
theme: Theme;
}) {
if (result == null) {
return "";
} else {
let language;
switch (result.status) {
case "ok":
switch (tool) {
case "Format":
language = "python";
break;
case "AST":
language = "RustPythonAst";
break;
case "Tokens":
language = "RustPythonTokens";
break;
case "FIR":
language = "fir";
break;
}
return (
<Editor
options={{
readOnly: true,
minimap: { enabled: false },
fontSize: 14,
roundedSelection: false,
scrollBeyondLastLine: false,
contextmenu: false,
}}
language={language}
value={result.content}
theme={theme === "light" ? "Ayu-Light" : "Ayu-Dark"}
/>
);
case "error":
return <code className="whitespace-pre-wrap">{result.error}</code>;
}
}
}

View file

@ -0,0 +1,49 @@
import SideBar, { SideBarEntry } from "./SideBar";
import { FormatIcon, StructureIcon, TokensIcon } from "./Icons";
import { SecondaryTool } from "./SecondaryPanel";
interface RightSideBarProps {
selected: SecondaryTool | null;
onSelected(tool: SecondaryTool): void;
}
export default function SecondarySideBar({
selected,
onSelected,
}: RightSideBarProps) {
return (
<SideBar position="right">
<SideBarEntry
title="Format (alpha)"
selected={selected === "Format"}
onClick={() => onSelected("Format")}
>
<FormatIcon />
</SideBarEntry>
<SideBarEntry
title="AST"
selected={selected === "AST"}
onClick={() => onSelected("AST")}
>
<StructureIcon />
</SideBarEntry>
<SideBarEntry
title="Tokens"
selected={selected === "Tokens"}
onClick={() => onSelected("Tokens")}
>
<TokensIcon />
</SideBarEntry>
<SideBarEntry
title="Formatter IR"
selected={selected === "FIR"}
onClick={() => onSelected("FIR")}
>
FIR
</SideBarEntry>
</SideBar>
);
}

View file

@ -46,6 +46,7 @@ export default function SettingsEditor({
fontSize: 14,
roundedSelection: false,
scrollBeyondLastLine: false,
contextmenu: false,
}}
wrapperProps={visible ? {} : { style: { display: "none" } }}
language={"json"}

View file

@ -1,43 +1,32 @@
import { FileIcon, SettingsIcon } from "./Icons";
import { type ReactNode } from "react";
type Tool = "Settings" | "Source";
import classNames from "classnames";
type SideBarProps = {
selected: Tool;
onSelectTool(tool: Tool): void;
children: ReactNode;
position: "right" | "left";
};
export default function SideBar({ selected, onSelectTool }: SideBarProps) {
export default function SideBar({ children, position }: SideBarProps) {
return (
<ul className="w-12 flex-initial border-r bg-galaxy flex flex-col items-stretch">
<SideBarEntry
title="Source"
onClick={() => onSelectTool("Source")}
selected={selected == "Source"}
>
<FileIcon />
</SideBarEntry>
<SideBarEntry
title="Settings"
onClick={() => onSelectTool("Settings")}
selected={selected == "Settings"}
>
<SettingsIcon />
</SideBarEntry>
<ul
className={classNames(
"w-12 flex-initial flex flex-col items-stretch bg-galaxy",
position === "left" ? "border-r" : "border-l",
)}
>
{children}
</ul>
);
}
interface SideBarEntryProps {
export interface SideBarEntryProps {
title: string;
selected: boolean;
onClick?(): void;
children: ReactNode;
onClick?(): void;
}
function SideBarEntry({
export function SideBarEntry({
title,
onClick,
children,
@ -49,12 +38,12 @@ function SideBarEntry({
onClick={onClick}
role="button"
className={`py-4 px-2 relative flex items-center flex-col ${
selected ? "fill-white" : "fill-slate-500"
selected ? "fill-white text-white" : "fill-slate-500 text-slate-500"
}`}
>
{children}
{selected && (
<span className="absolute start-0 inset-y-0 bg-white w-0.5 rounded-full transition-opacity duration-150 opacity-100"></span>
<span className="absolute start-0 inset-y-0 bg-white w-0.5"></span>
)}
</li>
);

View file

@ -2,9 +2,9 @@
* Editor for the Python source code.
*/
import Editor, { useMonaco } from "@monaco-editor/react";
import Editor, { BeforeMount, Monaco } from "@monaco-editor/react";
import { MarkerSeverity, MarkerTag } from "monaco-editor";
import { useCallback, useEffect } from "react";
import { useCallback, useEffect, useRef } from "react";
import { Diagnostic } from "../pkg";
import { Theme } from "./theme";
@ -21,7 +21,8 @@ export default function SourceEditor({
theme: Theme;
onChange: (pythonSource: string) => void;
}) {
const monaco = useMonaco();
const monacoRef = useRef<Monaco | null>(null);
const monaco = monacoRef.current;
useEffect(() => {
const editor = monaco?.editor;
@ -98,14 +99,21 @@ export default function SourceEditor({
[onChange],
);
const handleMount: BeforeMount = useCallback(
(instance) => (monacoRef.current = instance),
[],
);
return (
<Editor
beforeMount={handleMount}
options={{
readOnly: false,
minimap: { enabled: false },
fontSize: 14,
roundedSelection: false,
scrollBeyondLastLine: false,
contextmenu: false,
}}
language={"python"}
wrapperProps={visible ? {} : { style: { display: "none" } }}

View file

@ -0,0 +1,719 @@
/**
* Non-rendering component that loads the Monaco editor themes.
*/
import { Monaco } from "@monaco-editor/react";
export const WHITE = "#ffffff";
export const RADIATE = "#d7ff64";
export const FLARE = "#6340ac";
export const ROCK = "#78876e";
export const GALAXY = "#261230";
export const SPACE = "#30173d";
export const COMET = "#6f5d6f";
export const COSMIC = "#de5fe9";
export const SUN = "#ffac2f";
export const ELECTRON = "#46ebe1";
export const AURORA = "#46eb74";
export const CONSTELLATION = "#5f6de9";
export const NEUTRON = "#cff3cf";
export const PROTON = "#f6afbc";
export const NEBULA = "#cdcbfb";
export const SUPERNOVA = "#f1aff6";
export const STARLIGHT = "#f4f4f1";
export const LUNAR = "#fbf2fc";
export const ASTEROID = "#e3cee3";
export const CRATER = "#f0dfdf";
export function setupMonaco(monaco: Monaco) {
defineAyuThemes(monaco);
defineFirLanguage(monaco);
defineRustPythonTokensLanguage(monaco);
defineRustPythonAstLanguage(monaco);
}
function defineAyuThemes(monaco: Monaco) {
// Generated via `monaco-vscode-textmate-theme-converter`.
// See: https://github.com/ayu-theme/vscode-ayu/blob/91839e8a9dfa78d61e58dbcf9b52272a01fee66a/ayu-light.json.
monaco.editor.defineTheme("Ayu-Light", {
inherit: false,
base: "vs",
colors: {
focusBorder: "#ffaa33b3",
foreground: "#8a9199",
"widget.shadow": "#00000026",
"selection.background": "#035bd626",
"icon.foreground": "#8a9199",
errorForeground: "#e65050",
descriptionForeground: "#8a9199",
"textBlockQuote.background": "#f3f4f5",
"textLink.foreground": "#ffaa33",
"textLink.activeForeground": "#ffaa33",
"textPreformat.foreground": "#5c6166",
"button.background": "#ffaa33",
"button.foreground": "#f8f9fa",
"button.hoverBackground": "#f9a52e",
"button.secondaryBackground": "#8a919933",
"button.secondaryForeground": "#5c6166",
"button.secondaryHoverBackground": "#8a919980",
"dropdown.background": "#fcfcfc",
"dropdown.foreground": "#8a9199",
"dropdown.border": "#8a919945",
"input.background": "#fcfcfc",
"input.border": "#8a919945",
"input.foreground": "#5c6166",
"input.placeholderForeground": "#8a919980",
"inputOption.activeBorder": "#f4a0284d",
"inputOption.activeBackground": "#ffaa3333",
"inputOption.activeForeground": "#f4a028",
"inputValidation.errorBackground": "#fcfcfc",
"inputValidation.errorBorder": "#e65050",
"inputValidation.infoBackground": "#f8f9fa",
"inputValidation.infoBorder": "#55b4d4",
"inputValidation.warningBackground": "#f8f9fa",
"inputValidation.warningBorder": "#f2ae49",
"scrollbar.shadow": "#6b7d8f00",
"scrollbarSlider.background": "#8a919966",
"scrollbarSlider.hoverBackground": "#8a919999",
"scrollbarSlider.activeBackground": "#8a9199b3",
"badge.background": "#ffaa3333",
"badge.foreground": "#f4a028",
"progressBar.background": "#ffaa33",
"list.activeSelectionBackground": "#56728f1f",
"list.activeSelectionForeground": "#5c6166",
"list.focusBackground": "#56728f1f",
"list.focusForeground": "#5c6166",
"list.focusOutline": "#56728f1f",
"list.highlightForeground": "#ffaa33",
"list.deemphasizedForeground": "#e65050",
"list.hoverBackground": "#56728f1f",
"list.inactiveSelectionBackground": "#6b7d8f1f",
"list.inactiveSelectionForeground": "#8a9199",
"list.invalidItemForeground": "#8a91994d",
"list.errorForeground": "#e65050",
"tree.indentGuidesStroke": "#8a919959",
"listFilterWidget.background": "#f3f4f5",
"listFilterWidget.outline": "#ffaa33",
"listFilterWidget.noMatchesOutline": "#e65050",
"list.filterMatchBackground": "#8f30efcc",
"list.filterMatchBorder": "#9f40ffcc",
"activityBar.background": "#f8f9fa",
"activityBar.foreground": "#8a9199cc",
"activityBar.inactiveForeground": "#8a919999",
"activityBar.border": "#f8f9fa",
"activityBar.activeBorder": "#ffaa33b3",
"activityBarBadge.background": "#ffaa33",
"activityBarBadge.foreground": "#f8f9fa",
"sideBar.background": "#f8f9fa",
"sideBar.border": "#f8f9fa",
"sideBarTitle.foreground": "#8a9199",
"sideBarSectionHeader.background": "#f8f9fa",
"sideBarSectionHeader.foreground": "#8a9199",
"sideBarSectionHeader.border": "#f8f9fa",
"minimap.background": "#f8f9fa",
"minimap.selectionHighlight": "#035bd626",
"minimap.errorHighlight": "#e65050",
"minimap.findMatchHighlight": "#9f40ff2b",
"minimapGutter.addedBackground": "#6cbf43",
"minimapGutter.modifiedBackground": "#478acc",
"minimapGutter.deletedBackground": "#ff7383",
"editorGroup.border": "#6b7d8f1f",
"editorGroup.background": "#f3f4f5",
"editorGroupHeader.noTabsBackground": "#f8f9fa",
"editorGroupHeader.tabsBackground": "#f8f9fa",
"editorGroupHeader.tabsBorder": "#f8f9fa",
"tab.activeBackground": "#f8f9fa",
"tab.activeForeground": "#5c6166",
"tab.border": "#f8f9fa",
"tab.activeBorder": "#ffaa33",
"tab.unfocusedActiveBorder": "#8a9199",
"tab.inactiveBackground": "#f8f9fa",
"tab.inactiveForeground": "#8a9199",
"tab.unfocusedActiveForeground": "#8a9199",
"tab.unfocusedInactiveForeground": "#8a9199",
"editor.background": "#f8f9fa",
"editor.foreground": "#5c6166",
"editorLineNumber.foreground": "#8a919966",
"editorLineNumber.activeForeground": "#8a9199cc",
"editorCursor.foreground": "#ffaa33",
"editor.inactiveSelectionBackground": "#035bd612",
"editor.selectionBackground": "#035bd626",
"editor.selectionHighlightBackground": "#6cbf4326",
"editor.selectionHighlightBorder": "#6cbf4300",
"editor.wordHighlightBackground": "#478acc14",
"editor.wordHighlightStrongBackground": "#6cbf4314",
"editor.wordHighlightBorder": "#478acc80",
"editor.wordHighlightStrongBorder": "#6cbf4380",
"editor.findMatchBackground": "#9f40ff2b",
"editor.findMatchBorder": "#9f40ff2b",
"editor.findMatchHighlightBackground": "#9f40ffcc",
"editor.findMatchHighlightBorder": "#8f30efcc",
"editor.findRangeHighlightBackground": "#9f40ff40",
"editor.rangeHighlightBackground": "#9f40ff33",
"editor.lineHighlightBackground": "#8a91991a",
"editorLink.activeForeground": "#ffaa33",
"editorWhitespace.foreground": "#8a919966",
"editorIndentGuide.background": "#8a91992e",
"editorIndentGuide.activeBackground": "#8a919959",
"editorRuler.foreground": "#8a91992e",
"editorCodeLens.foreground": "#787b8099",
"editorBracketMatch.background": "#8a91994d",
"editorBracketMatch.border": "#8a91994d",
"editor.snippetTabstopHighlightBackground": "#6cbf4333",
"editorOverviewRuler.border": "#6b7d8f1f",
"editorOverviewRuler.modifiedForeground": "#478acc",
"editorOverviewRuler.addedForeground": "#6cbf43",
"editorOverviewRuler.deletedForeground": "#ff7383",
"editorOverviewRuler.errorForeground": "#e65050",
"editorOverviewRuler.warningForeground": "#ffaa33",
"editorOverviewRuler.bracketMatchForeground": "#8a9199b3",
"editorOverviewRuler.wordHighlightForeground": "#478acc66",
"editorOverviewRuler.wordHighlightStrongForeground": "#6cbf4366",
"editorOverviewRuler.findMatchForeground": "#9f40ff2b",
"editorError.foreground": "#e65050",
"editorWarning.foreground": "#ffaa33",
"editorGutter.modifiedBackground": "#478acccc",
"editorGutter.addedBackground": "#6cbf43cc",
"editorGutter.deletedBackground": "#ff7383cc",
"diffEditor.insertedTextBackground": "#6cbf431f",
"diffEditor.removedTextBackground": "#ff73831f",
"diffEditor.diagonalFill": "#6b7d8f1f",
"editorWidget.background": "#f3f4f5",
"editorWidget.border": "#6b7d8f1f",
"editorHoverWidget.background": "#f3f4f5",
"editorHoverWidget.border": "#6b7d8f1f",
"editorSuggestWidget.background": "#f3f4f5",
"editorSuggestWidget.border": "#6b7d8f1f",
"editorSuggestWidget.highlightForeground": "#ffaa33",
"editorSuggestWidget.selectedBackground": "#56728f1f",
"debugExceptionWidget.border": "#6b7d8f1f",
"debugExceptionWidget.background": "#f3f4f5",
"editorMarkerNavigation.background": "#f3f4f5",
"peekView.border": "#56728f1f",
"peekViewTitle.background": "#56728f1f",
"peekViewTitleDescription.foreground": "#8a9199",
"peekViewTitleLabel.foreground": "#5c6166",
"peekViewEditor.background": "#f3f4f5",
"peekViewEditor.matchHighlightBackground": "#9f40ffcc",
"peekViewEditor.matchHighlightBorder": "#8f30efcc",
"peekViewResult.background": "#f3f4f5",
"peekViewResult.fileForeground": "#5c6166",
"peekViewResult.lineForeground": "#8a9199",
"peekViewResult.matchHighlightBackground": "#9f40ffcc",
"peekViewResult.selectionBackground": "#56728f1f",
"panel.background": "#f8f9fa",
"panel.border": "#6b7d8f1f",
"panelTitle.activeBorder": "#ffaa33",
"panelTitle.activeForeground": "#5c6166",
"panelTitle.inactiveForeground": "#8a9199",
"statusBar.background": "#f8f9fa",
"statusBar.foreground": "#8a9199",
"statusBar.border": "#f8f9fa",
"statusBar.debuggingBackground": "#ed9366",
"statusBar.debuggingForeground": "#fcfcfc",
"statusBar.noFolderBackground": "#f3f4f5",
"statusBarItem.activeBackground": "#8a919933",
"statusBarItem.hoverBackground": "#8a919933",
"statusBarItem.prominentBackground": "#6b7d8f1f",
"statusBarItem.prominentHoverBackground": "#00000030",
"statusBarItem.remoteBackground": "#ffaa33",
"statusBarItem.remoteForeground": "#fcfcfc",
"titleBar.activeBackground": "#f8f9fa",
"titleBar.activeForeground": "#5c6166",
"titleBar.inactiveBackground": "#f8f9fa",
"titleBar.inactiveForeground": "#8a9199",
"titleBar.border": "#f8f9fa",
"extensionButton.prominentForeground": "#fcfcfc",
"extensionButton.prominentBackground": "#ffaa33",
"extensionButton.prominentHoverBackground": "#f9a52e",
"pickerGroup.border": "#6b7d8f1f",
"pickerGroup.foreground": "#8a919980",
"debugToolBar.background": "#f3f4f5",
"debugIcon.breakpointForeground": "#ed9366",
"debugIcon.breakpointDisabledForeground": "#ed936680",
"debugConsoleInputIcon.foreground": "#ffaa33",
"welcomePage.tileBackground": "#f8f9fa",
"welcomePage.tileShadow": "#00000026",
"welcomePage.progress.background": "#8a91991a",
"welcomePage.buttonBackground": "#ffaa3366",
"walkThrough.embeddedEditorBackground": "#f3f4f5",
"gitDecoration.modifiedResourceForeground": "#478accb3",
"gitDecoration.deletedResourceForeground": "#ff7383b3",
"gitDecoration.untrackedResourceForeground": "#6cbf43b3",
"gitDecoration.ignoredResourceForeground": "#8a919980",
"gitDecoration.conflictingResourceForeground": "",
"gitDecoration.submoduleResourceForeground": "#a37accb3",
"settings.headerForeground": "#5c6166",
"settings.modifiedItemIndicator": "#478acc",
"keybindingLabel.background": "#8a91991a",
"keybindingLabel.foreground": "#5c6166",
"keybindingLabel.border": "#5c61661a",
"keybindingLabel.bottomBorder": "#5c61661a",
"terminal.background": "#f8f9fa",
"terminal.foreground": "#5c6166",
"terminal.ansiBlack": "#000000",
"terminal.ansiRed": "#ea6c6d",
"terminal.ansiGreen": "#6cbf43",
"terminal.ansiYellow": "#eca944",
"terminal.ansiBlue": "#3199e1",
"terminal.ansiMagenta": "#9e75c7",
"terminal.ansiCyan": "#46ba94",
"terminal.ansiWhite": "#c7c7c7",
"terminal.ansiBrightBlack": "#686868",
"terminal.ansiBrightRed": "#f07171",
"terminal.ansiBrightGreen": "#86b300",
"terminal.ansiBrightYellow": "#f2ae49",
"terminal.ansiBrightBlue": "#399ee6",
"terminal.ansiBrightMagenta": "#a37acc",
"terminal.ansiBrightCyan": "#4cbf99",
"terminal.ansiBrightWhite": "#d1d1d1",
},
rules: [
{
fontStyle: "italic",
foreground: "#787b8099",
token: "comment",
},
{
foreground: ROCK,
token: "string",
},
{
foreground: SUN,
token: "keyword",
},
{
foreground: CONSTELLATION,
token: "number",
},
{
token: "tag",
foreground: ROCK,
},
],
encodedTokensColors: [],
});
// Generated via `monaco-vscode-textmate-theme-converter`.
// See: https://github.com/ayu-theme/vscode-ayu/blob/91839e8a9dfa78d61e58dbcf9b52272a01fee66a/ayu-dark.json.
monaco.editor.defineTheme("Ayu-Dark", {
inherit: false,
base: "vs-dark",
colors: {
focusBorder: "#e6b450b3",
foreground: "#565b66",
"widget.shadow": "#00000080",
"selection.background": "#409fff4d",
"icon.foreground": "#565b66",
errorForeground: "#d95757",
descriptionForeground: "#565b66",
"textBlockQuote.background": "#0f131a",
"textLink.foreground": "#e6b450",
"textLink.activeForeground": "#e6b450",
"textPreformat.foreground": "#bfbdb6",
"button.background": "#e6b450",
"button.foreground": "#0b0e14",
"button.hoverBackground": "#e1af4b",
"button.secondaryBackground": "#565b6633",
"button.secondaryForeground": "#bfbdb6",
"button.secondaryHoverBackground": "#565b6680",
"dropdown.background": "#0d1017",
"dropdown.foreground": "#565b66",
"dropdown.border": "#565b6645",
"input.background": "#0d1017",
"input.border": "#565b6645",
"input.foreground": "#bfbdb6",
"input.placeholderForeground": "#565b6680",
"inputOption.activeBorder": "#e6b4504d",
"inputOption.activeBackground": "#e6b45033",
"inputOption.activeForeground": "#e6b450",
"inputValidation.errorBackground": "#0d1017",
"inputValidation.errorBorder": "#d95757",
"inputValidation.infoBackground": "#0b0e14",
"inputValidation.infoBorder": "#39bae6",
"inputValidation.warningBackground": "#0b0e14",
"inputValidation.warningBorder": "#ffb454",
"scrollbar.shadow": "#11151c00",
"scrollbarSlider.background": "#565b6666",
"scrollbarSlider.hoverBackground": "#565b6699",
"scrollbarSlider.activeBackground": "#565b66b3",
"badge.background": "#e6b45033",
"badge.foreground": "#e6b450",
"progressBar.background": "#e6b450",
"list.activeSelectionBackground": "#47526640",
"list.activeSelectionForeground": "#bfbdb6",
"list.focusBackground": "#47526640",
"list.focusForeground": "#bfbdb6",
"list.focusOutline": "#47526640",
"list.highlightForeground": "#e6b450",
"list.deemphasizedForeground": "#d95757",
"list.hoverBackground": "#47526640",
"list.inactiveSelectionBackground": "#47526633",
"list.inactiveSelectionForeground": "#565b66",
"list.invalidItemForeground": "#565b664d",
"list.errorForeground": "#d95757",
"tree.indentGuidesStroke": "#6c738080",
"listFilterWidget.background": "#0f131a",
"listFilterWidget.outline": "#e6b450",
"listFilterWidget.noMatchesOutline": "#d95757",
"list.filterMatchBackground": "#5f4c7266",
"list.filterMatchBorder": "#6c598066",
"activityBar.background": "#0b0e14",
"activityBar.foreground": "#565b66cc",
"activityBar.inactiveForeground": "#565b6699",
"activityBar.border": "#0b0e14",
"activityBar.activeBorder": "#e6b450b3",
"activityBarBadge.background": "#e6b450",
"activityBarBadge.foreground": "#0b0e14",
"sideBar.background": "#0b0e14",
"sideBar.border": "#0b0e14",
"sideBarTitle.foreground": "#565b66",
"sideBarSectionHeader.background": "#0b0e14",
"sideBarSectionHeader.foreground": "#565b66",
"sideBarSectionHeader.border": "#0b0e14",
"minimap.background": "#0b0e14",
"minimap.selectionHighlight": "#409fff4d",
"minimap.errorHighlight": "#d95757",
"minimap.findMatchHighlight": "#6c5980",
"minimapGutter.addedBackground": "#7fd962",
"minimapGutter.modifiedBackground": "#73b8ff",
"minimapGutter.deletedBackground": "#f26d78",
"editorGroup.border": "#11151c",
"editorGroup.background": "#0f131a",
"editorGroupHeader.noTabsBackground": "#0b0e14",
"editorGroupHeader.tabsBackground": "#0b0e14",
"editorGroupHeader.tabsBorder": "#0b0e14",
"tab.activeBackground": "#0b0e14",
"tab.activeForeground": "#bfbdb6",
"tab.border": "#0b0e14",
"tab.activeBorder": "#e6b450",
"tab.unfocusedActiveBorder": "#565b66",
"tab.inactiveBackground": "#0b0e14",
"tab.inactiveForeground": "#565b66",
"tab.unfocusedActiveForeground": "#565b66",
"tab.unfocusedInactiveForeground": "#565b66",
"editor.background": "#0b0e14",
"editor.foreground": "#bfbdb6",
"editorLineNumber.foreground": "#6c738099",
"editorLineNumber.activeForeground": "#6c7380e6",
"editorCursor.foreground": "#e6b450",
"editor.inactiveSelectionBackground": "#409fff21",
"editor.selectionBackground": "#409fff4d",
"editor.selectionHighlightBackground": "#7fd96226",
"editor.selectionHighlightBorder": "#7fd96200",
"editor.wordHighlightBackground": "#73b8ff14",
"editor.wordHighlightStrongBackground": "#7fd96214",
"editor.wordHighlightBorder": "#73b8ff80",
"editor.wordHighlightStrongBorder": "#7fd96280",
"editor.findMatchBackground": "#6c5980",
"editor.findMatchBorder": "#6c5980",
"editor.findMatchHighlightBackground": "#6c598066",
"editor.findMatchHighlightBorder": "#5f4c7266",
"editor.findRangeHighlightBackground": "#6c598040",
"editor.rangeHighlightBackground": "#6c598033",
"editor.lineHighlightBackground": "#131721",
"editorLink.activeForeground": "#e6b450",
"editorWhitespace.foreground": "#6c738099",
"editorIndentGuide.background": "#6c738033",
"editorIndentGuide.activeBackground": "#6c738080",
"editorRuler.foreground": "#6c738033",
"editorCodeLens.foreground": "#acb6bf8c",
"editorBracketMatch.background": "#6c73804d",
"editorBracketMatch.border": "#6c73804d",
"editor.snippetTabstopHighlightBackground": "#7fd96233",
"editorOverviewRuler.border": "#11151c",
"editorOverviewRuler.modifiedForeground": "#73b8ff",
"editorOverviewRuler.addedForeground": "#7fd962",
"editorOverviewRuler.deletedForeground": "#f26d78",
"editorOverviewRuler.errorForeground": "#d95757",
"editorOverviewRuler.warningForeground": "#e6b450",
"editorOverviewRuler.bracketMatchForeground": "#6c7380b3",
"editorOverviewRuler.wordHighlightForeground": "#73b8ff66",
"editorOverviewRuler.wordHighlightStrongForeground": "#7fd96266",
"editorOverviewRuler.findMatchForeground": "#6c5980",
"editorError.foreground": "#d95757",
"editorWarning.foreground": "#e6b450",
"editorGutter.modifiedBackground": "#73b8ffcc",
"editorGutter.addedBackground": "#7fd962cc",
"editorGutter.deletedBackground": "#f26d78cc",
"diffEditor.insertedTextBackground": "#7fd9621f",
"diffEditor.removedTextBackground": "#f26d781f",
"diffEditor.diagonalFill": "#11151c",
"editorWidget.background": "#0f131a",
"editorWidget.border": "#11151c",
"editorHoverWidget.background": "#0f131a",
"editorHoverWidget.border": "#11151c",
"editorSuggestWidget.background": "#0f131a",
"editorSuggestWidget.border": "#11151c",
"editorSuggestWidget.highlightForeground": "#e6b450",
"editorSuggestWidget.selectedBackground": "#47526640",
"debugExceptionWidget.border": "#11151c",
"debugExceptionWidget.background": "#0f131a",
"editorMarkerNavigation.background": "#0f131a",
"peekView.border": "#47526640",
"peekViewTitle.background": "#47526640",
"peekViewTitleDescription.foreground": "#565b66",
"peekViewTitleLabel.foreground": "#bfbdb6",
"peekViewEditor.background": "#0f131a",
"peekViewEditor.matchHighlightBackground": "#6c598066",
"peekViewEditor.matchHighlightBorder": "#5f4c7266",
"peekViewResult.background": "#0f131a",
"peekViewResult.fileForeground": "#bfbdb6",
"peekViewResult.lineForeground": "#565b66",
"peekViewResult.matchHighlightBackground": "#6c598066",
"peekViewResult.selectionBackground": "#47526640",
"panel.background": "#0b0e14",
"panel.border": "#11151c",
"panelTitle.activeBorder": "#e6b450",
"panelTitle.activeForeground": "#bfbdb6",
"panelTitle.inactiveForeground": "#565b66",
"statusBar.background": "#0b0e14",
"statusBar.foreground": "#565b66",
"statusBar.border": "#0b0e14",
"statusBar.debuggingBackground": "#f29668",
"statusBar.debuggingForeground": "#0d1017",
"statusBar.noFolderBackground": "#0f131a",
"statusBarItem.activeBackground": "#565b6633",
"statusBarItem.hoverBackground": "#565b6633",
"statusBarItem.prominentBackground": "#11151c",
"statusBarItem.prominentHoverBackground": "#00000030",
"statusBarItem.remoteBackground": "#e6b450",
"statusBarItem.remoteForeground": "#0d1017",
"titleBar.activeBackground": "#0b0e14",
"titleBar.activeForeground": "#bfbdb6",
"titleBar.inactiveBackground": "#0b0e14",
"titleBar.inactiveForeground": "#565b66",
"titleBar.border": "#0b0e14",
"extensionButton.prominentForeground": "#0d1017",
"extensionButton.prominentBackground": "#e6b450",
"extensionButton.prominentHoverBackground": "#e1af4b",
"pickerGroup.border": "#11151c",
"pickerGroup.foreground": "#565b6680",
"debugToolBar.background": "#0f131a",
"debugIcon.breakpointForeground": "#f29668",
"debugIcon.breakpointDisabledForeground": "#f2966880",
"debugConsoleInputIcon.foreground": "#e6b450",
"welcomePage.tileBackground": "#0b0e14",
"welcomePage.tileShadow": "#00000080",
"welcomePage.progress.background": "#131721",
"welcomePage.buttonBackground": "#e6b45066",
"walkThrough.embeddedEditorBackground": "#0f131a",
"gitDecoration.modifiedResourceForeground": "#73b8ffb3",
"gitDecoration.deletedResourceForeground": "#f26d78b3",
"gitDecoration.untrackedResourceForeground": "#7fd962b3",
"gitDecoration.ignoredResourceForeground": "#565b6680",
"gitDecoration.conflictingResourceForeground": "",
"gitDecoration.submoduleResourceForeground": "#d2a6ffb3",
"settings.headerForeground": "#bfbdb6",
"settings.modifiedItemIndicator": "#73b8ff",
"keybindingLabel.background": "#565b661a",
"keybindingLabel.foreground": "#bfbdb6",
"keybindingLabel.border": "#bfbdb61a",
"keybindingLabel.bottomBorder": "#bfbdb61a",
"terminal.background": "#0b0e14",
"terminal.foreground": "#bfbdb6",
"terminal.ansiBlack": "#11151c",
"terminal.ansiRed": "#ea6c73",
"terminal.ansiGreen": "#7fd962",
"terminal.ansiYellow": "#f9af4f",
"terminal.ansiBlue": "#53bdfa",
"terminal.ansiMagenta": "#cda1fa",
"terminal.ansiCyan": "#90e1c6",
"terminal.ansiWhite": "#c7c7c7",
"terminal.ansiBrightBlack": "#686868",
"terminal.ansiBrightRed": "#f07178",
"terminal.ansiBrightGreen": "#aad94c",
"terminal.ansiBrightYellow": "#ffb454",
"terminal.ansiBrightBlue": "#59c2ff",
"terminal.ansiBrightMagenta": "#d2a6ff",
"terminal.ansiBrightCyan": "#95e6cb",
"terminal.ansiBrightWhite": "#ffffff",
},
rules: [
{
fontStyle: "italic",
foreground: "#acb6bf8c",
token: "comment",
},
{
foreground: RADIATE,
token: "string",
},
{
foreground: ELECTRON,
token: "number",
},
{
foreground: STARLIGHT,
token: "identifier",
},
{
foreground: SUN,
token: "keyword",
},
{
foreground: PROTON,
token: "tag",
},
{
foreground: ASTEROID,
token: "delimiter",
},
],
encodedTokensColors: [],
});
}
// https://microsoft.github.io/monaco-editor/monarch.html
function defineRustPythonAstLanguage(monaco: Monaco) {
monaco.languages.register({
id: "RustPythonAst",
});
monaco.languages.setMonarchTokensProvider("RustPythonAst", {
keywords: ["None", "Err"],
tokenizer: {
root: [
[
/[a-zA-Z_$][\w$]*/,
{
cases: {
"@keywords": "keyword",
"@default": "identifier",
},
},
],
// Whitespace
[/[ \t\r\n]+/, "white"],
// Strings
[/"/, { token: "string.quote", bracket: "@open", next: "@string" }],
[/\d+/, "number"],
[/[{}()[\]]/, "@brackets"],
],
string: [
[/[^\\"]+/, "string"],
[/"/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],
},
brackets: [
{
open: "(",
close: ")",
token: "delimiter.parenthesis",
},
{
open: "{",
close: "}",
token: "delimiter.curly",
},
{
open: "[",
close: "]",
token: "delimiter.bracket",
},
],
});
}
function defineRustPythonTokensLanguage(monaco: Monaco) {
monaco.languages.register({
id: "RustPythonTokens",
});
monaco.languages.setMonarchTokensProvider("RustPythonTokens", {
keywords: ["Ok", "Err"],
tokenizer: {
root: [
[
/[a-zA-Z_$][\w$]*/,
{
cases: {
"@keywords": "keyword",
"@default": "identifier",
},
},
],
// Whitespace
[/[ \t\r\n]+/, "white"],
// Strings
[/"/, { token: "string.quote", bracket: "@open", next: "@string" }],
[/\d+/, "number"],
[/[{}()[\]]/, "@brackets"],
],
string: [
[/[^\\"]+/, "string"],
[/"/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],
},
brackets: [
{
open: "(",
close: ")",
token: "delimiter.parenthesis",
},
{
open: "{",
close: "}",
token: "delimiter.curly",
},
{
open: "[",
close: "]",
token: "delimiter.bracket",
},
],
});
}
function defineFirLanguage(monaco: Monaco) {
monaco.languages.register({
id: "fir",
});
monaco.languages.setMonarchTokensProvider("fir", {
tokenizer: {
root: [
[/[a-z_$][\w$]*/, "keyword"],
// Whitespace
[/[ \t\r\n]+/, "white"],
[/[{}()[\]<>]/, "@brackets"],
// Strings
[/"/, { token: "string.quote", bracket: "@open", next: "@string" }],
[/\d+/, "number"],
],
string: [
[/[^\\"]+/, "string"],
[/"/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],
},
brackets: [
{
open: "(",
close: ")",
token: "delimiter.parenthesis",
},
{
open: "[",
close: "]",
token: "delimiter.bracket",
},
{
open: "<",
close: ">",
token: "delimiter.angle",
},
],
});
}

View file

@ -2,6 +2,10 @@ import React from "react";
import ReactDOM from "react-dom/client";
import Editor from "./Editor";
import "./index.css";
import { loader } from "@monaco-editor/react";
import { setupMonaco } from "./Editor/setupMonaco";
loader.init().then(setupMonaco);
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>