cat / 012
clone

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

Docs: one home per fact in the new tree; link text names pages

Dami committed 5f1e569
Column and row formats and widths live in formatting.md, tabs in
sheets-and-tabs.md; editing.md and keys.md link to them. The format page
says once what isn't saved (results, pivots, spills) instead of a
sentence under pivot tables. arrays.md gives spilled cells a table and
a section on when an array can't spill. Links that named a file
(data.md, formulas.md) name the page they lead to.
commit
5f1e569a70adc15e8e8ff41277cf346069ccd6a9
parent
6cea7499f72116a27c5df786558f65d8ff1788cd
author
Dami <dami.etoile@gmail.com>
23 files changed, +117 -119
MCLAUDE.md5++-
MROADMAP.md58+++++++++++++++---------------
Mdocs/contributing/architecture.md20+++++-----
Mdocs/contributing/extending.md12+++---
Mdocs/contributing/limits.md4+-
Mdocs/contributing/observability.md2+-
Mdocs/contributing/testing.md8++--
Mdocs/contributing/ux.md6++--
Mdocs/files/README.md4+-
Mdocs/files/excel.md2+-
Mdocs/files/format.md13++++---
Mdocs/files/saving.md2+-
Mdocs/formulas/arrays.md38+++++++++++---------
Mdocs/formulas/jev.md2+-
Mdocs/formulas/references.md2+-
Mdocs/reference/config.md2+-
Mdocs/reference/keys.md33++++++++---------
Mdocs/reference/macro-api.md2+-
Mdocs/sheets/editing.md11+-----
Mdocs/sheets/macros.md2+-
Mdocs/sheets/rules.md2+-
Mdocs/terminal/ssh.md4+-
Mdocs/terminal/themes.md2+-
M CLAUDE.md +3 -2
M ROADMAP.md +29 -29
@@ -4,7 +4,7 @@ Principles: inside the grid 012 behaves like Google Sheets; 1-2-3 is the
44 visual identity around it. The main binary stays pure Go55 (`CGO_ENABLED=0`), and every feature ships with unit tests, a libghostty66 e2e test and reviewed golden screens. Visual and UX quality keep pace7-with features: see [docs/UX.md](docs/contributing/ux.md).7+with features: see [UX and visual bar](docs/contributing/ux.md).88 99 This page is what's ahead. What has shipped is listed once, at the end,1010 with the doc that describes it; when an item ships, it moves there as
@@ -20,7 +20,7 @@ Sizes: S (a day or two), M (about a week), L (weeks).
2020 |---|---|---|2121 | Open 012's XLSX output in Excel and LibreOffice before releases, as was done for Google Sheets | The writer is otherwise checked by excelize and 012's reader | S |2222 | Conditional formatting and validation, what's left: data bars and icon sets, "top 10", "duplicate values", date periods (this week, last month), validation on pastes and fills, rules moving with cut and paste, a dropdown's chip look, and custom checkbox values | Excel's other rule types come in as notes | M |23-| Remaining overlays get narrow hosts: filter picker, sort and choice bars, chart editor, shortcuts, named ranges, cell entry and prompts | Components testable without the model ([architecture.md](docs/contributing/architecture.md#the-ui)) | M |23+| Remaining overlays get narrow hosts: filter picker, sort and choice bars, chart editor, shortcuts, named ranges, cell entry and prompts | Components testable without the model ([Architecture](docs/contributing/architecture.md#the-ui)) | M |2424 2525 ### 2. Spreadsheet features Sheets users reach for2626
@@ -33,7 +33,7 @@ Sizes: S (a day or two), M (about a week), L (weeks).
3333 3434 The grid is Excel's, 1,048,576 x 16,384, and memory is bounded by the3535 `max-cells` budget rather than the grid. The budget rises in measured36-steps; see [docs/limits.md](docs/contributing/limits.md#what-would-raise-the-bounds).36+steps; see [Bounds of support](docs/contributing/limits.md#what-would-raise-the-bounds).3737 3838 | Item | Result | Size |3939 |---|---|---|
@@ -79,44 +79,44 @@ by a gateway dialing the iroh ticket.
7979 8080 **Engine**8181 82-- Undo and redo for every change, across sheets: [data.md](docs/sheets/editing.md#undo)83-- Copy, cut, paste and fill with relative and `$absolute` references; insert and delete rows and columns: [data.md](docs/sheets/editing.md#copy-paste-and-fill)84-- Entries detected as typed (currency, percent, dates, times) and number formats: [formulas.md](docs/formulas/README.md#what-you-type)85-- Named ranges; several sheets with references between them, hidden sheets: [formulas.md](docs/formulas/references.md)86-- Sheets' everyday, math, text, lookup, date and finance functions, checked against excelize: [functions.md](docs/reference/functions.md), [testing.md](docs/contributing/testing.md#the-excelize-oracle)87-- Dynamic arrays that spill (FILTER, SORT, UNIQUE, SEQUENCE and more, ARRAYFORMULA), LET and LAMBDA, SPLIT and the REGEX functions: [formulas.md](docs/formulas/arrays.md)88-- Opt-in decimal arithmetic for money: [formulas.md](docs/formulas/decimal.md)89-- An Excel-sized grid with a `max-cells` budget; operations cost the data, not the grid: [limits.md](docs/contributing/limits.md#sheet-size)82+- Undo and redo for every change, across sheets: [Editing](docs/sheets/editing.md#undo)83+- Copy, cut, paste and fill with relative and `$absolute` references; insert and delete rows and columns: [Editing](docs/sheets/editing.md#copy-paste-and-fill)84+- Entries detected as typed (currency, percent, dates, times) and number formats: [Formulas](docs/formulas/README.md#what-you-type)85+- Named ranges; several sheets with references between them, hidden sheets: [References](docs/formulas/references.md)86+- Sheets' everyday, math, text, lookup, date and finance functions, checked against excelize: [Functions](docs/reference/functions.md), [Testing](docs/contributing/testing.md#the-excelize-oracle)87+- Dynamic arrays that spill (FILTER, SORT, UNIQUE, SEQUENCE and more, ARRAYFORMULA), LET and LAMBDA, SPLIT and the REGEX functions: [Arrays and spills](docs/formulas/arrays.md)88+- Opt-in decimal arithmetic for money: [Decimal arithmetic](docs/formulas/decimal.md)89+- An Excel-sized grid with a `max-cells` budget; operations cost the data, not the grid: [Bounds of support](docs/contributing/limits.md#sheet-size)9090 9191 **Finding and using features**9292 93-- Sheets-structured menus, a command palette and a key for every command: [keys.md](docs/reference/keys.md)94-- Formula suggestions, argument hints and pointing at cells and sheets: [formulas.md](docs/formulas/building.md)95-- Tracing precedents and dependents, hidden sheets explained: [formulas.md](docs/formulas/building.md)96-- An optional vim keymap with a `:` command line: [keys.md](docs/reference/keys.md#vim-keys)93+- Sheets-structured menus, a command palette and a key for every command: [Keys and mouse](docs/reference/keys.md)94+- Formula suggestions, argument hints and pointing at cells and sheets: [Building formulas](docs/formulas/building.md)95+- Tracing precedents and dependents, hidden sheets explained: [Building formulas](docs/formulas/building.md)96+- An optional vim keymap with a `:` command line: [Keys and mouse](docs/reference/keys.md#vim-keys)9797 9898 **Data tools**9999 100-- Freeze, multi-column sort, filters with value pickers and conditions: [data.md](docs/sheets/sort-filter.md#freeze)101-- Find and replace, with regular expressions, across sheets: [data.md](docs/sheets/find-replace.md)102-- Conditional formatting (single-color rules, color scales) and data validation (dropdowns, checkboxes, bounds): [data.md](docs/sheets/rules.md#conditional-formatting)103-- Pivot tables and frequency tables, live, with subtotals and renamed values: [data.md](docs/sheets/pivots.md)104-- Notes on cells: [data.md](docs/sheets/notes-protection.md#notes)105-- Protected sheets and ranges that warn on edit: [data.md](docs/sheets/notes-protection.md#protected-sheets-and-ranges)106-- Charts (column, bar, line, area, pie, scatter; stacking, trend lines, axis and legend options), as images or text: [charts.md](docs/sheets/charts.md)107-- Macros, recorded or written in Starlark: [macros.md](docs/sheets/macros.md)108-- JEV functions, with the API key in the OS keychain: [jev.md](docs/formulas/jev.md)100+- Freeze, multi-column sort, filters with value pickers and conditions: [Freeze, sort and filter](docs/sheets/sort-filter.md#freeze)101+- Find and replace, with regular expressions, across sheets: [Find and replace](docs/sheets/find-replace.md)102+- Conditional formatting (single-color rules, color scales) and data validation (dropdowns, checkboxes, bounds): [Conditional formatting and data validation](docs/sheets/rules.md#conditional-formatting)103+- Pivot tables and frequency tables, live, with subtotals and renamed values: [Pivot tables](docs/sheets/pivots.md)104+- Notes on cells: [Notes and protection](docs/sheets/notes-protection.md#notes)105+- Protected sheets and ranges that warn on edit: [Notes and protection](docs/sheets/notes-protection.md#protected-sheets-and-ranges)106+- Charts (column, bar, line, area, pie, scatter; stacking, trend lines, axis and legend options), as images or text: [Charts](docs/sheets/charts.md)107+- Macros, recorded or written in Starlark: [Macros](docs/sheets/macros.md)108+- JEV functions, with the API key in the OS keychain: [JEV functions](docs/formulas/jev.md)109109 110110 **The terminal**111111 112-- System clipboard, hyperlinks, curly error underlines, cursor shapes, progress and notifications, light and dark: [charts.md](docs/terminal/README.md#terminal-features-012-uses)113-- Color schemes and a config file: [themes.md](docs/terminal/themes.md), [config.md](docs/reference/config.md)114-- `012 serve` over SSH, with files on the ssh command line and recovery of unsaved work: [ssh.md](docs/terminal/ssh.md)112+- System clipboard, hyperlinks, curly error underlines, cursor shapes, progress and notifications, light and dark: [The terminal](docs/terminal/README.md#terminal-features-012-uses)113+- Color schemes and a config file: [Themes](docs/terminal/themes.md), [Configuration](docs/reference/config.md)114+- `012 serve` over SSH, with files on the ssh command line and recovery of unsaved work: [Serving over SSH](docs/terminal/ssh.md)115115 116116 **Files**117117 118-- Import CSV, TSV, XLSX, SQLite, Parquet and Lotus `.wk1`; export CSV, TSV, XLSX and SQLite; import locations; save-as and overwrite checks: [files.md](docs/files/README.md)118+- Import CSV, TSV, XLSX, SQLite, Parquet and Lotus `.wk1`; export CSV, TSV, XLSX and SQLite; import locations; save-as and overwrite checks: [Files](docs/files/README.md)119119 120120 **Upkeep**121121 122-- `make check` before every push; demo tapes (`make demos`); version tags from v0.1.0: [testing.md](docs/contributing/testing.md)122+- `make check` before every push; demo tapes (`make demos`); version tags from v0.1.0: [Testing](docs/contributing/testing.md)
M docs/contributing/architecture.md +10 -10
@@ -128,7 +128,7 @@ style.
128128 - **Functions.** One table (`FuncDef`, in `internal/functions`) holds129129 every function's name, signature, description and arity; it drives130130 parsing, evaluation, autocomplete, in-app help and131- [functions.md](../reference/functions.md). See [Functions](#functions).131+ [Functions](../reference/functions.md). See [Functions](#functions).132132 - **Undo.** Every mutation goes through a small set of paths that snapshot133133 the cells, widths, names, charts, view state and sheet list they change,134134 on any sheet, so a step can be reversed exactly; multi-cell operations
@@ -186,7 +186,7 @@ style.
186186 (one file per category: `everyday.go`, `math.go`, `stats.go`,187187 `logic.go`, `text.go`, `regex.go`, `lookup.go`, `dynamic.go`,188188 `lambda.go`, `date.go`, `finance.go`, `link.go`, `jev.go`, which189-[functions.md](../reference/functions.md) is grouped by), the evaluation of formulas189+[Functions](../reference/functions.md) is grouped by), the evaluation of formulas190190 (`eval.go`: operators and calls; arrays in `array.go`, functions mapped191191 over them in `lift.go`, the names LET and LAMBDA bind in `scope.go`), the helpers192192 functions share (arguments and blocks of cells in `args.go`, criteria
@@ -260,7 +260,7 @@ instead:
260260 The engine fills a chunk from the occupancy index without a call per cell261261 (`colFill`, `rangeFill`), and keeps each sheet's reader between262262 recalculations, so the buffers are made once. See263-[limits.md](limits.md#the-function-library) for its costs.263+[Bounds of support](limits.md#the-function-library) for its costs.264264 265265 What stays in the engine is what needs cells or the workbook: the266266 running aggregates' storage and extension (`rangememo.go`), the links a
@@ -270,7 +270,7 @@ setting (`SetDecimal`, which marks formulas with `functions.Decimalize`).
270270 271271 ### Where the engine can grow272272 273-The package boundaries leave the bounds in [limits.md](limits.md) room to273+The package boundaries leave the bounds in [Bounds of support](limits.md) room to274274 move without touching callers:275275 276276 - **Storage.** Compact cell storage (column blocks of values, formulas and
@@ -295,7 +295,7 @@ move without touching callers:
295295 296296 `internal/ui` is a Bubble Tea program. Inside the grid it follows Google297297 Sheets; around it, the control panel keeps a 1-2-3 look. See298-[UX.md](ux.md) for the rules every change follows.298+[UX and visual bar](ux.md) for the rules every change follows.299299 300300 **Commands.** Every action is a registered command with a title and301301 description (`commands.go`), reached from key bindings, the menu bar,
@@ -479,7 +479,7 @@ file names. Everything a model knows lives in the model, so sessions
479479 share nothing but read-only tables (the command and function480480 registries), the process-wide telemetry and, with JEV on, the HTTP481481 client; each gets its own `jev.Cache`, whose queue belongs to that482-session's program. See [ssh.md](../terminal/ssh.md).482+session's program. See [Serving over SSH](../terminal/ssh.md).483483 484484 **Unsaved work.** `Server.Shutdown` closes a channel every session485485 watches; a session quitting on it, or on its idle timeout, asks its
@@ -504,7 +504,7 @@ config directory; the same directory holds `themes/` and 012 serve's host
504504 key. Every option is one entry in `config.Options`: name, type, default,505505 environment variables, flag, whether Reload config applies it, and a506506 description. Parsing and validation, the flags `cmd/012` accepts, `012507-config`'s listing and default file, and [config.md](../reference/config.md)'s507+config`'s listing and default file, and [Configuration](../reference/config.md)'s508508 reference (checked by a test) all come from that table. Values are layered defaults < file < environment < flags, each509509 remembering its source; problems are warnings, never fatal. The UI gets a510510 `ui.Settings` (the config, a reload function, the credential store, a JEV
@@ -550,7 +550,7 @@ color scheme (`theme.Palette`: VHS's embedded catalog, or a Ghostty,
550550 kitty or VHS JSON file in `themes/`) is drawn by `theme.FromPalette`,551551 which maps each ANSI color to the scheme's, adds full-width bands for the552552 bars and a screen background, and corrects contrast (see553-[themes.md](../terminal/themes.md)). Bands are applied by `theme.Fill`, one pass over553+[Themes](../terminal/themes.md)). Bands are applied by `theme.Fill`, one pass over554554 a rendered line's escape sequences that sets the band's colors at the555555 start and after each reset and pads to the width; `View` fills the bar556556 lines before overlays are composited and the whole screen after, so bars
@@ -561,7 +561,7 @@ when there is one, and from the terminal's palette otherwise.
561561 562562 `internal/telemetry` is off unless asked for. When on, spans, events and563563 per-second frame summaries go to a JSON log, an OTLP/HTTP collector, or564-both (see [observability.md](observability.md)). The OTLP exporter uses564+both (see [Observability](observability.md)). The OTLP exporter uses565565 only the standard library: bounded queues per signal, drained by one566566 goroutine in batches; when a queue is full new items are dropped and567567 counted, so the UI never waits on the network. Operation durations are
@@ -573,4 +573,4 @@ command that caused them.
573573 574574 ## Testing575575 576-See [testing.md](testing.md).576+See [Testing](testing.md).
M docs/contributing/extending.md +6 -6
@@ -19,12 +19,12 @@ shows it is derived from the table rather than listing it again.
1919 2020 | Registry | Entry | Derived from it |2121 |---|---|---|22-| `functions.FuncDef` (one file per category in `internal/functions`) | a function: name, signature, description, arity, eval, result format, decimal twin | parsing, autocomplete, argument hints, help, [functions.md](../reference/functions.md) |22+| `functions.FuncDef` (one file per category in `internal/functions`) | a function: name, signature, description, arity, eval, result format, decimal twin | parsing, autocomplete, argument hints, help, [Functions](../reference/functions.md) |2323 | `ui.command` | an action: id, title, description, run, enabled, checked, what it edits, and how macros treat it | key bindings (Sheets and vim), menu bar, context menus, palette, shortcuts help, the `:` command line and its completions, macro recording and `run()` in scripts |2424 | `fileio` formats (`formats.go`) | a format: name, extensions, labels, traits, importer, exporter | `Import`, `Export`, detection, import picker, File > Download, command line |2525 | `chart.types`, with `sheet.ChartTypes` | a type: name and order (sheet, saved in files), a layout drawing text and image and the series its legend lists (chart) | `chart.Draw`, `chart.Image`, chart editor, Insert > Chart |2626 | theme roles (`theme.Theme`) | a role: dark and light styles on the 16 ANSI colors, with a contrast minimum for schemes (`minContrast`) | every style in the UI, drawn in the terminal's palette or any color scheme (`FromPalette`); `TestEveryThemeReadable` checks each role under every built-in scheme |27-| `config.Options` | an option: name, type, default, environment variables, flag, live or not, description, check | parsing and warnings, flags, `012 config` and its default file, [config.md](../reference/config.md), Reload config |27+| `config.Options` | an option: name, type, default, environment variables, flag, live or not, description, check | parsing and warnings, flags, `012 config` and its default file, [Configuration](../reference/config.md), Reload config |2828 2929 Adding a function, command, format, chart type, option or role means3030 adding an entry (and its file), not editing switch statements elsewhere.
@@ -119,7 +119,7 @@ Code reads and writes cells through a narrow API (`cellStore` in
119119 `internal/sheet/store.go`: get, set, delete, count, iterate everything or120120 a range, a column being a range), not the map underneath. That lets the121121 store change shape (compact column blocks, side tables for formulas and122-formats; see [limits.md](limits.md)) without touching the rest of the122+formats; see [Bounds of support](limits.md)) without touching the rest of the123123 engine. Beside the map, occupancy indexes (`occupancy.go`) say which rows124124 of each column hold a cell, and which hold contents, so a range yields its125125 cells in row order at the cost of what it holds, and the used range, data
@@ -175,7 +175,7 @@ builds can safely ignore (decimal arithmetic) don't raise the version.
175175 ### 10. Measure at the seams176176 177177 Every seam above has a telemetry span and a `-tags stress` benchmark178-(`make stress`, `make stress-report`), and [limits.md](limits.md) records178+(`make stress`, `make stress-report`), and [Bounds of support](limits.md) records179179 the bounds. A change to a seam comes with its numbers, measured against180180 the code it replaces.181181
@@ -185,7 +185,7 @@ causes; hand work on another goroutine `m.spans.Parent()` (in the
185185 `context.Context` if the API already takes one); and give a workbook a186186 new owner's trace with `SetTrace`. Never keep a "current span" in a187187 global: `012 serve` runs many programs in one process (see188-[observability.md](observability.md#nested-spans)).188+[Observability](observability.md#nested-spans)).189189 190190 ### 11. Shape limits191191
@@ -201,7 +201,7 @@ aliases so callers don't change.
201201 202202 Unit tests against the engine or model, an e2e test through libghostty, and203203 a golden screen reviewed in the gallery for anything visible (see204-[testing.md](testing.md)).204+[Testing](testing.md)).205205 206206 ## Gaps207207
M docs/contributing/limits.md +2 -2
M docs/contributing/observability.md +1 -1
M docs/contributing/testing.md +4 -4
M docs/contributing/ux.md +3 -3
M docs/files/README.md +2 -2
M docs/files/excel.md +1 -1
M docs/files/format.md +8 -5
@@ -24,11 +24,16 @@ object:
2424 ```2525 2626 A formatted cell has its `input` and the formatting that isn't the27-default: `format` (as `number_format` in [macros](../reference/macro-api.md#cells) names28-it: `currency`, `percent`, `date`, ...), `decimals`, `pattern` for a27+default: `format` (as `number_format` in28+[macros](../reference/macro-api.md#cells) names it: `currency`, `percent`, `date`, ...), `decimals`, `pattern` for a2929 custom format, `bold`, `italic`, `underline`, `strikethrough` and3030 `align` (`left`, `center`, `right`).3131 32+Only what's typed is saved. What 012 computes is computed again when the33+file opens: formula results, [pivot tables](#pivot-tables)' results, and34+the arrays formulas [spill](../formulas/arrays.md), whose cells are kept35+only for their formatting and notes.36+3237 ## Versions3338 3439 012 writes the lowest version that holds the workbook, so older builds
@@ -58,7 +63,7 @@ save), so they raise no version:
5863 | `protected` | a sheet | [Protected ranges](../sheets/notes-protection.md#protected-sheets-and-ranges): `{"range":"B2:C9","description":"Totals"}`, or `{"sheet":true}` |5964 | `conditionalFormats`, `validations` | a sheet | [Rules](#conditional-formats-and-data-validation), one per line |6065 | `arithmetic` | the workbook | `decimal` for [decimal arithmetic](../formulas/decimal.md) |61-| `macros`, `macroOrigin` | the workbook | Macros as Starlark scripts, and the computer they were made or trusted on: see [macros.md](../reference/macro-api.md#in-the-file). Opening a file never runs them |66+| `macros`, `macroOrigin` | the workbook | Macros as Starlark scripts, and the computer they were made or trusted on: see [Macro scripting API](../reference/macro-api.md#in-the-file). Opening a file never runs them |6267 6368 ## Column and row formats6469
@@ -107,8 +112,6 @@ A pivot's sheet has a `pivot` field, on one line after its cells,
107112 holding the definition. The results are never saved; they are computed108113 again when the file opens, so the file stays small and can't disagree109114 with its data.110-Arrays that formulas spill are kept the same way: the file keeps the formula,111-and the cells it spills into only for their formatting and notes.112115 113116 ```json114117 {
M docs/files/saving.md +1 -1
M docs/formulas/arrays.md +21 -17
@@ -33,18 +33,27 @@ right and below, as in Sheets:
3333 `=IFERROR(FILTER(A2:A99, B2:B99="x"), "none")` spills or says none, and3434 `=INDEX(A2:C9, 0, 2)` spills the second column.3535 36-The context line says where a spilled cell's value comes from37-("Spilled from B2"), and on the formula's own cell where it spills38-("Spills into B2:C9"); spilled values are drawn in a color of their own,39-and the formula bar shows a spilled cell's formula dimmed. A spilled cell40-can't be typed into, cleared, pasted over or filled: the context line41-names the formula to edit instead. Selecting the formula with its spill42-and pressing Del clears it, formatting spilled cells keeps the43-formatting, and inserting or deleting rows and columns through a spill44-spills it again. Copying spilled cells pastes their values. Conditional45-formats color spilled cells by their values, and data validation marks46-spilled values it doesn't accept, but never stops an array from47-spilling: rules judge what's typed, and a spilled value isn't.36+## Spilled cells37+38+Spilled values are drawn in a color of their own. The context line says39+where a spilled cell's value comes from ("Spilled from B2"), and on the40+formula's own cell where it spills ("Spills into B2:C9"); the formula41+bar shows a spilled cell's formula dimmed.42+43+| Doing this to spilled cells | Does |44+|---|---|45+| Typing, clearing, pasting over or filling one | Nothing: the context line names the formula to edit instead |46+| Del on the formula with its spill selected | Clears the formula |47+| Formatting them | Keeps the formatting, which the file saves |48+| Inserting or deleting rows or columns through the spill | Spills it again |49+| Copying them | Pastes their values |50+| Conditional formats and data validation on them | Color them by their values, and mark values a rule doesn't accept; a rule never stops an array from spilling |51+52+Formulas reading spilled cells recalculate when the array changes, on53+any sheet, and undo brings back what an array spilled with the formula.54+The file keeps only the formula ([format](../files/format.md)).55+56+## When an array can't spill4857 4958 When a cell in the way of an array isn't empty, the formula shows5059 `#REF!` and says why, as Sheets does: "Array result was not expanded
@@ -52,11 +61,6 @@ because it would overwrite data in C3". Clearing that cell lets the
5261 array spill. The same goes for an array that would pass the sheet's5362 edge, or write more cells than `max-cells` allows.5463 55-Formulas reading spilled cells recalculate when the array changes, on56-any sheet, and undo brings back what an array spilled with the formula.57-Files keep only the formula: its array is computed again when the file58-opens.59-6064 ## Names in a formula: LET and LAMBDA6165 6266 `=LET(total, SUM(B2:B99), count, COUNT(B2:B99), total/count)` names
M docs/formulas/jev.md +1 -1
M docs/formulas/references.md +1 -1
M docs/reference/config.md +1 -1
M docs/reference/keys.md +15 -18
@@ -28,7 +28,7 @@ mouse and the vim keymap added.
2828 2929 | Key | Action |3030 |---|---|31-| Type | Replace the cell: `=` starts a formula, `'` forces text, and `$1,200`, `12%`, `9/26/2026` or `14:30` are numbers that keep their format ([formulas.md](../formulas/README.md#what-you-type)) |31+| Type | Replace the cell: `=` starts a formula, `'` forces text, and `$1,200`, `12%`, `9/26/2026` or `14:30` are numbers that keep their format ([Formulas](../formulas/README.md#what-you-type)) |3232 | Enter, Tab | Accept and move down or right; Enter goes back to the column a run of Tabs began in |3333 | Enter, F2, double-click | Edit the cell |3434 | Esc | Cancel the entry |
@@ -58,7 +58,7 @@ mouse and the vim keymap added.
5858 | Ctrl+D, Ctrl+R | Fill down, fill right; a series started in the top rows (1, 2 over blanks) continues |5959 | Ctrl+Alt+=, Ctrl+Alt+- | Insert rows above, delete the selected rows (columns when whole columns are selected) |6060 61-[data.md](../sheets/editing.md#copy-paste-and-fill) says how formats travel with61+[Editing](../sheets/editing.md#copy-paste-and-fill) says how formats travel with6262 copies and which series the fill handle continues.6363 6464 ## Formatting
@@ -89,20 +89,20 @@ The rest of the formats are in the Format menu.
8989 9090 | Key | Action | More |9191 |---|---|---|92-| Ctrl+F, Ctrl+H | Find; find and replace | [data.md](../sheets/find-replace.md) |92+| Ctrl+F, Ctrl+H | Find; find and replace | [Find and replace](../sheets/find-replace.md) |9393 | Alt+Down | Open the active cell's dropdown (type to search, Enter picks); elsewhere, with a filter on (Data > Create a filter), the column's filter (Space checks values, type to search, or pick a condition) | [validation](../sheets/rules.md#data-validation), [filter](../sheets/sort-filter.md#filter) |94-| Space | Check or uncheck the selected checkboxes (Insert > Checkbox); elsewhere Space starts an entry | [data.md](../sheets/rules.md#data-validation) |95-| Alt+, Alt+. | Trace precedents, dependents: highlight the cells a formula reads, or the formulas that read the cell, and jump to the first; again for the next, Esc to go back (Excel's Ctrl+[ and Ctrl+], which terminals send as Esc) | [formulas.md](../formulas/building.md) |96-| Alt+Shift+F | Frequency table of the active column on a new sheet, as VisiData's Shift+F | [data.md](../sheets/pivots.md#frequency-tables) |97-| Shift+F2 | Add or edit the active cell's note; Alt+Enter or Shift+Enter starts a new line | [data.md](../sheets/notes-protection.md#notes) |94+| Space | Check or uncheck the selected checkboxes (Insert > Checkbox); elsewhere Space starts an entry | [Conditional formatting and data validation](../sheets/rules.md#data-validation) |95+| Alt+, Alt+. | Trace precedents, dependents: highlight the cells a formula reads, or the formulas that read the cell, and jump to the first; again for the next, Esc to go back (Excel's Ctrl+[ and Ctrl+], which terminals send as Esc) | [Building formulas](../formulas/building.md) |96+| Alt+Shift+F | Frequency table of the active column on a new sheet, as VisiData's Shift+F | [Pivot tables](../sheets/pivots.md#frequency-tables) |97+| Shift+F2 | Add or edit the active cell's note; Alt+Enter or Shift+Enter starts a new line | [Notes and protection](../sheets/notes-protection.md#notes) |9898 9999 Tools with no key of their own have their keys on screen while they're100100 open, and in their docs: sorting by several columns101-([data.md](../sheets/sort-filter.md#sort)), conditional formatting and data validation101+([Freeze, sort and filter](../sheets/sort-filter.md#sort)), conditional formatting and data validation102102 ([rules panel](../sheets/rules.md#conditional-formatting)), pivot tables103103 ([pivot editor](../sheets/pivots.md)), protected ranges104-([data.md](../sheets/notes-protection.md#protected-sheets-and-ranges)) and charts105-([charts.md](../sheets/charts.md)). In Data > Named ranges, Enter goes to a104+([Notes and protection](../sheets/notes-protection.md#protected-sheets-and-ranges)) and charts105+([Charts](../sheets/charts.md)). In Data > Named ranges, Enter goes to a106106 range, F2 renames or repoints it and Ctrl+D deletes it.107107 108108 ## Files, menus and help
@@ -119,7 +119,7 @@ range, F2 renames or repoints it and Ctrl+D deletes it.
119119 120120 | Key | Action |121121 |---|---|122-| Ctrl+Alt+Shift+0 to 9 | Run the macro with that shortcut ([macros.md](../sheets/macros.md#running)) |122+| Ctrl+Alt+Shift+0 to 9 | Run the macro with that shortcut ([Macros](../sheets/macros.md#running)) |123123 | Esc | Stop a macro while it runs (the mode indicator says CMD) |124124 125125 ## Vim keys
@@ -127,7 +127,7 @@ range, F2 renames or repoints it and Ctrl+D deletes it.
127127 File > Settings > Vim keys (also `:settings.vim` or the palette) turns128128 on a vim keymap in the spirit of sc-im and VisiData. It is off by129129 default and belongs to you, not the sheet: it's kept in the config file130-as `keymap = vim` ([config.md](config.md#keymap)), never in `.012` files.130+as `keymap = vim` ([Configuration](config.md#keymap)), never in `.012` files.131131 The mode indicator says **NORMAL** where it would say READY, **VISUAL**132132 while selecting with `v` or `V`, and **COMMAND** on the `:` line; typing133133 into a cell is ENTER or EDIT, as always, and Enter, Tab or Esc there
@@ -204,12 +204,9 @@ line isn't a command itself (`:fill d` Enter fills down).
204204 | Cmd- or Ctrl-click a link | Open a URL in a cell or a `=HYPERLINK(url, [label])` |205205 | Hover a cell with a note | Show the note beside it |206206 207-The sheet tabs at the left of the status line take the mouse too: click208-a tab to show its sheet, double-click to rename it, right-click for its209-menu (rename, duplicate, delete, hide, move left or right), drag it onto210-another tab to move it there, and click `+` to add a sheet. When the211-tabs don't all fit, `‹` and `›` step through them. While typing a212-formula, clicking a cell or a tab points at it, as in Sheets.207+The sheet tabs take the mouse too: see [sheets and tabs](../sheets/sheets-and-tabs.md).208+While typing a formula, clicking a cell or a tab points at it, as in209+Sheets.213210 214211 The pointer changes shape over cells, resize handles and the formula bar215212 in terminals that support it (OSC 22). In Ghostty and xterm, Shift+click
M docs/reference/macro-api.md +1 -1
M docs/sheets/editing.md +2 -9
M docs/sheets/macros.md +1 -1
M docs/sheets/rules.md +1 -1
M docs/terminal/ssh.md +2 -2
M docs/terminal/themes.md +1 -1