cat / 012
clone

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

Regions: formulas follow a table that shrinks, and a label line moved onto old rows is cleared

Dami committed d0c7d95
A region run with fewer rows, or undone to them, left formulas naming it
reading the larger table. Undone and redone, a region pushed down onto
rows its table showed kept those cells beside its label.
commit
d0c7d959e17c836f864abb0a2edd85c772a9e565
parent
abb0201c69eda4bb32ff08c4c21f7ffb1534f6ec
author
Dami <dami.etoile@gmail.com>
kind
fix risk score 1.5 of 3, Jev's estimate
2 files changed, +76 -3
Minternal/sheet/region_test.go41++++++++++++++++++++++++++++++
Minternal/sheet/regionwrite.go38++++++++++++++++++++++++++--
M internal/sheet/region_test.go +41 -0
@@ -125,6 +125,47 @@ func TestRegionFormulaName(t *testing.T) {
125125 }126126 }127127 128+// A region pushed down onto rows its table showed, then undone and129+// redone, shows its label line alone: nothing of those rows is left130+// beside the label.131+func TestRegionRedoneOverItsOldRows(t *testing.T) {132+ s := notebook(t)133+ w := s.Book()134+ addShown(t, s, "r1", "ls", table([]string{"a", "b"}, []string{"14", "13"}))135+ w.ClearHistory()136+ addShown(t, s, "r2", "$r1 | first 2", table([]string{"x", "y", "z"}, []string{"12", "1", "7"}, []string{"2", "10", "0"}))137+ s.ShowRegion("r1", table([]string{"a"}, []string{"4"}, []string{"12"}, []string{"8"}, []string{"13"}))138+ want := map[string]string{"A8": "r2 $r1 | first 2", "B8": "", "C8": "", "A9": "x", "C11": "0"}139+ wantShown(t, s, want)140+ for w.CanUndo() {141+ w.Undo()142+ }143+ for w.CanRedo() {144+ w.Redo()145+ }146+ wantShown(t, s, want)147+}148+149+// A formula naming a region follows its table as it shrinks, run with150+// fewer rows or undone to them, as it does as it grows.151+func TestRegionFormulaFollowsShrinking(t *testing.T) {152+ s := notebook(t)153+ w := s.Book()154+ other, _ := w.AddSheet("Sheet2", 1)155+ other.Set(at("A1"), "=SUM(nu.r1)")156+ addShown(t, s, "r1", "ls", table([]string{"n"}))157+ s.ShowRegion("r1", table([]string{"n"}, []string{"7"}, []string{"2"}))158+ wantShown(t, other, map[string]string{"A1": "9"})159+ s.ShowRegion("r1", table([]string{"n"}, []string{"7"}))160+ wantShown(t, other, map[string]string{"A1": "7"})161+ w.Undo()162+ wantShown(t, other, map[string]string{"A1": "9"})163+ w.Undo()164+ wantShown(t, other, map[string]string{"A1": "0"})165+ w.Redo()166+ wantShown(t, other, map[string]string{"A1": "9"})167+}168+128169 func TestRegionGraph(t *testing.T) {129170 s := notebook(t)130171 w := s.Book()
M internal/sheet/regionwrite.go +35 -3
@@ -116,8 +116,11 @@ func (s *Sheet) writeRegions() []loc {
116116 cols, nrows := tableSize(me, header, rows, true)117117 keep := s.tableArea(r, cols, nrows)118118 changed = append(changed, s.clearOwned(me, keep)...)119- if me.has {119+ if was := me.written; me.has {120120 me.written, me.has = intersectRect(me.written, keep) // what it holds now121+ if me.written != was {122+ changed = s.regionUsers(r, changed) // its table shrank123+ }121124 }122125 case me.reread:123126 me.reread = false
@@ -199,6 +202,7 @@ func (s *Sheet) writeTable(r Region, me *regionMeta, header LiveRow, rows []Live
199202 me.written, me.has = need, true200203 if r.labelled() {201204 changed = s.writeRegionCell(r.At, LiveCell{V: Value{Kind: Text, Str: s.regionLabel(r)}}, me, changed)205+ changed = s.clearBesideLabel(r, need, me, changed)202206 } else if me.why != "" || nrows == 0 && me.err != "" {203207 changed = s.writeRegionCell(r.At, LiveCell{V: ErrRef}, me, changed)204208 }
@@ -222,10 +226,38 @@ func (s *Sheet) writeTable(r Region, me *regionMeta, header LiveRow, rows []Live
222226 s.freedFor(c.a)223227 }224228 if !had || was != me.written {225- for u := range s.wb.nameUsers[nameKey(r.FormulaName())] {226- changed = append(changed, u)229+ changed = s.regionUsers(r, changed)230+ }231+ return changed232+}233+234+// clearBesideLabel clears the cells of the label line, beside the label,235+// that the region wrote as part of its table before it moved down onto236+// them (undone and redone, a region may find its old rows there).237+func (s *Sheet) clearBesideLabel(r Region, need Rect, me *regionMeta, changed []loc) []loc {238+ line := Rect{From: Addr{Col: r.At.Col + 1, Row: r.At.Row}, To: Addr{Col: need.To.Col, Row: r.At.Row}}239+ if line.To.Col < line.From.Col {240+ return changed241+ }242+ var gone []Addr243+ for a := range s.cells.anyKeysIn(line) {244+ if s.cells.filledAt(a) && s.regionOwns(a, me) {245+ gone = append(gone, a)227246 }228247 }248+ for _, a := range gone {249+ s.setDerived(a, s.cells.get(a).leftover())250+ changed = append(changed, loc{s, a})251+ }252+ return changed253+}254+255+// regionUsers appends the formulas naming r to changed, to recalculate256+// when its table moves or changes size.257+func (s *Sheet) regionUsers(r Region, changed []loc) []loc {258+ for u := range s.wb.nameUsers[nameKey(r.FormulaName())] {259+ changed = append(changed, u)260+ }229261 return changed230262 }231263