diff options
| author | adamdottv <[email protected]> | 2025-06-12 16:00:20 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-06-12 16:00:26 -0500 |
| commit | 653965ef5908a240f6038609e17bc8fa27640203 (patch) | |
| tree | 439910084fdcea0c45856ad0132f916fd9038a4b /packages/tui/internal/components/dialog/help.go | |
| parent | ca0ea3f94dc1929071efc93bfcf708c8cf054be8 (diff) | |
| download | opencode-653965ef5908a240f6038609e17bc8fa27640203.tar.gz opencode-653965ef5908a240f6038609e17bc8fa27640203.zip | |
wip: refactoring tui
Diffstat (limited to 'packages/tui/internal/components/dialog/help.go')
| -rw-r--r-- | packages/tui/internal/components/dialog/help.go | 239 |
1 files changed, 79 insertions, 160 deletions
diff --git a/packages/tui/internal/components/dialog/help.go b/packages/tui/internal/components/dialog/help.go index 6ceeb40b2..a1508a01a 100644 --- a/packages/tui/internal/components/dialog/help.go +++ b/packages/tui/internal/components/dialog/help.go @@ -6,196 +6,115 @@ import ( "github.com/charmbracelet/bubbles/v2/key" tea "github.com/charmbracelet/bubbletea/v2" "github.com/charmbracelet/lipgloss/v2" + "github.com/sst/opencode/internal/components/modal" "github.com/sst/opencode/internal/layout" - "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" ) -type helpComponent struct { - width int - height int - keys []key.Binding +type helpDialog struct { + width int + height int + modal *modal.Modal + bindings []key.Binding } -func (h *helpComponent) Init() tea.Cmd { +// func (i bindingItem) Render(selected bool, width int) string { +// t := theme.CurrentTheme() +// baseStyle := styles.BaseStyle(). +// Width(width - 2). +// Background(t.BackgroundElement()) +// +// if selected { +// baseStyle = baseStyle. +// Background(t.Primary()). +// Foreground(t.BackgroundElement()). +// Bold(true) +// } else { +// baseStyle = baseStyle. +// Foreground(t.Text()) +// } +// +// return baseStyle.Padding(0, 1).Render(i.binding.Help().Desc) +// } + +func (h *helpDialog) Init() tea.Cmd { return nil } -func (h *helpComponent) SetBindings(k []key.Binding) { - h.keys = k -} - -func (h *helpComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (h *helpDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: - h.width = 90 + h.width = msg.Width h.height = msg.Height } return h, nil } -func removeDuplicateBindings(bindings []key.Binding) []key.Binding { - seen := make(map[string]struct{}) - result := make([]key.Binding, 0, len(bindings)) - - // Process bindings in reverse order - for i := len(bindings) - 1; i >= 0; i-- { - b := bindings[i] - k := strings.Join(b.Keys(), " ") - if _, ok := seen[k]; ok { - // duplicate, skip - continue - } - seen[k] = struct{}{} - // Add to the beginning of result to maintain original order - result = append([]key.Binding{b}, result...) - } - - return result -} - -func (h *helpComponent) render() string { +// func removeDuplicateBindings(bindings []key.Binding) []key.Binding { +// seen := make(map[string]struct{}) +// result := make([]key.Binding, 0, len(bindings)) +// +// // Process bindings in reverse order +// for i := len(bindings) - 1; i >= 0; i-- { +// b := bindings[i] +// k := strings.Join(b.Keys(), " ") +// if _, ok := seen[k]; ok { +// // duplicate, skip +// continue +// } +// seen[k] = struct{}{} +// // Add to the beginning of result to maintain original order +// result = append([]key.Binding{b}, result...) +// } +// +// return result +// } + +func (h *helpDialog) View() string { t := theme.CurrentTheme() - baseStyle := styles.BaseStyle() - - helpKeyStyle := styles.Bold(). - Background(t.Background()). + keyStyle := lipgloss.NewStyle(). + Background(t.BackgroundElement()). Foreground(t.Text()). - Padding(0, 1, 0, 0) - - helpDescStyle := styles.Regular(). - Background(t.Background()). + Bold(true) + descStyle := lipgloss.NewStyle(). + Background(t.BackgroundElement()). Foreground(t.TextMuted()) - // Compile list of bindings to render - bindings := removeDuplicateBindings(h.keys) - - // Enumerate through each group of bindings, populating a series of - // pairs of columns, one for keys, one for descriptions - var ( - pairs []string - width int - rows = 12 - 2 - ) - - for i := 0; i < len(bindings); i += rows { - var ( - keys []string - descs []string - ) - for j := i; j < min(i+rows, len(bindings)); j++ { - keys = append(keys, helpKeyStyle.Render(bindings[j].Help().Key)) - descs = append(descs, helpDescStyle.Render(bindings[j].Help().Desc)) - } - - // Render pair of columns; beyond the first pair, render a three space - // left margin, in order to visually separate the pairs. - var cols []string - if len(pairs) > 0 { - cols = []string{baseStyle.Render(" ")} - } - - maxDescWidth := 0 - for _, desc := range descs { - if maxDescWidth < lipgloss.Width(desc) { - maxDescWidth = lipgloss.Width(desc) - } - } - for i := range descs { - remainingWidth := maxDescWidth - lipgloss.Width(descs[i]) - if remainingWidth > 0 { - descs[i] = descs[i] + baseStyle.Render(strings.Repeat(" ", remainingWidth)) - } - } - maxKeyWidth := 0 - for _, key := range keys { - if maxKeyWidth < lipgloss.Width(key) { - maxKeyWidth = lipgloss.Width(key) - } - } - for i := range keys { - remainingWidth := maxKeyWidth - lipgloss.Width(keys[i]) - if remainingWidth > 0 { - keys[i] = keys[i] + baseStyle.Render(strings.Repeat(" ", remainingWidth)) + lines := []string{} + for _, b := range h.bindings { + content := keyStyle.Render(b.Help().Key) + content += descStyle.Render(" " + b.Help().Desc) + for i, key := range b.Keys() { + if i == 0 { + keyString := " (" + strings.ToUpper(key) + ")" + // space := max(h.width-lipgloss.Width(content)-lipgloss.Width(keyString), 0) + // spacer := strings.Repeat(" ", space) + // content += descStyle.Render(spacer) + content += descStyle.Render(keyString) } } - cols = append(cols, - strings.Join(keys, "\n"), - strings.Join(descs, "\n"), - ) - - pair := baseStyle.Render(lipgloss.JoinHorizontal(lipgloss.Top, cols...)) - // check whether it exceeds the maximum width avail (the width of the - // terminal, subtracting 2 for the borders). - width += lipgloss.Width(pair) - if width > h.width-2 { - break - } - pairs = append(pairs, pair) + lines = append(lines, content) } - // https://github.com/charmbracelet/lipgloss/v2/issues/209 - if len(pairs) > 1 { - prefix := pairs[:len(pairs)-1] - lastPair := pairs[len(pairs)-1] - prefix = append(prefix, lipgloss.Place( - lipgloss.Width(lastPair), // width - lipgloss.Height(prefix[0]), // height - lipgloss.Left, // x - lipgloss.Top, // y - lastPair, // content - // lipgloss.WithWhitespaceBackground(t.Background()), - )) - content := baseStyle.Width(h.width).Render( - lipgloss.JoinHorizontal( - lipgloss.Top, - prefix..., - ), - ) - return content - } - - // Join pairs of columns and enclose in a border - content := baseStyle.Width(h.width).Render( - lipgloss.JoinHorizontal( - lipgloss.Top, - pairs..., - ), - ) - return content + return strings.Join(lines, "\n") } -func (h *helpComponent) View() string { - t := theme.CurrentTheme() - baseStyle := styles.BaseStyle() - - content := h.render() - header := baseStyle. - Bold(true). - Width(lipgloss.Width(content)). - Foreground(t.Primary()). - Render("Keyboard Shortcuts") +func (h *helpDialog) Render(background string) string { + return h.modal.Render(h.View(), background) +} - return baseStyle.Padding(1). - Border(lipgloss.RoundedBorder()). - BorderForeground(t.TextMuted()). - Width(h.width). - BorderBackground(t.Background()). - Render( - lipgloss.JoinVertical(lipgloss.Center, - header, - baseStyle.Render(strings.Repeat(" ", lipgloss.Width(header))), - content, - ), - ) +func (h *helpDialog) Close() tea.Cmd { + return nil } -type HelpComponent interface { - layout.ModelWithView - SetBindings([]key.Binding) +type HelpDialog interface { + layout.Modal } -func NewHelpCmp() HelpComponent { - return &helpComponent{} +func NewHelpDialog(bindings ...key.Binding) HelpDialog { + return &helpDialog{ + bindings: bindings, + modal: modal.New(), + } } |
