on main help sign in
refactor(ui): pass app.App to common.Common and access config via common
commitba9e4528b292d4ad01e90fda3726829adfd7e14b authorAyman Bagabas <ayman.bagabas@gmail.com> dateMon 17 Nov 2025, 16:56 (1 year ago) parent7bc57e7
5 files changed+19−19
internal/cmd/root.go+2−2 internal/ui/common/common.go+9−3 internal/ui/model/editor.go+4−7 internal/ui/model/sidebar.go+1−1 internal/ui/model/ui.go+3−6
internal/cmd/root.go+2−2
@@ -87,8 +87,8 @@ crush -y
8787
8888 // Set up the TUI.
8989 var env uv.Environ = os.Environ()
90− com := common.DefaultCommon(app.Config())
91− ui := ui.New(com, app)
90+ com := common.DefaultCommon(app)
91+ ui := ui.New(com)
9292 ui.QueryVersion = shouldQueryTerminalVersion(env)
9393 program := tea.NewProgram(
9494 ui,
internal/ui/common/common.go+9−3
@@ -3,6 +3,7 @@ package common
33import (
44 "image"
55
6+ "github.com/charmbracelet/crush/internal/app"
67 "github.com/charmbracelet/crush/internal/config"
78 "github.com/charmbracelet/crush/internal/ui/styles"
89 uv "github.com/charmbracelet/ultraviolet"
@@ -10,15 +11,20 @@ import (
1011
1112// Common defines common UI options and configurations.
1213type Common struct {
13− Config *config.Config
14+ App *app.App
1415 Styles *styles.Styles
1516}
1617
18+// Config returns the configuration associated with this [Common] instance.
19+func (c *Common) Config() *config.Config {
20+ return c.App.Config()
21+}
22+
1723// DefaultCommon returns the default common UI configurations.
18−func DefaultCommon(cfg *config.Config) *Common {
24+func DefaultCommon(app *app.App) *Common {
1925 s := styles.DefaultStyles()
2026 return &Common{
21− Config: cfg,
27+ App: app,
2228 Styles: &s,
2329 }
2430}
internal/ui/model/editor.go+4−7
@@ -6,7 +6,6 @@ import (
66 "charm.land/bubbles/v2/key"
77 "charm.land/bubbles/v2/textarea"
88 tea "charm.land/bubbletea/v2"
9− "github.com/charmbracelet/crush/internal/app"
109 "github.com/charmbracelet/crush/internal/ui/common"
1110)
1211
@@ -61,7 +60,6 @@ func DefaultEditorKeyMap() EditorKeyMap {
6160// EditorModel represents the editor UI model.
6261type EditorModel struct {
6362 com *common.Common
64− app *app.App
6563
6664 keyMap EditorKeyMap
6765 textarea *textarea.Model
@@ -73,7 +71,7 @@ type EditorModel struct {
7371}
7472
7573// NewEditorModel creates a new instance of EditorModel.
76−func NewEditorModel(com *common.Common, app *app.App) *EditorModel {
74+func NewEditorModel(com *common.Common) *EditorModel {
7775 ta := textarea.New()
7876 ta.SetStyles(com.Styles.TextArea)
7977 ta.ShowLineNumbers = false
@@ -82,7 +80,6 @@ func NewEditorModel(com *common.Common, app *app.App) *EditorModel {
8280 ta.Focus()
8381 e := &EditorModel{
8482 com: com,
85− app: app,
8683 keyMap: DefaultEditorKeyMap(),
8784 textarea: ta,
8885 }
@@ -108,12 +105,12 @@ func (m *EditorModel) Update(msg tea.Msg) (*EditorModel, tea.Cmd) {
108105 cmds = append(cmds, cmd)
109106
110107 // Textarea placeholder logic
111− if m.app.AgentCoordinator != nil && m.app.AgentCoordinator.IsBusy() {
108+ if m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
112109 m.textarea.Placeholder = m.workingPlaceholder
113110 } else {
114111 m.textarea.Placeholder = m.readyPlaceholder
115112 }
116− if m.app.Permissions.SkipRequests() {
113+ if m.com.App.Permissions.SkipRequests() {
117114 m.textarea.Placeholder = "Yolo mode!"
118115 }
119116
@@ -183,7 +180,7 @@ func (m *EditorModel) SetSize(width, height int) {
183180}
184181
185182func (m *EditorModel) setEditorPrompt() {
186− if m.app.Permissions.SkipRequests() {
183+ if m.com.App.Permissions.SkipRequests() {
187184 m.textarea.SetPromptFunc(4, m.yoloPromptFunc)
188185 return
189186 }
internal/ui/model/sidebar.go+1−1
@@ -32,7 +32,7 @@ func NewSidebarModel(com *common.Common) *SidebarModel {
3232 return &SidebarModel{
3333 com: com,
3434 compact: true,
35− cwd: com.Config.WorkingDir(),
35+ cwd: com.Config().WorkingDir(),
3636 }
3737}
3838
internal/ui/model/ui.go+3−6
@@ -10,7 +10,6 @@ import (
1010 "charm.land/bubbles/v2/key"
1111 tea "charm.land/bubbletea/v2"
1212 "charm.land/lipgloss/v2"
13− "github.com/charmbracelet/crush/internal/app"
1413 "github.com/charmbracelet/crush/internal/ui/common"
1514 "github.com/charmbracelet/crush/internal/ui/dialog"
1615 uv "github.com/charmbracelet/ultraviolet"
@@ -27,7 +26,6 @@ const (
2726
2827// UI represents the main user interface model.
2928type UI struct {
30− app *app.App
3129 com *common.Common
3230
3331 state uiState
@@ -52,13 +50,12 @@ type UI struct {
5250}
5351
5452// New creates a new instance of the [UI] model.
55−func New(com *common.Common, app *app.App) *UI {
53+func New(com *common.Common) *UI {
5654 return &UI{
57− app: app,
5855 com: com,
5956 dialog: dialog.NewOverlay(),
6057 keyMap: DefaultKeyMap(),
61− editor: NewEditorModel(com, app),
58+ editor: NewEditorModel(com),
6259 side: NewSidebarModel(com),
6360 help: help.New(),
6461 }
@@ -183,7 +180,7 @@ func (m *UI) View() tea.View {
183180 layers = append(layers, mainLayer)
184181
185182 v.Content = lipgloss.NewCanvas(layers...)
186− if m.sendProgressBar && m.app != nil && m.app.AgentCoordinator != nil && m.app.AgentCoordinator.IsBusy() {
183+ if m.sendProgressBar && m.com.App != nil && m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
187184 // HACK: use a random percentage to prevent ghostty from hiding it
188185 // after a timeout.
189186 v.ProgressBar = tea.NewProgressBar(tea.ProgressBarIndeterminate, rand.Intn(100))