mirror of
https://github.com/sst/opencode.git
synced 2025-07-07 16:14:59 +00:00
chore: simplify completions
This commit is contained in:
parent
3e2a0c7281
commit
fce59db94a
5 changed files with 30 additions and 104 deletions
|
@ -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
|
||||
|
|
|
@ -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"]
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue