summaryrefslogtreecommitdiff
path: root/internal/tui/flamegraph/controls.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-06 13:36:51 +0200
committerPaul Buetow <paul@buetow.org>2026-03-06 13:36:51 +0200
commitef12ce837176bd21deb455eb50a6c839af02b510 (patch)
treec262ceeda0b419236a4b0b1826df8eb5e418b852 /internal/tui/flamegraph/controls.go
parent10c5d48413afaef88626419d8c4bf9fbf6f1c902 (diff)
Add live flamegraph test modes and dynamic synthetic live feed
Diffstat (limited to 'internal/tui/flamegraph/controls.go')
-rw-r--r--internal/tui/flamegraph/controls.go39
1 files changed, 37 insertions, 2 deletions
diff --git a/internal/tui/flamegraph/controls.go b/internal/tui/flamegraph/controls.go
index 959a5b0..f411a13 100644
--- a/internal/tui/flamegraph/controls.go
+++ b/internal/tui/flamegraph/controls.go
@@ -29,6 +29,7 @@ func (m *Model) resetBaseline() {
m.matchIndices = make(map[int]bool)
m.filterVisible = make(map[int]bool)
m.subtreeSet = make(map[int]bool)
+ m.hasNavigableSnapshot = false
m.statusMessage = "Baseline reset"
}
@@ -55,6 +56,7 @@ func (m *Model) cycleFieldOrder() {
m.matchIndices = make(map[int]bool)
m.filterVisible = make(map[int]bool)
m.subtreeSet = make(map[int]bool)
+ m.hasNavigableSnapshot = false
m.statusMessage = "Order: " + strings.Join(nextPreset, "/")
}
@@ -68,13 +70,16 @@ func (m Model) toolbarLine() string {
state = lipgloss.NewStyle().Foreground(common.ColorDanger).Bold(true).Render("[PAUSED]")
}
order := m.currentFieldPresetLabel()
- line := fmt.Sprintf("%s | view:%s | o:order(%s) | /:search | enter:zoom | u:undo | r:reset | p:pause", state, compactFramePath(m.currentRootPath()), order)
+ line := fmt.Sprintf("%s | view:%s | o:order(%s) | /:search | enter:zoom | u:undo | r:reset | space/p:pause", state, compactFramePath(m.currentRootPath()), order)
if m.searchQuery != "" {
line += " | filter:" + m.searchQuery
}
if m.statusMessage != "" {
line += " | " + m.statusMessage
}
+ if m.lastKeyDebug != "" {
+ line += " | " + m.lastKeyDebug
+ }
width := m.width
if width <= 0 {
width = 80
@@ -87,10 +92,40 @@ func (m Model) helpOverlay() string {
if width <= 0 {
width = 80
}
- help := "Flame help: j/k depth h/l sibling enter zoom u/backspace undo esc reset / search n/N matches p pause r reset baseline o order ? help"
+ help := "Flame help: j/k depth h/l sibling enter zoom u/backspace undo esc reset / search n/N matches space/p pause r reset baseline o order ? help"
return common.HelpBarStyle.Width(width).Render(padOrTrim(help, width))
}
+func (m Model) selectionStatusLine() string {
+ width := m.width
+ if width <= 0 {
+ width = 80
+ }
+ mode := "LIVE"
+ if m.paused {
+ mode = "PAUSED"
+ }
+ if len(m.frames) == 0 {
+ line := fmt.Sprintf("[%s] sel:none | arrows/hjkl navigate | enter zoom | / filter", mode)
+ return common.HelpBarStyle.Width(width).Render(padOrTrim(line, width))
+ }
+ selIdx := m.selectedIdx
+ if selIdx < 0 || selIdx >= len(m.frames) {
+ selIdx = 0
+ }
+ frame := m.frames[selIdx]
+ systemShare := frame.Percent
+ if m.globalTotal > 0 {
+ systemShare = percentOfTotal(frame.Total, m.globalTotal)
+ }
+ line := fmt.Sprintf("[%s] sel:%d/%d %s | path:%s | depth:%d | total:%d | %.2f%% system",
+ mode, selIdx+1, len(m.frames), frame.Name, compactFramePath(frame.Path), frame.Depth, frame.Total, systemShare)
+ if m.searchQuery != "" {
+ line += " | filter:" + m.searchQuery
+ }
+ return common.HelpBarStyle.Width(width).Render(padOrTrim(line, width))
+}
+
func (m Model) currentFieldPresetLabel() string {
if len(m.fieldPresets) == 0 {
return "n/a"