From b18d96ac13539bd18e891bb8b6c934910d36800f Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Thu, 19 Feb 2026 08:35:21 +0300 Subject: Enha: remade within a popup --- helpfuncs.go | 53 ----------------------------------------------------- popups.go | 38 ++++++++++++++++++++++++++++++++++++++ tui.go | 51 +-------------------------------------------------- 3 files changed, 39 insertions(+), 103 deletions(-) diff --git a/helpfuncs.go b/helpfuncs.go index f5e64ae..350b6ed 100644 --- a/helpfuncs.go +++ b/helpfuncs.go @@ -726,56 +726,3 @@ func scanFiles(dir, filter string) []string { } return files } - -func showFileCompletion(filter string) { - baseDir := cfg.CodingDir - if baseDir == "" { - baseDir = "." - } - complMatches = scanFiles(baseDir, filter) - go func() { - app.QueueUpdateDraw(func() { - if len(complMatches) == 0 { - hideCompletion() // Make sure hideCompletion also uses QueueUpdate if it modifies UI - return - } - // Limit the number of complMatches - if len(complMatches) > 10 { - complMatches = complMatches[:10] - } - // Update the popup's content - complPopup.Clear() - for _, f := range complMatches { - complPopup.AddItem(f, "", 0, nil) - } - // Update state and UI - complPopup.SetCurrentItem(0) - complActive = true - // Show the popup and set focus - pages.AddPage("complPopup", complPopup, true, true) - app.SetFocus(complPopup) - // No need to call app.Draw() here, QueueUpdateDraw does it automatically - }) - }() -} - -func insertCompletion() { - if complIndex >= 0 && complIndex < len(complMatches) { - match := complMatches[complIndex] - currentText := textArea.GetText() - atIdx := strings.LastIndex(currentText, "@") - if atIdx >= 0 { - before := currentText[:atIdx] - textArea.SetText(before+match, true) - } - } - hideCompletion() -} - -func hideCompletion() { - complActive = false - complMatches = nil - pages.RemovePage("complPopup") - app.SetFocus(textArea) - app.Draw() -} diff --git a/popups.go b/popups.go index 9a1a278..c83bce4 100644 --- a/popups.go +++ b/popups.go @@ -312,3 +312,41 @@ func showBotRoleSelectionPopup() { pages.AddPage("botRoleSelectionPopup", modal(roleListWidget, 80, 20), true, true) app.SetFocus(roleListWidget) } + +func showFileCompletionPopup(filter string) { + baseDir := cfg.CodingDir + if baseDir == "" { + baseDir = "." + } + complMatches := scanFiles(baseDir, filter) + if len(complMatches) == 0 { + return + } + widget := tview.NewList().ShowSecondaryText(false). + SetSelectedBackgroundColor(tcell.ColorGray) + widget.SetTitle("file completion").SetBorder(true) + for _, m := range complMatches { + widget.AddItem(m, "", 0, nil) + } + widget.SetSelectedFunc(func(index int, mainText string, secondaryText string, shortcut rune) { + currentText := textArea.GetText() + atIdx := strings.LastIndex(currentText, "@") + if atIdx >= 0 { + before := currentText[:atIdx] + textArea.SetText(before+mainText, true) + } + pages.RemovePage("fileCompletionPopup") + }) + modal := func(p tview.Primitive, width, height int) tview.Primitive { + return tview.NewFlex(). + AddItem(nil, 0, 1, false). + AddItem(tview.NewFlex().SetDirection(tview.FlexRow). + AddItem(nil, 0, 1, false). + AddItem(p, height, 1, true). + AddItem(nil, 0, 1, false), width, 1, true). + AddItem(nil, 0, 1, false) + } + // Add modal page and make it visible + pages.AddPage("fileCompletionPopup", modal(widget, 80, 20), true, true) + app.SetFocus(widget) +} diff --git a/tui.go b/tui.go index 275aab7..a681358 100644 --- a/tui.go +++ b/tui.go @@ -49,14 +49,6 @@ var ( imgPage = "imgPage" filePickerPage = "filePicker" exportDir = "chat_exports" - - // file completion - complPopup *tview.List - complActive bool - complAtPos int - complMatches []string - complIndex int - // For overlay search functionality searchField *tview.InputField searchPageName = "searchOverlay" @@ -185,53 +177,12 @@ func init() { textArea = tview.NewTextArea(). SetPlaceholder("input is multiline; press to start the next line;\npress to send the message.") textArea.SetBorder(true).SetTitle("input") - - // Setup file completion popup - complPopup = tview.NewList() - complPopup.SetBorder(true).SetTitle("Files (@ to trigger)") - pages.AddPage("complPopup", complPopup, false, false) - // Add input capture for @ completion textArea.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if shellMode && event.Key() == tcell.KeyRune && event.Rune() == '@' { - complAtPos = len(textArea.GetText()) - showFileCompletion("") + showFileCompletionPopup("") return event } - if complActive { - switch event.Key() { - case tcell.KeyUp: - if complIndex > 0 { - complIndex-- - complPopup.SetCurrentItem(complIndex) - } - return nil - case tcell.KeyDown: - if complIndex < len(complMatches)-1 { - complIndex++ - complPopup.SetCurrentItem(complIndex) - } - return nil - case tcell.KeyTab, tcell.KeyEnter: - if len(complMatches) > 0 { - insertCompletion() - } - return nil - case tcell.KeyEsc: - hideCompletion() - return nil - } - } - if complActive && event.Key() == tcell.KeyRune { - r := event.Rune() - if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '-' || r == '_' || r == '/' || r == '.' { - currentText := textArea.GetText() - if len(currentText) > complAtPos { - filter := currentText[complAtPos+1:] - showFileCompletion(filter) - } - } - } return event }) textView = tview.NewTextView(). -- cgit v1.2.3