cat / 012
clone

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

main
012 / internal / sheet / linereaders.go
linereaders.go 1.8K
1package sheet23// Formulas infer their format from the cells they read (=B5*2 shows4// currency when B5 does), blank ones included. A blank cell has no entry5// of its own to mark changed when its column, row or the sheet is6// formatted, so the formulas reading anywhere in the line are marked7// instead, found through the indexes recalculation uses: the cost is the8// formulas, not the line's million cells.910// readersIn returns the formulas, on any sheet, that read a cell of r on11// s: by reference, through a range, a named range, or naming s.12func (s *Sheet) readersIn(r Rect) []loc {13 seen := map[loc]struct{}{}14 add := func(l loc) { seen[l] = struct{}{} }15 for a, users := range s.dependents {16 if r.Contains(a) {17 for u := range users {18 add(loc{s, u})19 }20 }21 }22 s.rangeUsers.usersIn(r, func(u Addr) { add(loc{s, u}) })23 w := s.wb24 for _, nu := range w.namedInUse() {25 if nu.s == s && overlaps(nu.r, r) {26 for u := range nu.users {27 add(u)28 }29 }30 }31 for u := range w.crossUsers {32 if c := u.s.cells.get(u.a); c != nil {33 for _, x := range c.xrefs {34 if w.byKey[x.key] == s && overlaps(x.r, r) {35 add(u)36 }37 }38 }39 }40 out := make([]loc, 0, len(seen))41 for l := range seen {42 out = append(out, l)43 }44 return out45}4647// usersIn calls fn with the formulas one of whose ranges overlaps r; a48// formula may come more than once.49func (x *rangeIndex) usersIn(r Rect, fn func(Addr)) {50 each := func(iv *intervals) {51 for rg, users := range iv.users {52 if overlaps(rg, r) {53 for u := range users {54 fn(u)55 }56 }57 }58 }59 for c, iv := range x.byCol {60 if c >= r.From.Col && c <= r.To.Col {61 each(iv)62 }63 }64 each(&x.wide)65}6667// overlaps reports whether two ranges share a cell.68func overlaps(p, q Rect) bool {69 return p.From.Col <= q.To.Col && q.From.Col <= p.To.Col && p.From.Row <= q.To.Row && q.From.Row <= p.To.Row70}