adamdottv 8 месяцев назад
Родитель
Сommit
d271b9f75b

+ 42 - 9
packages/tui/internal/components/commands/commands.go

@@ -25,6 +25,7 @@ type commandsComponent struct {
 	app           *app.App
 	width, height int
 	showKeybinds  bool
+	showAll       bool
 	background    *compat.AdaptiveColor
 	limit         *int
 }
@@ -75,17 +76,32 @@ func (c *commandsComponent) View() string {
 		keybindStyle = keybindStyle.Background(*c.background)
 	}
 
-	var commandsWithTriggers []commands.Command
+	var commandsToShow []commands.Command
+	var triggeredCommands []commands.Command
+	var untriggeredCommands []commands.Command
+
 	for _, cmd := range c.app.Commands.Sorted() {
-		if cmd.Trigger != "" {
-			commandsWithTriggers = append(commandsWithTriggers, cmd)
+		if c.showAll || cmd.Trigger != "" {
+			if cmd.Trigger != "" {
+				triggeredCommands = append(triggeredCommands, cmd)
+			} else if c.showAll {
+				untriggeredCommands = append(untriggeredCommands, cmd)
+			}
 		}
 	}
-	if c.limit != nil && len(commandsWithTriggers) > *c.limit {
-		commandsWithTriggers = commandsWithTriggers[:*c.limit]
+
+	// Combine triggered commands first, then untriggered
+	commandsToShow = append(commandsToShow, triggeredCommands...)
+	commandsToShow = append(commandsToShow, untriggeredCommands...)
+
+	if c.limit != nil && len(commandsToShow) > *c.limit {
+		commandsToShow = commandsToShow[:*c.limit]
 	}
 
-	if len(commandsWithTriggers) == 0 {
+	if len(commandsToShow) == 0 {
+		if c.showAll {
+			return styles.Muted().Render("No commands available")
+		}
 		return styles.Muted().Render("No commands with triggers available")
 	}
 
@@ -101,10 +117,15 @@ func (c *commandsComponent) View() string {
 		keybinds    string
 	}
 
-	rows := make([]commandRow, 0, len(commandsWithTriggers))
+	rows := make([]commandRow, 0, len(commandsToShow))
 
-	for _, cmd := range commandsWithTriggers {
-		trigger := "/" + cmd.Trigger
+	for _, cmd := range commandsToShow {
+		trigger := ""
+		if cmd.Trigger != "" {
+			trigger = "/" + cmd.Trigger
+		} else {
+			trigger = string(cmd.Name)
+		}
 		description := cmd.Description
 
 		// Format keybindings
@@ -144,6 +165,7 @@ func (c *commandsComponent) View() string {
 	// Build the output
 	var output strings.Builder
 
+	maxWidth := 0
 	for _, row := range rows {
 		// Pad each column to align properly
 		trigger := fmt.Sprintf("%-*s", maxTriggerWidth, row.trigger)
@@ -160,10 +182,14 @@ func (c *commandsComponent) View() string {
 		}
 
 		output.WriteString(line + "\n")
+		maxWidth = max(maxWidth, lipgloss.Width(line))
 	}
 
 	// Remove trailing newline
 	result := strings.TrimSuffix(output.String(), "\n")
+	if c.background != nil {
+		result = lipgloss.NewStyle().Background(c.background).Width(maxWidth).Render(result)
+	}
 
 	return result
 }
@@ -188,11 +214,18 @@ func WithLimit(limit int) Option {
 	}
 }
 
+func WithShowAll(showAll bool) Option {
+	return func(c *commandsComponent) {
+		c.showAll = showAll
+	}
+}
+
 func New(app *app.App, opts ...Option) CommandsComponent {
 	c := &commandsComponent{
 		app:          app,
 		background:   nil,
 		showKeybinds: true,
+		showAll:      false,
 	}
 	for _, opt := range opts {
 		opt(c)

+ 35 - 9
packages/tui/internal/components/dialog/help.go

@@ -1,6 +1,7 @@
 package dialog
 
 import (
+	"github.com/charmbracelet/bubbles/v2/viewport"
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/sst/opencode/internal/app"
 	commandsComponent "github.com/sst/opencode/internal/components/commands"
@@ -15,28 +16,47 @@ type helpDialog struct {
 	modal             *modal.Modal
 	app               *app.App
 	commandsComponent commandsComponent.CommandsComponent
+	viewport          viewport.Model
 }
 
 func (h *helpDialog) Init() tea.Cmd {
-	return h.commandsComponent.Init()
+	return tea.Batch(
+		h.commandsComponent.Init(),
+		h.viewport.Init(),
+	)
 }
 
 func (h *helpDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+	var cmds []tea.Cmd
+
 	switch msg := msg.(type) {
 	case tea.WindowSizeMsg:
 		h.width = msg.Width
 		h.height = msg.Height
-		h.commandsComponent.SetSize(msg.Width, msg.Height)
+		// Set viewport size with some padding for the modal
+		h.viewport = viewport.New(viewport.WithWidth(msg.Width-4), viewport.WithHeight(msg.Height-6))
+		h.commandsComponent.SetSize(msg.Width-4, msg.Height-6)
 	}
-	
-	_, cmd := h.commandsComponent.Update(msg)
-	return h, cmd
+
+	// Update commands component first to get the latest content
+	_, cmdCmd := h.commandsComponent.Update(msg)
+	cmds = append(cmds, cmdCmd)
+
+	// Update viewport content
+	h.viewport.SetContent(h.commandsComponent.View())
+
+	// Update viewport
+	var vpCmd tea.Cmd
+	h.viewport, vpCmd = h.viewport.Update(msg)
+	cmds = append(cmds, vpCmd)
+
+	return h, tea.Batch(cmds...)
 }
 
 func (h *helpDialog) View() string {
 	t := theme.CurrentTheme()
 	h.commandsComponent.SetBackgroundColor(t.BackgroundElement())
-	return h.commandsComponent.View()
+	return h.viewport.View()
 }
 
 func (h *helpDialog) Render(background string) string {
@@ -52,9 +72,15 @@ type HelpDialog interface {
 }
 
 func NewHelpDialog(app *app.App) HelpDialog {
+	vp := viewport.New(viewport.WithHeight(12))
 	return &helpDialog{
-		app:               app,
-		commandsComponent: commandsComponent.New(app, commandsComponent.WithBackground(theme.CurrentTheme().BackgroundElement())),
-		modal:             modal.New(modal.WithTitle("Help")),
+		app: app,
+		commandsComponent: commandsComponent.New(app,
+			commandsComponent.WithBackground(theme.CurrentTheme().BackgroundElement()),
+			commandsComponent.WithShowAll(true),
+			commandsComponent.WithKeybinds(true),
+		),
+		modal:    modal.New(modal.WithTitle("Help")),
+		viewport: vp,
 	}
 }