on main help sign in
chore: add a way to persist configurations
849c8feKujtim Hoxha
internal/config/config.go+32
@@ -2,10 +2,12 @@ package config
2
2
3import (
3import (
4 "fmt"
4 "fmt"
5+ "os"
5 "slices"
6 "slices"
6 "strings"
7 "strings"
7
8
8 "github.com/charmbracelet/crush/internal/fur/provider"
9 "github.com/charmbracelet/crush/internal/fur/provider"
10+ "github.com/tidwall/sjson"
9)
11)
10
12
11const (
13const (
@@ -274,6 +276,14 @@ func (c *Config) SmallModel() *provider.Model {
274 return c.GetModel(model.Provider, model.Model)
276 return c.GetModel(model.Provider, model.Model)
275}
277}
276
278
279+func (c *Config) SetCompactMode(enabled bool) error {
280+ if c.Options == nil {
281+ c.Options = &Options{}
282+ }
283+ c.Options.TUI.CompactMode = enabled
284+ return c.SetConfigField("options.tui.compact_mode", enabled)
285+}
286+
277func (c *Config) Resolve(key string) (string, error) {
287func (c *Config) Resolve(key string) (string, error) {
278 if c.resolver == nil {
288 if c.resolver == nil {
279 return "", fmt.Errorf("no variable resolver configured")
289 return "", fmt.Errorf("no variable resolver configured")
@@ -287,3 +297,25 @@ func UpdatePreferredModel(modelType SelectedModelType, model SelectedModel) erro
287 cfg.Models[modelType] = model
297 cfg.Models[modelType] = model
288 return nil
298 return nil
289}
299}
300+
301+func (c *Config) SetConfigField(key string, value any) error {
302+ configPath := globalConfigData()
303+ // read the data
304+ data, err := os.ReadFile(configPath)
305+ if err != nil {
306+ if os.IsNotExist(err) {
307+ data = []byte("{}")
308+ } else {
309+ return fmt.Errorf("failed to read config file: %w", err)
310+ }
311+ }
312+
313+ newValue, err := sjson.Set(string(data), key, value)
314+ if err != nil {
315+ return fmt.Errorf("failed to set config field %s: %w", key, err)
316+ }
317+ if err := os.WriteFile(configPath, []byte(newValue), 0o644); err != nil {
318+ return fmt.Errorf("failed to write config file: %w", err)
319+ }
320+ return nil
321+}
internal/tui/page/chat/chat.go+17−1
@@ -156,12 +156,15 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
156 return p, p.setSession(msg)
156 return p, p.setSession(msg)
157 case commands.ToggleCompactModeMsg:
157 case commands.ToggleCompactModeMsg:
158 p.forceCompact = !p.forceCompact
158 p.forceCompact = !p.forceCompact
159+ var cmd tea.Cmd
159 if p.forceCompact {
160 if p.forceCompact {
160 p.setCompactMode(true)
161 p.setCompactMode(true)
162+ cmd = p.updateCompactConfig(true)
161 } else if p.width >= CompactModeBreakpoint {
163 } else if p.width >= CompactModeBreakpoint {
162 p.setCompactMode(false)
164 p.setCompactMode(false)
165+ cmd = p.updateCompactConfig(false)
163 }
166 }
164− return p, p.SetSize(p.width, p.height)
167+ return p, tea.Batch(p.SetSize(p.width, p.height), cmd)
165 case pubsub.Event[session.Session]:
168 case pubsub.Event[session.Session]:
166 // this needs to go to header/sidebar
169 // this needs to go to header/sidebar
167 u, cmd := p.header.Update(msg)
170 u, cmd := p.header.Update(msg)
@@ -337,6 +340,19 @@ func (p *chatPage) View() tea.View {
337 return view
340 return view
338}
341}
339
342
343+func (p *chatPage) updateCompactConfig(compact bool) tea.Cmd {
344+ return func() tea.Msg {
345+ err := config.Get().SetCompactMode(compact)
346+ if err != nil {
347+ return util.InfoMsg{
348+ Type: util.InfoTypeError,
349+ Msg: "Failed to update compact mode configuration: " + err.Error(),
350+ }
351+ }
352+ return nil
353+ }
354+}
355+
340func (p *chatPage) setCompactMode(compact bool) {
356func (p *chatPage) setCompactMode(compact bool) {
341 if p.compact == compact {
357 if p.compact == compact {
342 return
358 return