Add auto-summary settings
This commit is contained in:
@@ -37,6 +37,9 @@ type paletteAction struct {
|
||||
|
||||
// For *-rename-submit actions, the user-typed new name.
|
||||
newName string
|
||||
|
||||
// For settings actions, the updated settings snapshot to persist.
|
||||
settings *settings
|
||||
}
|
||||
|
||||
// Group ids order the section bands the palette renders when no query
|
||||
@@ -47,14 +50,16 @@ const (
|
||||
groupFocused = iota
|
||||
groupOpen
|
||||
groupSpawn
|
||||
groupSettings
|
||||
groupQuit
|
||||
)
|
||||
|
||||
var groupLabels = map[int]string{
|
||||
groupFocused: "Focused",
|
||||
groupOpen: "Open",
|
||||
groupSpawn: "Spawn",
|
||||
groupQuit: "Quit",
|
||||
groupFocused: "Focused",
|
||||
groupOpen: "Open",
|
||||
groupSpawn: "Spawn",
|
||||
groupSettings: "Settings",
|
||||
groupQuit: "Quit",
|
||||
}
|
||||
|
||||
type paletteItem struct {
|
||||
@@ -77,6 +82,9 @@ const (
|
||||
paletteModePicker paletteMode = iota
|
||||
paletteModeSpawnForm
|
||||
paletteModeRenameForm
|
||||
paletteModeSettings
|
||||
paletteModeAutoSummary
|
||||
paletteModeSettingsInput
|
||||
)
|
||||
|
||||
// spawnProcessForm is the state for the "Spawn process…" two-field
|
||||
@@ -101,6 +109,13 @@ type renameForm struct {
|
||||
subjectLine string // e.g. "scratchpad: notes.md" rendered above the input
|
||||
}
|
||||
|
||||
type settingsInputForm struct {
|
||||
title string
|
||||
field string
|
||||
value []rune
|
||||
subtitle string
|
||||
}
|
||||
|
||||
// paletteState is the in-memory model for the overlay. SPEC §4: a
|
||||
// single fuzzy-searchable list of commands scoped to the current focus.
|
||||
type paletteState struct {
|
||||
@@ -110,12 +125,14 @@ type paletteState struct {
|
||||
focused string
|
||||
focusedPad string
|
||||
presets preset.Set
|
||||
settings settings
|
||||
|
||||
items []paletteItem
|
||||
|
||||
mode paletteMode
|
||||
form *spawnProcessForm
|
||||
renameForm *renameForm
|
||||
mode paletteMode
|
||||
form *spawnProcessForm
|
||||
renameForm *renameForm
|
||||
settingsInput *settingsInputForm
|
||||
|
||||
// showHelp swaps the item list for a static keybinding cheat-sheet
|
||||
// until the next keystroke. Toggled by `?` in picker mode.
|
||||
@@ -171,8 +188,12 @@ func findChildByID(children []*Child, id string) *Child {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newPalette(children []*Child, focused, focusedPad string, presets preset.Set) *paletteState {
|
||||
p := &paletteState{children: children, focused: focused, focusedPad: focusedPad, presets: presets}
|
||||
func newPalette(children []*Child, focused, focusedPad string, presets preset.Set, appSettings ...settings) *paletteState {
|
||||
st := defaultSettings()
|
||||
if len(appSettings) > 0 {
|
||||
st = appSettings[0].clone()
|
||||
}
|
||||
p := &paletteState{children: children, focused: focused, focusedPad: focusedPad, presets: presets, settings: st}
|
||||
p.rebuild()
|
||||
return p
|
||||
}
|
||||
@@ -325,7 +346,15 @@ func (p *paletteState) buildItems(macro string) []paletteItem {
|
||||
group: groupSpawn,
|
||||
})
|
||||
|
||||
// Group 3: Quit.
|
||||
// Group 3: Settings.
|
||||
out = append(out, paletteItem{
|
||||
label: "Open Settings",
|
||||
hint: "configure agents and auto-summary",
|
||||
action: paletteAction{kind: "settings-open"},
|
||||
group: groupSettings,
|
||||
})
|
||||
|
||||
// Group 4: Quit.
|
||||
out = append(out, paletteItem{
|
||||
label: "Quit",
|
||||
hint: "exit patterm; SIGTERM every child",
|
||||
@@ -519,6 +548,15 @@ func (p *paletteState) handleInput(chunk []byte, i int) (action paletteAction, d
|
||||
if p.mode == paletteModeRenameForm {
|
||||
return p.handleRenameInput(chunk, i)
|
||||
}
|
||||
if p.mode == paletteModeSettings {
|
||||
return p.handleSettingsInput(chunk, i)
|
||||
}
|
||||
if p.mode == paletteModeAutoSummary {
|
||||
return p.handleAutoSummaryInput(chunk, i)
|
||||
}
|
||||
if p.mode == paletteModeSettingsInput {
|
||||
return p.handleSettingsTextInput(chunk, i)
|
||||
}
|
||||
|
||||
b := chunk[i]
|
||||
|
||||
@@ -602,6 +640,12 @@ func (p *paletteState) acceptOrEnterForm(adv int) (paletteAction, bool, int) {
|
||||
p.mode = paletteModeSpawnForm
|
||||
p.form = &spawnProcessForm{}
|
||||
return paletteAction{}, false, adv
|
||||
case "settings-open":
|
||||
p.mode = paletteModeSettings
|
||||
p.query = nil
|
||||
p.cursor = 0
|
||||
p.rebuildSettings()
|
||||
return paletteAction{}, false, adv
|
||||
case "pad-rename-form":
|
||||
p.enterRenameForm("pad", a.padName, a.padName, "scratchpad: "+a.padName)
|
||||
return paletteAction{}, false, adv
|
||||
@@ -1112,6 +1156,427 @@ func (p *paletteState) focusedSubject() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (p *paletteState) rebuildSettings() {
|
||||
items := []paletteItem{{
|
||||
label: "Agents / Auto-summarization",
|
||||
hint: "provider, models, cadence, test",
|
||||
action: paletteAction{kind: "settings-auto-summary"},
|
||||
group: groupSettings,
|
||||
}}
|
||||
q := strings.TrimSpace(strings.ToLower(string(p.query)))
|
||||
if q == "" {
|
||||
p.items = items
|
||||
p.cursor = 0
|
||||
return
|
||||
}
|
||||
p.items = p.items[:0]
|
||||
for _, it := range items {
|
||||
if strings.Contains(strings.ToLower(it.label+" "+it.hint), q) {
|
||||
p.items = append(p.items, it)
|
||||
}
|
||||
}
|
||||
p.clampCursor()
|
||||
}
|
||||
|
||||
func (p *paletteState) handleSettingsInput(chunk []byte, i int) (paletteAction, bool, int) {
|
||||
b := chunk[i]
|
||||
if b == 0x1b {
|
||||
if n := csiLen(chunk, i); n > 0 {
|
||||
final := chunk[i+n-1]
|
||||
switch final {
|
||||
case 'A':
|
||||
p.cursorUp()
|
||||
case 'B':
|
||||
p.cursorDown()
|
||||
}
|
||||
return paletteAction{}, false, n
|
||||
}
|
||||
return paletteAction{kind: "cancel"}, true, 1
|
||||
}
|
||||
switch b {
|
||||
case '\r', '\n':
|
||||
if len(p.items) == 0 {
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
a := p.items[p.cursor].action
|
||||
if a.kind == "settings-auto-summary" {
|
||||
p.mode = paletteModeAutoSummary
|
||||
p.cursor = 0
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
case 0x7f, 0x08:
|
||||
p.backspace()
|
||||
p.rebuildSettings()
|
||||
case 0x15:
|
||||
p.query = nil
|
||||
p.rebuildSettings()
|
||||
case 0x0e:
|
||||
p.cursorDown()
|
||||
case 0x10:
|
||||
p.cursorUp()
|
||||
default:
|
||||
if b >= 0x20 && b < 0x7f {
|
||||
p.query = append(p.query, rune(b))
|
||||
p.rebuildSettings()
|
||||
}
|
||||
}
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
|
||||
func (p *paletteState) handleAutoSummaryInput(chunk []byte, i int) (paletteAction, bool, int) {
|
||||
b := chunk[i]
|
||||
if b == 0x1b {
|
||||
if n := csiLen(chunk, i); n > 0 {
|
||||
final := chunk[i+n-1]
|
||||
switch final {
|
||||
case 'A':
|
||||
p.cursor--
|
||||
if p.cursor < 0 {
|
||||
p.cursor = len(autoSummaryRows()) - 1
|
||||
}
|
||||
case 'B':
|
||||
p.cursor++
|
||||
if p.cursor >= len(autoSummaryRows()) {
|
||||
p.cursor = 0
|
||||
}
|
||||
}
|
||||
return paletteAction{}, false, n
|
||||
}
|
||||
return paletteAction{kind: "cancel"}, true, 1
|
||||
}
|
||||
switch b {
|
||||
case '\r', '\n':
|
||||
return p.activateAutoSummaryRow()
|
||||
case 0x0e:
|
||||
p.cursor++
|
||||
case 0x10:
|
||||
p.cursor--
|
||||
}
|
||||
if p.cursor < 0 {
|
||||
p.cursor = len(autoSummaryRows()) - 1
|
||||
}
|
||||
if p.cursor >= len(autoSummaryRows()) {
|
||||
p.cursor = 0
|
||||
}
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
|
||||
func (p *paletteState) handleSettingsTextInput(chunk []byte, i int) (paletteAction, bool, int) {
|
||||
if p.settingsInput == nil {
|
||||
p.mode = paletteModeAutoSummary
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
b := chunk[i]
|
||||
if b == 0x1b {
|
||||
if n := csiLen(chunk, i); n > 0 {
|
||||
return paletteAction{}, false, n
|
||||
}
|
||||
p.mode = paletteModeAutoSummary
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
switch b {
|
||||
case '\r', '\n':
|
||||
p.applySettingsInput()
|
||||
p.mode = paletteModeAutoSummary
|
||||
case 0x7f, 0x08:
|
||||
if len(p.settingsInput.value) > 0 {
|
||||
p.settingsInput.value = p.settingsInput.value[:len(p.settingsInput.value)-1]
|
||||
}
|
||||
case 0x15:
|
||||
p.settingsInput.value = nil
|
||||
default:
|
||||
if b >= 0x20 && b < 0x7f {
|
||||
p.settingsInput.value = append(p.settingsInput.value, rune(b))
|
||||
}
|
||||
}
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
|
||||
type autoSummaryRow struct {
|
||||
key string
|
||||
label string
|
||||
}
|
||||
|
||||
func autoSummaryRows() []autoSummaryRow {
|
||||
return []autoSummaryRow{
|
||||
{key: "enabled", label: "Enabled"},
|
||||
{key: "provider", label: "Provider"},
|
||||
{key: "codex_model", label: "Codex model"},
|
||||
{key: "opencode_model", label: "OpenCode model"},
|
||||
{key: "claude_model", label: "Claude model"},
|
||||
{key: "cadence", label: "Cadence"},
|
||||
{key: "test", label: "Test summarizer"},
|
||||
{key: "run_now", label: "Summarize current top-level agent now"},
|
||||
{key: "save", label: "Save settings"},
|
||||
{key: "cancel", label: "Cancel"},
|
||||
{key: "back", label: "Back to Settings"},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *paletteState) activateAutoSummaryRow() (paletteAction, bool, int) {
|
||||
rows := autoSummaryRows()
|
||||
if p.cursor < 0 || p.cursor >= len(rows) {
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
switch rows[p.cursor].key {
|
||||
case "enabled":
|
||||
p.settings.AutoSummary.Enabled = !p.settings.AutoSummary.Enabled
|
||||
case "provider":
|
||||
switch p.settings.AutoSummary.Provider {
|
||||
case "codex":
|
||||
p.settings.AutoSummary.Provider = "opencode"
|
||||
case "opencode":
|
||||
p.settings.AutoSummary.Provider = "claude"
|
||||
default:
|
||||
p.settings.AutoSummary.Provider = "codex"
|
||||
}
|
||||
case "codex_model", "opencode_model", "claude_model":
|
||||
provider := strings.TrimSuffix(rows[p.cursor].key, "_model")
|
||||
p.settingsInput = &settingsInputForm{
|
||||
title: provider + " model",
|
||||
field: rows[p.cursor].key,
|
||||
value: []rune(p.settings.AutoSummary.modelFor(provider)),
|
||||
subtitle: "model flag passed to " + provider,
|
||||
}
|
||||
p.mode = paletteModeSettingsInput
|
||||
case "cadence":
|
||||
switch p.settings.AutoSummary.Cadence {
|
||||
case "5m":
|
||||
p.settings.AutoSummary.Cadence = "15m"
|
||||
case "15m":
|
||||
p.settings.AutoSummary.Cadence = "30m"
|
||||
default:
|
||||
p.settings.AutoSummary.Cadence = "5m"
|
||||
}
|
||||
case "test":
|
||||
return p.settingsAction("settings-test"), true, 1
|
||||
case "run_now":
|
||||
return p.settingsAction("settings-run-now"), true, 1
|
||||
case "save":
|
||||
return p.settingsAction("settings-close"), true, 1
|
||||
case "cancel":
|
||||
return paletteAction{kind: "cancel"}, true, 1
|
||||
case "back":
|
||||
p.mode = paletteModeSettings
|
||||
p.cursor = 0
|
||||
p.query = nil
|
||||
p.rebuildSettings()
|
||||
}
|
||||
p.settings.normalize()
|
||||
return paletteAction{}, false, 1
|
||||
}
|
||||
|
||||
func (p *paletteState) applySettingsInput() {
|
||||
if p.settingsInput == nil {
|
||||
return
|
||||
}
|
||||
val := strings.TrimSpace(string(p.settingsInput.value))
|
||||
if val == "" {
|
||||
return
|
||||
}
|
||||
if p.settings.AutoSummary.Models == nil {
|
||||
p.settings.AutoSummary.Models = defaultSummaryModels()
|
||||
}
|
||||
switch p.settingsInput.field {
|
||||
case "codex_model":
|
||||
p.settings.AutoSummary.Models["codex"] = val
|
||||
case "opencode_model":
|
||||
p.settings.AutoSummary.Models["opencode"] = val
|
||||
case "claude_model":
|
||||
p.settings.AutoSummary.Models["claude"] = val
|
||||
}
|
||||
p.settings.normalize()
|
||||
}
|
||||
|
||||
func (p *paletteState) settingsCloseAction() paletteAction {
|
||||
return p.settingsAction("settings-close")
|
||||
}
|
||||
|
||||
func (p *paletteState) settingsAction(kind string) paletteAction {
|
||||
st := p.settings.clone()
|
||||
return paletteAction{kind: kind, settings: &st}
|
||||
}
|
||||
|
||||
func (p *paletteState) renderSettings(out writeFlusher, cols, rows int) {
|
||||
p.renderSimplePicker(out, cols, rows, "Settings", "esc cancel", "search settings")
|
||||
}
|
||||
|
||||
func (p *paletteState) renderSimplePicker(out writeFlusher, cols, rows int, title, hint, placeholder string) {
|
||||
width, leftPad, content := paletteBox(cols)
|
||||
maxItems := rows - 7
|
||||
if maxItems > 10 {
|
||||
maxItems = 10
|
||||
}
|
||||
if maxItems < 1 {
|
||||
maxItems = 1
|
||||
}
|
||||
var b strings.Builder
|
||||
b.WriteString("\x1b[?25l\x1b[H\x1b[2J\x1b[3J")
|
||||
row := 2
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╭─ " + styleActive + title + styleReset + styleBorder + " " + strings.Repeat("─", max(2, width-visibleLen(title)-visibleLen(hint)-9)) + " " + styleHint + hint + styleReset + styleBorder + " ─╮" + styleReset)
|
||||
row++
|
||||
query := string(p.query)
|
||||
if query == "" {
|
||||
query = styleDim + placeholder + styleReset
|
||||
}
|
||||
pad := content - 2 - visibleLen(query)
|
||||
if pad < 0 {
|
||||
pad = 0
|
||||
}
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + styleAccent + "❯" + styleReset + " " + query + strings.Repeat(" ", pad) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "├" + strings.Repeat("─", width-2) + "┤" + styleReset)
|
||||
row++
|
||||
p.renderItemRows(&b, &row, leftPad, width, content, maxItems)
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "├" + strings.Repeat("─", width-2) + "┤" + styleReset)
|
||||
row++
|
||||
footer := styleHint + "↵ open · esc cancel · ↑↓ navigate" + styleReset
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + footer + strings.Repeat(" ", max(0, content-visibleLen(footer))) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╰" + strings.Repeat("─", width-2) + "╯" + styleReset)
|
||||
_, _ = out.Write([]byte(b.String()))
|
||||
_ = out.Flush()
|
||||
}
|
||||
|
||||
func (p *paletteState) renderAutoSummary(out writeFlusher, cols, rows int) {
|
||||
width, leftPad, content := paletteBox(cols)
|
||||
var b strings.Builder
|
||||
b.WriteString("\x1b[?25l\x1b[H\x1b[2J\x1b[3J")
|
||||
row := 2
|
||||
title := "Auto-summarization"
|
||||
hint := "esc cancel"
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╭─ " + styleActive + title + styleReset + styleBorder + " " + strings.Repeat("─", max(2, width-visibleLen(title)-visibleLen(hint)-9)) + " " + styleHint + hint + styleReset + styleBorder + " ─╮" + styleReset)
|
||||
row++
|
||||
lines := p.autoSummaryDisplayRows()
|
||||
for i, line := range lines {
|
||||
moveTo(&b, row, leftPad)
|
||||
prefix := " "
|
||||
if i == p.cursor {
|
||||
prefix = styleAccent + "▎" + styleReset + " "
|
||||
line = styleBold + line + styleReset
|
||||
}
|
||||
pad := content - visibleLen(prefix) - visibleLen(line)
|
||||
if pad < 0 {
|
||||
pad = 0
|
||||
}
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + prefix + line + strings.Repeat(" ", pad) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
}
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "├" + strings.Repeat("─", width-2) + "┤" + styleReset)
|
||||
row++
|
||||
footer := styleHint + "↵ edit/toggle · save row commits · esc cancel" + styleReset
|
||||
if visibleLen(footer) > content {
|
||||
footer = clipRunes(footer, content-1) + "…"
|
||||
}
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + footer + strings.Repeat(" ", max(0, content-visibleLen(footer))) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╰" + strings.Repeat("─", width-2) + "╯" + styleReset)
|
||||
_, _ = out.Write([]byte(b.String()))
|
||||
_ = out.Flush()
|
||||
}
|
||||
|
||||
func (p *paletteState) autoSummaryDisplayRows() []string {
|
||||
a := p.settings.AutoSummary
|
||||
enabled := "off"
|
||||
if a.Enabled {
|
||||
enabled = "on"
|
||||
}
|
||||
values := map[string]string{
|
||||
"enabled": enabled,
|
||||
"provider": a.Provider,
|
||||
"codex_model": a.modelFor("codex"),
|
||||
"opencode_model": a.modelFor("opencode"),
|
||||
"claude_model": a.modelFor("claude"),
|
||||
"cadence": a.Cadence + " minimum after activity",
|
||||
}
|
||||
var out []string
|
||||
for _, row := range autoSummaryRows() {
|
||||
if v, ok := values[row.key]; ok {
|
||||
out = append(out, row.label+": "+v)
|
||||
} else {
|
||||
out = append(out, row.label)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (p *paletteState) renderSettingsInput(out writeFlusher, cols, rows int) {
|
||||
if p.settingsInput == nil {
|
||||
p.settingsInput = &settingsInputForm{title: "Setting"}
|
||||
}
|
||||
width, leftPad, content := paletteBox(cols)
|
||||
var b strings.Builder
|
||||
b.WriteString("\x1b[?25l\x1b[H\x1b[2J\x1b[3J")
|
||||
row := 2
|
||||
title := p.settingsInput.title
|
||||
hint := "esc cancel"
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╭─ " + styleActive + title + styleReset + styleBorder + " " + strings.Repeat("─", max(2, width-visibleLen(title)-visibleLen(hint)-9)) + " " + styleHint + hint + styleReset + styleBorder + " ─╮" + styleReset)
|
||||
row++
|
||||
if p.settingsInput.subtitle != "" {
|
||||
sub := p.settingsInput.subtitle
|
||||
if visibleLen(sub) > content {
|
||||
sub = clipRunes(sub, content-1) + "…"
|
||||
}
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + styleHint + sub + styleReset + strings.Repeat(" ", max(0, content-visibleLen(sub))) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
}
|
||||
value := string(p.settingsInput.value)
|
||||
if visibleLen(value) > content-2 {
|
||||
value = clipRunes(value, content-3) + "…"
|
||||
}
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + styleAccent + "❯" + styleReset + " " + value + strings.Repeat(" ", max(0, content-2-visibleLen(value))) + " " + styleBorder + "│" + styleReset)
|
||||
inputRow := row
|
||||
row++
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "├" + strings.Repeat("─", width-2) + "┤" + styleReset)
|
||||
row++
|
||||
footer := styleHint + "↵ save · esc cancel · ⌃u clear" + styleReset
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "│" + styleReset + " " + footer + strings.Repeat(" ", max(0, content-visibleLen(footer))) + " " + styleBorder + "│" + styleReset)
|
||||
row++
|
||||
moveTo(&b, row, leftPad)
|
||||
b.WriteString(styleBorder + "╰" + strings.Repeat("─", width-2) + "╯" + styleReset)
|
||||
moveTo(&b, inputRow, leftPad+4+visibleLen(value))
|
||||
b.WriteString("\x1b[?25h")
|
||||
_, _ = out.Write([]byte(b.String()))
|
||||
_ = out.Flush()
|
||||
}
|
||||
|
||||
func paletteBox(cols int) (width, leftPad, content int) {
|
||||
if cols < 32 {
|
||||
cols = 32
|
||||
}
|
||||
width = cols - 8
|
||||
if width > 72 {
|
||||
width = 72
|
||||
}
|
||||
if width < 40 {
|
||||
width = cols - 2
|
||||
}
|
||||
if width < 32 {
|
||||
width = 32
|
||||
}
|
||||
leftPad = (cols - width) / 2
|
||||
if leftPad < 1 {
|
||||
leftPad = 1
|
||||
}
|
||||
content = width - 4
|
||||
return width, leftPad, content
|
||||
}
|
||||
|
||||
// render draws the palette onto out. Layout is a rounded box with a
|
||||
// title bar, query line, chip strip, divider, item list, divider, and
|
||||
// footer. The caller is responsible for the screen clear before the
|
||||
@@ -1125,6 +1590,18 @@ func (p *paletteState) render(out writeFlusher, cols, rows int) {
|
||||
p.renderRename(out, cols, rows)
|
||||
return
|
||||
}
|
||||
if p.mode == paletteModeSettings {
|
||||
p.renderSettings(out, cols, rows)
|
||||
return
|
||||
}
|
||||
if p.mode == paletteModeAutoSummary {
|
||||
p.renderAutoSummary(out, cols, rows)
|
||||
return
|
||||
}
|
||||
if p.mode == paletteModeSettingsInput {
|
||||
p.renderSettingsInput(out, cols, rows)
|
||||
return
|
||||
}
|
||||
if cols < 32 {
|
||||
cols = 32
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user