- commit
- f053732168141bfc55d0a9fc1932f6157fa4a729
- parent
- c4ae0c4a5ccb332ccb5c4451240158d7dbfffcd5
- author
- Dami <dami.etoile@gmail.com>
- kind
- docs risk score 0.4 of 3, Jev's estimate
| M | README.md | 11 | ++- |
| M | ROADMAP.md | 13 | +-- |
| M | docs/ | 119 | +++++++++++++++++------------- |
| M | docs/ | 4 | +- |
| M | docs/ | 11 | ++- |
| M | docs/ | 80 | +++++++++++++------- |
| M | docs/ | 22 | +++--- |
| M | docs/ | 59 | ++++++++------- |
| M | docs/ | 5 | +- |
| M | docs/ | 2 | +- |
| M | docs/ | 36 | ++++++++-- |
| M | docs/ | 14 | ++-- |
| M | internal/ | 2 | +- |
@@ -47,10 +47,11 @@ rest: building from a clone, importing files, `012 serve` and settings.
4747 nushell module `012 nu --install-module` installs, or as4848 `ls | to nuon | ^012 --pipe | from nuon` without it4949 ([pipelines](docs/nushell/pipelines.md)).50-- **Nushell notebooks**: `012 nu` (or Data > Shell in any workbook) runs nushell51- pipelines whose tables become live, named regions of the sheet;52- `$r1` reads one in the next command, and refreshing it runs what reads53- it ([notebooks](docs/nushell/notebooks.md)).50+- **Nushell notebooks**: `012 nu` (or Data > Notebook in any workbook)51+ opens a notebook tab of code and note cells, run with Jupyter's keys,52+ each output under its cell; later cells read it as `$name`, and sent to53+ a sheet it's a live table formulas read as `nu.name`54+ ([notebooks](docs/nushell/notebooks.md)).5455 - **Macros**, recorded or written as Starlark scripts saved with the sheet5556 ([macros](docs/sheets/macros.md)).5657 - **Made for terminals**: the mouse, hyperlinks, the system clipboard over@@ -66,7 +67,7 @@ rest: building from a clone, importing files, `012 serve` and settings.
6667 | Menus and the command palette (Ctrl+K) | Charts that float over the grid and follow their data |6768 |  |  |6869 | Conditional formatting and data validation | Pivot tables, live |69-|  |  |70+|  |  |7071 | Arrays that spill | Nushell notebooks |7172 |  |  |7273 | JEV functions in formulas | Macros |@@ -26,16 +26,13 @@ rises in measured steps; see [Bounds of support](docs/contributing/limits.md#wha
2626 2727 ### 2. A TUI Jupyter for nushell2828 29-A notebook is its own kind of tab in a workbook: cells, not a grid. Code30-cells hold a nushell pipeline (several lines if needed) with its output31-under it (a scrollable table view, text, a record or an error); note cells32-hold Markdown. You run cells in the order you choose, with the usual33-controls, and send any output to a sheet, where it is a live region that34-formulas, charts and pivots use. It replaces the grid-based notebook sheet.29+Notebook tabs are a TUI Jupyter for nushell30+([Notebooks](docs/nushell/notebooks.md)): code and note cells, outputs in31+place, sent to sheets as live regions. What's ahead makes writing a cell32+feel like nushell's own prompt.3533 3634 | Item | Result | Size |3735 |---|---|---|38-| Notebook tabs: code and note cells, outputs rendered in place (tables that scroll and open full-screen as a grid, text, records, errors), Jupyter keys inside the notebook (Shift+Enter run and next, Ctrl+Enter run, a/b add above/below, dd delete, m/y note/code, Esc/Enter command/edit mode) plus menus and palette; run cell, run all, run above, run below, stop, clear outputs; run counts and timings; cells named for their output (`$files`), stale marks when a cell they read has changed, an opt-in reactive mode that re-runs dependents; send an output to a sheet as a live region (`nu.files`); outputs saved in the workbook up to a size cap; existing notebook sheets converted, one code cell per region; `012 nu` opens a notebook | A TUI Jupyter with nushell and 012 | L |3936 | Code cells highlighted, completed and checked as you type by nushell itself: `nu --ide-ast` token shapes mapped to theme roles, `nu --ide-complete` plus 012's cell, region and sheet names on Tab, `nu --ide-check` errors underlined; debounced in the background, plain text when nu is missing or slow; hover docs through `nu --lsp` later | Writing pipelines in 012 feels like nushell's own prompt | S to M |4037 4138 ### 3. Toward multiplayer@@ -115,7 +112,7 @@ stream above rather than a design of their own.
115112 116113 - 012 as a stage in a pipeline: `012 -` reads a table from standard input, `012 --pipe` sends the sheet or selection on, with nushell's types kept through NUON: [Pipelines](docs/nushell/pipelines.md)117114 - The `sheet` command: a nushell module shipped in the binary (`012 nu --install-module`), so nu calls 012 without `^012` or NUON on either side: [Pipelines](docs/nushell/pipelines.md#the-sheet-command)118-- `012 nu` and notebook sheets: nushell pipelines at a prompt on the formula bar become live, named regions that read each other and refresh in dependency order, saved as commands and never run on open: [Notebooks](docs/nushell/notebooks.md)115+- Notebook tabs, a TUI Jupyter for nushell: code and note cells with Jupyter's keys, outputs drawn in place and opened full-screen, `$name` between cells, stale marks and a reactive mode, outputs sent to sheets as live regions (`nu.name`), saved up to a cap, and earlier notebook sheets converted on open: [Notebooks](docs/nushell/notebooks.md)119116 120117 **Files**121118 @@ -24,7 +24,8 @@ internal/chart chart layout, text rendering and kitty image encoding
2424 internal/jev the API key's resolution, answer cache and TypeSafe client2525 internal/keyring the OS credential store the API key lives in2626 internal/macro macros: the Starlark scripting API, recorded actions as scripts, step limits27-internal/nushell a notebook's commands: nu run as a process, tables in as NUON files, a table back27+internal/notebook a notebook's document: code and note cells, names, what each reads, run orders, stale outputs, save caps28+internal/nushell a notebook cell's run: nu as a process, tables in as NUON files, NUON back2829 module 012.nu, the nushell module with sheet, embedded for 012 nu --module and --install-module2930 internal/telemetry opt-in JSON log and OTLP export of spans, events and frame stats3031 internal/serve the SSH server: auth, host key, a Model per session (charm.land/wish/v2)@@ -35,10 +36,10 @@ internal/ui the Bubble Tea model: modes, menus, overlays, rendering
3536 rowtext laying out a row of cell text across the columns on screen3637 formula reading the formula being typed (F4, the word and call at the caret)3738 overlay the contract of what takes over input: Overlay, boxes, mouse events, lists38- lineedit the one-line editor every text field shares39+ lineedit the one-line editor every text field shares, and the multi-line one of notebook cells3940 picker the searchable list behind the palette and every picker4041 cmdline the : command line and its completions41- nuprompt the nushell prompt on the formula bar, its history and completions42+ nbview a notebook tab: its cells, outputs, command and edit modes, the code editor and its language providers4243 findbar find and replace, a bar on the context line4344 themepicker File > Settings > Theme, previewing as it moves4445 rules the conditional formatting and data validation panel@@ -217,35 +218,35 @@ style.
217218 `#REF!` with the reason. `Set` refuses spilled cells; files keep only218219 the anchor.219220 - **Regions.** A region (`region.go`) is a block of cells whose values220- come from outside the engine, of two kinds: a command region, a221- notebook's nushell command (opaque to the engine) with a label line222- above its table, and a linked file (`linked.go`), a file the UI223- follows, its table at its anchor. Both are one list per sheet, the224- sheet's `regionState`, replaced whole on every change so undo steps225- keep the definitions; what isn't undone (a label's status, the cells226- written, how a linked file's reading goes) is kept beside it227- (`regionMeta`). Their cells have one write path, `writeTable`228- (`regionwrite.go`): a header and rows, written as spilled cells are,229- derived and outside the undo history, only those that differ, with230- the region's cells it no longer needs cleared; a table that would231- overwrite other contents isn't shown, its label or first cell saying232- where, and clearing that cell shows it. Rows arrive as live233- operations, the change stream below. What undo keeps of the rows is a234- policy per kind: a command region's table (`RegionData`, handed over235- by `ShowRegion`) is in the undo state, since a run was the user's236- action and its output can't be had again, and is written again from237- there whenever its region moves; a linked file's rows are only in its238- cells, since undo can't bring back what a file held, so a linked file239- undo brings back or moves is emptied and read again. Placing a cell in240- a region (a format, undo) keeps the region's value. On a notebook241- sheet a command region's table that grows or shrinks inserts or242- deletes rows under it inside the same step, so the rows below move as243- they would by hand (`regionshape.go`). Formulas name a region's table244- as `nu.name`, resolved when evaluated as named ranges are; commands245- read regions as `$name`, which makes a dependency graph246- (`regiongraph.go`) giving refresh and run orders, cycles refused, and247- a linked file in it never runs. The file keeps the definitions248- (`regionfile.go`).221+ come from outside the engine, of two kinds: a linked file222+ (`linked.go`), a file the UI follows, and a notebook cell's output sent223+ to a sheet (`Region.Output`), each its table at its anchor. Both are224+ one list per sheet, the sheet's `regionState`, replaced whole on every225+ change so undo steps keep the definitions; what isn't undone (the226+ cells written, how the rows arrive) is kept beside it (`regionMeta`).227+ Their cells have one write path, `writeTable` (`regionwrite.go`): a228+ header and rows, written as spilled cells are, derived and outside the229+ undo history, only those that differ, with the region's cells it no230+ longer needs cleared; a table that would overwrite other contents231+ isn't shown, its first cell saying where, and clearing that cell shows232+ it. Rows arrive only as live operations, the change stream below, and233+ are never part of the undo state, since undo can't bring back what a234+ file held or a run printed: a region undo brings back or moves is235+ emptied and marked stale, and the UI sends its rows again, the file236+ read again or the cell's output as it is. Placing a cell in a region237+ (a format, undo) keeps the region's value. Formulas name a region's238+ table as `nu.name`, resolved when evaluated as named ranges are. The239+ file keeps the definitions (`regionfile.go`), and converts the command240+ regions of earlier files into notebook cells (`notebookfile.go`).241+- **Notebooks.** A notebook tab is a sheet whose `regionState` holds242+ cells (`notebook.go`), so adding, editing, moving and deleting cells243+ are undo steps as any change is, and the tab is named, moved, hidden244+ and deleted as a sheet is. The document itself, cells, names, what a245+ cell reads, run orders and stale outputs, is `internal/notebook`,246+ which knows nothing of sheets. Outputs aren't undone: the workbook247+ keeps each cell's last `notebook.Output` by the cell's ID, its NUON as248+ nu printed it, and the file keeps them up to the caps249+ (`notebookfile.go`).249250 - **Rules.** A sheet's conditional formats and data validation250251 (`rules.go`, `condfmt.go`, `validation.go`) are lists of rules on251252 ranges, replaced whole on every change so undo steps keep them as they@@ -268,8 +269,8 @@ style.
268269 269270 Rows reach a region as `sheet.LiveOp`s, each applied at once by270271 `Workbook.ApplyLive` through the regions' one write path: what follows271-a linked file sends them, and a command region's table is written the272-same way from its `RegionData`.272+a linked file sends them, and the UI sends a notebook cell's output to273+the region it was sent to whenever the cell runs.273274 274275 | Field | Holds |275276 |---|---|@@ -288,8 +289,7 @@ step (a macro run) they recalculate when it ends. An op carries whole
288289 values and names nothing but its region, so applying the same ops in the289290 same order to the same workbook makes the same cells: it is what a290291 session following another's over `012 serve` would be sent, beside the291-steps `Batch` records (a command region's run is one of those, since292-its table is in the undo state). `OnLive` times each op for telemetry.292+steps `Batch` records. `OnLive` times each op for telemetry.293293 294294 ### Functions295295 @@ -438,7 +438,7 @@ draw. The components:
438438 | mouse | `mouseState` | drags, hover, double clicks, the fill handle (`mouse.go`, `fill.go`) |439439 | import | `transfer.Transfer`, `pipeState` | the import in progress, its progress display and cancelling (package `transfer`); choosing and placing imports (`transfer.go`, `importplace.go`); standard input read as a sheet, and what a pipeline gets on quitting (`pipe.go`) |440440 | linked files | `followState` | a source (`live.Source`) for each linked region, polled one poll at a time on a command every `live.Interval` and reconciled with the workbook after every update, so undo, opening a file and unlinking need nothing of their own; trust in files outside a workbook's folder (`follow.go`); Data > Linked file and Import's Follow the file (`linked.go`) |441-| notebooks | `nuprompt.Prompt`, `shellState` | the prompt (package `nuprompt`); the commands running one at a time in the background, their queue and what they said (`nurun.go`); the notebook's commands, keys, lines and trust (`notebook.go`) |441+| notebooks | `nbview.View`, `nbState` | a view of each notebook tab, its selection, mode, scroll and editor (package `nbview`); the tab on the screen (`nbscreen.go`); the notebook's commands and keys (`notebook.go`); cells running one at a time in the background, their queue, stale outputs, trust (`nbrun.go`); what a run reads (`nbjob.go`); outputs sent to sheets (`nbsend.go`) |442442 | macros | `recorder`, `macroState` | a recording in progress (`macrorec.go`); a macro running, trust in the file's macros (`macrorun.go`); what scripts act on (`macrohost.go`, `macrohostnav.go`); Data > Macros and the manager (`macro.go`, `macromanage.go`) |443443 | others | `clipboard`, `trace`, `chartState`, `jevRunner`, `terminal`, `session` | what Ctrl+V pastes, a trace being shown, chart commands' target, JEV questions in flight, what the terminal supports and the chart images sent to it, what outlasts the file open (the `:` history, whether keys can be held: `keyboard.go`) |444444 @@ -465,7 +465,7 @@ methods off `ui.Model`'s exported API:
465465 | `sortbar` | `sortbar.Host` | theme, size, the sheet, close, sort (recorded as the bar's command) (5) |466466 | `filterpick` | `filterpick.Host` | theme, size, the edit line, close, the locale (5); what applying and cancelling do are callbacks, as the sheet's filter and a pivot's differ |467467 | `cmdline` | `cmdline.Host` | theme, size, the edit line, close, the commands to complete, run a line, fail, the session's history (8) |468-| `nuprompt` | `nuprompt.Host` | theme, size, the edit line, close, run a line, the words to complete, the workbook's history, what's running, stop it, what the last run said (10) |468+| `nbview` | `nbview.Host` | theme, locale, the cells, a cell's output, how its run stands, run a command, keep a cell's new source (7); the language's highlighter, completer and checker are `nbview.Providers`, small interfaces of their own |469469 | `suggest` | `suggest.Host` | theme, size, the edit line, whether an entry is being typed, the entry's sheet, the formula as parsed, where the formula bar's text starts (7) |470470 | `themepicker` | `themepicker.Host` | a picker's host, and the current theme, the themes directory, preview, keep, whether keys can be held (10) |471471 | `rules` | `rules.Host` | theme, size, the edit line, close, the sheet and selection, save a conditional format or a validation rule, follow a rule removed or moved (each recorded as the commands that do it), the terminal's palette colors (10) |@@ -511,7 +511,7 @@ hints) are what every overlay is drawn with.
511511 512512 **Packages.** `theme`, `rowtext`, `formula`, `overlay` and `lineedit`513513 depend on nothing in `ui`, so they can be tested and measured alone. The514-components in `picker`, `cmdline`, `nuprompt`, `themepicker`, `findbar`, `rules`,514+components in `picker`, `cmdline`, `nbview`, `themepicker`, `findbar`, `rules`,515515 `sortbar`, `filterpick`, `choicebar`, `shortcuts`, `suggest`, `tabstrip`516516 and `transfer` build on them and reach the model only through their517517 hosts, with unit tests of their own against fake hosts. A component moves out of package@@ -600,19 +600,34 @@ the user's editor (`AllowEditor`), since that starts a program.
600600 601601 ## Notebooks602602 603-`internal/nushell` runs a notebook's command: a `Job` holds the command604-and the NUON of the tables it reads, and the script `nu -c` runs binds605-each table from a file named by an environment variable606-(`let r1 = (open --raw $env.NU012_TABLE_0 | from nuon)`), feeds the607-selection as `$in` on standard input, and ends in `to nuon`, so no data608-is ever spliced into the command. What nu prints is read as it's609-written by the NUON importer, capped at max-cells. `Runner` is the610-seam: tests hand the UI a fake, the e2e screens a stand-in `nu`611-script. The UI runs one command at a time as a `tea.Cmd` with a612-context Esc cancels and a timeout, and shows each table as an undo613-step when it arrives; the queue a refresh makes comes from the614-engine's graph. Trust is the macros': a file's commands run only once615-they were made or trusted on this computer, or the user agrees.603+`internal/nushell` runs a code cell: a `Job` holds the pipeline and the604+NUON of what it reads, and the script `nu -c` runs binds each from a605+file named by an environment variable606+(`let files = (open --raw $env.NU012_TABLE_0 | from nuon)`) and ends in607+`to nuon`, so no data is ever spliced into the pipeline; a range of a608+sheet (`$sheet.A1:C9`) is renamed to a variable of its own first609+(`notebook.Bind`). What nu prints is kept as it is, NUON, the cell's610+output: a later cell reads it byte for byte as `$name`, `nbview` parses611+it once to draw it, and `fileio.NUONRows` reads it as a region's rows to612+send to a sheet. `Runner` is the seam: tests hand the UI a fake, the e2e613+screens a stand-in `nu` script. The UI runs one cell at a time as a614+`tea.Cmd` with a context Stop cancels and a timeout; the queue a run615+makes comes from `notebook.Order` (each cell after those it reads) and616+`notebook.Inputs` (what it reads that hasn't run), and a reactive617+notebook adds `notebook.Dependents`. An output records the source it618+ran and the `Seq` of each output it read, so `notebook.Stale` tells619+which outputs may be out of date without running anything. Trust is620+the macros': a file's cells run only once they were made or trusted on621+this computer, or the user agrees.622+623+`nbview` draws each cell as a block of lines, working out only how many624+lines each takes and drawing those on screen, so an expanded output of625+ten thousand rows costs the rows showing; a table's column widths are626+fitted once, when its output is parsed. The code editor627+(`lineedit.Area`) wraps at the cell's width, before pipes where it can;628+highlighting, completion and diagnostics come from `nbview.Providers`,629+asked in the background once typing pauses, with a tokenizer and the630+notebook's names as the built-in answers.616631 617632 ## Charts618633 @@ -93,12 +93,12 @@ there.
9393 | Entries failing validation | A dotted underline, and `Invalid:` with the rule on the context line |9494 | Values an array spilled | Italic, and `Spilled from B2` on the context line |9595 | Linked files' rows, following, paused or failing | Italic; `●`, `‖` or `!` beside the tab's name and on the context line, with the state in words (`Following`, `Paused`, the error) |96-| A notebook's regions | The label line's text (`r1 ls`, and `Running…` or `failed`) underlined as wide as the table, and `Region r1 of ls` on the context line |96+| A notebook's cells and outputs | `❯` before the tab's name; the selected cell's head in reverse video; the head's words for its state (`[*]` and `running`, `waiting`, `failed`, `stale`); `×` before an error; an output table's header bold and underlined; an output sent to a sheet in italic, with `Output of files` on the context line |9797 | Pivot table results | Their headings (`SUM of Units`, `Grand Total`), and a note in words when an edit is refused |9898 | Protected ranges | A question in words before an edit (`A1:B2 is protected.`) |9999 | Notes | A `▝` in the cell's top-right corner |100100 | Macro recording | `REC` beside the mode indicator |101-| Mode | The mode indicator's word (`READY`, `ENTER`, `POINT`, `MENU`) |101+| Mode | The mode indicator's word (`READY`, `ENTER`, `POINT`, `MENU`, and on a notebook `NOTEBOOK`, `EDIT` or `OUTPUT`) |102102 | Search matches, traced cells | Reverse video, with a count or the list on the context line |103103 | The copied range | A dashed underline |104104 | Dropdowns, checkboxes, active filters | `▾`, or a chip in reverse video between `▐` and `▌`; `[ ]` and `[✓]`; `▼` instead of `▾` |@@ -49,11 +49,12 @@ file's rows, typed as an import types them. The region is the file's:
4949 the file again there; deleting its first cell's row or column unlinks5050 it.5151 52-A linked file is a region, as a [notebook's](../nushell/notebooks.md)53-shell regions are, named after the file (`app` for `app.csv`, `app_2`54-for a second link to it): formulas on any sheet read its table as55-`nu.app`, and nushell pipelines as `$app`56-([Linked files](../nushell/notebooks.md#linked-files)).52+A linked file is a region, as a [notebook](../nushell/notebooks.md)53+cell's output sent to a sheet is, named after the file (`app` for54+`app.csv`, `app_2` for a second link to it): formulas on any sheet read55+its table as `nu.app`, and notebook cells as `$app`, its rows as they56+are when the cell runs ([Names and57+$name](../nushell/notebooks.md#names-and-name)).5758 5859 The sheet's tab carries a mark, and the context line says what the5960 region under the pointer is doing:@@ -88,9 +88,9 @@ save), so they raise no version:
8888 | `conditionalFormats`, `validations` | a sheet | [Rules](#conditional-formats-and-data-validation), one per line |8989 | `arithmetic` | the workbook | `decimal` for [decimal arithmetic](../formulas/decimal.md) |9090 | `locale` | the workbook | The [locale](../sheets/locale.md) it's typed and shown in (`"de-DE"`), when File > Settings > Locale chose one; without it, the file follows the reader's `locale` setting. Cells are stored the same way in every locale: `input` is always as typed in en-US (`1,234.5`, `9/26/2026`, `=ROUND(A1,2)`) |91-| `macros`, `macroOrigin` | the workbook | Macros as Starlark scripts, and the computer they were made or trusted on (macros', shell regions' and [linked files'](following.md#files-from-elsewhere) alike): see [Macro scripting API](../reference/macro-api.md#in-the-file). Opening a file never runs them |92-| `notebook`, `regions` | a sheet | A [notebook sheet](../nushell/notebooks.md), and its shell regions and [linked files](following.md): see [Regions](#regions). Older builds open the sheet without them |93-| `shellHistory` | the workbook | The lines typed at its [notebook prompt](../nushell/notebooks.md#the-prompt), oldest first, for Up and Down |91+| `macros`, `macroOrigin` | the workbook | Macros as Starlark scripts, and the computer they were made or trusted on (macros', notebook cells' and [linked files'](following.md#files-from-elsewhere) alike): see [Macro scripting API](../reference/macro-api.md#in-the-file). Opening a file never runs them |92+| `regions` | a sheet | Its [linked files](following.md) and notebook cells' [outputs sent there](../nushell/notebooks.md#send-to-a-sheet): see [Regions](#regions). Older builds open the sheet without them |93+| `tab`, `reactive`, `notebookCells` | a sheet | A [notebook](../nushell/notebooks.md) tab and its cells: see [Notebooks](#notebooks). Older builds open it as an empty sheet |9494 9595 ## Column and row formats9696 @@ -163,39 +163,65 @@ with its data.
163163 164164 ## Regions165165 166-A sheet's regions, a [notebook's](../nushell/notebooks.md)167-shell regions and [linked files](following.md), are a `regions` list168-after its cells, charts and rules, one per line, in the order they were169-made; a notebook sheet also has `"notebook": true`. The file keeps what170-each region reads, never its table: reopening shows shell regions as not171-run, and nothing runs until you run it; linked files are read again.166+A sheet's regions, [linked files](following.md) and notebook cells'167+[outputs sent there](../nushell/notebooks.md#send-to-a-sheet), are a168+`regions` list after its cells, charts and rules, one per line, in the169+order they were made. The file keeps where each region is and what feeds170+it, never its table: opening the file reads linked files again and sends171+each output from its cell's saved output.172172 173173 ```json174- "notebook": true,175174 "regions": [176- {"name":"r1","command":"ls","at":"A1","rows":12,"cols":4},177- {"name":"big","command":"$r1 | where size > 1kb","at":"A16","rows":3,"cols":4,"reads":["r1"],"sort":[{"column":3,"desc":true}]},175+ {"name":"big","at":"A1","output":true},178176 {"name":"app","at":"F1","path":"logs/app.csv","window":500}179177 ]180178 ```181179 182-- `name` is what commands read it as (`$r1`) and formulas name it by183- (`nu.r1`); `command` is a shell region's nushell pipeline.184-- `at` is its label line's cell; `rows` and `cols` the size of its table185- when saved, header row included, which it keeps until it runs.186-- `reads` are the regions its command reads, `input` the range it read187- as `$in` (`Sheet1!A1:C9`), and `sort` the columns its table is sorted188- by, counting from 1 at its first column, with `desc` for Z to A.189-- A linked file has `path` instead of a command: the file, relative to190- the workbook's folder when it's saved there or below, and otherwise as191- it was linked; `at` is its table's first cell. `format` names the192- file's format (`CSV`, `TSV`, `JSON`, `NUON`, `XLSX`, `SQLite`,193- `Parquet`) when the extension doesn't tell it, `table` or `query` say194- what to read from a SQLite database, and `window` keeps the last rows195- under the header.180+- `name` is what formulas name it by (`nu.big`, `nu.app`) and notebook181+ cells read a linked file as (`$app`); an output's is its cell's.182+- `at` is its table's first cell, the header row's.183+- `output` marks a notebook cell's output.184+- A linked file has `path`: the file, relative to the workbook's folder185+ when it's saved there or below, and otherwise as it was linked.186+ `format` names the file's format (`CSV`, `TSV`, `JSON`, `NUON`,187+ `XLSX`, `SQLite`, `Parquet`) when the extension doesn't tell it,188+ `table` or `query` say what to read from a SQLite database, and189+ `window` keeps the last rows under the header.196190 197191 The table's cells are saved only for their formatting and notes, as a198-spill's are.192+spill's are. A region with a `command`, which the notebook sheets of193+earlier versions wrote (with `input`, the range it read as `$in`, and194+`rows`, `cols`, `reads` and `sort`, which opening it doesn't need),195+opens as a code cell of the workbook's notebook, its table sent where it196+was ([Notebook sheets](../nushell/notebooks.md#notebook-sheets)).197+198+## Notebooks199+200+A notebook tab is a sheet with `"tab": "notebook"`, `"reactive": true`201+when it's [reactive](../nushell/notebooks.md#stale-outputs-and-reactive-notebooks),202+and its cells in `notebookCells`, one per line:203+204+```json205+ "tab": "notebook",206+ "notebookCells": [207+ {"kind":"note","source":"# Files"},208+ {"source":"files = ls","output":"[[name, size]; [go.mod, 812b]]"},209+ {"source":"$files | nope","error":"Command `nope` not found","detail":"help: ..."},210+ {"source":"ls **/*","unsaved":true}211+ ]212+```213+214+- `kind` is `note` for Markdown, left out for code; `source` is what the215+ cell holds, a code cell's name and all (`files = ls`).216+- `output` is what the cell's last run printed, as NUON text, kept when217+ it fits the `nu-save-cell-kb` and `nu-save-notebook-kb` caps218+ ([Configuration](../reference/config.md#nushell-notebooks)); `unsaved`219+ marks one left out for its size.220+- `error` and `detail` are a failed run's message and help line, `note`221+ what an output left out.222+223+Run counts, timings and stale marks aren't saved: an output read from224+the file is what its cell's source and inputs gave.199225 200226 ## Conditional formats and data validation201227 @@ -9,8 +9,8 @@ sidebar_position: 1
99 tables: `ls`, `ps`, `open data.csv` and `http get` all hand the next1010 command rows and columns, with file sizes, durations and dates as values1111 of their own type. 012 is a spreadsheet for those tables. A table can go12-through 012 in the middle of a pipeline, and nushell can run inside 012,13-each pipeline's table a live part of the sheet.12+through 012 in the middle of a pipeline, and nushell can run inside 01213+in a notebook, its cells' outputs live parts of the sheets.1414 1515 1616 @@ -19,13 +19,13 @@ each pipeline's table a live part of the sheet.
1919 | Way | Looks like | For |2020 |---|---|---|2121 | [A stage in a pipeline](pipelines.md) | `ls \| sheet \| where size > 1kb` | Looking at a table on the terminal, editing it, and sending it on to the next command |22-| [A notebook](notebooks.md) | `012 nu`, then `ls \| select name size` at the `nu❯` prompt | Pipelines you keep: each one's table is a named region of the sheet that formulas, charts and other pipelines read, run again when you ask |22+| [A notebook](notebooks.md) | `sheet nu`, then `files = ls \| select name size` in a code cell | Pipelines you keep, as in Jupyter: cells run when you ask, each output under its cell, read by later cells as `$files` and, sent to a sheet, by formulas and charts |2323 | [A followed file](../files/following.md) | Data > Linked file, then `$app \| where status >= 500` | A log or export that keeps growing: its rows come in as they're written, and pipelines read the rows it has now |2424 2525 The first needs nothing but nushell. The other two run `nu` from inside2626 012, so it has to be installed ([Installing27-nushell](https://www.nushell.sh/book/installation.html)); without it the28-prompt says so, and the rest of 012 works as before.27+nushell](https://www.nushell.sh/book/installation.html)); without it a28+cell's output says so, and the rest of 012 works as before.2929 3030 ## Install the `sheet` command3131 @@ -67,27 +67,27 @@ shells run it as `012`.
6767 # A table in, edited, and out again, with its types6868 ls | select name size | sheet | where size > 1kb6969 70-# A notebook: each pipeline's table lands in the grid70+# A notebook of nushell cells, their outputs under them7171 sheet nu work.0127272 ```7373 74-At the notebook's `nu❯` prompt:74+In the notebook's cells, each run with Shift+Enter:7575 7676 ```nu7777 sales = open sales.csv | update Revenue { str replace -ar '[$,]' '' | into float }7878 $sales | group-by Region --to-table | update items { get Revenue | math sum }7979 ```8080 81-The second region reads the first as `$sales`; typing a new command for82-`sales` runs it and then the region that reads it. In a formula on any83-sheet, `=SUM(nu.sales)` reads the same table.81+The second cell reads the first's output as `$sales`; running `sales`82+again marks the second `stale` until it runs too. `G` sends an output to83+a sheet, where `=SUM(nu.sales)` reads it and follows each run.8484 8585 ## Pages8686 8787 | Page | For |8888 |---|---|8989 | [Pipelines](pipelines.md) | `sheet`, `012 -` and `012 --pipe`: tables in on standard input and out on standard output, sending back, the exit status |90-| [Notebooks](notebooks.md) | `012 nu` and the `nu❯` prompt: regions, `$r1` and `$in`, `nu.r1` in formulas, refreshing, saving and trust |90+| [Notebooks](notebooks.md) | `sheet nu` and `012 nu`: code and note cells, their keys, running, `$name`, `$selection` and `$sheet.A1:C9`, outputs sent to sheets as `nu.name`, saving and trust |9191 | [Types](types.md) | How each nushell type becomes a cell and goes back, and what doesn't survive the trip |9292 | [Cookbook](cookbook.md) | Worked examples: disk usage, a log followed live, a CSV cleaned and summarized, an API, processes, git history |9393 @@ -5,31 +5,37 @@ sidebar_position: 5
55 66 # Cookbook77 8-Short worked examples. Pipelines that end in `^012` run in a nushell9-session; lines that start with a region's name and `=` are typed at a10-[notebook's](notebooks.md) `nu❯` prompt (`012 nu`, or **Data > Shell** in any workbook). Nushell's own8+Short worked examples. Pipelines that end in `sheet` or `sheet view`9+run in a nushell session, with 012's module installed ([Install the10+`sheet` command](README.md#install-the-sheet-command)); lines that start11+with a name and `=` are code cells of a [notebook](notebooks.md)12+(`sheet nu`, or **Data > Notebook > Open notebook** in any workbook), one13+cell a line, each run with Shift+Enter. Nushell's own1114 [cookbook](https://www.nushell.sh/cookbook/) has more pipelines to start1215 from.1316 1417 ## A CSV cleaned, then summarized1518 1619 Money written as text (`"$2,252.50"`) becomes numbers in nushell, and a17-second region totals it by region, with a chart that follows it.20+second cell totals it by region, sent to a sheet with a chart that21+follows it.1822 19-23+2024 2125 ```nu2226 sales = open sales.csv | update Revenue { str replace -ar '[$,]' '' | into float }2327 totals = $sales | group-by Region --to-table | update items { get Revenue | math sum } | rename Region Revenue2428 ```2529 26-To chart it, select the totals table, its header row and rows, and27-**Insert > Chart**. Change `sales`'s command (F2 on its label) to read28-another file, and `totals` runs again after it and the chart redraws.30+To chart it, `G` on `totals` sends its output to a new sheet; there,31+**Insert > Chart** charts the table around the pointer. Edit `sales` to32+read another file and run it: `totals` shows `stale` until it runs too33+(at once in a [reactive notebook](notebooks.md#stale-outputs-and-reactive-notebooks)),34+and then the sheet and the chart follow.2935 30-To pivot rather than total, select the `sales` table and31-**Data > Pivot table** ([Pivot tables](../sheets/pivots.md)): Region in32-rows, Quarter in columns, Revenue in values.36+To pivot rather than total, send `sales` to a sheet and **Data > Pivot37+table** there ([Pivot tables](../sheets/pivots.md)): Region in rows,38+Quarter in columns, Revenue in values.3339 3440 Nushell:3541 [`update`](https://www.nushell.sh/commands/docs/update.html),@@ -42,20 +48,20 @@ Nushell:
4248 4349 A JSON lines log (`app.jsonl`) linked with **Data > Linked file > Link a4450 table** takes in rows as they're written ([Following45-files](../files/following.md)). A region reads it as `$app`:51+files](../files/following.md)). A notebook's cells read it as `$app`:4652 47-53+4854 4955 ```nu5056 errors = $app | where status >= 500 | select time path status ms5157 by_path = $errors | group-by path --to-table | update items { length } | rename path errors5258 ```5359 54-The linked region grows by itself; Enter on `errors`'s label reads the55-rows the log has now, and `by_path` follows. A log in CSV or TSV works56-the same; a plain text log needs a line of nushell to become a table,57-such as [`parse`](https://www.nushell.sh/commands/docs/parse.html) in a58-region's command:60+The linked region grows by itself; running `errors` again (Ctrl+Enter)61+reads the rows the log has now, and a reactive notebook runs `by_path`62+after it. A log in CSV or TSV works the same; a plain text log needs a63+line of nushell to become a table, such as64+[`parse`](https://www.nushell.sh/commands/docs/parse.html) in a cell:5965 6066 ```nu6167 lines = open --raw app.log | lines | parse "{time} {level} {message}"@@ -67,23 +73,24 @@ lines = open --raw app.log | lines | parse "{time} {level} {message}"
6773 usage = du * | select path physical | update path { path basename } | sort-by physical --reverse6874 ```6975 70-Sizes arrive in the Size format ([Types](types.md)), so a chart's axis71-and `=SUM(nu.usage)` read them as bytes. Select the table and72-**Insert > Chart** for a column chart; Enter on the label runs `du`73-again.76+Sizes arrive in the Size format ([Types](types.md)), so once `G` sends77+the output to a sheet, a chart's axis and `=SUM(nu.usage)` read them as78+bytes: **Insert > Chart** there for a column chart. Ctrl+Enter on the79+cell runs `du` again, and the sheet follows.7480 7581 Nushell: [`du`](https://www.nushell.sh/commands/docs/du.html).7682 7783 ## An API response as a table7884 7985 ```nu80-http get https://api.github.com/repos/nushell/nushell/issues | select number title user.login comments created_at | update created_at { into datetime } | to nuon | ^012 -86+http get https://api.github.com/repos/nushell/nushell/issues | select number title user.login comments created_at | update created_at { into datetime } | sheet view8187 ```8288 8389 Sort by comments, filter by author, or make a pivot table of issues by8490 author, in the sheet. In a notebook, the same pipeline without85-`| to nuon | ^012 -` is a region that fetches the list again when86-refreshed; `nu-timeout` stops a request that hangs.91+`| sheet view` is a cell that fetches the list again each time it runs;92+Enter on its output opens it full-screen to sort and filter, and93+`nu-timeout` stops a request that hangs.8794 8895 Nushell: [`http get`](https://www.nushell.sh/commands/docs/http_get.html),8996 [`into datetime`](https://www.nushell.sh/commands/docs/into_datetime.html),@@ -93,7 +100,7 @@ page.
93100 ## Processes, sorted, filtered and sent back94101 95102 ```nu96-ps | where cpu > 1 | sort-by cpu --reverse | select pid name cpu mem | to nuon | ^012 --pipe | from nuon | get pid | each {|pid| kill $pid }103+ps | where cpu > 1 | sort-by cpu --reverse | select pid name cpu mem | sheet | get pid | each {|pid| kill $pid }97104 ```98105 99106 In 012, sort the list and filter it down to the processes to stop@@ -19,7 +19,8 @@ $files | where size > 1kb | sort-by size --reverse
1919 2020 2121 Open one from a shell with `012 nu`, or from nushell with `sheet nu`22-(`sheet` is 012's nushell module: [Pipelines](pipelines.md)):22+(`sheet` comes from 012's nushell module: [Install the `sheet`23+command](README.md#install-the-sheet-command)):2324 2425 ```sh2526 012 nu # a new notebook, its first cell ready to type in@@ -164,7 +165,7 @@ A cell reads the sheets two ways, each a table:
164165 |---|---|165166 | `$selection` | The range selected on the sheet shown last before the notebook, with its first row as the header |166167 | `$sheet.A1:C9`, `$sheet.Sales!A1:C9`, `$sheet.'Q1 data'!B2:B40` | That range, of the sheet shown last or the sheet named |167-| `$app` | A [linked file](../files/following.md) named `app`, its rows as they are now |168+| `$app` | A [linked file](../files/following.md) named `app`, its rows as they are when the cell runs |168169 169170 They reach nu as NUON in a file it reads, never as text spliced into170171 the pipeline, so types survive ([Types](types.md)): sizes stay sizes,@@ -18,7 +18,7 @@ ls | select name size | sheet | describe
1818 ```1919 2020 This holds wherever NUON carries a table: [pipelines](pipelines.md),21-[notebook regions](notebooks.md), `.nuon` files opened, imported or21+[notebook cells](notebooks.md) and their outputs sent to sheets, `.nuon` files opened, imported or2222 downloaded, and linked `.nuon` files.2323 2424 | Nushell | Cell | Sent back as |@@ -128,13 +128,37 @@ range, F2 renames or repoints it and Ctrl+D deletes it.
128128 129129 ## Notebooks130130 131-| Key | Action |131+On a [notebook's](../nushell/notebooks.md#keys) tab, as in Jupyter:132+command mode (`NOTEBOOK`) acts on cells, edit mode (`EDIT`) types into133+one. **Data > Notebook > Open notebook** opens the workbook's notebook;134+on a sheet, `!` starts an entry as any character does.135+136+| Key | In command mode |137+|---|---|138+| Up, Down, `j`, `k`, Home, End, PgUp, PgDn | Move between cells and their outputs |139+| Enter | Edit the cell; on an output, open it full-screen |140+| Shift+Enter, Ctrl+Enter, Alt+Enter | Run the cell and select the next; run it in place; run it and add a cell under it |141+| F9 | Run every cell |142+| `a`, `b`, `!` | Add a code cell above, below; add one below and edit it |143+| `dd`, `z` | Delete the cell; undo |144+| `m`, `y` | Make the cell a note, or code |145+| `c`, `x`, `v` | Copy, cut, paste a cell |146+| `n`, `o`, `G` | Name the cell; show all of its output or its first rows; send the output to a sheet |147+| `ii`, `00` | Stop what's running; restart, clearing every output |148+149+| Key | In edit mode |150+|---|---|151+| Esc | Back to command mode, keeping what was typed |152+| Shift+Enter, Ctrl+Enter, Alt+Enter | Run, as in command mode |153+| Enter, Tab | A new line; complete the word at the caret |154+| Up, Down, Home, End, Ctrl+A, Ctrl+E | Move by the lines on screen; the start, the end of the line |155+156+| Key | On an output full-screen |132157 |---|---|133-| ! | On a notebook sheet, open the nushell prompt on the formula bar (the mode indicator says NU); on other sheets `!` starts an entry, and **Data > Shell** opens the prompt ([Notebooks](../nushell/notebooks.md)) |134-| Enter, Tab, Up, Down, Esc | At the prompt: run the line; complete a region or command; the workbook's earlier lines; stop a command running, or else go back to the grid |135-| Enter, F2 | On a region's label line: run it again (and what reads it); edit its command at the prompt |136-| F9 | Run all regions, each after those it reads |137-| Esc | Stop a region's command while it runs |158+| Arrows, `h`, `j`, `k`, `l`, PgUp, PgDn, `g`, `G` | Move |159+| `s`, `S` | Sort by the pointer's column, A to Z or Z to A; again for the output's order |160+| `/` | Keep the rows holding what's typed; Esc clears it |161+| Esc, `q` | Back to the notebook |138162 139163 ## Keys the terminal has to tell apart140164 @@ -88,7 +88,7 @@ the authorized keys. Everything else is closed.
8888 others.8989 - **What a session can do.** Run 012, nothing else; no command is9090 executed, unless the server's config turns on notebooks' nushell91- commands (see [Notebooks](#notebooks)). A shell request starts 012 on a new sheet. An exec request91+ cells (see [Notebooks](#notebooks)). A shell request starts 012 on a new sheet. An exec request9292 is accepted only with a terminal (`ssh -t`) and only when it is one9393 word, which is taken as a file name and never run: it resolves inside9494 the served directory like a name typed in File > Open, and anything@@ -152,12 +152,12 @@ network or clock access in any case.
152152 ## Notebooks153153 154154 A session opens [notebooks](../nushell/notebooks.md) and shows their155-regions, but runs none of their commands: a command is a program on the156-server, with the server's user and every file it can reach, well157-beyond the served directory. `serve-shell = on` in the server's config158-lets sessions run them, as the user 012 serve runs as, following the159-`shell` option as the local app does; a file's commands still ask once160-per session before they run. Only turn it on when everyone holding an155+cells and saved outputs, but runs none of their cells: a cell is a156+program on the server, with the server's user and every file it can157+reach, well beyond the served directory. `serve-shell = on` in the158+server's config lets sessions run them, as the user 012 serve runs as,159+following the `shell` option as the local app does; a file's cells still160+ask once per session before they run. Only turn it on when everyone holding an161161 authorized key may run programs on the server.162162 163163 ## Unsaved work@@ -23,7 +23,7 @@ import (
2323 // part of the undo state: the source is where they come from, and undo2424 // can't bring back what it held. When undo puts a region back, or it2525 // moves, it is emptied and marked stale, and the UI sends its rows26-// again: the file read again, or the cell's output as it is now.26+// again: the file read again, or the cell's output as it stands.2727 //2828 // The definitions are undo steps. So are a notebook tab's cells, which2929 // the same state holds (notebook.go).