Enha: remade within a popup

This commit is contained in:
Grail Finder
2026-02-19 08:35:21 +03:00
parent b861b92e5d
commit b18d96ac13
3 changed files with 39 additions and 103 deletions

View File

@@ -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()
}

View File

@@ -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)
}

51
tui.go
View File

@@ -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().