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
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>