refactor: restructure dist/ and implement aggregated Zed theme
- Updated build.py to support app-centric directory structure (dist/<app>/). - Modified build.py to allow aggregated multi-scheme rendering (for Zed). - Refactored Zed template to include both Neon and Aeon variants in a single JSON. - Standardized theme file naming in dist/.
This commit is contained in:
87
build.py
87
build.py
@@ -6,7 +6,7 @@ from jinja2 import Environment, FileSystemLoader
|
||||
SRC_DIR = 'src'
|
||||
TEMPLATES_DIR = 'templates'
|
||||
DIST_DIR = 'dist'
|
||||
SCHEMES = ['neon.yaml', 'aeon.yaml']
|
||||
SCHEME_FILES = ['neon.yaml', 'aeon.yaml']
|
||||
|
||||
def load_scheme(filename):
|
||||
with open(os.path.join(SRC_DIR, filename), 'r') as f:
|
||||
@@ -18,47 +18,72 @@ def render_template(template_path, context):
|
||||
return template.render(context)
|
||||
|
||||
def build():
|
||||
# Load all schemes first
|
||||
schemes = []
|
||||
for f in SCHEME_FILES:
|
||||
schemes.append(load_scheme(f))
|
||||
|
||||
# Ensure dist directory exists
|
||||
if not os.path.exists(DIST_DIR):
|
||||
os.makedirs(DIST_DIR)
|
||||
|
||||
for scheme_file in SCHEMES:
|
||||
scheme_data = load_scheme(scheme_file)
|
||||
scheme_name_slug = scheme_data['scheme'].lower().replace(' ', '-')
|
||||
print(f"Building {scheme_data['scheme']}...")
|
||||
# Walk through templates
|
||||
for root, dirs, files in os.walk(TEMPLATES_DIR):
|
||||
for file in files:
|
||||
if not file.endswith('.j2'):
|
||||
continue
|
||||
|
||||
# Find all templates
|
||||
for root, dirs, files in os.walk(TEMPLATES_DIR):
|
||||
for file in files:
|
||||
if file.endswith('.j2'):
|
||||
# Calculate relative path to mirror structure in dist
|
||||
rel_path = os.path.relpath(root, TEMPLATES_DIR)
|
||||
template_rel_path = os.path.join(rel_path, file)
|
||||
rel_path = os.path.relpath(root, TEMPLATES_DIR)
|
||||
app_name = rel_path # e.g., 'nvim', 'zed', 'kitty'
|
||||
|
||||
template_rel_path = os.path.join(rel_path, file)
|
||||
output_filename_base = file.replace('.j2', '')
|
||||
|
||||
# Create app directory in dist
|
||||
app_dist_dir = os.path.join(DIST_DIR, app_name)
|
||||
if not os.path.exists(app_dist_dir):
|
||||
os.makedirs(app_dist_dir)
|
||||
|
||||
print(f"Processing template: {template_rel_path}")
|
||||
|
||||
# Special case for Zed: Aggregated output (single JSON for all themes)
|
||||
if app_name == 'zed':
|
||||
context = {'schemes': schemes}
|
||||
rendered_content = render_template(template_rel_path, context)
|
||||
|
||||
# Output file: dist/zed/apex.json (matches base name)
|
||||
output_path = os.path.join(app_dist_dir, output_filename_base)
|
||||
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(rendered_content)
|
||||
print(f" -> {output_path} (Aggregated)")
|
||||
|
||||
# Default behavior: Per-scheme output
|
||||
else:
|
||||
for scheme in schemes:
|
||||
scheme_slug = scheme['scheme'].lower().replace(' ', '-')
|
||||
|
||||
# Prepare output path
|
||||
output_filename = file.replace('.j2', '')
|
||||
# If the template is generic (apex.lua), rename it to the scheme name (apex-neon.lua)
|
||||
if 'apex' in output_filename:
|
||||
output_filename = output_filename.replace('apex', scheme_name_slug)
|
||||
# Rename output file: e.g., apex.conf -> apex-neon.conf
|
||||
# or apex.lua -> apex-neon.lua
|
||||
# If filename is generic 'apex', replace with slug.
|
||||
# If filename is 'apex.lua', result 'apex-neon.lua'
|
||||
|
||||
output_dir = os.path.join(DIST_DIR, scheme_name_slug, rel_path)
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
if 'apex' in output_filename_base:
|
||||
final_filename = output_filename_base.replace('apex', f"apex-{scheme_slug.replace('apex-', '')}")
|
||||
else:
|
||||
final_filename = f"{scheme_slug}-{output_filename_base}"
|
||||
|
||||
# Clean up double prefixes if any (e.g. apex-apex-neon)
|
||||
final_filename = final_filename.replace('apex-apex-', 'apex-')
|
||||
|
||||
output_path = os.path.join(app_dist_dir, final_filename)
|
||||
|
||||
output_path = os.path.join(output_dir, output_filename)
|
||||
|
||||
# Render and write
|
||||
# We pass template_rel_path because jinja loader is rooted at TEMPLATES_DIR
|
||||
# But os.walk returns paths relative to CWD usually, but we constructed it.
|
||||
# Actually Environment loader is correct. We just need the path relative to templates dir.
|
||||
template_name_for_jinja = template_rel_path
|
||||
|
||||
rendered_content = render_template(template_name_for_jinja, scheme_data)
|
||||
rendered_content = render_template(template_rel_path, scheme)
|
||||
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(rendered_content)
|
||||
|
||||
print(f" -> {output_path}")
|
||||
print(f" -> {output_path} ({scheme['scheme']})")
|
||||
|
||||
if __name__ == '__main__':
|
||||
build()
|
||||
|
||||
|
||||
321
templates/zed/apex.json.j2
Normal file
321
templates/zed/apex.json.j2
Normal file
@@ -0,0 +1,321 @@
|
||||
{
|
||||
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
|
||||
"name": "Apex",
|
||||
"author": "S0wlz (Owlibou)",
|
||||
"themes": [
|
||||
{% for s in schemes %}
|
||||
{
|
||||
"name": "{{ s.scheme }}",
|
||||
"appearance": "{{ s.type }}",
|
||||
"style": {
|
||||
"background": "{{ s.palette.background }}",
|
||||
"background.appearance": "opaque",
|
||||
"surface.background": "{{ s.ui.panel }}",
|
||||
"elevated_surface.background": "{% if s.type == 'dark' %}{{ s.ui.panel }}{% else %}#ffffff{% endif %}",
|
||||
"panel.background": "{{ s.ui.panel }}",
|
||||
"panel.focused_border": "{{ s.palette.cursor }}",
|
||||
"panel.indent_guide": "{{ s.ui.border }}66",
|
||||
"panel.indent_guide_active": "{{ s.ui.dim }}aa",
|
||||
"panel.indent_guide_hover": "{{ s.ui.dim }}cc",
|
||||
"tab_bar.background": "{% if s.type == 'dark' %}{{ s.ui.panel }}{% else %}{{ s.ui.panel }}{% endif %}",
|
||||
"tab.inactive_background": "{{ s.ui.panel }}",
|
||||
"tab.active_background": "{{ s.palette.background }}",
|
||||
"title_bar.background": "{{ s.palette.background }}",
|
||||
"title_bar.inactive_background": "{{ s.ui.panel }}",
|
||||
"toolbar.background": "{{ s.ui.panel }}",
|
||||
"status_bar.background": "{{ s.ui.panel }}",
|
||||
"border": "{{ s.ui.border }}",
|
||||
"border.variant": "{% if s.type == 'dark' %}{{ s.ui.panel }}{% else %}{{ s.ui.stealth }}{% endif %}",
|
||||
"border.focused": "{{ s.palette.cursor }}",
|
||||
"border.selected": "{{ s.palette.cursor }}",
|
||||
"border.disabled": "{% if s.type == 'dark' %}{{ s.ui.panel }}{% else %}{{ s.ui.stealth }}{% endif %}",
|
||||
"border.transparent": "transparent",
|
||||
"text": "{{ s.palette.foreground }}",
|
||||
"text.muted": "{{ s.ui.dim }}",
|
||||
"text.placeholder": "{{ s.ui.dim }}",
|
||||
"text.disabled": "{% if s.type == 'dark' %}{{ s.ui.dim }}{% else %}{{ s.ui.stealth }}{% endif %}",
|
||||
"text.accent": "{{ s.palette.info }}",
|
||||
"icon": "{{ s.palette.foreground }}",
|
||||
"icon.muted": "{{ s.ui.dim }}",
|
||||
"icon.placeholder": "{{ s.ui.dim }}",
|
||||
"icon.disabled": "{% if s.type == 'dark' %}{{ s.ui.dim }}{% else %}{{ s.ui.stealth }}{% endif %}",
|
||||
"icon.accent": "{{ s.palette.info }}",
|
||||
"accents": [
|
||||
"{{ s.palette.cursor }}",
|
||||
"{{ s.palette.info }}",
|
||||
"{{ s.palette.special }}",
|
||||
"{{ s.palette.success }}",
|
||||
"{{ s.palette.warning }}"
|
||||
],
|
||||
"element.background": "{% if s.type == 'dark' %}{{ s.ui.panel }}{% else %}#ffffff{% endif %}",
|
||||
"element.hover": "{{ s.ui.border }}",
|
||||
"element.active": "{{ s.ui.border }}",
|
||||
"element.selected": "{{ s.ui.border }}",
|
||||
"element.disabled": "{{ s.ui.panel }}",
|
||||
"ghost_element.background": null,
|
||||
"ghost_element.hover": "{{ s.ui.border }}66",
|
||||
"ghost_element.active": "{{ s.ui.border }}88",
|
||||
"ghost_element.selected": "{{ s.ui.border }}66",
|
||||
"ghost_element.disabled": null,
|
||||
"drop_target.background": "{% if s.type == 'dark' %}{{ s.palette.info }}22{% else %}{{ s.ansi.bright.cyan }}22{% endif %}",
|
||||
"editor.background": "{{ s.palette.background }}",
|
||||
"editor.foreground": "{{ s.palette.foreground }}",
|
||||
"editor.gutter.background": "{{ s.palette.background }}",
|
||||
"editor.subheader.background": "{{ s.ui.panel }}",
|
||||
"editor.active_line.background": "{{ s.ui.panel }}",
|
||||
"editor.highlighted_line.background": "{{ s.ui.panel }}",
|
||||
"editor.line_number": "{{ s.ui.dim }}",
|
||||
"editor.active_line_number": "{{ s.palette.cursor }}",
|
||||
"editor.wrap_guide": "{{ s.ui.border }}",
|
||||
"editor.active_wrap_guide": "{{ s.ui.dim }}",
|
||||
"editor.indent_guide": "{{ s.ui.border }}66",
|
||||
"editor.indent_guide_active": "{{ s.ui.dim }}aa",
|
||||
"editor.invisible": "{{ s.ui.border }}88",
|
||||
"editor.document_highlight.read_background": "{{ s.palette.info }}{% if s.type == 'dark' %}22{% else %}1a{% endif %}",
|
||||
"editor.document_highlight.write_background": "{{ s.palette.cursor }}{% if s.type == 'dark' %}22{% else %}1a{% endif %}",
|
||||
"editor.document_highlight.bracket_background": "{{ s.ui.border }}66",
|
||||
"search.match_background": "{% if s.type == 'dark' %}{{ s.palette.info }}33{% else %}{{ s.ansi.bright.cyan }}44{% endif %}",
|
||||
"scrollbar.track.background": "{{ s.palette.background }}",
|
||||
"scrollbar.track.border": "{{ s.palette.background }}",
|
||||
"scrollbar.thumb.background": "{% if s.type == 'dark' %}{{ s.ui.border }}aa{% else %}{{ s.ui.stealth }}aa{% endif %}",
|
||||
"scrollbar.thumb.hover_background": "{% if s.type == 'dark' %}{{ s.ui.stealth }}{% else %}{{ s.ui.dim }}{% endif %}",
|
||||
"scrollbar.thumb.border": "transparent",
|
||||
"pane.focused_border": "{{ s.palette.cursor }}",
|
||||
"pane_group.border": "{% if s.type == 'dark' %}{{ s.ui.border }}{% else %}{{ s.ui.stealth }}{% endif %}",
|
||||
"link_text.hover": "{% if s.type == 'dark' %}{{ s.ansi.bright.blue }}{% else %}{{ s.ansi.bright.blue }}{% endif %}",
|
||||
"success": "{{ s.palette.success }}",
|
||||
"success.background": "{{ s.palette.success }}1a",
|
||||
"success.border": "{{ s.palette.success }}",
|
||||
"warning": "{{ s.palette.warning }}",
|
||||
"warning.background": "{{ s.palette.warning }}1a",
|
||||
"warning.border": "{{ s.palette.warning }}",
|
||||
"error": "{{ s.ansi.bright.red }}",
|
||||
"error.background": "{{ s.ansi.bright.red }}1a",
|
||||
"error.border": "{{ s.ansi.bright.red }}",
|
||||
"info": "{{ s.palette.info }}",
|
||||
"info.background": "{{ s.palette.info }}1a",
|
||||
"info.border": "{{ s.palette.info }}",
|
||||
"hint": "{{ s.palette.azure }}",
|
||||
"hint.background": "{{ s.palette.azure }}1a",
|
||||
"hint.border": "{{ s.palette.azure }}",
|
||||
"predictive": "{% if s.type == 'dark' %}{{ s.palette.azure }}{% else %}{{ s.palette.azure }}{% endif %}",
|
||||
"predictive.background": "{{ s.palette.azure }}1a",
|
||||
"predictive.border": "{{ s.palette.azure }}",
|
||||
"unreachable": "{{ s.palette.special }}",
|
||||
"unreachable.background": "{{ s.palette.special }}1a",
|
||||
"unreachable.border": "{{ s.palette.special }}",
|
||||
"created": "{{ s.palette.success }}",
|
||||
"created.background": "{{ s.palette.success }}1a",
|
||||
"created.border": "{{ s.palette.success }}",
|
||||
"modified": "{{ s.palette.warning }}",
|
||||
"modified.background": "{{ s.palette.warning }}1a",
|
||||
"modified.border": "{{ s.palette.warning }}",
|
||||
"deleted": "{{ s.ansi.bright.red }}",
|
||||
"deleted.background": "{{ s.ansi.bright.red }}1a",
|
||||
"deleted.border": "{{ s.ansi.bright.red }}",
|
||||
"renamed": "{{ s.palette.info }}",
|
||||
"renamed.background": "{{ s.palette.info }}1a",
|
||||
"renamed.border": "{{ s.palette.info }}",
|
||||
"conflict": "{{ s.ansi.bright.red }}",
|
||||
"conflict.background": "{{ s.ansi.bright.red }}1a",
|
||||
"conflict.border": "{{ s.ansi.bright.red }}",
|
||||
"ignored": "{{ s.ui.dim }}",
|
||||
"ignored.background": "{{ s.ui.dim }}1a",
|
||||
"ignored.border": "{{ s.ui.border }}",
|
||||
"hidden": "{{ s.ui.dim }}",
|
||||
"hidden.background": "{{ s.ui.dim }}1a",
|
||||
"hidden.border": "{{ s.ui.border }}",
|
||||
"terminal.background": "{{ s.palette.background }}",
|
||||
"terminal.foreground": "{{ s.palette.foreground }}",
|
||||
"terminal.bright_foreground": "{% if s.type == 'dark' %}#ffffff{% else %}{{ s.palette.foreground }}{% endif %}",
|
||||
"terminal.dim_foreground": "{{ s.ui.dim }}",
|
||||
"terminal.ansi.background": "{{ s.palette.background }}",
|
||||
"terminal.ansi.black": "{{ s.ansi.normal.black }}",
|
||||
"terminal.ansi.red": "{{ s.ansi.normal.red }}",
|
||||
"terminal.ansi.green": "{{ s.ansi.normal.green }}",
|
||||
"terminal.ansi.yellow": "{{ s.ansi.normal.yellow }}",
|
||||
"terminal.ansi.blue": "{{ s.ansi.normal.blue }}",
|
||||
"terminal.ansi.magenta": "{{ s.ansi.normal.magenta }}",
|
||||
"terminal.ansi.cyan": "{{ s.ansi.normal.cyan }}",
|
||||
"terminal.ansi.white": "{{ s.ansi.normal.white }}",
|
||||
"terminal.ansi.bright_black": "{{ s.ansi.bright.black }}",
|
||||
"terminal.ansi.bright_red": "{{ s.ansi.bright.red }}",
|
||||
"terminal.ansi.bright_green": "{{ s.ansi.bright.green }}",
|
||||
"terminal.ansi.bright_yellow": "{{ s.ansi.bright.yellow }}",
|
||||
"terminal.ansi.bright_blue": "{{ s.ansi.bright.blue }}",
|
||||
"terminal.ansi.bright_magenta": "{{ s.ansi.bright.magenta }}",
|
||||
"terminal.ansi.bright_cyan": "{{ s.ansi.bright.cyan }}",
|
||||
"terminal.ansi.bright_white": "{{ s.ansi.bright.white }}",
|
||||
"terminal.ansi.dim_black": "{{ s.ansi.normal.black }}",
|
||||
"terminal.ansi.dim_red": "{{ s.ansi.normal.red }}",
|
||||
"terminal.ansi.dim_green": "{{ s.ansi.normal.green }}",
|
||||
"terminal.ansi.dim_yellow": "{{ s.ansi.normal.yellow }}",
|
||||
"terminal.ansi.dim_blue": "{{ s.ansi.normal.blue }}",
|
||||
"terminal.ansi.dim_magenta": "{{ s.ansi.normal.magenta }}",
|
||||
"terminal.ansi.dim_cyan": "{{ s.ansi.normal.cyan }}",
|
||||
"terminal.ansi.dim_white": "{{ s.ansi.normal.white }}",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "{{ s.palette.cursor }}",
|
||||
"background": "{{ s.palette.cursor }}",
|
||||
"selection": "{{ s.palette.cursor }}33"
|
||||
},
|
||||
{
|
||||
"cursor": "{{ s.palette.info }}",
|
||||
"background": "{{ s.palette.info }}",
|
||||
"selection": "{{ s.palette.info }}33"
|
||||
},
|
||||
{
|
||||
"cursor": "{{ s.palette.special }}",
|
||||
"background": "{{ s.palette.special }}",
|
||||
"selection": "{{ s.palette.special }}33"
|
||||
},
|
||||
{
|
||||
"cursor": "{{ s.palette.success }}",
|
||||
"background": "{{ s.palette.success }}",
|
||||
"selection": "{{ s.palette.success }}33"
|
||||
},
|
||||
{
|
||||
"cursor": "{{ s.palette.warning }}",
|
||||
"background": "{{ s.palette.warning }}",
|
||||
"selection": "{{ s.palette.warning }}33"
|
||||
}
|
||||
],
|
||||
"version_control.added": "{{ s.palette.success }}",
|
||||
"version_control.modified": "{{ s.palette.warning }}",
|
||||
"version_control.deleted": "{{ s.ansi.bright.red }}",
|
||||
"version_control.conflict": "{{ s.ansi.bright.red }}",
|
||||
"version_control.renamed": "{{ s.palette.info }}",
|
||||
"version_control.ignored": "{{ s.ui.dim }}",
|
||||
"syntax": {
|
||||
"comment": {
|
||||
"color": "{{ s.ui.dim }}",
|
||||
"font_style": "italic"
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "{{ s.ui.dim }}",
|
||||
"font_style": "italic"
|
||||
},
|
||||
"keyword": {
|
||||
"color": "{{ s.palette.info }}"
|
||||
},
|
||||
"keyword.import": {
|
||||
"color": "{{ s.palette.info }}"
|
||||
},
|
||||
"keyword.storage": {
|
||||
"color": "{{ s.palette.info }}"
|
||||
},
|
||||
"function": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"function.method": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"function.special.definition": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"type": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"type.builtin": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"string": {
|
||||
"color": "{{ s.palette.success }}"
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "{{ s.ansi.bright.green }}"
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "{{ s.palette.warning }}"
|
||||
},
|
||||
"number": {
|
||||
"color": "{{ s.palette.warning }}"
|
||||
},
|
||||
"boolean": {
|
||||
"color": "{{ s.palette.warning }}"
|
||||
},
|
||||
"constant": {
|
||||
"color": "{{ s.palette.foreground }}"
|
||||
},
|
||||
"constant.builtin": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"variable": {
|
||||
"color": "{{ s.palette.foreground }}"
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"property": {
|
||||
"color": "{{ s.palette.foreground }}"
|
||||
},
|
||||
"attribute": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"tag": {
|
||||
"color": "{{ s.palette.info }}"
|
||||
},
|
||||
"label": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"operator": {
|
||||
"color": "{{ s.palette.foreground }}"
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "{{ s.ui.dim }}"
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "{{ s.ui.dim }}"
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "{{ s.ui.dim }}"
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "{{ s.ui.dim }}",
|
||||
"font_weight": 700
|
||||
},
|
||||
"link_text": {
|
||||
"color": "{{ s.palette.info }}"
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"emphasis": {
|
||||
"font_style": "italic"
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"font_weight": 700
|
||||
},
|
||||
"title": {
|
||||
"color": "{{ s.palette.foreground }}",
|
||||
"font_weight": 700
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "{{ s.palette.success }}"
|
||||
},
|
||||
"preproc": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"constructor": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"enum": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"variant": {
|
||||
"color": "{{ s.palette.special }}"
|
||||
},
|
||||
"hint": {
|
||||
"color": "{{ s.palette.azure }}"
|
||||
},
|
||||
"predictive": {
|
||||
"color": "{{ s.ui.dim }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user