diff --git a/src/components/header.tsx b/src/components/header.tsx
index 495ed12..2bdb12c 100644
--- a/src/components/header.tsx
+++ b/src/components/header.tsx
@@ -3,7 +3,7 @@
import { useEditor } from "./editor-provider";
import { Button, buttonVariants } from "~/components/ui/button";
import { THEME_MAP } from "~/utils/themes";
-import { LANGUAGES } from "~/utils/languages";
+import { LANGUAGE_NAMES } from "~/utils/languages";
import { SaveButton } from "./save-button";
import { SearchableSelect } from "./searchable-select";
import { Icons } from "./icons";
@@ -44,7 +44,7 @@ export function Header() {
({ value: l, label: l }))}
+ options={LANGUAGE_NAMES.map((l) => ({ value: l, label: l }))}
placeholder="language"
value={language}
onValueChange={setLanguage}
diff --git a/src/components/monaco-editor.tsx b/src/components/monaco-editor.tsx
index 12b9642..61a2a62 100644
--- a/src/components/monaco-editor.tsx
+++ b/src/components/monaco-editor.tsx
@@ -10,7 +10,7 @@ import {
} from "monaco-editor-auto-typings/custom-editor";
import { useEditor } from "./editor-provider";
import { THEME_MAP } from "~/utils/themes";
-import { LANGUAGES } from "~/utils/languages";
+import { LANGUAGES, LANGUAGE_NAMES } from "~/utils/languages";
export function MonacoEditor() {
const { language, theme, content, setContent } = useEditor();
@@ -32,8 +32,8 @@ export function MonacoEditor() {
.filter(([key]) => key !== theme)
.map(([key, value]) => value.theme ?? key);
- LANGUAGES.forEach((l) => monaco.languages.register({ id: l }));
-
+ LANGUAGE_NAMES.forEach((l) => monaco.languages.register({ id: l }));
+
const highlighter = await createHighlighter({
themes: [currentTheme, ...restThemes],
langs: LANGUAGES,
diff --git a/src/utils/languages.ts b/src/utils/languages.ts
index 43a4eb9..4a989b8 100644
--- a/src/utils/languages.ts
+++ b/src/utils/languages.ts
@@ -1,3 +1,5 @@
+import sfml from "./languages/sfml.json";
+
export const LANGUAGES = [
"text",
"abap",
@@ -208,4 +210,9 @@ export const LANGUAGES = [
"yaml",
// "zenscript",
"zig",
+ sfml,
];
+
+export const LANGUAGE_NAMES = LANGUAGES.map((l) =>
+ typeof l === "string" ? l : l.name,
+);
diff --git a/src/utils/languages/sfml.json b/src/utils/languages/sfml.json
new file mode 100644
index 0000000..ba30f74
--- /dev/null
+++ b/src/utils/languages/sfml.json
@@ -0,0 +1,116 @@
+{
+ "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
+ "name": "sfml",
+ "patterns": [
+ {
+ "include": "#keywords"
+ },
+ {
+ "include": "#strings"
+ },
+ {
+ "include": "#numbers"
+ },
+ {
+ "include": "#comments"
+ }
+ ],
+ "repository": {
+ "keywords": {
+ "patterns": [
+ {
+ "name": "variable.parameter.sfml",
+ "match": "(?i)\\b(TICKS|TICK)\\b"
+ },
+ {
+ "name": "variable.parameter.sfml",
+ "match": "(?i)\\b(FLUID|GAS|ITEM|FE)\\b\\s*:\\s*(\\S+)"
+ },
+ {
+ "name": "variable.parameter.sfml",
+ "match": "(?i)(?<=INPUT\\s)(.*?)\\s+(?=FROM|EXCEPT|RETAIN|WITH|WITHOUT)"
+ },
+ {
+ "name": "variable.parameter.sfml",
+ "match": "(?i)(?<=OUTPUT\\s)(.*?)\\s+(?=TO|EXCEPT|RETAIN|WITH|WITHOUT)"
+ },
+
+ {
+ "name": "storage.type.primitive.sfml",
+ "match": "(?i)\\b(FORGET)\\b"
+ },
+ {
+ "name": "storage.type.primitive.sfml",
+ "match": "(?i)\\bROUND(\\s+ROBIN(\\s+BY(\\s+(LABEL|BLOCK))?)?)?\\b"
+ },
+ {
+ "name": "storage.type.primitive.sfml",
+ "match": "(?i)(?<=\\s)(EQ|GT|LT|LE|GE)(?=\\s)"
+ },
+ {
+ "name": "storage.type.primitive.sfml",
+ "match": "(?<=\\s)(=|>|<|<=|>=)(?=\\s)"
+ },
+
+ {
+ "name": "keyword.control.sfml",
+ "match": "(?i)\\b(EXCEPT|MOVE|FROM|TO|INPUT|OUTPUT|WHERE|SLOTS|RETAIN|EACH|TOP|BOTTOM|NORTH|EAST|SOUTH|WEST|SIDE|SELF|SECONDS|EVERY|PULSE|WORLD|PROGRAM|WITH|WITHOUT)\\b"
+ },
+
+ {
+ "name": "storage.type.name.sfml",
+ "match": "(?i)\\b(NAME)\\b"
+ },
+
+ {
+ "name": "keyword.control.flow.sfml",
+ "match": "(?i)\\b(DO|END|IF|ELSE|THEN)\\b"
+ },
+
+ {
+ "name": "invalid",
+ "match": "(?i)(?<=\\bEVERY\\s+)REDSTONE(?=\\s+PULSE\\b)"
+ },
+ {
+ "name": "invalid",
+ "match": "(?i)(?<=\\bIF\\s+)REDSTONE(?=\\s+(EQ|GT|LT|LE|GE)\\b)"
+ }
+ ]
+
+ },
+ "comments": {
+ "patterns": [
+ {
+ "begin": "--",
+ "beginCaptures": {
+ "0": {
+ "name": "punctuation.definition.comment.sfml"
+ }
+ },
+ "end": "\\n",
+ "name": "comment.line.double-dash.sfml"
+ }
+ ]
+ },
+ "numbers": {
+ "patterns": [
+ {
+ "name": "constant.numeric.sfml",
+ "match": "\\b\\d+\\b"
+ }
+ ]
+ },
+ "strings": {
+ "name": "string.quoted.double.sfml",
+ "begin": "\"",
+ "end": "\"",
+ "patterns": [
+ {
+ "name": "constant.character.escape.sfml",
+ "match": "\\\\."
+ }
+ ]
+ }
+ },
+ "scopeName": "source.sfml"
+}
diff --git a/src/utils/themes.ts b/src/utils/themes.ts
index b2ffc18..dc93694 100644
--- a/src/utils/themes.ts
+++ b/src/utils/themes.ts
@@ -1,7 +1,7 @@
import { ThemeInput } from "shiki";
-import horizonTheme from "./custom/horizon.json";
-import shadesOfPurpleTheme from "./custom/shades-of-purple.json";
-import darkSquaredTheme from "./custom/dark-squared.json";
+import horizonTheme from "./themes/horizon.json";
+import shadesOfPurpleTheme from "./themes/shades-of-purple.json";
+import darkSquaredTheme from "./themes/dark-squared.json";
type ShadCnKeys =
| "background"
diff --git a/src/utils/custom/dark-squared.json b/src/utils/themes/dark-squared.json
similarity index 100%
rename from src/utils/custom/dark-squared.json
rename to src/utils/themes/dark-squared.json
diff --git a/src/utils/custom/horizon.json b/src/utils/themes/horizon.json
similarity index 100%
rename from src/utils/custom/horizon.json
rename to src/utils/themes/horizon.json
diff --git a/src/utils/custom/shades-of-purple.json b/src/utils/themes/shades-of-purple.json
similarity index 100%
rename from src/utils/custom/shades-of-purple.json
rename to src/utils/themes/shades-of-purple.json