Skip to content

CodeEditor Plugins

Ambystech.Elaris.UI.CodeEditor.Plugins is an optional package that extends the CodeEditor widget with JSON-driven syntax rules and themes. Languages and color schemes can be added without recompiling — drop a JSON file into a directory and register it at startup.

The core CodeEditor ships with built-in rules for csharp, javascript, and python, plus a default theme. This package adds two providers that plug into PluginManager:

  • JsonSyntaxRuleProvider — loads language rules from .json files in a directory.
  • JsonThemeProvider — loads color themes from .json files in a directory.

Both providers are lazy (files are parsed on first use), cached (in memory per process), and thread-safe. When a language or theme isn’t found in the plugin directory, CodeEditor transparently falls back to the built-in provider.

Terminal window
dotnet add package Ambystech.Elaris.UI.CodeEditor.Plugins

The package targets .NET 8 and .NET 9 and depends on the core Ambystech.Elaris.UI library.

Call PluginInitializer.Initialize once at startup, pointing it at the directories that contain your JSON files. Either argument may be null if you only need one kind of plugin.

using Ambystech.Elaris.UI.CodeEditor.Plugins;
PluginInitializer.Initialize(
syntaxRulesDirectory: "plugins/syntax",
themesDirectory: "plugins/themes"
);

After initialization, any CodeEditor instance can reference the new languages and themes by name:

var codeEditor = new CodeEditor
{
Language = "rust", // loaded from plugins/syntax/rust.json
Theme = "monokai" // loaded from plugins/themes/monokai.json
};

The file name (without extension) is the identifier used at runtime:

plugins/
├── syntax/
│ ├── rust.json
│ ├── go.json
│ └── ...
└── themes/
├── monokai.json
├── solarized.json
└── ...

Each syntax rule file describes how to tokenize a single language.

{
"language": "rust",
"keywords": ["fn", "let", "mut", "pub", "struct", "enum"],
"stringDelimiters": ["\"", "r#\""],
"commentPatterns": ["//.*", "/\\*.*?\\*/"],
"numberPattern": "\\b\\d+(\\.\\d+)?\\b",
"bracketPairs": {
"(": ")",
"[": "]",
"{": "}"
}
}
FieldTypeDescription
languagestringThe identifier used in CodeEditor.Language.
keywordsstring[]Reserved words highlighted as keywords.
stringDelimitersstring[]Delimiter pairs that open and close string literals.
commentPatternsstring[] (regex)Patterns matched against the start of remaining text on a line.
numberPatternstring (regex)Pattern used to detect numeric literals.
bracketPairsobject (char → char)Opening-to-closing bracket mapping used for bracket matching.

Each theme file maps token types to 24-bit RGB colors.

{
"name": "monokai",
"displayName": "Monokai",
"colors": {
"Keyword": { "r": 249, "g": 38, "b": 114 },
"String": { "r": 230, "g": 219, "b": 116 },
"Comment": { "r": 117, "g": 113, "b": 94 },
"Number": { "r": 174, "g": 129, "b": 255 },
"Operator": { "r": 248, "g": 248, "b": 242 },
"Identifier": { "r": 248, "g": 248, "b": 242 }
}
}
FieldTypeDescription
namestringThe identifier used in CodeEditor.Theme.
displayNamestringHuman-readable label (used by tools and demos).
colorsobjectToken-type name → { r, g, b } color. Unmapped token types fall back to the widget’s ForegroundColor.
  • Keyword — language keywords
  • String — string literals
  • Comment — line and block comments
  • Number — numeric literals
  • Operator — operators and punctuation
  • Identifier — identifiers and variable names
  • Lazy loading. JSON files are parsed the first time a language or theme is requested, not at registration time. Invalid files fail on first use, not at startup.
  • Caching. Parsed rules and themes are cached in memory for the lifetime of the process.
  • Fallback. When a requested language or theme isn’t found in any registered provider, CodeEditor falls back to the built-ins (csharp / default).
  • Multiple providers. You may register the JSON providers alongside custom providers; PluginManager resolves requests in registration order.