summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-07-03 12:48:14 -0500
committeradamdottv <[email protected]>2025-07-03 12:48:22 -0500
commitfce59db94ac3efd3c3977dfdd4e1a12fe590f517 (patch)
treee1281ba8fa1009bce24d6258798072307cdc601c
parent3e2a0c7281d449452d6808fdff80e2a1d8cf998d (diff)
downloadopencode-fce59db94ac3efd3c3977dfdd4e1a12fe590f517.tar.gz
opencode-fce59db94ac3efd3c3977dfdd4e1a12fe590f517.zip
chore: simplify completions
-rw-r--r--packages/tui/internal/app/app.go14
-rw-r--r--packages/tui/internal/completions/manager.go32
-rw-r--r--packages/tui/internal/components/dialog/complete.go15
-rw-r--r--packages/tui/internal/components/dialog/find.go18
-rw-r--r--packages/tui/internal/tui/tui.go55
5 files changed, 30 insertions, 104 deletions
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go
index 9b341c19b..6b59acaec 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 5368208f7..000000000
--- 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 f204d910c..caf754c71 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 3ca0d105b..489b9f297 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 cc437f804..29235229d 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,