Browse Source

chore: use new search component in find dialog

adamdotdevin 7 months ago
parent
commit
a1c8e5af45
1 changed files with 37 additions and 135 deletions
  1. 37 135
      packages/tui/internal/components/dialog/find.go

+ 37 - 135
packages/tui/internal/components/dialog/find.go

@@ -3,14 +3,10 @@ package dialog
 import (
 	"log/slog"
 
-	"github.com/charmbracelet/bubbles/v2/key"
-	"github.com/charmbracelet/bubbles/v2/textinput"
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/sst/opencode/internal/components/list"
 	"github.com/sst/opencode/internal/components/modal"
 	"github.com/sst/opencode/internal/layout"
-	"github.com/sst/opencode/internal/styles"
-	"github.com/sst/opencode/internal/theme"
 	"github.com/sst/opencode/internal/util"
 )
 
@@ -30,120 +26,61 @@ type FindDialog interface {
 }
 
 type findDialogComponent struct {
-	query              string
 	completionProvider CompletionProvider
 	width, height      int
 	modal              *modal.Modal
-	textInput          textinput.Model
-	list               list.List[CompletionItemI]
-}
-
-type findDialogKeyMap struct {
-	Select key.Binding
-	Cancel key.Binding
-}
-
-var findDialogKeys = findDialogKeyMap{
-	Select: key.NewBinding(
-		key.WithKeys("enter"),
-	),
-	Cancel: key.NewBinding(
-		key.WithKeys("esc"),
-	),
+	searchDialog       *SearchDialog
 }
 
 func (f *findDialogComponent) Init() tea.Cmd {
-	return textinput.Blink
+	return f.searchDialog.Init()
 }
 
 func (f *findDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
-	var cmd tea.Cmd
-	var cmds []tea.Cmd
-
 	switch msg := msg.(type) {
 	case []CompletionItemI:
-		f.list.SetItems(msg)
-	case tea.KeyMsg:
-		switch msg.String() {
-		case "ctrl+c":
-			if f.textInput.Value() == "" {
-				return f, nil
-			}
-			f.textInput.SetValue("")
-			return f.update(msg)
+		// Convert CompletionItemI to list.ListItem
+		items := make([]list.ListItem, len(msg))
+		for i, item := range msg {
+			items[i] = item
 		}
+		f.searchDialog.SetItems(items)
+		return f, nil
 
-		switch {
-		case key.Matches(msg, findDialogKeys.Select):
-			item, i := f.list.GetSelectedItem()
-			if i == -1 {
-				return f, nil
-			}
+	case SearchSelectionMsg:
+		// Handle selection from search dialog
+		if item, ok := msg.Item.(CompletionItemI); ok {
 			return f, f.selectFile(item)
-		case key.Matches(msg, findDialogKeys.Cancel):
-			return f, f.Close()
-		default:
-			f.textInput, cmd = f.textInput.Update(msg)
-			cmds = append(cmds, cmd)
-
-			f, cmd = f.update(msg)
-			cmds = append(cmds, cmd)
 		}
-	}
-
-	return f, tea.Batch(cmds...)
-}
+		return f, nil
 
-func (f *findDialogComponent) update(msg tea.Msg) (*findDialogComponent, tea.Cmd) {
-	var cmd tea.Cmd
-	var cmds []tea.Cmd
+	case SearchCancelledMsg:
+		return f, f.Close()
 
-	query := f.textInput.Value()
-	if query != f.query {
-		f.query = query
-		cmd = func() tea.Msg {
-			items, err := f.completionProvider.GetChildEntries(query)
+	case SearchQueryChangedMsg:
+		// Update completion items based on search query
+		return f, func() tea.Msg {
+			items, err := f.completionProvider.GetChildEntries(msg.Query)
 			if err != nil {
 				slog.Error("Failed to get completion items", "error", err)
 			}
 			return items
 		}
-		cmds = append(cmds, cmd)
 	}
 
-	u, cmd := f.list.Update(msg)
-	f.list = u.(list.List[CompletionItemI])
-	cmds = append(cmds, cmd)
-
-	return f, tea.Batch(cmds...)
+	// Forward all other messages to the search dialog
+	updatedDialog, cmd := f.searchDialog.Update(msg)
+	f.searchDialog = updatedDialog.(*SearchDialog)
+	return f, cmd
 }
 
 func (f *findDialogComponent) View() string {
-	t := theme.CurrentTheme()
-	f.textInput.SetWidth(f.width - 8)
-	f.list.SetMaxWidth(f.width - 4)
-	inputView := f.textInput.View()
-	inputView = styles.NewStyle().
-		Background(t.BackgroundElement()).
-		Height(1).
-		Width(f.width-4).
-		Padding(0, 0).
-		Render(inputView)
-
-	listView := f.list.View()
-	return styles.NewStyle().
-		Height(12).
-		Background(t.BackgroundPanel()).
-		Width(f.width - 4).
-		Render(inputView + "\n" + listView)
+	return f.searchDialog.View()
 }
 
 func (f *findDialogComponent) SetWidth(width int) {
 	f.width = width
-	if width > 4 {
-		f.textInput.SetWidth(width - 4)
-		f.list.SetMaxWidth(width - 4)
-	}
+	f.searchDialog.SetWidth(width - 4)
 }
 
 func (f *findDialogComponent) SetHeight(height int) {
@@ -151,7 +88,7 @@ func (f *findDialogComponent) SetHeight(height int) {
 }
 
 func (f *findDialogComponent) IsEmpty() bool {
-	return f.list.IsEmpty()
+	return f.searchDialog.GetQuery() == ""
 }
 
 func (f *findDialogComponent) selectFile(item CompletionItemI) tea.Cmd {
@@ -168,67 +105,32 @@ func (f *findDialogComponent) Render(background string) string {
 }
 
 func (f *findDialogComponent) Close() tea.Cmd {
-	f.textInput.Reset()
-	f.textInput.Blur()
+	f.searchDialog.SetQuery("")
+	f.searchDialog.Blur()
 	return util.CmdHandler(modal.CloseModalMsg{})
 }
 
-func createTextInput(existing *textinput.Model) textinput.Model {
-	t := theme.CurrentTheme()
-	bgColor := t.BackgroundElement()
-	textColor := t.Text()
-	textMutedColor := t.TextMuted()
-
-	ti := textinput.New()
-
-	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.Text = styles.NewStyle().Foreground(textColor).Background(bgColor).Lipgloss()
-	ti.Styles.Cursor.Color = t.Primary()
-	ti.VirtualCursor = true
-
-	ti.Prompt = " "
-	ti.CharLimit = -1
-	ti.Focus()
-
-	if existing != nil {
-		ti.SetValue(existing.Value())
-		ti.SetWidth(existing.Width())
-	}
-
-	return ti
-}
-
 func NewFindDialog(completionProvider CompletionProvider) FindDialog {
-	ti := createTextInput(nil)
-
-	li := list.NewListComponent(
-		[]CompletionItemI{},
-		10, // max visible items
-		completionProvider.GetEmptyMessage(),
-		false,
-	)
+	searchDialog := NewSearchDialog("Search files...", 10)
 
+	// Initialize with empty query to get initial items
 	go func() {
 		items, err := completionProvider.GetChildEntries("")
 		if err != nil {
 			slog.Error("Failed to get completion items", "error", err)
+			return
+		}
+		// Convert CompletionItemI to list.ListItem
+		listItems := make([]list.ListItem, len(items))
+		for i, item := range items {
+			listItems[i] = item
 		}
-		li.SetItems(items)
+		searchDialog.SetItems(listItems)
 	}()
 
 	return &findDialogComponent{
-		query:              "",
 		completionProvider: completionProvider,
-		textInput:          ti,
-		list:               li,
+		searchDialog:       searchDialog,
 		modal: modal.New(
 			modal.WithTitle("Find Files"),
 			modal.WithMaxWidth(80),