feat: add dynamic Obsidian vault theming support to theme_sync engine

This commit is contained in:
Sho 2026-08-02 02:13:03 +09:00
parent 2ce914650c
commit 6520f54ee9

View File

@ -1453,6 +1453,141 @@ def sync_xresources(bg, surface, current_line, fg, accent, sub_accent):
except Exception: except Exception:
pass pass
def sync_obsidian(bg, surface, current_line, fg, accent, sub_accent, is_dark):
import json
home = os.path.expanduser('~')
# CSS Template for Obsidian Vaults
obsidian_css = f"""/* Auto-generated by Quickshell Theme Engine */
.theme-dark, .theme-light, :root, body {{
--bg-primary: {bg} !important;
--bg-primary-alt: {surface} !important;
--bg-secondary: {surface} !important;
--bg-secondary-alt: {current_line} !important;
--background-primary: {bg} !important;
--background-primary-alt: {surface} !important;
--background-secondary: {surface} !important;
--background-secondary-alt: {current_line} !important;
--background-modifier-border: {current_line} !important;
--background-modifier-border-hover: {accent} !important;
--background-modifier-form-field: {surface} !important;
--text-normal: {fg} !important;
--text-muted: {fg} !important;
--text-faint: {current_line} !important;
--interactive-accent: {accent} !important;
--interactive-accent-hover: {sub_accent} !important;
--interactive-hover: {current_line} !important;
--text-accent: {accent} !important;
--text-accent-hover: {sub_accent} !important;
--nav-item-color-active: {accent} !important;
--nav-item-background-active: {surface} !important;
--tab-text-color-active: {accent} !important;
--bold-color: {accent} !important;
--italic-color: {sub_accent} !important;
--title-color: {fg} !important;
--h1-color: {accent} !important;
--h2-color: {sub_accent} !important;
--h3-color: {fg} !important;
--h4-color: {fg} !important;
--h5-color: {fg} !important;
--h6-color: {fg} !important;
--code-normal: {accent} !important;
--code-background: {surface} !important;
--scrollbar-thumb-bg: {current_line} !important;
--status-bar-bg: {surface} !important;
--titlebar-background: {bg} !important;
--titlebar-background-focused: {bg} !important;
}}
"""
vault_dirs = set()
# Search common Documents and Home locations for .obsidian folders
search_bases = [
home,
os.path.join(home, 'Documents'),
os.path.join(home, 'Obsidian'),
os.path.join(home, 'Vaults'),
os.path.join(home, 'Notes'),
os.path.join(home, '.var', 'app', 'md.obsidian.Obsidian', 'config', 'obsidian'),
os.path.join(home, '.config', 'obsidian')
]
for sb in search_bases:
if os.path.exists(sb):
obs_dir = os.path.join(sb, '.obsidian')
if os.path.isdir(obs_dir):
vault_dirs.add(obs_dir)
try:
for child in os.listdir(sb):
child_path = os.path.join(sb, child)
if os.path.isdir(child_path):
child_obs = os.path.join(child_path, '.obsidian')
if os.path.isdir(child_obs):
vault_dirs.add(child_obs)
except Exception: pass
# Search registered vault paths in obsidian.json
obsidian_json_paths = [
os.path.join(home, '.config', 'obsidian', 'obsidian.json'),
os.path.join(home, '.var', 'app', 'md.obsidian.Obsidian', 'config', 'obsidian', 'obsidian.json')
]
for ojp in obsidian_json_paths:
if os.path.exists(ojp):
try:
with open(ojp, 'r', encoding='utf-8') as f:
data = json.load(f)
vaults = data.get('vaults', {})
if isinstance(vaults, dict):
for v_id, v_info in vaults.items():
v_path = v_info.get('path')
if v_path:
obs_folder = os.path.join(v_path, '.obsidian')
if os.path.isdir(obs_folder):
vault_dirs.add(obs_folder)
except Exception: pass
# Apply quickshell-theme.css and update appearance.json to enable the snippet automatically
for obs_dir in vault_dirs:
try:
snippets_dir = os.path.join(obs_dir, 'snippets')
os.makedirs(snippets_dir, exist_ok=True)
css_path = os.path.join(snippets_dir, 'quickshell-theme.css')
with open(css_path, 'w', encoding='utf-8') as f:
f.write(obsidian_css)
app_file = os.path.join(obs_dir, 'appearance.json')
app_data = {}
if os.path.exists(app_file):
try:
with open(app_file, 'r', encoding='utf-8') as f:
app_data = json.load(f)
except Exception:
app_data = {}
enabled_snippets = app_data.get('enabledCssSnippets', [])
if not isinstance(enabled_snippets, list):
enabled_snippets = []
if 'quickshell-theme' not in enabled_snippets:
enabled_snippets.append('quickshell-theme')
app_data['enabledCssSnippets'] = enabled_snippets
app_data['baseOption'] = 'dark' if is_dark else 'light'
with open(app_file, 'w', encoding='utf-8') as f:
json.dump(app_data, f, indent=2)
except Exception: pass
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--bg', required=True) parser.add_argument('--bg', required=True)
@ -1472,6 +1607,7 @@ def main():
sync_vscode(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark) sync_vscode(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark)
sync_zen(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark) sync_zen(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark)
sync_feishin(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark, args.variantName) sync_feishin(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark, args.variantName)
sync_obsidian(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark)
sync_starship(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark) sync_starship(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark)
sync_vim(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark) sync_vim(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent, is_dark)
sync_btop(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent) sync_btop(args.bg, args.surface, args.currentLine, args.fg, args.accent, args.subAccent)
@ -1483,4 +1619,3 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() main()