-
Notifications
You must be signed in to change notification settings - Fork 0
Theme Authoring
This page covers built-in theme families contributed to Neotheme. User configuration should use the complete semantic palette described in Palette Customization.
A built-in module must return a complete NeothemePalette. It can:
- Define every semantic role directly.
- Define a compact
NeothemeSimplifiedPaletteand call the family-neutral transform.
All current built-in families use the simplified model because related semantic roles intentionally reuse the same configured colors.
local transform = require("neotheme.themes.simplified").transform
---@type NeothemeSimplifiedPalette
local simplified = {
-- Supply every required field from the schema below.
}
return transform(simplified)Keep raw color literals in this theme definition. Highlight and integration modules consume semantic roles and must not special-case a family or variant.
All surface inputs are required and map directly to the same complete-palette role:
surface_deepestsurface_darksurface_basesurface_raisedsurface_selectedsurface_bordersurface_mutedsurface_additionsurface_error
| Input | Complete role | Fallback |
|---|---|---|
text_primary |
text.primary |
Required |
text_bright |
text.bright |
Required |
text_strong |
text.strong |
Required |
text_muted |
text.muted |
syntax_type |
text_on_accent |
text.on_accent |
surface_deepest |
text_on_error |
text.on_error |
Required |
text_muted and text_on_accent are optional. Every other simplified field is required.
Required syntax inputs:
syntax_commentsyntax_stringsyntax_keywordsyntax_function_namesyntax_typesyntax_propertysyntax_literaldiagnostic_errorversion_control_conflict
The transformer maps direct syntax inputs and derives related roles as follows:
| Complete role or roles | Simplified source |
|---|---|
syntax.comment |
syntax_comment |
syntax.string |
syntax_string |
syntax.keyword, syntax.operator
|
syntax_keyword |
syntax.function_name, syntax.tag
|
syntax_function_name |
syntax.type, syntax.attribute
|
syntax_type |
syntax.property |
syntax_property |
syntax.literal |
syntax_literal |
syntax.punctuation |
text_bright |
syntax.regexp, syntax.special
|
diagnostic_error |
diagnostic.error |
diagnostic_error |
diagnostic.warning |
syntax_keyword |
diagnostic.information |
syntax_function_name |
diagnostic.hint |
syntax_literal |
diagnostic.success |
syntax_string |
markup.heading_1, markup.link_label, markup.list
|
syntax_keyword |
markup.heading_2, markup.link
|
syntax_function_name |
markup.heading_3, markup.raw, markup.checked
|
syntax_string |
markup.heading_4, markup.math
|
syntax_literal |
markup.heading_5, markup.unchecked
|
syntax_type |
markup.heading_6, markup.quote
|
syntax_comment |
version_control.added |
syntax_string |
version_control.changed |
syntax_keyword |
version_control.removed |
diagnostic_error |
version_control.ignored |
surface_muted |
version_control.conflict |
version_control_conflict |
ui.accent, ui.cursor, ui.search
|
syntax_keyword |
ui.directory |
syntax_function_name |
ui.current_search |
text_on_error |
ui.match |
syntax_literal |
ui.focus |
text_strong |
The transformer contains no family-specific values or names, so new families can use the same model when their reuse pattern matches.
Add the module to the private registry with its public name and background metadata:
local modules = {
["family-variant"] = {
module = "neotheme.themes.family.variant",
background = "dark",
family = "family",
},
}Then update the NeothemeOptions.theme annotation so editor tooling exposes the new public name.
Neotheme does not create a separate colors/<theme>.lua file. All built-in variants use colors/neotheme.lua.
The built-in contract should verify:
- The public name appears in
themes(). - The family appears in
families()andthemes(family)returns the member. - Every semantic palette path resolves to a six-digit color.
- The theme can be selected and loaded.
- Its
backgroundmetadata is applied. - Returned palettes and name lists are mutation-safe copies.
Do not add exact hex-value assertions for curated built-in colors. Tests should protect registry, completeness, selection, copying, and semantic behavior.
For a new built-in variant:
- Add it to the relevant
docs/themes/<family>/README.mdinventory. - Add a new family to the root README and Themes family tables.
- Regenerate the family previews and matrices with
assets/scripts/generate-theme-assets.sh. - Confirm
:NeothemeList <family>and the visual browser expose it.
The portable asset tools and dependencies are documented in the repository's assets/scripts/README.md.