summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-06-20 08:20:10 -0500
committeradamdottv <[email protected]>2025-06-20 08:20:10 -0500
commit311b9c74dd1b1d853f8fee0f9d54182bde3beee5 (patch)
tree2382fc35f2960a07eb22f8ace89db6f5d509f149
parentf7e8dd2ff8b83f69fd32969b5aafff1da8e81467 (diff)
downloadopencode-311b9c74dd1b1d853f8fee0f9d54182bde3beee5.tar.gz
opencode-311b9c74dd1b1d853f8fee0f9d54182bde3beee5.zip
fix(tui): typeahead open/close perf
-rw-r--r--packages/tui/internal/completions/commands.go15
-rw-r--r--packages/tui/internal/components/dialog/complete.go5
-rw-r--r--packages/tui/internal/tui/tui.go52
3 files changed, 32 insertions, 40 deletions
diff --git a/packages/tui/internal/completions/commands.go b/packages/tui/internal/completions/commands.go
index e3215a88f..3becb7790 100644
--- a/packages/tui/internal/completions/commands.go
+++ b/packages/tui/internal/completions/commands.go
@@ -35,8 +35,7 @@ func (c *CommandCompletionProvider) GetEmptyMessage() string {
return "no matching commands"
}
-func getCommandCompletionItem(cmd commands.Command, space int) dialog.CompletionItemI {
- t := theme.CurrentTheme()
+func getCommandCompletionItem(cmd commands.Command, space int, t theme.Theme) dialog.CompletionItemI {
spacer := strings.Repeat(" ", space)
title := " /" + cmd.Trigger + lipgloss.NewStyle().Foreground(t.TextMuted()).Render(spacer+cmd.Description)
value := string(cmd.Name)
@@ -47,6 +46,9 @@ func getCommandCompletionItem(cmd commands.Command, space int) dialog.Completion
}
func (c *CommandCompletionProvider) GetChildEntries(query string) ([]dialog.CompletionItemI, error) {
+ t := theme.CurrentTheme()
+ commands := c.app.Commands
+
space := 1
for _, cmd := range c.app.Commands {
if lipgloss.Width(cmd.Trigger) > space {
@@ -55,15 +57,16 @@ func (c *CommandCompletionProvider) GetChildEntries(query string) ([]dialog.Comp
}
space += 2
+ sorted := commands.Sorted()
if query == "" {
// If no query, return all commands
items := []dialog.CompletionItemI{}
- for _, cmd := range c.app.Commands {
+ for _, cmd := range sorted {
if cmd.Trigger == "" {
continue
}
space := space - lipgloss.Width(cmd.Trigger)
- items = append(items, getCommandCompletionItem(cmd, space))
+ items = append(items, getCommandCompletionItem(cmd, space, t))
}
return items, nil
}
@@ -72,13 +75,13 @@ func (c *CommandCompletionProvider) GetChildEntries(query string) ([]dialog.Comp
var commandNames []string
commandMap := make(map[string]dialog.CompletionItemI)
- for _, cmd := range c.app.Commands {
+ for _, cmd := range sorted {
if cmd.Trigger == "" {
continue
}
space := space - lipgloss.Width(cmd.Trigger)
commandNames = append(commandNames, cmd.Trigger)
- commandMap[cmd.Trigger] = getCommandCompletionItem(cmd, space)
+ commandMap[cmd.Trigger] = getCommandCompletionItem(cmd, space, t)
}
// Find fuzzy matches
diff --git a/packages/tui/internal/components/dialog/complete.go b/packages/tui/internal/components/dialog/complete.go
index e73afed01..212df49f7 100644
--- a/packages/tui/internal/components/dialog/complete.go
+++ b/packages/tui/internal/components/dialog/complete.go
@@ -173,7 +173,6 @@ func (c *completionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
cmds = append(cmds, cmd)
cmds = append(cmds, c.pseudoSearchTextArea.Focus())
- // c.pseudoSearchTextArea.SetValue(msg.String())
return c, tea.Batch(cmds...)
}
case tea.WindowSizeMsg:
@@ -218,12 +217,12 @@ 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
}
@@ -242,10 +241,8 @@ func (c *completionDialogComponent) complete(item CompletionItemI) tea.Cmd {
}
func (c *completionDialogComponent) close() tea.Cmd {
- c.list.SetItems([]CompletionItemI{})
c.pseudoSearchTextArea.Reset()
c.pseudoSearchTextArea.Blur()
-
return util.CmdHandler(CompletionDialogCloseMsg{})
}
diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go
index 176960429..f88e3e976 100644
--- a/packages/tui/internal/tui/tui.go
+++ b/packages/tui/internal/tui/tui.go
@@ -123,22 +123,23 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
a.completions = updated.(dialog.CompletionDialog)
cmds = append(cmds, cmd)
- updated, cmd = a.completions.Update(msg)
- a.completions = updated.(dialog.CompletionDialog)
- cmds = append(cmds, cmd)
-
updated, cmd = a.editor.Update(msg)
a.editor = updated.(chat.EditorComponent)
cmds = append(cmds, cmd)
+
+ updated, cmd = a.updateCompletions(msg)
+ a.completions = updated.(dialog.CompletionDialog)
+ cmds = append(cmds, cmd)
+
return a, tea.Sequence(cmds...)
}
if a.showCompletionDialog {
switch keyString {
case "tab", "enter", "esc", "ctrl+c":
- context, contextCmd := a.completions.Update(msg)
- a.completions = context.(dialog.CompletionDialog)
- cmds = append(cmds, contextCmd)
+ updated, cmd := a.updateCompletions(msg)
+ a.completions = updated.(dialog.CompletionDialog)
+ cmds = append(cmds, cmd)
return a, tea.Batch(cmds...)
}
@@ -146,13 +147,10 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
a.editor = updated.(chat.EditorComponent)
cmds = append(cmds, cmd)
- currentInput := a.editor.Value()
- provider := a.completionManager.GetProvider(currentInput)
- a.completions.SetProvider(provider)
+ updated, cmd = a.updateCompletions(msg)
+ a.completions = updated.(dialog.CompletionDialog)
+ cmds = append(cmds, cmd)
- context, contextCmd := a.completions.Update(msg)
- a.completions = context.(dialog.CompletionDialog)
- cmds = append(cmds, contextCmd)
return a, tea.Batch(cmds...)
}
@@ -178,10 +176,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return a, util.CmdHandler(commands.ExecuteCommandsMsg(matches))
}
- // 7. Fallback to editor. This shouldn't happen?
- // All printable characters were already sent, and
- // any other keypress that didn't match a command
- // is likely a noop.
+ // 7. Fallback to editor. This is for other characters
+ // likek backspace, tab, etc.
updatedEditor, cmd := a.editor.Update(msg)
a.editor = updatedEditor.(chat.EditorComponent)
return a, cmd
@@ -216,7 +212,6 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, cmd)
case dialog.CompletionDialogCloseMsg:
a.showCompletionDialog = false
- a.completions.SetProvider(a.completionManager.DefaultProvider())
case client.EventInstallationUpdated:
return a, toast.NewSuccessToast(
"opencode updated to "+msg.Properties.Version+", restart to apply.",
@@ -512,30 +507,18 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
a.messages = updated.(chat.MessagesComponent)
cmds = append(cmds, cmd)
case commands.MessagesPageUpCommand:
- if a.showCompletionDialog {
- return a, nil
- }
updated, cmd := a.messages.PageUp()
a.messages = updated.(chat.MessagesComponent)
cmds = append(cmds, cmd)
case commands.MessagesPageDownCommand:
- if a.showCompletionDialog {
- return a, nil
- }
updated, cmd := a.messages.PageDown()
a.messages = updated.(chat.MessagesComponent)
cmds = append(cmds, cmd)
case commands.MessagesHalfPageUpCommand:
- if a.showCompletionDialog {
- return a, nil
- }
updated, cmd := a.messages.HalfPageUp()
a.messages = updated.(chat.MessagesComponent)
cmds = append(cmds, cmd)
case commands.MessagesHalfPageDownCommand:
- if a.showCompletionDialog {
- return a, nil
- }
updated, cmd := a.messages.HalfPageDown()
a.messages = updated.(chat.MessagesComponent)
cmds = append(cmds, cmd)
@@ -545,6 +528,15 @@ 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()