From fce59db94ac3efd3c3977dfdd4e1a12fe590f517 Mon Sep 17 00:00:00 2001 From: adamdottv <2363879+adamdottv@users.noreply.github.com> Date: Thu, 3 Jul 2025 12:48:14 -0500 Subject: [PATCH] chore: simplify completions --- packages/tui/internal/app/app.go | 14 +++-- packages/tui/internal/completions/manager.go | 32 ----------- .../internal/components/dialog/complete.go | 15 ----- .../tui/internal/components/dialog/find.go | 18 +++--- packages/tui/internal/tui/tui.go | 55 +++++-------------- 5 files changed, 30 insertions(+), 104 deletions(-) delete mode 100644 packages/tui/internal/completions/manager.go diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index 9b341c19..6b59acae 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -46,9 +46,6 @@ type SendMsg struct { Text string Attachments []Attachment } -type CompletionDialogTriggeredMsg struct { - InitialValue string -} type OptimisticMessageAddedMsg struct { Message opencode.Message } @@ -129,7 +126,11 @@ func New( func (a *App) Key(commandName commands.CommandName) string { t := theme.CurrentTheme() base := styles.NewStyle().Background(t.Background()).Foreground(t.Text()).Bold(true).Render - muted := styles.NewStyle().Background(t.Background()).Foreground(t.TextMuted()).Faint(true).Render + muted := styles.NewStyle(). + Background(t.Background()). + Foreground(t.TextMuted()). + Faint(true). + Render command := a.Commands[commandName] kb := command.Keybindings[0] key := kb.Key @@ -201,7 +202,10 @@ func (a *App) InitializeProvider() tea.Cmd { } } -func getDefaultModel(response *opencode.ConfigProvidersResponse, provider opencode.Provider) *opencode.Model { +func getDefaultModel( + response *opencode.ConfigProvidersResponse, + provider opencode.Provider, +) *opencode.Model { if match, ok := response.Default[provider.ID]; ok { model := provider.Models[match] return &model diff --git a/packages/tui/internal/completions/manager.go b/packages/tui/internal/completions/manager.go deleted file mode 100644 index 5368208f..00000000 --- a/packages/tui/internal/completions/manager.go +++ /dev/null @@ -1,32 +0,0 @@ -package completions - -import ( - "strings" - - "github.com/sst/opencode/internal/app" - "github.com/sst/opencode/internal/components/dialog" -) - -type CompletionManager struct { - providers map[string]dialog.CompletionProvider -} - -func NewCompletionManager(app *app.App) *CompletionManager { - return &CompletionManager{ - providers: map[string]dialog.CompletionProvider{ - "files": NewFileAndFolderContextGroup(app), - "commands": NewCommandCompletionProvider(app), - }, - } -} - -func (m *CompletionManager) DefaultProvider() dialog.CompletionProvider { - return m.providers["commands"] -} - -func (m *CompletionManager) GetProvider(input string) dialog.CompletionProvider { - if strings.HasPrefix(input, "/") { - return m.providers["commands"] - } - return m.providers["files"] -} diff --git a/packages/tui/internal/components/dialog/complete.go b/packages/tui/internal/components/dialog/complete.go index f204d910..caf754c7 100644 --- a/packages/tui/internal/components/dialog/complete.go +++ b/packages/tui/internal/components/dialog/complete.go @@ -7,7 +7,6 @@ import ( "github.com/charmbracelet/bubbles/v2/textarea" tea "github.com/charmbracelet/bubbletea/v2" "github.com/charmbracelet/lipgloss/v2" - "github.com/sst/opencode/internal/app" "github.com/sst/opencode/internal/components/list" "github.com/sst/opencode/internal/styles" "github.com/sst/opencode/internal/theme" @@ -79,7 +78,6 @@ type CompletionDialog interface { tea.ViewModel SetWidth(width int) IsEmpty() bool - SetProvider(provider CompletionProvider) } type completionDialogComponent struct { @@ -114,8 +112,6 @@ func (c *completionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case []CompletionItemI: c.list.SetItems(msg) - case app.CompletionDialogTriggeredMsg: - c.pseudoSearchTextArea.SetValue(msg.InitialValue) case tea.KeyMsg: if c.pseudoSearchTextArea.Focused() { if !key.Matches(msg, completionDialogKeys.Complete) { @@ -214,19 +210,8 @@ func (c *completionDialogComponent) IsEmpty() bool { return c.list.IsEmpty() } -func (c *completionDialogComponent) SetProvider(provider CompletionProvider) { - if c.completionProvider.GetId() != provider.GetId() { - c.completionProvider = provider - c.list.SetEmptyMessage(" " + provider.GetEmptyMessage()) - c.list.SetItems([]CompletionItemI{}) - } -} - func (c *completionDialogComponent) complete(item CompletionItemI) tea.Cmd { value := c.pseudoSearchTextArea.Value() - if value == "" { - return nil - } // Check if this is a command completion isCommand := c.completionProvider.GetId() == "commands" diff --git a/packages/tui/internal/components/dialog/find.go b/packages/tui/internal/components/dialog/find.go index 3ca0d105..489b9f29 100644 --- a/packages/tui/internal/components/dialog/find.go +++ b/packages/tui/internal/components/dialog/find.go @@ -27,7 +27,6 @@ type FindDialog interface { SetWidth(width int) SetHeight(height int) IsEmpty() bool - SetProvider(provider CompletionProvider) } type findDialogComponent struct { @@ -151,12 +150,6 @@ func (f *findDialogComponent) IsEmpty() bool { return f.list.IsEmpty() } -func (f *findDialogComponent) SetProvider(provider CompletionProvider) { - f.completionProvider = provider - f.list.SetEmptyMessage(" " + provider.GetEmptyMessage()) - f.list.SetItems([]CompletionItemI{}) -} - func (f *findDialogComponent) selectFile(item CompletionItemI) tea.Cmd { return tea.Sequence( f.Close(), @@ -184,9 +177,15 @@ func createTextInput(existing *textinput.Model) textinput.Model { ti := textinput.New() - ti.Styles.Blurred.Placeholder = styles.NewStyle().Foreground(textMutedColor).Background(bgColor).Lipgloss() + ti.Styles.Blurred.Placeholder = styles.NewStyle(). + Foreground(textMutedColor). + Background(bgColor). + Lipgloss() ti.Styles.Blurred.Text = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss() - ti.Styles.Focused.Placeholder = styles.NewStyle().Foreground(textMutedColor).Background(bgColor).Lipgloss() + ti.Styles.Focused.Placeholder = styles.NewStyle(). + Foreground(textMutedColor). + Background(bgColor). + Lipgloss() ti.Styles.Focused.Text = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss() ti.Styles.Cursor.Color = t.Primary() ti.VirtualCursor = true @@ -213,7 +212,6 @@ func NewFindDialog(completionProvider CompletionProvider) FindDialog { false, ) - // Load initial items go func() { items, err := completionProvider.GetChildEntries("") if err != nil { diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go index cc437f80..29235229 100644 --- a/packages/tui/internal/tui/tui.go +++ b/packages/tui/internal/tui/tui.go @@ -51,7 +51,7 @@ type appModel struct { editor chat.EditorComponent messages chat.MessagesComponent completions dialog.CompletionDialog - completionManager *completions.CompletionManager + commandProvider dialog.CompletionProvider showCompletionDialog bool leaderBinding *key.Binding isLeaderSequence bool @@ -105,6 +105,7 @@ var BUGGED_SCROLL_KEYS = map[string]bool{ "m": true, "[": true, ";": true, + "<": true, } func isScrollRelatedInput(keyString string) bool { @@ -134,6 +135,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyPressMsg: keyString := msg.String() + if time.Since(a.lastScroll) < time.Millisecond*100 && (BUGGED_SCROLL_KEYS[keyString] || isScrollRelatedInput(keyString)) { return a, nil } @@ -174,37 +176,16 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } // 3. Handle completions trigger - if keyString == "/" && !a.showCompletionDialog { + if keyString == "/" && + !a.showCompletionDialog && + a.editor.Value() == "" { a.showCompletionDialog = true - initialValue := "/" - currentInput := a.editor.Value() - - // if the input doesn't end with a space, - // then we want to include the last word - // (ie, `packages/`) - if !strings.HasSuffix(currentInput, " ") { - words := strings.Split(a.editor.Value(), " ") - if len(words) > 0 { - lastWord := words[len(words)-1] - lastWord = strings.TrimSpace(lastWord) - initialValue = lastWord + "/" - } - } - - updated, cmd := a.completions.Update( - app.CompletionDialogTriggeredMsg{ - InitialValue: initialValue, - }, - ) - a.completions = updated.(dialog.CompletionDialog) - cmds = append(cmds, cmd) - - updated, cmd = a.editor.Update(msg) + updated, cmd := a.editor.Update(msg) a.editor = updated.(chat.EditorComponent) cmds = append(cmds, cmd) - updated, cmd = a.updateCompletions(msg) + updated, cmd = a.completions.Update(msg) a.completions = updated.(dialog.CompletionDialog) cmds = append(cmds, cmd) @@ -214,7 +195,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if a.showCompletionDialog { switch keyString { case "tab", "enter", "esc", "ctrl+c": - updated, cmd := a.updateCompletions(msg) + updated, cmd := a.completions.Update(msg) a.completions = updated.(dialog.CompletionDialog) cmds = append(cmds, cmd) return a, tea.Batch(cmds...) @@ -224,7 +205,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { a.editor = updated.(chat.EditorComponent) cmds = append(cmds, cmd) - updated, cmd = a.updateCompletions(msg) + updated, cmd = a.completions.Update(msg) a.completions = updated.(dialog.CompletionDialog) cmds = append(cmds, cmd) @@ -971,22 +952,12 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd) return a, tea.Batch(cmds...) } -func (a appModel) updateCompletions(msg tea.Msg) (tea.Model, tea.Cmd) { - currentInput := a.editor.Value() - if currentInput != "" { - provider := a.completionManager.GetProvider(currentInput) - a.completions.SetProvider(provider) - } - return a.completions.Update(msg) -} - func NewModel(app *app.App) tea.Model { - completionManager := completions.NewCompletionManager(app) - initialProvider := completionManager.DefaultProvider() + commandProvider := completions.NewCommandCompletionProvider(app) messages := chat.NewMessagesComponent(app) editor := chat.NewEditorComponent(app) - completions := dialog.NewCompletionDialogComponent(initialProvider) + completions := dialog.NewCompletionDialogComponent(commandProvider) var leaderBinding *key.Binding if app.Config.Keybinds.Leader != "" { @@ -1000,7 +971,7 @@ func NewModel(app *app.App) tea.Model { editor: editor, messages: messages, completions: completions, - completionManager: completionManager, + commandProvider: commandProvider, leaderBinding: leaderBinding, isLeaderSequence: false, showCompletionDialog: false,