feat(tui-go): slash command menu in the chat input

Typing `/` as the first char of a chat line opens the command palette inline
(opencode-style), instead of typing a literal slash; mid-line `/` stays literal.
Factors openPalette() (shared with the `p` key) and advertises `/ cmds` in the
insert-mode footer when the line is empty.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 09:35:34 +00:00
parent 9143d554f1
commit 85bfddf1c4
3 changed files with 66 additions and 3 deletions
+45
View File
@@ -0,0 +1,45 @@
package app
import (
"testing"
tea "github.com/charmbracelet/bubbletea"
)
// `/` as the first char of a chat line opens the command palette inline (opencode-style),
// without typing a literal slash.
func TestSlashOpensPaletteOnEmptyLine(t *testing.T) {
m := NewModel(nil)
m.editMode = ModeInsert
m.inputMode = ModeRouter
m.inputBuffer = ""
next, _ := m.handleInsertKey(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("/")})
nm := next.(Model)
if nm.overlay != OverlayPalette {
t.Fatalf("'/' on an empty line should open the palette; overlay=%d", nm.overlay)
}
if nm.inputBuffer != "" {
t.Fatalf("'/' should not be typed literally; buffer=%q", nm.inputBuffer)
}
}
// Mid-line `/` is a literal slash (e.g. a path), not a command trigger.
func TestSlashLiteralMidLine(t *testing.T) {
m := NewModel(nil)
m.editMode = ModeInsert
m.inputMode = ModeRouter
m.inputBuffer = "path"
m.inputCursor = len("path")
next, _ := m.handleInsertKey(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("/")})
nm := next.(Model)
if nm.overlay != OverlayNone {
t.Fatalf("mid-line '/' must stay literal, not open the palette; overlay=%d", nm.overlay)
}
if nm.inputBuffer != "path/" {
t.Fatalf("mid-line '/' should be typed; buffer=%q", nm.inputBuffer)
}
}