on main help sign in
refactor(ui): use uiutil for command handling and error reporting
2f95dccAyman Bagabas
internal/ui/dialog/commands.go+23−16
@@ -15,16 +15,23 @@ import (
15 "github.com/charmbracelet/crush/internal/agent"
15 "github.com/charmbracelet/crush/internal/agent"
16 "github.com/charmbracelet/crush/internal/config"
16 "github.com/charmbracelet/crush/internal/config"
17 "github.com/charmbracelet/crush/internal/csync"
17 "github.com/charmbracelet/crush/internal/csync"
18− "github.com/charmbracelet/crush/internal/tui/components/chat"
18+ "github.com/charmbracelet/crush/internal/message"
19− "github.com/charmbracelet/crush/internal/tui/util"
20 "github.com/charmbracelet/crush/internal/ui/common"
19 "github.com/charmbracelet/crush/internal/ui/common"
21 "github.com/charmbracelet/crush/internal/ui/list"
20 "github.com/charmbracelet/crush/internal/ui/list"
22 "github.com/charmbracelet/crush/internal/uicmd"
21 "github.com/charmbracelet/crush/internal/uicmd"
22+ "github.com/charmbracelet/crush/internal/uiutil"
23)
23)
24
24
25// CommandsID is the identifier for the commands dialog.
25// CommandsID is the identifier for the commands dialog.
26const CommandsID = "commands"
26const CommandsID = "commands"
27
27
28+// SendMsg represents a message to send a chat message.
29+// TODO: Move to chat package?
30+type SendMsg struct {
31+ Text string
32+ Attachments []message.Attachment
33+}
34+
28// Messages for commands
35// Messages for commands
29type (
36type (
30 SwitchSessionsMsg struct{}
37 SwitchSessionsMsg struct{}
@@ -323,7 +330,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
323 Description: "start a new session",
330 Description: "start a new session",
324 Shortcut: "ctrl+n",
331 Shortcut: "ctrl+n",
325 Handler: func(cmd uicmd.Command) tea.Cmd {
332 Handler: func(cmd uicmd.Command) tea.Cmd {
326− return util.CmdHandler(NewSessionsMsg{})
333+ return uiutil.CmdHandler(NewSessionsMsg{})
327 },
334 },
328 },
335 },
329 {
336 {
@@ -332,7 +339,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
332 Description: "Switch to a different session",
339 Description: "Switch to a different session",
333 Shortcut: "ctrl+s",
340 Shortcut: "ctrl+s",
334 Handler: func(cmd uicmd.Command) tea.Cmd {
341 Handler: func(cmd uicmd.Command) tea.Cmd {
335− return util.CmdHandler(SwitchSessionsMsg{})
342+ return uiutil.CmdHandler(SwitchSessionsMsg{})
336 },
343 },
337 },
344 },
338 {
345 {
@@ -341,7 +348,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
341 Description: "Switch to a different model",
348 Description: "Switch to a different model",
342 Shortcut: "ctrl+l",
349 Shortcut: "ctrl+l",
343 Handler: func(cmd uicmd.Command) tea.Cmd {
350 Handler: func(cmd uicmd.Command) tea.Cmd {
344− return util.CmdHandler(SwitchModelMsg{})
351+ return uiutil.CmdHandler(SwitchModelMsg{})
345 },
352 },
346 },
353 },
347 }
354 }
@@ -353,7 +360,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
353 Title: "Summarize Session",
360 Title: "Summarize Session",
354 Description: "Summarize the current session and create a new one with the summary",
361 Description: "Summarize the current session and create a new one with the summary",
355 Handler: func(cmd uicmd.Command) tea.Cmd {
362 Handler: func(cmd uicmd.Command) tea.Cmd {
356− return util.CmdHandler(CompactMsg{
363+ return uiutil.CmdHandler(CompactMsg{
357 SessionID: c.sessionID,
364 SessionID: c.sessionID,
358 })
365 })
359 },
366 },
@@ -379,7 +386,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
379 Title: status + " Thinking Mode",
386 Title: status + " Thinking Mode",
380 Description: "Toggle model thinking for reasoning-capable models",
387 Description: "Toggle model thinking for reasoning-capable models",
381 Handler: func(cmd uicmd.Command) tea.Cmd {
388 Handler: func(cmd uicmd.Command) tea.Cmd {
382− return util.CmdHandler(ToggleThinkingMsg{})
389+ return uiutil.CmdHandler(ToggleThinkingMsg{})
383 },
390 },
384 })
391 })
385 }
392 }
@@ -391,7 +398,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
391 Title: "Select Reasoning Effort",
398 Title: "Select Reasoning Effort",
392 Description: "Choose reasoning effort level (low/medium/high)",
399 Description: "Choose reasoning effort level (low/medium/high)",
393 Handler: func(cmd uicmd.Command) tea.Cmd {
400 Handler: func(cmd uicmd.Command) tea.Cmd {
394− return util.CmdHandler(OpenReasoningDialogMsg{})
401+ return uiutil.CmdHandler(OpenReasoningDialogMsg{})
395 },
402 },
396 })
403 })
397 }
404 }
@@ -405,7 +412,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
405 Title: "Toggle Sidebar",
412 Title: "Toggle Sidebar",
406 Description: "Toggle between compact and normal layout",
413 Description: "Toggle between compact and normal layout",
407 Handler: func(cmd uicmd.Command) tea.Cmd {
414 Handler: func(cmd uicmd.Command) tea.Cmd {
408− return util.CmdHandler(ToggleCompactModeMsg{})
415+ return uiutil.CmdHandler(ToggleCompactModeMsg{})
409 },
416 },
410 })
417 })
411 }
418 }
@@ -420,7 +427,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
420 Shortcut: "ctrl+f",
427 Shortcut: "ctrl+f",
421 Description: "Open file picker",
428 Description: "Open file picker",
422 Handler: func(cmd uicmd.Command) tea.Cmd {
429 Handler: func(cmd uicmd.Command) tea.Cmd {
423− return util.CmdHandler(OpenFilePickerMsg{})
430+ return uiutil.CmdHandler(OpenFilePickerMsg{})
424 },
431 },
425 })
432 })
426 }
433 }
@@ -435,7 +442,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
435 Shortcut: "ctrl+o",
442 Shortcut: "ctrl+o",
436 Description: "Open external editor to compose message",
443 Description: "Open external editor to compose message",
437 Handler: func(cmd uicmd.Command) tea.Cmd {
444 Handler: func(cmd uicmd.Command) tea.Cmd {
438− return util.CmdHandler(OpenExternalEditorMsg{})
445+ return uiutil.CmdHandler(OpenExternalEditorMsg{})
439 },
446 },
440 })
447 })
441 }
448 }
@@ -446,7 +453,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
446 Title: "Toggle Yolo Mode",
453 Title: "Toggle Yolo Mode",
447 Description: "Toggle yolo mode",
454 Description: "Toggle yolo mode",
448 Handler: func(cmd uicmd.Command) tea.Cmd {
455 Handler: func(cmd uicmd.Command) tea.Cmd {
449− return util.CmdHandler(ToggleYoloModeMsg{})
456+ return uiutil.CmdHandler(ToggleYoloModeMsg{})
450 },
457 },
451 },
458 },
452 {
459 {
@@ -455,7 +462,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
455 Shortcut: "ctrl+g",
462 Shortcut: "ctrl+g",
456 Description: "Toggle help",
463 Description: "Toggle help",
457 Handler: func(cmd uicmd.Command) tea.Cmd {
464 Handler: func(cmd uicmd.Command) tea.Cmd {
458− return util.CmdHandler(ToggleHelpMsg{})
465+ return uiutil.CmdHandler(ToggleHelpMsg{})
459 },
466 },
460 },
467 },
461 {
468 {
@@ -465,9 +472,9 @@ func (c *Commands) defaultCommands() []uicmd.Command {
465 Handler: func(cmd uicmd.Command) tea.Cmd {
472 Handler: func(cmd uicmd.Command) tea.Cmd {
466 initPrompt, err := agent.InitializePrompt(*c.com.Config())
473 initPrompt, err := agent.InitializePrompt(*c.com.Config())
467 if err != nil {
474 if err != nil {
468− return util.ReportError(err)
475+ return uiutil.ReportError(err)
469 }
476 }
470− return util.CmdHandler(chat.SendMsg{
477+ return uiutil.CmdHandler(SendMsg{
471 Text: initPrompt,
478 Text: initPrompt,
472 })
479 })
473 },
480 },
@@ -478,7 +485,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
478 Description: "Quit",
485 Description: "Quit",
479 Shortcut: "ctrl+c",
486 Shortcut: "ctrl+c",
480 Handler: func(cmd uicmd.Command) tea.Cmd {
487 Handler: func(cmd uicmd.Command) tea.Cmd {
481− return util.CmdHandler(QuitMsg{})
488+ return uiutil.CmdHandler(QuitMsg{})
482 },
489 },
483 },
490 },
484 }...)
491 }...)
internal/ui/model/ui.go+9
@@ -330,6 +330,15 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
330 }
330 }
331 case tea.KeyPressMsg:
331 case tea.KeyPressMsg:
332 cmds = append(cmds, m.handleKeyPressMsg(msg)...)
332 cmds = append(cmds, m.handleKeyPressMsg(msg)...)
333+
334+ // Command dialog messages
335+ // TODO: Properly structure and handle these messages
336+ case dialog.ToggleYoloModeMsg:
337+ m.com.App.Permissions.SetSkipRequests(!m.com.App.Permissions.SkipRequests())
338+ m.dialog.RemoveDialog(dialog.CommandsID)
339+ case dialog.SwitchSessionsMsg:
340+ cmds = append(cmds, m.loadSessionsCmd)
341+ m.dialog.RemoveDialog(dialog.CommandsID)
333 }
342 }
334
343
335 // This logic gets triggered on any message type, but should it?
344 // This logic gets triggered on any message type, but should it?