mirror of
https://github.com/sst/opencode.git
synced 2025-07-07 16:14:59 +00:00
109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
package completions
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/sst/opencode-sdk-go"
|
|
"github.com/sst/opencode/internal/app"
|
|
"github.com/sst/opencode/internal/components/dialog"
|
|
"github.com/sst/opencode/internal/styles"
|
|
"github.com/sst/opencode/internal/theme"
|
|
)
|
|
|
|
type filesAndFoldersContextGroup struct {
|
|
app *app.App
|
|
prefix string
|
|
gitFiles []dialog.CompletionItemI
|
|
}
|
|
|
|
func (cg *filesAndFoldersContextGroup) GetId() string {
|
|
return cg.prefix
|
|
}
|
|
|
|
func (cg *filesAndFoldersContextGroup) GetEmptyMessage() string {
|
|
return "no matching files"
|
|
}
|
|
|
|
func (cg *filesAndFoldersContextGroup) getGitFiles() []dialog.CompletionItemI {
|
|
t := theme.CurrentTheme()
|
|
items := make([]dialog.CompletionItemI, 0)
|
|
base := styles.NewStyle().Background(t.BackgroundElement())
|
|
green := base.Foreground(t.Success()).Render
|
|
red := base.Foreground(t.Error()).Render
|
|
|
|
status, _ := cg.app.Client.File.Status(context.Background())
|
|
if status != nil {
|
|
files := *status
|
|
sort.Slice(files, func(i, j int) bool {
|
|
return files[i].Added+files[i].Removed > files[j].Added+files[j].Removed
|
|
})
|
|
|
|
for _, file := range files {
|
|
title := file.File
|
|
if file.Added > 0 {
|
|
title += green(" +" + strconv.Itoa(int(file.Added)))
|
|
}
|
|
if file.Removed > 0 {
|
|
title += red(" -" + strconv.Itoa(int(file.Removed)))
|
|
}
|
|
item := dialog.NewCompletionItem(dialog.CompletionItem{
|
|
Title: title,
|
|
Value: file.File,
|
|
})
|
|
items = append(items, item)
|
|
}
|
|
}
|
|
|
|
return items
|
|
}
|
|
|
|
func (cg *filesAndFoldersContextGroup) GetChildEntries(query string) ([]dialog.CompletionItemI, error) {
|
|
items := make([]dialog.CompletionItemI, 0)
|
|
|
|
query = strings.TrimSpace(query)
|
|
if query == "" {
|
|
items = append(items, cg.gitFiles...)
|
|
}
|
|
|
|
files, err := cg.app.Client.Find.Files(
|
|
context.Background(),
|
|
opencode.FindFilesParams{Query: opencode.F(query)},
|
|
)
|
|
if err != nil {
|
|
slog.Error("Failed to get completion items", "error", err)
|
|
}
|
|
|
|
for _, file := range *files {
|
|
exists := false
|
|
for _, existing := range cg.gitFiles {
|
|
if existing.GetValue() == file {
|
|
if query != "" {
|
|
items = append(items, existing)
|
|
}
|
|
exists = true
|
|
}
|
|
}
|
|
if !exists {
|
|
item := dialog.NewCompletionItem(dialog.CompletionItem{
|
|
Title: file,
|
|
Value: file,
|
|
})
|
|
items = append(items, item)
|
|
}
|
|
}
|
|
|
|
return items, nil
|
|
}
|
|
|
|
func NewFileAndFolderContextGroup(app *app.App) dialog.CompletionProvider {
|
|
cg := &filesAndFoldersContextGroup{
|
|
app: app,
|
|
prefix: "file",
|
|
}
|
|
cg.gitFiles = cg.getGitFiles()
|
|
return cg
|
|
}
|