feat(theming): integrate NvChad chadrc rewrite into Apply
This commit is contained in:
@@ -88,6 +88,44 @@ func (m Module) resolvedTheme() string {
|
|||||||
return "gruvbox"
|
return "gruvbox"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteChadrc renders chadrc.lua for the given NvChad theme name and writes
|
||||||
|
// it to ~/.config/nvim/lua/chadrc.lua. If the file does not already exist
|
||||||
|
// and the surrounding nvim config dir does not exist, the function returns
|
||||||
|
// nil without writing anything (the user hasn't installed neovim yet).
|
||||||
|
//
|
||||||
|
// Exported so the theming package can re-render chadrc on theme switches
|
||||||
|
// without re-running the full Module pipeline.
|
||||||
|
func WriteChadrc(nvChadThemeName string) error {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg := filepath.Join(home, ".config", "nvim")
|
||||||
|
chadrcPath := filepath.Join(cfg, "lua", "chadrc.lua")
|
||||||
|
|
||||||
|
// If chadrc doesn't exist, only write when the parent dir exists. A
|
||||||
|
// fresh system where nvim was never installed should be a no-op.
|
||||||
|
if _, err := os.Stat(chadrcPath); err != nil {
|
||||||
|
if _, err := os.Stat(cfg); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmplBytes, err := assets.ReadFile("assets/chadrc.lua.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tmpl, err := template.New("chadrc").Parse(string(tmplBytes))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := tmpl.Execute(&buf, struct{ NvChadTheme string }{NvChadTheme: nvChadThemeName}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return platform.WriteUserFile(chadrcPath, buf.Bytes(), 0o644)
|
||||||
|
}
|
||||||
|
|
||||||
func (m Module) renderChadrc() ([]byte, error) {
|
func (m Module) renderChadrc() ([]byte, error) {
|
||||||
tmplBytes, err := assets.ReadFile("assets/chadrc.lua.tmpl")
|
tmplBytes, err := assets.ReadFile("assets/chadrc.lua.tmpl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -177,4 +177,34 @@ func TestUnknownThemeFallsBackToFirst(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWriteChadrcWritesFile(t *testing.T) {
|
||||||
|
home := t.TempDir()
|
||||||
|
t.Setenv("HOME", home)
|
||||||
|
cfg := filepath.Join(home, ".config", "nvim")
|
||||||
|
if err := os.MkdirAll(cfg, 0o755); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := WriteChadrc("dracula"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(filepath.Join(cfg, "lua", "chadrc.lua"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(string(data), `theme = "dracula"`) {
|
||||||
|
t.Fatalf("theme not applied: %s", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteChadrcNoopWithoutConfigDir(t *testing.T) {
|
||||||
|
home := t.TempDir()
|
||||||
|
t.Setenv("HOME", home)
|
||||||
|
if err := WriteChadrc("gruvbox"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(filepath.Join(home, ".config", "nvim", "lua", "chadrc.lua")); !os.IsNotExist(err) {
|
||||||
|
t.Fatal("chadrc should not be created on a bare system")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _ module.Module = Module{}
|
var _ module.Module = Module{}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/MDietermann/ArduinoArchSetup/internal/config"
|
"github.com/MDietermann/ArduinoArchSetup/internal/config"
|
||||||
|
"github.com/MDietermann/ArduinoArchSetup/internal/modules/neovim"
|
||||||
"github.com/MDietermann/ArduinoArchSetup/internal/platform"
|
"github.com/MDietermann/ArduinoArchSetup/internal/platform"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
@@ -144,6 +145,15 @@ func Apply(cfg config.Config, themeID string) error {
|
|||||||
if err := updateOverlayActive(th.ID); err != nil {
|
if err := updateOverlayActive(th.ID); err != nil {
|
||||||
return fmt.Errorf("update overlay: %w", err)
|
return fmt.Errorf("update overlay: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := neovim.WriteChadrc(th.NvChadTheme); err != nil {
|
||||||
|
return fmt.Errorf("update chadrc: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear NvChad's base46 theme cache so the new theme activates on next
|
||||||
|
// nvim launch. Errors ignored — the cache may not exist.
|
||||||
|
_ = os.RemoveAll(filepath.Join(home, ".cache", "nvim", "base46"))
|
||||||
|
_ = os.RemoveAll(filepath.Join(home, ".local", "share", "nvim", "lazy", "base46", "lua", "base46", "themes"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,3 +117,34 @@ func TestApplyPreservesOtherOverlayKeys(t *testing.T) {
|
|||||||
t.Fatalf("active theme missing after preserve: %s", data)
|
t.Fatalf("active theme missing after preserve: %s", data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApplyRewritesChadrcIfPresent(t *testing.T) {
|
||||||
|
home := t.TempDir()
|
||||||
|
t.Setenv("HOME", home)
|
||||||
|
nvimCfg := filepath.Join(home, ".config", "nvim", "lua")
|
||||||
|
if err := os.MkdirAll(nvimCfg, 0o755); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(nvimCfg, "chadrc.lua"),
|
||||||
|
[]byte(`M.base46 = { theme = "onedark" }`), 0o644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := Apply(config.Config{}, "gruvbox"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
data, _ := os.ReadFile(filepath.Join(nvimCfg, "chadrc.lua"))
|
||||||
|
if !strings.Contains(string(data), `theme = "gruvbox"`) {
|
||||||
|
t.Fatalf("chadrc not rewritten: %s", data)
|
||||||
|
}
|
||||||
|
if strings.Contains(string(data), `theme = "onedark"`) {
|
||||||
|
t.Fatalf("old theme still present: %s", data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestApplyNoChadrcIsFine(t *testing.T) {
|
||||||
|
home := t.TempDir()
|
||||||
|
t.Setenv("HOME", home)
|
||||||
|
if err := Apply(config.Config{}, "gruvbox"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user