summaryrefslogtreecommitdiff
path: root/internal/tui/tui.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-24 09:17:20 +0200
committerPaul Buetow <paul@buetow.org>2026-02-24 09:17:20 +0200
commit1cbb2430d027c9d8850bf3a2b79a05338efea3ea (patch)
tree5572c87d76b18ec8ea2956fb9e9a20dc7e69b2ac /internal/tui/tui.go
parentceb5c392d363f9f6afccd310b0a7a7efb14bb4e3 (diff)
tui: add help overlay behavior and docs update
Diffstat (limited to 'internal/tui/tui.go')
-rw-r--r--internal/tui/tui.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index 90b0162..4d7a7dc 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -10,12 +10,14 @@ import (
tuiexport "ior/internal/tui/export"
"ior/internal/tui/pidpicker"
"os"
+ "strings"
"sync"
"time"
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/spinner"
tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/lipgloss"
)
// Screen identifies the currently active TUI screen.
@@ -85,6 +87,7 @@ type Model struct {
attaching bool
spin spinner.Model
lastErr error
+ showHelp bool
startTrace TraceStarter
traceStop context.CancelFunc
@@ -139,6 +142,17 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.stopTrace()
return m, tea.Quit
}
+ if !m.exporter.Visible() && key.Matches(msg, m.keys.Help) {
+ m.showHelp = !m.showHelp
+ return m, nil
+ }
+ if !m.exporter.Visible() && m.showHelp && key.Matches(msg, m.keys.Esc) {
+ m.showHelp = false
+ return m, nil
+ }
+ if !m.exporter.Visible() && m.showHelp {
+ return m, nil
+ }
if m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.Export) && !m.exporter.Visible() {
m.exporter = m.exporter.Open()
return m, nil
@@ -264,12 +278,18 @@ func (m Model) View() string {
if m.exporter.Visible() {
return m.exporter.View(m.width, m.height) + "\n" + base
}
+ if m.showHelp {
+ return renderHelpOverlay(m.width, m.height, [][]key.Binding{m.keys.PickerShortHelp()}) + "\n" + base
+ }
return base
case ScreenDashboard:
base := m.dashboard.View()
if m.exporter.Visible() {
return m.exporter.View(m.width, m.height) + "\n" + base
}
+ if m.showHelp {
+ return renderHelpOverlay(m.width, m.height, m.keys.DashboardFullHelp()) + "\n" + base
+ }
return base
default:
return ""
@@ -407,3 +427,29 @@ func snapValueF(snap *statsengine.Snapshot, get func(*statsengine.Snapshot) floa
func exportFlamegraph() (string, error) {
return "", errors.New("flamegraph export is not yet available in TUI mode")
}
+
+func renderHelpOverlay(width, height int, groups [][]key.Binding) string {
+ if width <= 0 {
+ width = 80
+ }
+ if height <= 0 {
+ height = 24
+ }
+
+ lines := []string{"Help"}
+ for _, group := range groups {
+ parts := make([]string, 0, len(group))
+ for _, binding := range group {
+ h := binding.Help()
+ parts = append(parts, fmt.Sprintf("%s %s", h.Key, h.Desc))
+ }
+ lines = append(lines, strings.Join(parts, " • "))
+ }
+ lines = append(lines, "", "Esc/? close")
+
+ box := PanelStyle.Copy().
+ Width(72).
+ Render(strings.Join(lines, "\n"))
+
+ return lipgloss.Place(width, height, lipgloss.Center, lipgloss.Center, box)
+}