Files
patterm/internal/app/tabbar.go
2026-05-14 13:37:20 +01:00

71 lines
1.4 KiB
Go

package app
import (
"fmt"
"os"
"strings"
)
const tabBarRows = 1
// drawTabBar renders SPEC §4's top tab bar at row 1. Tabs are top-level
// children (ParentID == ""); the focused tab is highlighted. The PTY
// region begins at row 2.
func (st *uiState) drawTabBar() {
st.mu.Lock()
palOpen := st.palette != nil
focus := st.focusedID
st.mu.Unlock()
if palOpen {
return
}
layout := st.layoutSnapshot()
width := int(layout.childCols())
var sessions []*Child
for _, c := range st.sess.Children() {
if c.ParentID == "" && c.Status() == StatusRunning {
sessions = append(sessions, c)
}
}
var b strings.Builder
b.WriteString("\x1b[1;1H")
cur := 0
for _, c := range sessions {
label := c.Name
seg := " " + label + " "
if cur+len(seg) > width-2 {
break
}
if c.ID == focus {
b.WriteString("\x1b[7m")
} else {
b.WriteString("\x1b[2m")
}
b.WriteString(seg)
b.WriteString("\x1b[0m")
cur += len(seg)
}
// "+" hint at end.
hint := "+"
if cur > 0 {
hint = " +"
}
if cur+len(hint) <= width {
b.WriteString("\x1b[2m")
b.WriteString(hint)
b.WriteString("\x1b[0m")
cur += len(hint)
}
// Fill the rest of the tab-bar row so stale chars don't linger.
if width-cur > 0 {
b.WriteString(strings.Repeat(" ", width-cur))
}
st.outMu.Lock()
defer st.outMu.Unlock()
// Save cursor, paint, restore.
fmt.Fprintf(os.Stdout, "\x1b7%s\x1b8", b.String())
}