cat / 012
clone

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

Named ranges picker: a narrow namesHost; its changes noted in recordings

Dami committed 633fc57
The picker stays in package ui, as the macro manager does: its keys open
the model's prompts, which reopen it. Deleting, renaming or adding a
range from it while recording now leaves a Not recorded comment instead
of nothing.
commit
633fc57739ac4f50acf3031fe6c205d3734fc7a6
parent
9c70055602c065c6885927c7851c443ed2ca44f4
author
Dami <dami.etoile@gmail.com>
kind
fix risk score 1.2 of 3, Jev's estimate
3 files changed, +52 -11
Minternal/ui/hosts.go1+
Minternal/ui/macrodialog_test.go12+++++++
Minternal/ui/names.go50+++++++++++++++++++++++-------
M internal/ui/hosts.go +1 -0
M internal/ui/macrodialog_test.go +12 -0
M internal/ui/names.go +39 -11
@@ -7,6 +7,7 @@ import (
77 88 "github.com/FelineStateMachine/012/internal/sheet"99 "github.com/FelineStateMachine/012/internal/ui/picker"10+ "github.com/FelineStateMachine/012/internal/ui/theme"1011 )1112 1213 // Named ranges, as Sheets' Data > Named ranges: a picker lists them with
@@ -28,9 +29,30 @@ func init() {
2829 )2930 }3031 32+// namesHost is what the named ranges picker acts on. The model33+// implements it. The picker stays in package ui: it is a few keys over a34+// picker, and what they do (naming, renaming and pointing at a range on35+// the context line, going to one) are the model's prompts and36+// selection, which open the picker again.37+type namesHost interface {38+ styles() *theme.Theme39+ sheetShown() *sheet.Sheet40+ closeOverlay()41+ // namesItems are the picker's rows: "Add a range" for sel, then the42+ // named ranges.43+ namesItems(sel sheet.Rect) []picker.Item44+ // editName asks for a new name and range for n, then opens the45+ // picker again with sel.46+ editName(n sheet.Name, sel sheet.Rect)47+ // nameChanged follows a named range changed from the picker: the48+ // file is modified, and a macro being recorded notes what it can't49+ // replay.50+ nameChanged()51+}52+3153 // namesPicker is the picker of named ranges with its extra keys.3254 type namesPicker struct {33- m *Model // the model it acts on55+ m namesHost // the model, through what the picker needs of it3456 *picker.Picker3557 sel sheet.Rect // the selection when the picker opened, for "Add a range"3658 msg string // feedback on the last action, e.g. a deletion
@@ -38,14 +60,19 @@ type namesPicker struct {
3860 3961 // openNames opens the picker; sel is what "Add a range" names.4062 func (m *Model) openNames(sel sheet.Rect) {41- p := m.newPicker("Named ranges", "Type a name", 60, namesItems(m, sel))63+ p := m.newPicker("Named ranges", "Type a name", 60, m.namesItems(sel))4264 p.Action = "go to"4365 m.clearSelection()4466 m.openOverlay(&namesPicker{m: m, Picker: p, sel: sel})4567 }4668 69+func (m *Model) nameChanged() {70+ m.syncChanged()71+ m.noteUnrecorded()72+}73+4774 // namesItems lists "Add a range" and then every named range.48-func namesItems(m *Model, sel sheet.Rect) []picker.Item {75+func (m *Model) namesItems(sel sheet.Rect) []picker.Item {4976 add := "+ Add a range"5077 items := []picker.Item{{5178 Title: add, Name: len(add), Detail: sel.String(), Desc: "Name " + sel.String() + ", to use the name in formulas",
@@ -84,11 +111,11 @@ func namesItems(m *Model, sel sheet.Rect) []picker.Item {
84111 }85112 86113 // current is the named range highlighted in the picker, if any.87-func (p *namesPicker) current(m *Model) (sheet.Name, bool) {114+func (p *namesPicker) current(m namesHost) (sheet.Name, bool) {88115 if p.Picker.Sel >= len(p.Shown()) {89116 return sheet.Name{}, false90117 }91- return m.sheet.LookupName(p.Shown()[p.Picker.Sel].Item.Title)118+ return m.sheetShown().LookupName(p.Shown()[p.Picker.Sel].Item.Title)92119 }93120 94121 func (p *namesPicker) Key(k tea.KeyPressMsg) tea.Cmd {
@@ -103,10 +130,10 @@ func (p *namesPicker) Key(k tea.KeyPressMsg) tea.Cmd {
103130 return nil104131 case "ctrl+d":105132 if n, ok := p.current(m); ok {106- m.sheet.DeleteName(n.Name)107- m.changed = true133+ m.sheetShown().DeleteName(n.Name)134+ m.nameChanged()108135 p.msg = "Deleted " + n.Name + "; Ctrl+Z brings it back"109- p.Items = namesItems(m, p.sel)136+ p.Items = m.namesItems(p.sel)110137 sel := p.Picker.Sel111138 p.Changed()112139 p.Picker.Sel = max(min(sel, len(p.Shown())-1), 0)
@@ -118,9 +145,9 @@ func (p *namesPicker) Key(k tea.KeyPressMsg) tea.Cmd {
118145 119146 func (p *namesPicker) Status() (string, string) {120147 m := p.m121- keys := m.th.KeyHints("Enter", "go to", "F2", "edit", "Ctrl+D", "delete", "Esc", "close")148+ keys := m.styles().KeyHints("Enter", "go to", "F2", "edit", "Ctrl+D", "delete", "Esc", "close")122149 if _, ok := p.current(m); !ok {123- keys = m.th.KeyHints("Enter", "add", "Esc", "close")150+ keys = m.styles().KeyHints("Enter", "add", "Esc", "close")124151 }125152 if p.msg != "" {126153 return p.msg, keys
@@ -139,6 +166,7 @@ func (m *Model) defineName(r sheet.Rect, back bool) {
139166 }140167 m.changed = true141168 if back {169+ m.noteUnrecorded() // named from the picker, not as the command142170 m.openNames(r)143171 return nil144172 }
@@ -169,7 +197,7 @@ func (m *Model) editName(n sheet.Name, sel sheet.Rect) {
169197 m.fail(err.Error())170198 return nil171199 }172- m.changed = true200+ m.nameChanged()173201 m.openNames(sel)174202 return nil175203 })