summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helpfuncs.go53
-rw-r--r--popups.go38
-rw-r--r--tui.go51
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 <Enter> to start the next line;\npress <Esc> 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().