cat / 012
clone

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

Format > Number > Size: bytes shown as nushell shows file sizes

Dami committed 8ace0e6
1.6 kB, with units a thousand apart from B to EB, one decimal place by
default; Excel downloads keep it as the conditional custom format Sheets
would write, which reads back as Size.
commit
8ace0e657f9f366152090f8669c1cad6d1a80f8e
parent
e3e1ac95287a989690d1fe13a20746601da48b9c
author
Dami <dami.etoile@gmail.com>
kind
feat risk score 1.1 of 3, Jev's estimate
12 files changed, +146 -8
Mdocs/reference/macro-api.md2+-
Mdocs/sheets/formatting.md11+++++++
Minternal/fileio/numfmt.go4++-
Minternal/fileio/xlsx_test.go4++
Ainternal/numfmt/size.go49++++++++++++++++++++++++++++++
Ainternal/numfmt/size_test.go40++++++++++++++++++++++++
Minternal/sheet/display.go13+++++++-
Minternal/sheet/values.go1+
Minternal/ui/format.go1+
Minternal/ui/format_test.go1+
Minternal/ui/menubar.go3+-
Minternal/value/format.go25+++++++++++++--
M docs/reference/macro-api.md +1 -1
M docs/sheets/formatting.md +11 -0
M internal/fileio/numfmt.go +3 -1
M internal/fileio/xlsx_test.go +4 -0
A internal/numfmt/size.go +49 -0
A internal/numfmt/size_test.go +40 -0
M internal/sheet/display.go +11 -2
M internal/sheet/values.go +1 -0
M internal/ui/format.go +1 -0
M internal/ui/format_test.go +1 -0
M internal/ui/menubar.go +2 -1
M internal/value/format.go +22 -3
@@ -24,10 +24,11 @@ const (
2424 FmtDateTime // 9/26/2026 15:59:002525 FmtDuration // 24:01:002626 FmtCustom // Pattern, e.g. from Increase decimal places on Automatic27+ FmtSize // 1.6 kB: a count of bytes, as nushell shows file sizes2728 )2829 2930 var kindNames = [...]string{"auto", "text", "number", "percent", "scientific", "accounting",30- "financial", "currency", "date", "time", "datetime", "duration", "custom"}31+ "financial", "currency", "date", "time", "datetime", "duration", "custom", "size"}3132 3233 // String returns the kind's name as stored in files.3334 func (k FormatKind) String() string {
@@ -50,7 +51,7 @@ func ParseFormatKind(s string) (FormatKind, bool) {
5051 // HasDecimals reports whether the kind takes a number of decimal places.5152 func (k FormatKind) HasDecimals() bool {5253 switch k {53- case FmtNumber, FmtPercent, FmtScientific, FmtAccounting, FmtFinancial, FmtCurrency:54+ case FmtNumber, FmtPercent, FmtScientific, FmtAccounting, FmtFinancial, FmtCurrency, FmtSize:5455 return true5556 }5657 return false
@@ -76,8 +77,11 @@ type Format struct {
7677 const MaxDecimals = 157778 7879 // Preset returns kind with Sheets' default decimals: two for the number79-// kinds.80+// kinds, and one for sizes, as nushell shows them.8081 func Preset(k FormatKind) Format {82+ if k == FmtSize {83+ return Format{Kind: k, Decimals: 1}84+ }8185 if k.HasDecimals() {8286 return Format{Kind: k, Decimals: 2}8387 }
@@ -118,10 +122,25 @@ func (f Format) Code() string {
118122 return "m/d/yyyy h:mm:ss"119123 case FmtDuration:120124 return "[h]:mm:ss"125+ case FmtSize:126+ return SizeCode(f.Decimals)121127 }122128 return ""123129 }124130 131+// SizeCode is the custom number format closest to the Size format with132+// dec decimals, written with conditions as Sheets and Excel take them:133+// bytes below 1000, then kB and MB, e.g.134+// [<1000]0" B";[<1000000]0.0," kB";0.0,," MB". Size itself goes on to135+// GB, TB, PB and EB; files keep this code for other programs.136+func SizeCode(dec int) string {137+ d := ""138+ if dec > 0 {139+ d = "." + strings.Repeat("0", min(dec, MaxDecimals))140+ }141+ return `[<1000]0" B";[<1000000]0` + d + `," kB";0` + d + `,," MB"`142+}143+125144 // WithDecimals returns f showing delta more (or fewer) decimal places, as126145 // Sheets' Increase and Decrease decimal places do. v is the value shown,127146 // used when f is Automatic to start from the decimals currently visible.