summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--popups.go37
-rw-r--r--tui.go36
2 files changed, 69 insertions, 4 deletions
diff --git a/popups.go b/popups.go
index c83bce4..db314e4 100644
--- a/popups.go
+++ b/popups.go
@@ -70,6 +70,10 @@ func showModelSelectionPopup() {
pages.RemovePage("modelSelectionPopup")
return nil
}
+ if event.Key() == tcell.KeyRune && event.Rune() == 'x' {
+ pages.RemovePage("modelSelectionPopup")
+ return nil
+ }
return event
})
modal := func(p tview.Primitive, width, height int) tview.Primitive {
@@ -163,6 +167,10 @@ func showAPILinkSelectionPopup() {
pages.RemovePage("apiLinkSelectionPopup")
return nil
}
+ if event.Key() == tcell.KeyRune && event.Rune() == 'x' {
+ pages.RemovePage("apiLinkSelectionPopup")
+ return nil
+ }
return event
})
modal := func(p tview.Primitive, width, height int) tview.Primitive {
@@ -229,6 +237,10 @@ func showUserRoleSelectionPopup() {
pages.RemovePage("userRoleSelectionPopup")
return nil
}
+ if event.Key() == tcell.KeyRune && event.Rune() == 'x' {
+ pages.RemovePage("userRoleSelectionPopup")
+ return nil
+ }
return event
})
modal := func(p tview.Primitive, width, height int) tview.Primitive {
@@ -297,6 +309,10 @@ func showBotRoleSelectionPopup() {
pages.RemovePage("botRoleSelectionPopup")
return nil
}
+ if event.Key() == tcell.KeyRune && event.Rune() == 'x' {
+ pages.RemovePage("botRoleSelectionPopup")
+ return nil
+ }
return event
})
modal := func(p tview.Primitive, width, height int) tview.Primitive {
@@ -322,6 +338,16 @@ func showFileCompletionPopup(filter string) {
if len(complMatches) == 0 {
return
}
+ // If only one match, auto-complete without showing popup
+ if len(complMatches) == 1 {
+ currentText := textArea.GetText()
+ atIdx := strings.LastIndex(currentText, "@")
+ if atIdx >= 0 {
+ before := currentText[:atIdx]
+ textArea.SetText(before+complMatches[0], true)
+ }
+ return
+ }
widget := tview.NewList().ShowSecondaryText(false).
SetSelectedBackgroundColor(tcell.ColorGray)
widget.SetTitle("file completion").SetBorder(true)
@@ -337,6 +363,17 @@ func showFileCompletionPopup(filter string) {
}
pages.RemovePage("fileCompletionPopup")
})
+ widget.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
+ if event.Key() == tcell.KeyEscape {
+ pages.RemovePage("fileCompletionPopup")
+ return nil
+ }
+ if event.Key() == tcell.KeyRune && event.Rune() == 'x' {
+ pages.RemovePage("fileCompletionPopup")
+ return nil
+ }
+ return event
+ })
modal := func(p tview.Primitive, width, height int) tview.Primitive {
return tview.NewFlex().
AddItem(nil, 0, 1, false).
diff --git a/tui.go b/tui.go
index a681358..517ba20 100644
--- a/tui.go
+++ b/tui.go
@@ -74,8 +74,6 @@ var (
[yellow]Ctrl+c[white]: close programm
[yellow]Ctrl+n[white]: start a new chat
[yellow]Ctrl+o[white]: open image file picker
-[yellow]@[white]: file completion (type @ in input to get file suggestions)
-[yellow]c[white]: (in file picker) set current dir as CodingDir
[yellow]Ctrl+p[white]: props edit form (min-p, dry, etc.)
[yellow]Ctrl+v[white]: show API link selection popup to choose current API
[yellow]Ctrl+r[white]: start/stop recording from your microphone (needs stt server or whisper binary)
@@ -109,6 +107,13 @@ var (
=== tables (chat history, agent pick, file pick, properties) ===
[yellow]x[white]: to exit the table page
+=== filepicker ===
+[yellow]c[white]: (in file picker) set current dir as CodingDir
+[yellow]x[white]: to exit
+
+=== shell mode ===
+[yellow]@match->Tab[white]: file completion (type @ in input to get file suggestions)
+
=== status line ===
%s
@@ -179,10 +184,33 @@ func init() {
textArea.SetBorder(true).SetTitle("input")
// Add input capture for @ completion
textArea.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
- if shellMode && event.Key() == tcell.KeyRune && event.Rune() == '@' {
- showFileCompletionPopup("")
+ if !shellMode {
return event
}
+ // Handle Tab key for file completion
+ if event.Key() == tcell.KeyTab {
+ currentText := textArea.GetText()
+ row, col, _, _ := textArea.GetCursor()
+ // Calculate absolute position from row/col
+ lines := strings.Split(currentText, "\n")
+ cursorPos := 0
+ for i := 0; i < row && i < len(lines); i++ {
+ cursorPos += len(lines[i]) + 1 // +1 for newline
+ }
+ cursorPos += col
+ // Look backwards from cursor to find @
+ if cursorPos > 0 {
+ // Find the last @ before cursor
+ textBeforeCursor := currentText[:cursorPos]
+ atIndex := strings.LastIndex(textBeforeCursor, "@")
+ if atIndex >= 0 {
+ // Extract the partial match text after @
+ filter := textBeforeCursor[atIndex+1:]
+ showFileCompletionPopup(filter)
+ return nil // Consume the Tab event
+ }
+ }
+ }
return event
})
textView = tview.NewTextView().