cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / ui / undocost.go
undocost.go 1.8K
1package ui23import (4 "fmt"56 tea "charm.land/bubbletea/v2"78 "src.rest/cat/012/internal/sheet"9)1011// A change whose undo step would hold more than sheet.MaxStepBytes12// (millions of formulas, or of distinct long texts, cleared or rewritten13// at once) asks first on the context line rather than holding gigabytes14// for undo: Enter runs it without undo, forgetting the history, and Esc15// backs out. Commands are checked through what they edit, as protected16// ranges are, and so is sorting. Macros that run don't ask.1718// maxStepBytes is sheet.MaxStepBytes; tests lower it.19var maxStepBytes int64 = sheet.MaxStepBytes2021// askUndoCost reports whether changing r would take more undo history22// than maxStepBytes, and if so asks whether to go on: Enter runs retry23// without undo, and retry isn't asked again.24func (m *Model) askUndoCost(r sheet.Rect, retry func(*Model) tea.Cmd) bool {25 if m.undoOK || m.macros.run != nil {26 return false27 }28 cost := m.sheet.UndoCost(r)29 if cost <= maxStepBytes {30 return false31 }32 protectOK := m.protectOK // agreed to before this asked33 m.ask(question{34 msg: "This can't be undone: it would take " + byteSize(cost) + " of undo history.", warn: true,35 desc: "Going on runs it without undo and forgets the changes before it",36 choices: []choice{37 {key: "enter", label: "Go on without undo", run: func(m *Model) tea.Cmd {38 m.undoOK, m.protectOK = true, protectOK39 defer func() { m.undoOK, m.protectOK = false, false }()40 var cmd tea.Cmd41 m.book().WithoutUndo(func() { cmd = retry(m) })42 m.syncChanged()43 return cmd44 }},45 {key: "esc", label: "Cancel", run: func(*Model) tea.Cmd { return nil }},46 },47 })48 return true49}5051// byteSize is n bytes in MB, or in GB from a thousand MB.52func byteSize(n int64) string {53 if mb := n >> 20; mb < 1000 {54 return fmt.Sprintf("%d MB", mb)55 }56 return fmt.Sprintf("%.1f GB", float64(n)/(1<<30))57}