cat / 012
clone

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

Merge branch 'main' into worktree-agent-a2264ce9952a1a538

Dami committed eb5e6ac
commit
eb5e6ac67083b0fbf446864780360c68ae71b7e4
parent
75f690faebe146513b02ca403127fbc4c8b757d3
parent
2d1e1fb2d8d09e471cb37b9426192006a66cc925
author
Dami <dami.etoile@gmail.com>
226 files changed, +9878 -1491
MNOTICE102+++++
MREADME.md7+-
MROADMAP.md33+-
Acmd/012/agentskill.go106+++++
Acmd/012/agentskill_test.go45++
Acmd/012/describe.go49+++
Mcmd/012/diffcmd.go31++-
Mcmd/012/export.go53++-
Acmd/012/exporthtml_test.go72++++
Mcmd/012/main.go10+-
Acmd/012/mcp.go86++++
Acmd/012/mcp_test.go50+++
Acmd/012/results_test.go76++++
Mcmd/012/scripts.go79++++-
Acmd/012/skill/SKILL.md95+++++
Mcmd/012/version.go25+-
Mdemos/decimal.tape4+-
Mdemos/notebook.tape39+-
Mdemos/nu-recipe.tape12+-
Mdocs/README.md3+-
Adocs/agents/README.md90+++++
Adocs/agents/_category_.json8+
Adocs/agents/mcp.md135+++++++
Mdocs/contributing/_category_.json2+-
Mdocs/contributing/architecture.md13+-
Mdocs/contributing/limits.md7+-
Mdocs/contributing/testing.md9+-
Mdocs/contributing/ux.md2+-
Mdocs/files/README.md29+-
Mdocs/files/following.md11+-
Mdocs/files/scripts.md35++-
Mdocs/formulas/README.md23+-
Mdocs/formulas/arrays.md6+-
Mdocs/formulas/decimal.md4+-
Adocs/media/notebook-grid.pngbin
Mdocs/media/notebook.gifbin
Mdocs/media/nu-recipe.gifbin
Mdocs/nushell/cookbook.md9+-
Mdocs/nushell/notebooks.md78+++-
Mdocs/reference/README.md1+
Mdocs/reference/_category_.json2+-
Mdocs/reference/command-line.md20+-
Mdocs/reference/functions.md22+-
Adocs/reference/json.md169+++++++++
Mdocs/reference/keys.md21+-
Me2e/jupyter_test.go33++
Me2e/screennotebook_test.go26+-
Me2e/settings_test.go4+-
Me2e/testdata/screens/functions-light.html2+-
Me2e/testdata/screens/functions.html2+-
Me2e/testdata/screens/menu-download.html4+-
Me2e/testdata/screens/notebook-cells-high-contrast.html20+-
Me2e/testdata/screens/notebook-cells-light.html20+-
Me2e/testdata/screens/notebook-cells.html20+-
Me2e/testdata/screens/notebook-error-high-contrast.html20+-
Me2e/testdata/screens/notebook-error-light.html20+-
Me2e/testdata/screens/notebook-error.html20+-
Ae2e/testdata/screens/notebook-grid-filter-high-contrast.html30++
Ae2e/testdata/screens/notebook-grid-filter-light.html30++
Ae2e/testdata/screens/notebook-grid-filter.html30++
Ae2e/testdata/screens/notebook-grid-high-contrast.html30++
Ae2e/testdata/screens/notebook-grid-light.html30++
Ae2e/testdata/screens/notebook-grid.html30++
Me2e/testdata/screens/notebook-nu-error-high-contrast.html20+-
Me2e/testdata/screens/notebook-nu-error-light.html20+-
Me2e/testdata/screens/notebook-nu-error.html20+-
Me2e/testdata/screens/notebook-nu-highlight-high-contrast.html20+-
Me2e/testdata/screens/notebook-nu-highlight-light.html20+-
Me2e/testdata/screens/notebook-nu-highlight.html20+-
Me2e/testdata/screens/notebook-output-high-contrast.html14+-
Me2e/testdata/screens/notebook-output-light.html14+-
Me2e/testdata/screens/notebook-output.html14+-
Me2e/testdata/screens/notebook-running-high-contrast.html20+-
Me2e/testdata/screens/notebook-running-light.html20+-
Me2e/testdata/screens/notebook-running.html20+-
Me2e/testdata/screens/notebook-scroll-high-contrast.html38+-
Me2e/testdata/screens/notebook-scroll-light.html38+-
Me2e/testdata/screens/notebook-scroll.html38+-
Me2e/testdata/screens/notebook-select-high-contrast.html20+-
Me2e/testdata/screens/notebook-select-light.html20+-
Me2e/testdata/screens/notebook-select.html20+-
Me2e/testdata/screens/notebook-stale-high-contrast.html20+-
Me2e/testdata/screens/notebook-stale-light.html20+-
Me2e/testdata/screens/notebook-stale.html20+-
Me2e/testdata/screens/notebook-wrap-high-contrast.html20+-
Me2e/testdata/screens/notebook-wrap-light.html20+-
Me2e/testdata/screens/notebook-wrap-narrow-high-contrast.html16+-
Me2e/testdata/screens/notebook-wrap-narrow-light.html16+-
Me2e/testdata/screens/notebook-wrap-narrow.html16+-
Me2e/testdata/screens/notebook-wrap.html20+-
Me2e/testdata/screens/palette.html2+-
Mgo.mod7+
Mgo.sum16+
Minternal/chart/image.go23+
Minternal/chart/scatter.go4+
Ainternal/chart/svg.go311++++++++++++++++
Ainternal/chart/svg_test.go71++++
Ainternal/fileio/fonts/OFL.txt93+++++
Ainternal/fileio/fonts/ibm-plex-mono-latin-400-italic.woff2bin
Ainternal/fileio/fonts/ibm-plex-mono-latin-400-normal.woff2bin
Ainternal/fileio/fonts/ibm-plex-mono-latin-600-normal.woff2bin
Minternal/fileio/formats.go20+-
Minternal/fileio/formats_test.go22+-
Ainternal/fileio/html.go125++++++
Ainternal/fileio/html_test.go139+++++++
Ainternal/fileio/htmlcell.go221+++++++++++
Ainternal/fileio/htmlgrid.go239++++++++++++
Ainternal/fileio/htmlstyle.go169+++++++++
Minternal/fileio/sheetscorpus_xlsx_test.go18+-
Ainternal/fileio/snapdrawn.go32++
Minternal/fileio/snapshot.go7+
Minternal/fileio/testdata/sheets_corpus.tsv580+++++++++++++++---------------
Minternal/formula/parse.go4+-
Minternal/functions/args.go25+-
Minternal/functions/dynamic.go5+-
Minternal/functions/eval.go6+-
Minternal/functions/everyday.go66++-
Minternal/functions/lambda.go10+-
Minternal/functions/lift.go6+-
Minternal/functions/logic.go29+-
Minternal/functions/lookup.go23+-
Minternal/functions/masked.go4+-
Minternal/functions/math.go20+-
Minternal/functions/text.go30+-
Ainternal/headless/build.go151++++++++
Ainternal/headless/charts.go47++
Ainternal/headless/describe.go241++++++++++++
Ainternal/headless/describe_test.go86++++
Ainternal/headless/describetext.go107++++++
Ainternal/headless/encode.go33++
Minternal/headless/jev.go8+-
Ainternal/headless/ops.go182+++++++++
Ainternal/headless/read.go87+++++
Ainternal/headless/results.go108++++++
Ainternal/headless/runcell.go55+++
Minternal/headless/set.go3+-
Ainternal/headless/tools.go177+++++++++
Ainternal/mcp/backend.go100+++++
Ainternal/mcp/prompts.go60+++
Ainternal/mcp/read.go103+++++
Ainternal/mcp/resources.go225++++++++++++
Ainternal/mcp/server.go96+++++
Ainternal/mcp/server_test.go340++++++++++++++++++
Ainternal/mcp/views.go119++++++
Ainternal/mcp/views_test.go74++++
Ainternal/mcp/write.go169+++++++++
Ainternal/numfmt/entered.go35++
Ainternal/numfmt/fraction.go166+++++++++
Minternal/numfmt/numfmt_test.go58+++
Minternal/numfmt/pattern.go3+
Ainternal/sheet/cyclefind.go377++++++++++++++++++++
Ainternal/sheet/cyclefind_test.go116++++++
Minternal/sheet/decimal_test.go9+-
Minternal/sheet/evaluate.go4+-
Minternal/sheet/functions_array_test.go2+-
Minternal/sheet/functions_lookup_test.go7+-
Minternal/sheet/functions_math_test.go7+-
Ainternal/sheet/functions_sheets_test.go71++++
Minternal/sheet/functions_text_test.go2+-
Minternal/sheet/merge.go28+-
Minternal/sheet/merge_undo_test.go17+
Minternal/sheet/randedit_ops_test.go3+-
Minternal/sheet/randedit_shared_test.go9+-
Minternal/sheet/randedit_test.go47+-
Minternal/sheet/recalc.go12+-
Minternal/sheet/region.go7+-
Ainternal/sheet/regionclash.go134+++++++
Ainternal/sheet/regionclash_test.go103+++++
Minternal/sheet/regionshape.go4+-
Minternal/sheet/regionwrite.go81++--
Minternal/sheet/sheet.go2+-
Minternal/sheet/spill.go24+-
Minternal/sheet/spill_test.go27+-
Minternal/sheet/spillblock.go108++++++-
Ainternal/sheet/spillcycle_test.go66+++
Minternal/sheet/tablebind.go2+-
Ainternal/sheet/testdata/fixtures/v0.4.0/plain.01210+
Ainternal/sheet/testdata/fixtures/v0.4.0/single.01221+
Ainternal/sheet/testdata/fixtures/v0.4.0/workbook.012169+++++++++
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/0cef393ee02403d82+
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/52d14ae960ebe41a2+
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/5b93384d423fd67f2+
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/7bd353237853b7472+
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/a1b814ebfaeff4cb2+
Ainternal/sheet/testdata/fuzz/FuzzRandomEdits/d2d49b6d88d8d44d2+
Minternal/sheet/workbook.go11+
Minternal/sheet/workbook_test.go2+-
Minternal/ui/cmdline.go2+-
Minternal/ui/commands.go25+-
Minternal/ui/context.go4+-
Minternal/ui/filter.go19+-
Minternal/ui/grid.go5+
Minternal/ui/gridlines.go3+
Minternal/ui/menuoverlay.go4+-
Minternal/ui/model.go6+
Minternal/ui/monochrome_test.go17+-
Minternal/ui/mouse.go4+-
Minternal/ui/nbcommands.go8+-
Ainternal/ui/nbgrid.go287+++++++++++++++
Ainternal/ui/nbgrid_test.go200++++++++++
Ainternal/ui/nbgridcmd.go215+++++++++++
Ainternal/ui/nbgridin.go275++++++++++++++
Minternal/ui/nbrun.go4+
Minternal/ui/nbscreen.go22+-
Minternal/ui/nbview/draw.go4+-
Minternal/ui/nbview/full.go271++------------
Ainternal/ui/nbview/grid.go199++++++++++
Minternal/ui/nbview/keys.go8+-
Minternal/ui/nbview/mouse.go4+
Minternal/ui/nbview/output.go158++------
Minternal/ui/nbview/outwin.go113+----
Minternal/ui/nbview/panel.go6+-
Minternal/ui/nbview/view.go7+
Minternal/ui/nbview/view_test.go108++++-
Minternal/ui/notebook.go8+-
Minternal/ui/panel.go22+-
Minternal/ui/pivot.go4+
Minternal/ui/settings_test.go2+-
Minternal/ui/sort.go7+-
Minternal/ui/speed_test.go22+
Minternal/ui/testdata/speed.json5+
Minternal/ui/view.go12+-
Minternal/value/value.go27+
Moracle/go.mod5+
Moracle/go.sum10+
Moracle/oracle_test.go5+-
M NOTICE +102 -0
@@ -28,3 +28,105 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2828 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,2929 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE3030 SOFTWARE.31+32+-------------------------------------------------------------------------------33+internal/fileio/fonts/*.woff234+35+IBM Plex Mono (regular, semibold and italic, Latin subset), embedded in the36+web pages 012 writes, as packaged by Fontsource37+(https://fontsource.org/fonts/ibm-plex-mono, @fontsource/ibm-plex-mono). The38+license is also in internal/fileio/fonts/OFL.txt.39+40+Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ThinItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLight.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Light.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-LightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Regular.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Italic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Medium.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-MediumItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Bold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-BoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved.41+42+This Font Software is licensed under the SIL Open Font License, Version 1.1.43+This license is copied below, and is also available with a FAQ at:44+http://scripts.sil.org/OFL45+46+47+-----------------------------------------------------------48+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200749+-----------------------------------------------------------50+51+PREAMBLE52+The goals of the Open Font License (OFL) are to stimulate worldwide53+development of collaborative font projects, to support the font creation54+efforts of academic and linguistic communities, and to provide a free and55+open framework in which fonts may be shared and improved in partnership56+with others.57+58+The OFL allows the licensed fonts to be used, studied, modified and59+redistributed freely as long as they are not sold by themselves. The60+fonts, including any derivative works, can be bundled, embedded,61+redistributed and/or sold with any software provided that any reserved62+names are not used by derivative works. The fonts and derivatives,63+however, cannot be released under any other type of license. The64+requirement for fonts to remain under this license does not apply65+to any document created using the fonts or their derivatives.66+67+DEFINITIONS68+"Font Software" refers to the set of files released by the Copyright69+Holder(s) under this license and clearly marked as such. This may70+include source files, build scripts and documentation.71+72+"Reserved Font Name" refers to any names specified as such after the73+copyright statement(s).74+75+"Original Version" refers to the collection of Font Software components as76+distributed by the Copyright Holder(s).77+78+"Modified Version" refers to any derivative made by adding to, deleting,79+or substituting -- in part or in whole -- any of the components of the80+Original Version, by changing formats or by porting the Font Software to a81+new environment.82+83+"Author" refers to any designer, engineer, programmer, technical84+writer or other person who contributed to the Font Software.85+86+PERMISSION & CONDITIONS87+Permission is hereby granted, free of charge, to any person obtaining88+a copy of the Font Software, to use, study, copy, merge, embed, modify,89+redistribute, and sell modified and unmodified copies of the Font90+Software, subject to the following conditions:91+92+1) Neither the Font Software nor any of its individual components,93+in Original or Modified Versions, may be sold by itself.94+95+2) Original or Modified Versions of the Font Software may be bundled,96+redistributed and/or sold with any software, provided that each copy97+contains the above copyright notice and this license. These can be98+included either as stand-alone text files, human-readable headers or99+in the appropriate machine-readable metadata fields within text or100+binary files as long as those fields can be easily viewed by the user.101+102+3) No Modified Version of the Font Software may use the Reserved Font103+Name(s) unless explicit written permission is granted by the corresponding104+Copyright Holder. This restriction only applies to the primary font name as105+presented to the users.106+107+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font108+Software shall not be used to promote, endorse or advertise any109+Modified Version, except to acknowledge the contribution(s) of the110+Copyright Holder(s) and the Author(s) or with their explicit written111+permission.112+113+5) The Font Software, modified or unmodified, in part or in whole,114+must be distributed entirely under this license, and must not be115+distributed under any other license. The requirement for fonts to116+remain under this license does not apply to any document created117+using the Font Software.118+119+TERMINATION120+This license becomes null and void if any of the above conditions are121+not met.122+123+DISCLAIMER124+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,125+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF126+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT127+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE128+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,129+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL130+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING131+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM132+OTHER DEALINGS IN THE FONT SOFTWARE.
M README.md +6 -1
M ROADMAP.md +11 -22
@@ -34,7 +34,6 @@ completed by nu as they're written.
3434 3535 | Item | Result | Size |3636 |---|---|---|37-| Outputs drawn as 012's own grid rather than text: column widths and number formats by type, the active cell and selection, sort, filter and find in place, copy a range, freeze the header, a chart or pivot from the output, and formulas beside it when sent to a sheet | An output works like the data it is | M |3837 | A command's signature and description for the word at the caret, on the context line, through `nu --ide-hover` or `nu --lsp` | Writing a cell without leaving for `help` | S |3938 4039 ### 3. Toward multiplayer
@@ -49,24 +48,7 @@ log macros record. Each step is useful on its own.
4948 | Shared viewing over SSH: several `012 serve` sessions open the same workbook; one edits, the others follow live with their own cursor, scroll and theme; presence shows who is where | Watch-along and review, one writer | M |5049 | Shared editing over SSH: every session edits, the server orders operations (no CRDT needed while one server holds the workbook), per-user undo, presence and edit ownership shown in the grid, saves by the server | Multiplayer 012 over SSH | L |5150 52-### 4. Toward 1.053-54-Solid before shared: what 012 already does keeps working from release to55-release, and shared editing builds on these guarantees. These come before56-shared editing in section 3.57-58-| Item | Result | Size |59-|---|---|---|60-| A workbook of formulas where 012 matches Sheets on purpose (dates, text, rounding, errors, spills), results checked once in Sheets and asserted after; differences chosen on purpose listed in the docs | Formula results people rely on stay put | S |61-| Cycles found from the formulas as written rather than as evaluation walks them: a cycle behind an error that ends a range read or an IF branch not taken, and arrays and notebook outputs in each other's way, settle the same whatever order they're computed in (`-randedit.seeds=20000` still finds about one sequence in 2,500 that reopens differently, and `randKnown` skips one of the default seeds) | Every workbook reads the same when reopened | M |62-63-### 5. Around the grid64-65-| Item | Result | Size |66-|---|---|---|67-| A sheet or chart exported as a static HTML page in 012's look | Sharing a sheet with someone without 012 | S |68-69-### 6. Agents51+### 4. Agents7052 7153 Agents work on workbooks through the same operations people do (the7254 `Batch`/`Change` path), so their edits are undoable, attributed and
@@ -75,9 +57,6 @@ section 3's shared editing with an agent as one participant.
7557 7658 | Step | Result | Size |7759 |---|---|---|78-| `012 describe` (sheets, used ranges, headers, names, tables, regions, charts), `--format json` on every command, `012 set --dry-run` printing the change as a diff, an agents page in the docs and a Claude Code skill installed by 012 | Agents with a shell use 012 well | S |79-| `012 mcp` over stdio on a workbook file: tools (describe, read, write, apply operations, evaluate without writing, find, sort, filter, chart, pivot, run a notebook cell), resources (`012://book/Sheet1!A1:D40`, tables, notebook cells), prompts | Any MCP host works with workbooks | M |80-| MCP Apps views: a sheet or chart rendered as an interactive view inside the host, from the HTML export | Workbooks shown in the chat | S to M |8160 | Live mode: `012 --listen` and `012 mcp --attach`; the agent's cursor and name in the grid, its changes arriving as a suggestion (marked cells, accepted or rejected whole or by cell) unless direct edits are allowed, its own undo, a scope (sheet, range, read-only), elicitation to ask the person | Coworking with an agent in the grid | M to L |8261 8362 ## Later: other transports (shelved)
@@ -108,6 +87,8 @@ stream above rather than a design of their own.
10887 - An Excel-sized grid in compact column storage, with a ten-million-cell `max-cells` budget; operations cost the data, not the grid: [Bounds of support](docs/contributing/limits.md#sheet-size)10988 - Undo steps in the compact form: clearing a full ten-million-cell sheet holds about what the sheet does, and a step past 1 GB asks first: [Bounds of support](docs/contributing/limits.md#undo)11089 - Spilled cells and pivot results in the compact form, about 20 B each: [Bounds of support](docs/contributing/limits.md#sheet-size)90+- Cycles found from the formulas as written, and arrays and notebook outputs in each other's way settled the same in any order, so a workbook reads the same when reopened: [Formulas](docs/formulas/README.md#values-and-errors)91+- Formula results checked against Google Sheets once and asserted after, with the differences 012 keeps on purpose listed: [Testing](docs/contributing/testing.md#the-sheets-corpus)11192 11293 **Finding and using features**11394
@@ -149,6 +130,7 @@ stream above rather than a design of their own.
149130 - 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)150131 - Cells run as streams: a pipeline that never ends (`tail -f`, `watch`) followed live, its rows reaching the output and its sheet as nu prints them: [Notebooks](docs/nushell/notebooks.md#streams)151132 - Code cells highlighted, checked and completed as they're written by nu itself (`--ide-ast`, `--ide-check`, `--ide-complete`), in the background, falling back to 012's own when nu is missing, old, slow or not trusted: [Notebooks](docs/nushell/notebooks.md#writing-a-cell)133+- Table and record outputs drawn and worked as 012's own grid: formats by type, fitted and resizable columns, select, copy, sort, filter and find in place, full-screen, charts and pivots on the sheet the output is sent to: [Notebooks](docs/nushell/notebooks.md#outputs-as-grids)152134 153135 **Files**154136
@@ -158,8 +140,15 @@ stream above rather than a design of their own.
158140 - `012 diff` cell by cell, as git's diff command or textconv, and `012 merge-driver` merging cell by cell with conflicts noted on the cells: [Diff and merge in git](docs/files/git.md)159141 - Following files: a linked region follows a CSV, TSV, JSON lines or NUON file as it grows and any importable file as it's rewritten, keeping every row or the last ones, its rows arriving as the change stream: [Following files](docs/files/following.md)160142 - The `.012` format written down with a version, and each release's workbooks kept as fixtures that every later build opens and saves unchanged: [The .012 format](docs/files/format.md#versions), [Releasing](docs/contributing/releasing.md#file-fixtures)143+- Web pages in 012's look: a sheet, a range or a chart as one self-contained `.html` file, charts as SVG, from File > Download and `012 export`: [Files](docs/files/README.md#web-pages)161144 - A crash keeps unsaved work for recovery, restores the terminal and writes a report, locally and in `012 serve`: [Saving](docs/files/saving.md#if-012-crashes)162145 146+**Agents**147+148+- `012 describe`, results as JSON with stable schemas, `012 set --dry-run` as a diff, and a Claude Code skill installed by `012 agent --install-skill`: [Agents](docs/agents/README.md)149+- `012 mcp`, an MCP server on a workbook file: tools that read, evaluate, write, sort, filter, chart, pivot and run notebook cells through the same checks as `012 set`, resources and prompts: [MCP server](docs/agents/mcp.md)150+- MCP Apps views: ranges read and charts made drawn in the chat from the HTML export, where the host supports the extension: [MCP server](docs/agents/mcp.md#views-in-the-chat)151+163152 **Upkeep**164153 165154 - `make check` before every push; demo tapes (`make demos`); annotated version tags with release notes (v0.2.0 onward; v0.1.0 remains on the Go module proxy): [Testing](docs/contributing/testing.md)
A cmd/012/agentskill.go +106 -0
@@ -0,0 +1,106 @@
1+package main2+3+import (4+ "bytes"5+ _ "embed"6+ "errors"7+ "fmt"8+ "io/fs"9+ "os"10+ "path/filepath"11+ "strings"12+)13+14+// 012 agent --skill and 012 agent --install-skill: the Claude Code15+// skill that teaches agents with a shell to use 012 (see16+// docs/agents/README.md), installed as 012 nu --install-module installs17+// the nushell module.18+19+//go:embed skill/SKILL.md20+var skillSource string21+22+const agentUsage = "usage: 012 agent --skill | --install-skill [--force] [dir]"23+24+// skillHome is where Claude Code looks for a person's own skills; tests25+// replace it.26+var skillHome = func() (string, error) {27+ home, err := os.UserHomeDir()28+ if err != nil {29+ return "", fmt.Errorf("finding your home directory: %w; name the folder instead: 012 agent --install-skill path/to/skills/012", err)30+ }31+ return filepath.Join(home, ".claude", "skills", "012"), nil32+}33+34+// runAgent is 012 agent --skill (print the skill) or --install-skill35+// [--force] [dir].36+func runAgent(args []string, e env) error {37+ a, err := parseArgs(args, nil, []string{"skill", "install-skill", "force", "help"})38+ switch {39+ case err != nil:40+ return usageError(err.Error(), agentUsage)41+ case a.has("help"):42+ fmt.Fprintln(e.stdout, agentUsage)43+ return nil44+ case a.has("skill") && !a.has("install-skill") && len(a.pos) == 0:45+ _, err := fmt.Fprint(e.stdout, skillSource)46+ return err47+ case !a.has("install-skill") || a.has("skill") || len(a.pos) > 1:48+ return usageError("", agentUsage)49+ }50+ path, err := skillPath(a.pos)51+ if err != nil {52+ return err53+ }54+ wrote, err := installSkill(path, a.has("force"))55+ if err != nil {56+ return err57+ }58+ if wrote {59+ fmt.Fprintln(e.stdout, "Wrote", path)60+ } else {61+ fmt.Fprintln(e.stdout, path, "is up to date")62+ }63+ fmt.Fprintln(e.stdout, "Claude Code finds it in the next session; /skills lists it.")64+ return nil65+}66+67+// skillPath is the SKILL.md to write: in the folder given (a file named68+// there, if it ends in .md), or in ~/.claude/skills/012.69+func skillPath(given []string) (string, error) {70+ dir := ""71+ if len(given) == 1 {72+ p, err := filepath.Abs(given[0])73+ if err != nil {74+ return "", err75+ }76+ if strings.EqualFold(filepath.Ext(p), ".md") {77+ return p, nil78+ }79+ dir = p80+ } else {81+ var err error82+ if dir, err = skillHome(); err != nil {83+ return "", err84+ }85+ }86+ return filepath.Join(dir, "SKILL.md"), nil87+}88+89+// installSkill writes the skill to path, creating its folder. A file90+// already there is replaced only with force, unless it's this skill;91+// wrote is false then.92+func installSkill(path string, force bool) (wrote bool, err error) {93+ old, err := os.ReadFile(path)94+ switch {95+ case err == nil && bytes.Equal(old, []byte(skillSource)):96+ return false, nil97+ case err == nil && !force:98+ return false, fmt.Errorf("%s exists and isn't this 012's skill; --force replaces it", path)99+ case err != nil && !errors.Is(err, fs.ErrNotExist):100+ return false, err101+ }102+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {103+ return false, err104+ }105+ return true, os.WriteFile(path, []byte(skillSource), 0o644)106+}
A cmd/012/agentskill_test.go +45 -0
@@ -0,0 +1,45 @@
1+package main2+3+import (4+ "os"5+ "path/filepath"6+ "strings"7+ "testing"8+)9+10+func TestAgentSkill(t *testing.T) {11+ e, out, _ := scriptEnv(t)12+ if code, err := status(e, "agent", "--skill"); code != 0 || !strings.HasPrefix(out.String(), "---\nname: 012\n") {13+ t.Fatalf("--skill: %d %v %.40q", code, err, out)14+ }15+ home := filepath.Join(t.TempDir(), "skills", "012")16+ old := skillHome17+ skillHome = func() (string, error) { return home, nil }18+ t.Cleanup(func() { skillHome = old })19+20+ out.Reset()21+ if code, err := status(e, "agent", "--install-skill"); code != 0 || !strings.Contains(out.String(), "Wrote "+filepath.Join(home, "SKILL.md")) {22+ t.Fatalf("install: %d %v %q", code, err, out)23+ }24+ out.Reset()25+ if status(e, "agent", "--install-skill"); !strings.Contains(out.String(), "is up to date") {26+ t.Errorf("again: %q", out)27+ }28+ os.WriteFile(filepath.Join(home, "SKILL.md"), []byte("mine"), 0o644)29+ if _, err := status(e, "agent", "--install-skill"); err == nil || !strings.Contains(err.Error(), "--force replaces it") {30+ t.Errorf("over another file: %v", err)31+ }32+ if code, err := status(e, "agent", "--install-skill", "--force"); code != 0 {33+ t.Error(err)34+ }35+ dir := filepath.Join(t.TempDir(), "project", ".claude", "skills", "012")36+ if code, err := status(e, "agent", "--install-skill", dir); code != 0 {37+ t.Fatal(err)38+ }39+ if data, _ := os.ReadFile(filepath.Join(dir, "SKILL.md")); string(data) != skillSource {40+ t.Errorf("project skill not written")41+ }42+ if code, _ := status(e, "agent"); code != 2 {43+ t.Errorf("agent alone: status %d", code)44+ }45+}
A cmd/012/describe.go +49 -0
M cmd/012/diffcmd.go +29 -2
@@ -19,7 +19,7 @@ import (
1919 const (2020 diffUsage = "usage: 012 diff a.012 b.012 [--format text|json|nuon] [--color auto|always|never]\n" +2121 " 012 diff --textconv file.012"22- mergeUsage = "usage: 012 merge-driver base.012 ours.012 theirs.012 [path]"22+ mergeUsage = "usage: 012 merge-driver base.012 ours.012 theirs.012 [path] [--format text|json|nuon]"2323 )2424 2525 // runDiff is 012 diff: exit status 0 when the workbooks are the same, 1
@@ -156,10 +156,13 @@ func textconv(path string, w io.Writer) error {
156156 // as a conflict to resolve; on trouble it leaves ours as it was and157157 // exits 2.158158 func runMergeDriver(args []string, e env) error {159- a, err := parseArgs(args, nil, []string{"help"})159+ a, err := parseArgs(args, []string{"format"}, []string{"help"})160+ format, ferr := resultFormat(a)160161 switch {161162 case err != nil:162163 return usageError(err.Error(), mergeUsage)164+ case ferr != nil:165+ return usageError(ferr.Error(), mergeUsage)163166 case a.has("help"):164167 fmt.Fprintln(e.stdout, mergeUsage)165168 return nil
@@ -188,6 +191,11 @@ func runMergeDriver(args []string, e env) error {
188191 return &exitError{code: 2, err: err}189192 }190193 }194+ if format != "text" {195+ if err := headless.Encode(e.stdout, format, mergeResult(conflicts)); err != nil {196+ return &exitError{code: 2, err: err}197+ }198+ }191199 if len(conflicts) == 0 {192200 return nil193201 }
@@ -207,3 +215,22 @@ func fileMode(path string) fs.FileMode {
207215 }208216 return st.Mode().Perm()209217 }218+219+// mergeConflict is a conflict as merge-driver --format json lists it.220+type mergeConflict struct {221+ Where string `json:"where"`222+ Field string `json:"field"`223+ Base string `json:"base"`224+ Ours string `json:"ours"`225+ Theirs string `json:"theirs"`226+ What string `json:"what"`227+}228+229+// mergeResult is what merge-driver --format json writes.230+func mergeResult(conflicts []diff.Conflict) map[string]any {231+ out := []mergeConflict{}232+ for _, c := range conflicts {233+ out = append(out, mergeConflict{c.Where, c.Field, c.Base, c.Ours, c.Theirs, c.What})234+ }235+ return map[string]any{"conflicts": out}236+}
M cmd/012/export.go +48 -5
@@ -3,6 +3,7 @@ package main
33 import (44 "context"55 "fmt"6+ "io"67 "os"78 "path/filepath"89 "strings"
@@ -12,13 +13,13 @@ import (
1213 "github.com/FelineStateMachine/012/internal/sheet"1314 )1415 15-const exportUsage = "usage: 012 export file.012 out.csv|tsv|xlsx|json|nuon|sqlite [ref] [--format kind] [--table name] [--notebooks] [--jev] [--trust]"16+const exportUsage = "usage: 012 export file.012 out.csv|tsv|xlsx|json|nuon|sqlite|html [ref] [--format kind] [--table name] [--chart n|title] [--report json|nuon] [--notebooks] [--jev] [--trust]"1617 1718 // runExport is 012 export: a sheet, a range or (to formats holding1819 // several sheets) the whole workbook written as File > Download writes1920 // it.2021 func runExport(args []string, e env) error {21- a, err := parseArgs(args, []string{"format", "table"}, append([]string{"help"}, evalFlags...))22+ a, err := parseArgs(args, []string{"format", "table", "chart", "report"}, append([]string{"help"}, evalFlags...))2223 switch {2324 case err != nil:2425 return usageError(err.Error(), exportUsage)
@@ -33,6 +34,13 @@ func runExport(args []string, e env) error {
3334 if err != nil {3435 return usageError(err.Error(), exportUsage)3536 }37+ report := strings.ToLower(a.flags["report"])38+ if a.has("report") && report != "json" && report != "nuon" {39+ return usageError("--report "+report+": json or nuon", exportUsage)40+ }41+ if a.has("chart") && k != fileio.HTML {42+ return usageError("--chart writes a web page: name an .html file", exportUsage)43+ }3644 if same(src, out) {3745 return fmt.Errorf("%s is the workbook being exported: name another file", out)3846 }
@@ -52,20 +60,37 @@ func runExport(args []string, e env) error {
5260 if err := failed.fatal(); err != nil {5361 return err5462 }63+ if a.has("chart") {64+ if err := exportChart(out, t, a.flags["chart"]); err != nil {65+ return err66+ }67+ return exportReport(e, report, headless.ExportResult{File: out, Format: "html", Notes: []string{}}, failed)68+ }5569 snap := exportSnap(t, k, ref == "")5670 res, err := fileio.Export(context.Background(), out, k, snap, fileio.ExportOptions{Table: a.flags["table"]})5771 if err != nil {5872 return fmt.Errorf("%s: %w", out, err)5973 }60- for _, n := range res.Notes {61- fmt.Fprintln(e.stderr, "012: note: "+n)74+ return exportReport(e, report, headless.ExportResult{File: out, Format: strings.ToLower(k.String()), Rows: res.Rows,75+ Notes: append([]string{}, res.Notes...)}, failed)76+}77+78+// exportReport says what was written: its notes on standard error, or79+// with --report the whole result on standard output.80+func exportReport(e env, report string, res headless.ExportResult, failed evalFailures) error {81+ if report == "" {82+ for _, n := range res.Notes {83+ fmt.Fprintln(e.stderr, "012: note: "+n)84+ }85+ } else if err := headless.Encode(e.stdout, report, res); err != nil {86+ return err6287 }6388 return failed.err()6489 }6590 6691 // exportKind is the format to write: --format's, or out's extension's.6792 func exportKind(out, named string) (fileio.Kind, error) {68- k, ok := fileio.KindOf(out)93+ k, ok := fileio.ExportKindOf(out)6994 if named != "" {7095 k, ok = fileio.KindNamed(named)7196 if !ok {
@@ -115,3 +140,21 @@ func same(a, b string) bool {
115140 sb, err2 := os.Stat(b)116141 return err1 == nil && err2 == nil && os.SameFile(sa, sb)117142 }143+144+// exportChart is 012 export --chart: one chart of the target's sheet as145+// a web page of its own, found by its number (1 is the first) or title.146+func exportChart(out string, t headless.Target, which string) error {147+ i, err := headless.FindChart(t.Sheet, which)148+ if err != nil {149+ return err150+ }151+ c, _ := fileio.ChartSnap(t.Sheet, i)152+ err = headless.WriteAtomic(out, 0o644, func(w io.Writer) error {153+ _, err := fileio.WriteHTML(w, fileio.HTMLPage{Title: headless.ChartTitle(c.Chart), Chart: &c})154+ return err155+ })156+ if err != nil {157+ return fmt.Errorf("%s: %w", out, err)158+ }159+ return nil160+}
A cmd/012/exporthtml_test.go +72 -0
@@ -0,0 +1,72 @@
1+package main2+3+import (4+ "os"5+ "path/filepath"6+ "strings"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// chartFile writes a workbook of two columns and a chart titled Sales.13+func chartFile(t *testing.T, dir string) string {14+ t.Helper()15+ w := sheet.NewBook()16+ s := w.Sheet(0)17+ for i, in := range []string{"Month", "Jan", "Feb"} {18+ s.Set(sheet.Addr{Row: i}, in)19+ }20+ for i, in := range []string{"Sales", "10", "20"} {21+ s.Set(sheet.Addr{Col: 1, Row: i}, in)22+ }23+ s.AddChart(sheet.Chart{Type: sheet.ChartLine, Data: sheet.Rect{To: sheet.Addr{Col: 1, Row: 2}}, Header: true, Labels: true,24+ Title: "Sales", At: sheet.Addr{Col: 3}, W: 30, H: 10})25+ path := filepath.Join(dir, "book.012")26+ f, err := os.Create(path)27+ if err != nil {28+ t.Fatal(err)29+ }30+ defer f.Close()31+ if err := w.Write(f); err != nil {32+ t.Fatal(err)33+ }34+ return path35+}36+37+func TestExportHTML(t *testing.T) {38+ e, _, _ := scriptEnv(t)39+ dir := t.TempDir()40+ path := chartFile(t, dir)41+ out := filepath.Join(dir, "book.html")42+ if code, err := status(e, "export", path, out); code != 0 {43+ t.Fatal(err)44+ }45+ data, _ := os.ReadFile(out)46+ if page := string(data); !strings.Contains(page, `data-a="B3" class="r">20<`) || !strings.Contains(page, "<polyline") {47+ t.Errorf("page lacks the cells or the chart")48+ }49+ chart := filepath.Join(dir, "chart.html")50+ for _, which := range []string{"1", "sales"} {51+ os.Remove(chart)52+ if code, err := status(e, "export", path, chart, "--chart", which); code != 0 {53+ t.Fatal(err)54+ }55+ data, _ := os.ReadFile(chart)56+ if page := string(data); !strings.Contains(page, "<title>Sales</title>") || strings.Contains(page, "<table") {57+ t.Errorf("--chart %s: not the chart alone", which)58+ }59+ }60+ for _, c := range []struct {61+ args []string62+ want string63+ }{64+ {[]string{path, chart, "--chart", "2"}, "Sheet1 has 1 chart: chart 2 isn't one"},65+ {[]string{path, chart, "--chart", "Costs"}, `no chart titled "Costs" (charts: Sales)`},66+ {[]string{path, filepath.Join(dir, "x.csv"), "--chart", "1"}, "--chart writes a web page"},67+ } {68+ if _, err := status(e, append([]string{"export"}, c.args...)...); err == nil || !strings.Contains(err.Error(), c.want) {69+ t.Errorf("export %v: %v, want %q", c.args, err, c.want)70+ }71+ }72+}
M cmd/012/main.go +6 -4
@@ -80,8 +80,10 @@ func usage() error {
8080 " 012 nu [flags] [file]: the workbook's nushell notebook (see docs/nushell/notebooks.md)\n" +8181 " 012 nu --module | --install-module [--force] [path]: the nushell module with sheet (see docs/nushell/README.md)\n" +8282 " 012 serve [flags] [dir]: serve sheets in dir over SSH (see docs/terminal/ssh.md)\n" +83- " 012 get|set|recalc|export file.012 ...: read and change a workbook without the screen (see docs/files/scripts.md)\n" +83+ " 012 get|set|recalc|export|describe file.012 ...: read and change a workbook without the screen (see docs/files/scripts.md)\n" +8484 " 012 diff a.012 b.012, 012 merge-driver base ours theirs: compare and merge workbooks (see docs/files/git.md)\n" +85+ " 012 mcp file.012 [--read-only] [--force] [--notebooks [--trust]] [--jev]: an MCP server on the workbook (see docs/agents/mcp.md)\n" +86+ " 012 agent --skill | --install-skill [--force] [dir]: the Claude Code skill (see docs/agents/README.md)\n" +8587 " 012 config [path|edit|default|themes|set-key|delete-key]\n" +8688 " 012 version")8789 }
@@ -90,8 +92,8 @@ func usage() error {
9092 // opens as ./name.9193 var subcommands = map[string]func([]string, env) error{9294 "config": runConfig, "serve": runServe,93- "get": runGet, "set": runSet, "recalc": runRecalc, "export": runExport,94- "diff": runDiff, "merge-driver": runMergeDriver,95+ "get": runGet, "set": runSet, "recalc": runRecalc, "export": runExport, "describe": runDescribe,96+ "diff": runDiff, "merge-driver": runMergeDriver, "agent": runAgent, "mcp": runMCP,9597 }9698 9799 func run(args []string, e env) error {
@@ -99,7 +101,7 @@ func run(args []string, e env) error {
99101 return subcommands[args[0]](args[1:], e)100102 }101103 if len(args) > 0 && (args[0] == "version" || args[0] == "--version") {102- return runVersion(e)104+ return runVersion(args[1:], e)103105 }104106 if len(args) > 0 && args[0] == "nu" && isModuleCommand(args[1:]) {105107 return runNuModule(args[1:], e)
A cmd/012/mcp.go +86 -0
@@ -0,0 +1,86 @@
1+package main2+3+import (4+ "context"5+ "fmt"6+ "io"7+ "os"8+ "os/signal"9+ "sync"10+11+ sdk "github.com/modelcontextprotocol/go-sdk/mcp"12+13+ "github.com/FelineStateMachine/012/internal/config"14+ "github.com/FelineStateMachine/012/internal/headless"15+ "github.com/FelineStateMachine/012/internal/jev"16+ "github.com/FelineStateMachine/012/internal/mcp"17+ "github.com/FelineStateMachine/012/internal/sheet"18+)19+20+// 012 mcp: a Model Context Protocol server over standard input and21+// output on one workbook file (see docs/agents/mcp.md).22+23+const mcpUsage = "usage: 012 mcp file.012 [--read-only] [--force] [--notebooks [--trust]] [--jev]"24+25+// runMCP is 012 mcp: it serves until the client closes standard input.26+// Nothing runs a program or reaches the network unless its flag says:27+// --notebooks offers run_notebook_cell, --jev answers JEV functions.28+func runMCP(args []string, e env) error {29+ a, err := parseArgs(args, nil, []string{"read-only", "force", "notebooks", "trust", "jev", "help"})30+ switch {31+ case err != nil:32+ return usageError(err.Error(), mcpUsage)33+ case a.has("help"):34+ fmt.Fprintln(e.stdout, mcpUsage)35+ return nil36+ case len(a.pos) != 1:37+ return usageError("", mcpUsage)38+ case a.has("trust") && !a.has("notebooks"):39+ return usageError("--trust goes with --notebooks", mcpUsage)40+ }41+ path := a.pos[0]42+ if _, err := headless.Open(path, true); err != nil {43+ return err44+ }45+ cfg, err := loadConfig(e, nil)46+ if err != nil {47+ return err48+ }49+ ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)50+ defer stop()51+ b := &mcp.FileBackend{Path: path, Save: func(f *headless.File) error { return save(f, e) }}52+ if a.has("jev") {53+ b.Prepare = jevPreparer(cfg, e)54+ }55+ o := mcp.Options{Version: buildVersion(), ReadOnly: a.has("read-only"), Force: a.has("force")}56+ if a.has("notebooks") && !a.has("read-only") {57+ o.Notebooks = &headless.NotebookOptions{Runner: e.nuRunner(), Timeout: cfg.Duration("nu-timeout"), NuConfig: cfg.Bool("nu-config")}58+ o.MayRun = func(w *sheet.Workbook) error {59+ return mayRun(&headless.File{Path: path, Book: w}, cfg, a.has("trust"))60+ }61+ }62+ t := &sdk.IOTransport{Reader: io.NopCloser(e.stdin), Writer: nopWriteCloser{e.stdout}}63+ return mcp.New(b, o).Run(ctx, t)64+}65+66+// jevPreparer answers a workbook's JEV functions each time it's opened,67+// connecting once and keeping the answers, so each question is asked68+// once a session.69+func jevPreparer(cfg *config.Config, e env) func(context.Context, *headless.File) error {70+ var once sync.Once71+ var client jev.Client72+ var connErr error73+ cache := jev.NewCache()74+ return func(ctx context.Context, f *headless.File) error {75+ once.Do(func() { client, connErr = jevClient(ctx, cfg, e) })76+ if connErr != nil {77+ return connErr78+ }79+ headless.AnswerJEVFrom(ctx, f.Book, client, cache, jevTimeout)80+ return nil81+ }82+}83+84+type nopWriteCloser struct{ io.Writer }85+86+func (nopWriteCloser) Close() error { return nil }
A cmd/012/mcp_test.go +50 -0
A cmd/012/results_test.go +76 -0
@@ -0,0 +1,76 @@
1+package main2+3+import (4+ "encoding/json"5+ "os"6+ "path/filepath"7+ "strings"8+ "testing"9+10+ "github.com/FelineStateMachine/012/internal/headless"11+)12+13+// TestSetDryRun prints the change as 012 diff would and leaves the14+// file as it was.15+func TestSetDryRun(t *testing.T) {16+ e, out, _ := scriptEnv(t)17+ path := filepath.Join(t.TempDir(), "book.012")18+ status(e, "set", path, "A1", "1")19+ before, _ := os.ReadFile(path)20+ out.Reset()21+ if code, err := status(e, "set", path, "A1", "2", "B1", "=A1*2", "--dry-run"); code != 0 {22+ t.Fatal(err)23+ }24+ if got := out.String(); !strings.Contains(got, "Sheet1!A1 input 1 → 2") || !strings.Contains(got, "Sheet1!B1 input + =A1*2") {25+ t.Errorf("dry run printed %q", got)26+ }27+ if after, _ := os.ReadFile(path); string(after) != string(before) {28+ t.Errorf("dry run saved")29+ }30+ out.Reset()31+ if code, err := status(e, "set", path, "A1", "3", "--format", "json"); code != 0 {32+ t.Fatal(err)33+ }34+ var res headless.SetResult35+ if err := json.Unmarshal(out.Bytes(), &res); err != nil {36+ t.Fatalf("%v: %s", err, out)37+ }38+ if !res.Saved || len(res.Changes) == 0 || res.Changes[0].Item != "A1" || string(res.Changes[0].New) != `"3"` {39+ t.Errorf("set result %+v", res)40+ }41+ // A new file's dry run lists what it would hold, and makes no file.42+ fresh := filepath.Join(t.TempDir(), "new.012")43+ out.Reset()44+ status(e, "set", fresh, "A1", "x", "--dry-run", "--format", "nuon")45+ if _, err := os.Stat(fresh); err == nil || !strings.Contains(out.String(), "saved: false") {46+ t.Errorf("dry run on a new file: %s", out)47+ }48+}49+50+// TestResultFormats checks the other commands' --format json results.51+func TestResultFormats(t *testing.T) {52+ e, out, _ := scriptEnv(t)53+ dir := t.TempDir()54+ path := filepath.Join(dir, "book.012")55+ status(e, "set", path, "A1", "Item", "B1", "Price", "A2", "Pen", "B2", "=1/0")56+ for _, c := range []struct {57+ args []string58+ code int59+ want string60+ }{61+ {[]string{"recalc", path, "--format", "json"}, 1, `"value": "#DIV/0!"`},62+ {[]string{"describe", path, "--format", "json"}, 0, `"columns": [`},63+ {[]string{"describe", path}, 0, "Sheet1 (shown) A1:B2, 2 rows x 2 columns, 4 cells, 1 formula (1 showing errors)"},64+ {[]string{"export", path, filepath.Join(dir, "out.csv"), "--report", "json"}, 0, `"format": "csv"`},65+ {[]string{"version", "--format", "json"}, 0, `"go": "go`},66+ } {67+ out.Reset()68+ code, err := status(e, c.args...)69+ if code != c.code || !strings.Contains(out.String(), c.want) {70+ t.Errorf("%v: %d %v %s, want %q", c.args, code, err, out, c.want)71+ }72+ }73+ if code, _ := status(e, "describe", path, "--format", "csv"); code != 2 {74+ t.Errorf("describe --format csv: status %d", code)75+ }76+}
M cmd/012/scripts.go +71 -8
@@ -7,6 +7,7 @@ import (
77 "slices"88 "strings"99 10+ "github.com/FelineStateMachine/012/internal/diff"1011 "github.com/FelineStateMachine/012/internal/headless"1112 "github.com/FelineStateMachine/012/internal/notebook"1213 )
@@ -17,8 +18,8 @@ import (
1718 1819 const (1920 getUsage = "usage: 012 get file.012 [ref] [--format text|csv|tsv|json|nuon] [--input] [--no-header] [--notebooks] [--jev] [--trust]"20- setUsage = "usage: 012 set file.012 ref input [ref input ...] [--force]"21- recalcUsage = "usage: 012 recalc file.012 [--notebooks] [--jev] [--trust]"21+ setUsage = "usage: 012 set file.012 ref input [ref input ...] [--force] [--dry-run] [--format text|json|nuon]"22+ recalcUsage = "usage: 012 recalc file.012 [--format text|json|nuon] [--notebooks] [--jev] [--trust]"2223 )2324 2425 // evalFlags are the flags that let a command run a workbook's notebook
@@ -63,9 +64,10 @@ func runGet(args []string, e env) error {
6364 return failed.err()6465 }6566 66-// runSet is 012 set: type entries into cells and save.67+// runSet is 012 set: type entries into cells and save, or with68+// --dry-run print what would change, as 012 diff would, and not save.6769 func runSet(args []string, e env) error {68- a, err := parseArgs(args, nil, []string{"force", "help"})70+ a, err := parseArgs(args, []string{"format"}, []string{"force", "dry-run", "help"})6971 switch {7072 case err != nil:7173 return usageError(err.Error(), setUsage)
@@ -75,6 +77,10 @@ func runSet(args []string, e env) error {
7577 case len(a.pos) < 3 || len(a.pos)%2 == 0:7678 return usageError("", setUsage)7779 }80+ format, err := resultFormat(a)81+ if err != nil {82+ return usageError(err.Error(), setUsage)83+ }7884 f, err := headless.Open(a.pos[0], true)7985 if err != nil {8086 return err
@@ -87,16 +93,55 @@ func runSet(args []string, e env) error {
8793 if err != nil {8894 return fmt.Errorf("%w; %s is unchanged", err, f.Path)8995 }90- for _, w := range warnings {91- fmt.Fprintln(e.stderr, "012: warning: "+w)96+ res := headless.SetResult{File: f.Path, Warnings: warnings, Changes: []headless.Change{}}97+ if format == "text" {98+ for _, w := range warnings {99+ fmt.Fprintln(e.stderr, "012: warning: "+w)100+ }101+ }102+ if format != "text" || a.has("dry-run") {103+ changes, err := f.Changes()104+ if err != nil {105+ return err106+ }107+ if format == "text" {108+ color, _ := useColor("", e)109+ return diff.WriteChanges(e.stdout, changes, "text", color)110+ }111+ res.Changes = headless.Changes(changes)112+ }113+ if !a.has("dry-run") {114+ if err := save(f, e); err != nil {115+ return err116+ }117+ res.Saved = true118+ }119+ if format == "text" {120+ return nil121+ }122+ if res.Warnings == nil {123+ res.Warnings = []string{}124+ }125+ return headless.Encode(e.stdout, format, res)126+}127+128+// resultFormat is --format's form for a command's result: text, json129+// or nuon.130+func resultFormat(a cliArgs) (string, error) {131+ switch f := strings.ToLower(a.flags["format"]); f {132+ case "", "text":133+ return "text", nil134+ case "json", "nuon":135+ return f, nil136+ default:137+ return "", errors.New("--format " + f + ": text, json or nuon")92138 }93- return save(f, e)94139 }95140 96141 // runRecalc is 012 recalc: recalculate, save, and list the cells whose97142 // formulas show errors, exiting 1 when there are any.98143 func runRecalc(args []string, e env) error {99- a, err := parseArgs(args, nil, append([]string{"help"}, evalFlags...))144+ a, err := parseArgs(args, []string{"format"}, append([]string{"help"}, evalFlags...))100145 switch {101146 case err != nil:102147 return usageError(err.Error(), recalcUsage)
@@ -106,6 +151,10 @@ func runRecalc(args []string, e env) error {
106151 case len(a.pos) != 1:107152 return usageError("", recalcUsage)108153 }154+ format, err := resultFormat(a)155+ if err != nil {156+ return usageError(err.Error(), recalcUsage)157+ }109158 f, err := headless.Open(a.pos[0], false)110159 if err != nil {111160 return err
@@ -118,6 +167,14 @@ func runRecalc(args []string, e env) error {
118167 if err := save(f, e); err != nil {119168 return err120169 }170+ if format != "text" {171+ res := headless.RecalcResult{File: f.Path, Errors: headless.Problems(problems), Circular: circular,172+ NotebookFailures: append([]string{}, failed.cells...)}173+ if err := headless.Encode(e.stdout, format, res); err != nil {174+ return err175+ }176+ return problemStatus(problems, circular, failed)177+ }121178 return reportProblems(e.stdout, problems, circular, failed)122179 }123180
@@ -149,6 +206,12 @@ func reportProblems(w io.Writer, problems []headless.Problem, circular bool, fai
149206 if circular {150207 fmt.Fprintln(w, "circular reference: a formula reads its own cell, directly or through others")151208 }209+ return problemStatus(problems, circular, failed)210+}211+212+// problemStatus is recalc's exit status: 1 when cells show errors or a213+// notebook cell failed.214+func problemStatus(problems []headless.Problem, circular bool, failed evalFailures) error {152215 if len(problems) > 0 || circular {153216 return &exitError{code: 1, err: fmt.Errorf("%d %s showing errors", len(problems), plural(len(problems), "cell", "cells"))}154217 }
A cmd/012/skill/SKILL.md +95 -0
@@ -0,0 +1,95 @@
1+---2+name: 0123+description: Read, change, check and share 012 spreadsheet workbooks (.012 files) from the shell with the 012 command. Use when a task involves a .012 file, or when a spreadsheet, table of numbers or chart should be built, inspected, recalculated or exported (CSV, XLSX, JSON, NUON, SQLite, HTML).4+---5+6+# Working with 012 workbooks7+8+012 is a terminal spreadsheet. Its `.012` files are workbooks of sheets,9+formulas, tables, charts and nushell notebooks. Work on them with the10+`012` command, never by editing the file's JSON: `012 set` checks every11+entry as the screen does and saves atomically, and its changes show in12+`012 diff` like a person's.13+14+## Look before you read15+16+```sh17+012 describe book.012 # sheets, used ranges, header rows, tables, names, charts, notebooks18+012 describe book.012 --format json # the same as JSON19+```20+21+Read what describe points at rather than whole sheets.22+23+## Read24+25+```sh26+012 get book.012 B7 # one cell, as shown: $1,200.0027+012 get book.012 B7 --input # what was typed: =SUM(B2:B6)28+012 get book.012 'Q3 plan'!A1:F20 --format json # records named by the first row29+012 get book.012 Sales --format json # a table or named range by name30+012 get book.012 'Sales[Amount]' --format json # one column of a table31+```32+33+References are written as in formulas: `B7`, `A1:C9`, `A:A`, `Q3!B7`,34+`'Q3 plan'!A1:C9`, a named range, a table (`Sales`, `Sales[Amount]`) or a35+sheet name for the whole sheet. Without a sheet, the sheet shown when the36+file was saved is meant. `--no-header` names JSON columns by letter.37+38+## Change39+40+Preview first, then write:41+42+```sh43+012 set book.012 B7 '=SUM(B2:B6)' B8 1200 --dry-run # prints the change as 012 diff would; saves nothing44+012 set book.012 B7 '=SUM(B2:B6)' B8 1200 # types the entries, as one change, and saves45+012 set book.012 B7 '=SUM(B2:B6)' --format json # {file, saved, changes, warnings}46+```47+48+- Inputs are what a person types, in en-US form whatever the workbook's49+ locale: `1.5`, `=ROUND(A1, 2)`, `$1,200` (sets a currency format),50+ `12%`, `2026-09-29`. An empty input clears a cell.51+- Formulas are Google Sheets' (`SUM`, `XLOOKUP`, `FILTER`, `LET`,52+ `LAMBDA`, structured references like `Sales[Amount]`).53+- `set` refuses, and changes nothing, on the first entry a cell can't54+ take: a formula that doesn't parse, a validation rule, a protected55+ range (`--force` overrides only that), or a cell of a spill, pivot56+ table or notebook output. Read the message; it names the cell.57+- An input starting with `--` goes after `--`: `012 set book.012 -- A1 --`.58+59+## Check60+61+```sh62+012 recalc book.012 # recalculates, saves, lists cells showing errors; exit 1 if any63+012 recalc book.012 --format json # {file, errors: [{cell, value, why}], circular, notebook_failures}64+012 diff old.012 new.012 --format json65+```66+67+Run `012 recalc` after changing formulas and fix what it lists.68+69+## Share70+71+```sh72+012 export book.012 out.xlsx # every sheet, with formulas and formats73+012 export book.012 out.csv 'Q3'!A1:F20 # values as shown74+012 export book.012 report.html # a web page in 012's look, charts as SVG75+012 export book.012 chart.html --chart 1 # one chart alone, by number or title76+```77+78+## Safety79+80+Nothing runs a program or reaches the network unless a flag asks:81+`--notebooks` runs the workbook's nushell notebook cells (and82+`--trust` a workbook saved on another computer), `--jev` asks the JEV83+model service. Don't add them unless the user wants that.84+85+## Exit status86+87+0 done; 1 an error on standard error (or, for `recalc`, cells showing88+errors; for `diff`, the workbooks differ); 2 the command was used89+wrongly, with its usage. Every command's `--help` prints its usage.90+91+When the 012 MCP server (`012 mcp book.012`) is connected, its tools92+(describe, read_range, write_cells with dry_run, evaluate, list_errors)93+do the same with the same checks.94+95+The full reference: https://github.com/FelineStateMachine/012/blob/main/docs/agents/README.md
M cmd/012/version.go +23 -2
M demos/decimal.tape +2 -2
M demos/notebook.tape +24 -15
@@ -1,6 +1,7 @@
11 # Notebooks: 012 nu opens a notebook, its first cell ready to type in.22 # A code cell reads a CSV as sales, a second reads it as $sales, and its3-# output goes to a sheet (G) where a formula sums it; with the notebook3+# output, entered with Enter, is a grid to select in, and goes to a4+# sheet (G) where a formula sums it; with the notebook45 # reactive, editing sales runs both again and the sheet follows. The terminal (ttyd) sends Shift+Enter as Enter, so56 # cells run with Esc then r. Needs nu on the PATH.67 Output out/notebook.gif
@@ -12,52 +13,60 @@ Sleep 2s
1213 Show1314 1415 Sleep 800ms15-Type@25ms "sales = open data/sales.csv | where Region in [North South] | select Region Quarter Units"16+Type@15ms "sales = open data/sales.csv | where Region in [North South] | select Region Quarter Units"1617 Sleep 500ms1718 Escape1819 Type "r"19-Sleep 1.5s20+Sleep 1s2021 Type "b"2122 Enter22-Type@25ms "top = $sales | where Units > 250 | sort-by Units --reverse"23+Type@15ms "top = $sales | where Units > 250 | sort-by Units --reverse"2324 Sleep 500ms2425 Escape2526 Type "r"2627 Sleep 2s2728 Screenshot out/stills/notebook-cells.png29+Down30+Enter31+Sleep 400ms32+Ctrl+Shift+Down33+Sleep 1s34+Screenshot out/stills/notebook-grid.png35+Escape Escape36+Sleep 500ms2837 Type "G"2938 Sleep 800ms3039 Enter3140 Sleep 1.2s3241 Ctrl+K33-Type@40ms "next sh"42+Type@20ms "next sh"3443 Sleep 500ms3544 Enter36-Sleep 600ms45+Sleep 400ms3746 Right Right Right Right3847 Type "=SUM(nu.top)" Enter39-Sleep 1.5s48+Sleep 1s4049 Screenshot out/stills/notebook-sent.png4150 Ctrl+K42-Type@40ms "previous sh"51+Type@20ms "previous sh"4352 Sleep 500ms4453 Enter45-Sleep 600ms54+Sleep 400ms4655 Ctrl+K47-Type@50ms "reacti"48-Sleep 600ms56+Type@20ms "reacti"57+Sleep 400ms4958 Enter5059 Sleep 400ms51-Up Up60+Up Up Up5261 Sleep 300ms5362 Enter54-Type@30ms " | where Quarter != Q1"63+Type@20ms " | where Quarter != Q1"5564 Escape5665 Type "r"57-Sleep 2.5s66+Sleep 2s5867 Screenshot out/stills/notebook-reactive.png5968 Ctrl+K60-Type@40ms "next sh"69+Type@20ms "next sh"6170 Sleep 500ms6271 Enter6372 Sleep 2s
M demos/nu-recipe.tape +3 -9
M docs/README.md +2 -1
A docs/agents/README.md +90 -0
@@ -0,0 +1,90 @@
1+---2+title: "Agents"3+sidebar_position: 14+---5+6+# Agents7+8+Coding agents and assistants work on `.012` workbooks through the same9+operations people use: every change is typed into cells as the screen10+types it, checked by the same rules, made as one change and11+shown by [`012 diff`](../files/git.md#012-diff) like anyone's. Nothing12+agents do runs a program or reaches the network unless they were13+started with the flags that allow it, as for scripts.14+15+| Page | For |16+|---|---|17+| This page | Agents with a shell: the commands, their JSON, and the Claude Code skill |18+| [MCP server](mcp.md) | `012 mcp`, for any MCP host: tools, resources, prompts, and adding it to Claude Code and Claude Desktop |19+| [JSON output](../reference/json.md) | The schemas of what commands write with `--format json`, and what the MCP tools return |20+21+## With a shell22+23+Agents that can run commands use the ones [scripts](../files/scripts.md)24+use, in this order:25+26+```sh27+012 describe book.012 --format json # what's where28+012 get book.012 Sales --format json # read what describe pointed at29+012 set book.012 D2 '=B2*C2' D3 '=B3*C3' --dry-run # preview a change as a diff30+012 set book.012 D2 '=B2*C2' D3 '=B3*C3' # make it: one change, saved atomically31+012 recalc book.012 --format json # check no formula shows an error32+012 export book.012 report.html # share it as a web page33+```34+35+`012 describe` lists each sheet with its used range, the row that looks36+like its header and the column names in it, frozen panes, filters,37+tables, notebook outputs and linked files sent to it, and charts38+(numbered, as `012 export --chart` names them); pivot tables with their39+source; notebook tabs with their cells and whether each ran; and the40+workbook's named ranges:41+42+```43+Sales (shown) A1:F9, 9 rows x 6 columns, 54 cells, 9 formulas44+ header row 1: Date, Region, Units, Price, Total, Share45+ frozen 1 row, 0 columns46+ table Orders A1:F9 Date, Region, Units, Price, Total, Share47+ chart 1 Units by date column of A1:C9 at H248+Notebook (notebook) 2 cells49+ 1 code files = ls (ran)50+ 2 code $files | where size > 1kb (not run)51+names52+ Rate Sales!B1253+```54+55+A header row is guessed: the first row with contents, when every cell56+in it is text and the rows below hold numbers, dates, booleans or57+formulas, or when it's bold. `--format json` gives the same as the58+[schema](../reference/json.md#describe).59+60+`012 set --dry-run` checks the entries as `set` does (a formula that61+doesn't parse, a validation rule, a protected range stop it the same62+way) and prints what would change, as `012 diff` would, without saving;63+`--format json` gives the changes as records instead. Every command's64+flags are in [Command line](../reference/command-line.md).65+66+## The Claude Code skill67+68+012 carries a [Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills):69+a `SKILL.md` that tells Claude when to reach for `012` and how to use70+it well (describe first, preview with `--dry-run`, `recalc` after71+changing formulas, never edit the file's JSON by hand).72+73+```sh74+012 agent --install-skill # into ~/.claude/skills/012, for every project75+012 agent --install-skill .claude/skills/012 # into this project, to commit with it76+012 agent --skill # print it77+```78+79+Installing over a file that isn't this 012's skill asks for `--force`;80+installing the same skill again says it's up to date. A newer 012 may81+carry a newer skill: install it again after upgrading.82+83+## Trust84+85+Agents get no more than scripts do. A workbook's86+[notebook](../nushell/notebooks.md) cells run only with `--notebooks`,87+and then only when the workbook was saved on this computer or88+`--trust` says so; [JEV functions](../formulas/jev.md) ask the network89+only with `--jev`. Protected ranges refuse changes unless `--force` is90+given. Leave these flags to the person asking.
A docs/agents/_category_.json +8 -0
A docs/agents/mcp.md +135 -0
@@ -0,0 +1,135 @@
1+---2+title: "MCP server"3+sidebar_position: 24+---5+6+# MCP server7+8+`012 mcp book.012` is a [Model Context Protocol](https://modelcontextprotocol.io)9+server on one workbook, over standard input and output, so any MCP host10+(Claude Code, Claude Desktop, editors) can read and change it. It is the11+same code as [the commands](README.md#with-a-shell): reads are12+`012 describe` and `012 get`, and every write is typed through the13+checks `012 set` makes, as one change, saved atomically at14+once.15+16+```mermaid17+flowchart LR18+ host[MCP host] -- "stdio: tools, resources, prompts" --> server["012 mcp book.012"]19+ server -- "open, read" --> file[(book.012)]20+ server -- "one change, Batch, atomic save" --> file21+ person["012 book.012, 012 set, git"] --> file22+```23+24+The file is opened afresh for every call, so what the screen, a script25+or git saved meanwhile is what the next call sees. A file that doesn't26+exist is an empty workbook, saved on the first change.27+28+## Adding it to a host29+30+Claude Code, for one workbook (`--scope project` writes `.mcp.json`31+to commit with the project; the default keeps it to you):32+33+```sh34+claude mcp add budget -- 012 mcp /path/to/budget.01235+claude mcp add --scope project budget -- 012 mcp budget.01236+```37+38+Claude Desktop, in `claude_desktop_config.json` (Settings > Developer >39+Edit Config), with the full paths, since Desktop doesn't start in your40+folder:41+42+```json43+{44+ "mcpServers": {45+ "budget": {46+ "command": "/usr/local/bin/012",47+ "args": ["mcp", "/Users/me/Documents/budget.012"]48+ }49+ }50+}51+```52+53+Other hosts take the same command and arguments.54+55+## Flags56+57+| Flag | Does |58+|---|---|59+| `--read-only` | Offers only the tools that read |60+| `--force` | Lets writes change [protected ranges](../sheets/notes-protection.md#protected-sheets-and-ranges), as `012 set --force` |61+| `--notebooks` | Offers `run_notebook_cell`, which runs a [notebook](../nushell/notebooks.md) cell with nu, if the workbook was saved on this computer |62+| `--trust` | With `--notebooks`, runs the cells of a workbook saved on another computer, and marks it trusted here |63+| `--jev` | Answers [JEV functions](../formulas/jev.md) over the network, each question once a session |64+65+Without them nothing runs a program or reaches the network: notebook66+outputs are read as the file keeps them, and JEV functions show `#N/A`.67+`shell = off` in the [configuration](../reference/config.md#shell) keeps68+notebook cells from running even with `--notebooks`.69+70+## Tools71+72+References are written as in formulas (`B7`, `Q3!A1:C9`,73+`'Q3 plan'!A:A`, a named range, a table, `Sales[Amount]`, a sheet's74+name), and inputs as a person types them, in en-US form. Every write75+takes `dry_run`, which returns the change without making it.76+77+| Tool | Does |78+|---|---|79+| `describe` | The workbook's sheets, used ranges, guessed header rows and column names, tables, outputs, charts, pivots, notebook cells and names, as [`012 describe`](../reference/json.md#describe) |80+| `read_range` | A range's values as rows, its formulas by cell, and with `text` each cell as shown |81+| `evaluate` | A formula's value, computed in the workbook (at `at`, or below the data) without writing it: its text, why it's an error, an array's spill |82+| `find` | Cells by what they show or, with `in_formulas`, their formulas' text, as Edit > Find |83+| `list_errors` | The formulas showing errors after recalculating, as `012 recalc` lists them, without saving |84+| `write_cells` | Entries typed into cells as one change, as `012 set` |85+| `apply_operations` | Several operations as one change: `set`, `clear`, `insert_rows`, `delete_rows`, `insert_columns`, `delete_columns`, `add_sheet`, `rename_sheet`, `delete_sheet`, `define_name`, `sort` |86+| `sort` | A range's rows sorted by columns, named by letter or header |87+| `filter` | A filter on a range by conditions (`gt`, `contains` and the rest) or values to hide, or the sheet's filter removed |88+| `create_chart` | A chart of a range, its type, title and place given or guessed as Insert > Chart guesses them |89+| `create_pivot` | A pivot table on a new sheet: rows, columns and summarized values by header |90+| `run_notebook_cell` | With `--notebooks`: one code cell run, its output kept and sent on to its sheet |91+92+A write returns `saved`, `changes` (as [`012 diff`](../reference/json.md#diff)93+lists them) and `warnings`; a refused one is an error naming the cell,94+with nothing changed. Every result's schema is in95+[JSON output](../reference/json.md#mcp-tools).96+97+## Views in the chat98+99+Hosts that support [MCP Apps](https://github.com/modelcontextprotocol/ext-apps)100+(the `io.modelcontextprotocol/ui` extension) draw what `read_range`101+read and the chart `create_chart` made beside the result, as 012 draws102+them: the [web page](../files/README.md#web-pages) export's grid, with103+its fonts, colors, styles and charts as SVG, in the host's light or104+dark theme. Clicking a cell, or the arrow keys, puts the pointer on it105+and shows what was typed in it.106+107+Both tools name the view's resource, `ui://012/view`108+(`text/html;profile=mcp-app`), in their `_meta`; the host loads it into109+a sandboxed frame, and the result's `_meta` carries what to draw, at110+most 500 rows of a range. Hosts without the extension get the same111+results without it, and the page asks for nothing from the network.112+113+## Resources114+115+Hosts that let people attach data to a conversation list these; the116+scheme is `o12` since a URI's scheme starts with a letter, and a sheet's117+name is percent-encoded:118+119+| URI | Is |120+|---|---|121+| `o12://book/Sheet1!A1:D40` | A range, as `read_range` returns it; each sheet's used range is listed |122+| `o12://book/table/Sales` | A table, header row included; each table is listed |123+| `o12://book/notebook/Notes/2` | A notebook cell's source, and its output as NUON or why it failed; each code cell is listed |124+125+The list follows the workbook: a change that adds a sheet or table126+updates it, and hosts that listen are told.127+128+## Prompts129+130+| Prompt | Asks |131+|---|---|132+| `summarize_workbook` | What each sheet holds and what its numbers say, without changing anything |133+| `fix_errors` | The formulas showing errors explained, fixes checked with `evaluate` and previewed before they're made |134+| `add_column` | A column of formulas computing something beside a range (`range`, `column`) |135+| `chart` | The chart that best answers a question about a range (`range`, `question`) |
M docs/contributing/_category_.json +1 -1
M docs/contributing/architecture.md +10 -3
@@ -177,8 +177,13 @@ style.
177177 name and resolved when evaluated, so renaming rewrites them and a deleted178178 sheet's references wait, as `#REF!`, for a sheet of that name. Changing a179179 cell marks it and everything that transitively depends on it, on any180- sheet, then evaluates the marked cells lazily in dependency order; a cell181- reached again while it is being evaluated is part of a cycle. Volatile180+ sheet, then evaluates the marked cells lazily in dependency order.181+ Before evaluating, cycles among the marked formulas are found from the182+ references as written, IF branches not taken and range reads cut short183+ included, with a segment tree per column standing in for ranges and184+ Tarjan's algorithm (`cyclefind.go`), so a cycle's cells are `#REF!`185+ whatever order they're computed in; a cell reached again while it is186+ being evaluated is part of a cycle too. Volatile182187 functions (TODAY, RAND, the JEV functions) are recomputed on every183188 recalculation (`recalc.go`). Formulas read other cells through each184189 sheet's `reader`, the engine's side of the function library's `Book`
@@ -243,7 +248,9 @@ style.
243248 undo history, only those that differ, with the region's cells it no244249 longer needs cleared; a table that would overwrite other contents245250 isn't shown, its first cell saying where, and clearing that cell shows246- it. Rows arrive only as live operations, the change stream below, and251+ it; regions in each other's way settle as arrays do, the first anchor252+ winning (`regionclash.go`), so the order rows arrive in doesn't253+ matter. Rows arrive only as live operations, the change stream below, and247254 are never part of the undo state, since undo can't bring back what a248255 file held or a run printed: a region undo brings back or moves is249256 emptied and marked stale, and the UI sends its rows again, the file
M docs/contributing/limits.md +4 -3
M docs/contributing/testing.md +6 -3
M docs/contributing/ux.md +1 -1
@@ -99,7 +99,7 @@ there.
9999 | Entries failing validation | A dotted underline, and `Invalid:` with the rule on the context line |100100 | Values an array spilled | Italic, and `Spilled from B2` on the context line |101101 | 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) |102-| A notebook's cells and outputs | `❯` before the tab's name; `▌` left of the active cell and `▎` left of the others selected; a heavy box around the cell being edited; the prompt's and the box's words for its state (`[*]:` and `running`, `waiting`, `failed`, `stale`); `■` for `▶` while it runs; `● live` and the rows it printed for a cell running as a stream; `output hidden` for a hidden output, and which rows show for one scrolled; `×` 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; a problem nu finds in the cell being written curly-underlined, in words on the context line with the caret on it |102+| A notebook's cells and outputs | `❯` before the tab's name; `▌` left of the active cell and `▎` left of the others selected; a heavy box around the cell being edited; the prompt's and the box's words for its state (`[*]:` and `running`, `waiting`, `failed`, `stale`); `■` for `▶` while it runs; `● live` and the rows it printed for a cell running as a stream; `output hidden` for a hidden output, and which rows show for one scrolled; `×` before an error; an output's grid entered by `OUTPUT` and a green bar, its pointer and selection in reverse video as on a sheet; an output sent to a sheet in italic, with `Output of files` on the context line; a problem nu finds in the cell being written curly-underlined, in words on the context line with the caret on it |103103 | A table's header row | Bold and underlined, when the table styles its header; `Table Sales, column Amount` on the context line |104104 | Pivot table results | Their headings (`SUM of Units`, `Grand Total`), and a note in words when an edit is refused |105105 | Protected ranges | A question in words before an edit (`A1:B2 is protected.`) |
M docs/files/README.md +27 -2
@@ -27,9 +27,10 @@ it back in its format.
2727 | Lotus 1-2-3 `.wk1`, `.wks` | Numbers, labels with their alignment, formats, column widths, formulas translated (references, operators, `@SUM`, `@AVG`, `@IF`, `@ROUND`, `@PMT` and 60 more) or kept as values | |2828 | JSON `.json`, `.ndjson`, `.jsonl` | A list of records (or records one after another, as NDJSON): keys become the header row, numbers, booleans and text keep their types, nested lists and records are their text | The sheet shown as a list of records named by its first row, numbers as numbers |2929 | Nushell `.nuon` | A nushell table with its types: file sizes, durations and dates become numbers in the Size, Duration and Date time formats; see [Nushell types](../nushell/types.md) | The sheet shown as a nushell table, first row as column names, types kept by the cells' formats |30+| Web page `.html` | | The sheet shown as a page in 012's look, for someone without 012: see [Web pages](#web-pages) |3031 31-CSV, TSV, JSON and NUON downloads hold the rows a filter shows, as32-Sheets copies a filtered range; XLSX keeps every row, the hidden ones32+CSV, TSV, JSON, NUON and HTML downloads hold the rows a filter shows,33+as Sheets copies a filtered range; XLSX keeps every row, the hidden ones3334 hidden.3435 3536 Formats other than XLSX import as one sheet named after the file (or the
@@ -66,6 +67,30 @@ the context line says how many rows were left out, e.g. `only the first
6667 Data past the grid's edges is left out the same way. WK1 files keep their6768 own 8,192 by 256. See [Bounds of support](../contributing/limits.md#imports) for speeds.6869 70+## Web pages71+72+A web page download is one `.html` file that needs nothing else: its73+fonts (IBM Plex Mono), styles, charts and a few lines of script are in74+it, so it opens offline and can be mailed or put on any web server. It75+draws the sheet as 012 does: column letters and row numbers, each cell's76+text as the grid shows it at its column's width, with its bold, italic,77+alignment, wrapping, borders, merges, row heights, notes (the `▝` mark,78+the note as its tooltip), tables' header rows and bands, and what79+conditional formats and validation show (fills, color scales, data80+bars, icons, checkboxes, dropdown marks). Charts float over the cells81+at their corner, in their frames, drawn as SVG: shapes rather than82+pixels, sharp at any zoom. The colors are the 16 ANSI colors of 012's83+reference palettes, dark or light as the reader's system prefers.84+85+Clicking a cell, or moving with the arrow keys, puts the pointer on it:86+the name box shows its address and the formula bar what was typed in87+it, a formula rather than its value. A page draws at most 200,00088+cells, blank ones included, and says on standard error or the context89+line how many rows it left out.90+91+`012 export` also writes a range as a page, or one chart alone with92+`--chart` ([Scripts](scripts.md#export)).93+6994 ## More7095 7196 | Page | For |
M docs/files/following.md +9 -2
M docs/files/scripts.md +29 -6
@@ -6,7 +6,8 @@ sidebar_position: 6
66 # Scripts77 88 Four commands read and change a `.012` workbook without the screen, for9-shell scripts, cron jobs, Makefiles and nushell pipelines:9+shell scripts, cron jobs, Makefiles, nushell pipelines and10+[agents](../agents/README.md), which also have `012 describe`:1011 1112 ```sh1213 012 get budget.012 B7 # a cell's value, as the sheet shows it
@@ -97,6 +98,18 @@ An entry a rule only marks invalid is set, with a warning on standard
9798 error. An input that starts with `--` (a flag's shape) comes after `--`:9899 `012 set budget.012 -- A1 --`.99100 101+`--dry-run` checks the entries the same way but saves nothing, and102+prints what would change as [`012 diff`](git.md#012-diff) would:103+104+```105+$ 012 set budget.012 B7 '=SUM(A1:A6)' B8 1200 --dry-run106+Sheet1!B7 input "=SUM(A1:A5)" → "=SUM(A1:A6)"107+Sheet1!B8 input + 1200108+```109+110+`--format json` writes the result, the changes as records, instead111+([JSON output](../reference/json.md#set)).112+100113 ## recalc101114 102115 `012 recalc file` recomputes every formula, saves the file (leaving it
@@ -109,14 +122,24 @@ Q3!D2 #N/A JEV functions need --jev and an API key to be answered
109122 ```110123 111124 It exits 1 when any cell shows an error or a formula reads its own cell,112-so `012 recalc budget.012 && deploy` stops on a broken sheet.125+so `012 recalc budget.012 && deploy` stops on a broken sheet. `--format126+json` writes the list as [JSON](../reference/json.md#recalc).113127 114128 ## export115129 116130 `012 export file out [ref]` writes the workbook in another format, as117131 File > Download does: the format by `out`'s extension or `--format`118-(`csv`, `tsv`, `xlsx`, `sqlite`, `json`, `nuon`). XLSX gets every sheet;119-the others get the sheet shown, or `ref`'s range or sheet. SQLite writes132+(`csv`, `tsv`, `xlsx`, `sqlite`, `json`, `nuon`, `html`). XLSX gets every133+sheet; the others get the sheet shown, or `ref`'s range or sheet. A134+[web page](README.md#web-pages) of a range draws the charts whose corner135+is in it; `--chart` writes one chart alone, found by its number on the136+sheet (1 for the first) or its title:137+138+```sh139+012 export budget.012 q3.html 'Q3 plan'!A1:F20140+012 export budget.012 spending.html Q3 --chart 'Spending by month'141+```142+ SQLite writes120143 a table named by `--table`, replacing one of that name. Formulas are121144 written as their values where the format has no formulas, and a note on122145 standard error says how many. CSV, TSV, JSON and NUON leave out the rows
@@ -150,5 +173,5 @@ things need more than the file:
150173 network, and show `#N/A` here unless `--jev` asks it, with the API key151174 from the environment, the credential store or `jev-api-key-command`.152175 153-`get`, `recalc` and `export` take these flags; `set` computes values only154-to check entries.176+`get`, `recalc`, `export` and `describe` take these flags; `set`177+computes values only to check entries.
M docs/formulas/README.md +19 -4
@@ -36,20 +36,35 @@ caret on the problem and says what's wrong on the context line, e.g.
3636 tighter than `^` as in Sheets and Excel, so `=-2^2` is 4. 1-2-3's `#AND#`,3737 `#OR#` and `#NOT#` still work; `AND()`, `OR()` and `NOT()` are the Sheets way.3838 39+Numbers are binary floating point, as in Sheets and Excel, and follow40+Sheets where that shows:41+42+- Comparisons, and criteria such as `COUNTIF`'s, look at the 1543+ significant digits a cell shows, so `=0.1+0.2=0.3` is TRUE. A44+ difference itself keeps every digit: `=0.1+0.2-0.3` is 5.551E-1745+ ([decimal arithmetic](decimal.md) makes it 0).46+- A number written in a formula keeps 15 significant digits:47+ `=123456789012345678` is 123456789012345000.48+- A negative number has odd roots: `=(-8)^(1/3)` and `=POWER(-8, 1/3)`49+ are -2; other fractional powers of it are `#NUM!`.50+3951 ## Values and errors4052 4153 Text in arithmetic is `#VALUE!` unless it reads as a number (`="3"*2` is 6);42-blanks count as 0 or empty text. Aggregates such as `SUM` over a range skip43-text. Errors use Sheets' codes:54+blanks count as 0 or empty text. A condition (`IF`, `IFS`, `AND`, `OR`,55+`NOT`) also reads the text `TRUE` or `FALSE`, and empty text as FALSE, so56+`=IF("TRUE", 1, 2)` is 1. Aggregates such as `SUM` over a range skip57+text; `COUNT` skips errors too and `COUNTA` counts them, where the others58+give the first error in the range. Errors use Sheets' codes:4459 4560 | Error | Meaning |4661 |---|---|4762 | `#DIV/0!` | division by zero |4863 | `#VALUE!` | the wrong kind of value, e.g. text in arithmetic |4964 | `#NAME?` | an unknown name |50-| `#REF!` | a reference to deleted cells, or a circular reference: every cell of the cycle, even one whose formula catches errors (`IFERROR`) or skips them (`COUNTIF`), as in Sheets |65+| `#REF!` | a reference to deleted cells, or a circular reference: every cell of the cycle, even one whose formula catches errors (`IFERROR`) or skips them (`COUNTIF`), and one reached only through an `IF` branch not taken or a part of a range the formula doesn't read (`INDEX`, `VLOOKUP`), as in Sheets |5166 | `#N/A` | not available, e.g. a lookup found nothing |52-| `#NUM!` | a number out of range, e.g. `SQRT(-1)` |67+| `#NUM!` | a number out of range, e.g. `SQRT(-1)`, or a position outside what `CHOOSE`, `INDEX` or `MID` reads from, as in Sheets (Excel says `#VALUE!` or `#REF!`) |5368 5469 Error cells are red with a curly underline, and the context line explains the5570 active cell's error and where it came from, e.g.
M docs/formulas/arrays.md +5 -1
M docs/formulas/decimal.md +3 -1
A docs/media/notebook-grid.png +0 -0

Binary file.

M docs/media/notebook.gif +0 -0

Binary file.

M docs/media/nu-recipe.gif +0 -0

Binary file.

M docs/nushell/cookbook.md +5 -4
@@ -20,15 +20,16 @@ Money written as text (`"$2,252.50"`) becomes numbers in nushell, and a
2020 second cell totals it by region, sent to a sheet with a chart that2121 follows it.2222 23-![Nushell turns a CSV's money text into numbers, a second cell totals it by region, and its output, sent to a sheet, feeds a column chart](../media/nu-recipe.gif)23+![Nushell turns a CSV's money text into numbers, a second cell totals it by region, and Insert > Chart on its output's grid sends it to a sheet and charts it there](../media/nu-recipe.gif)2424 2525 ```nu2626 sales = open sales.csv | update Revenue { str replace -ar '[$,]' '' | into float }2727 totals = $sales | group-by Region --to-table | update items { get Revenue | math sum } | rename Region Revenue2828 ```2929 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` to30+To chart it, Enter on `totals`'s output, then **Insert > Chart**: the31+output goes to a new sheet named `totals` and the chart goes beside it32+([Outputs as grids](notebooks.md#outputs-as-grids)). Edit `sales` to3233 read another file and run it: `totals` shows `stale` until it runs too3334 (at once in a [reactive notebook](notebooks.md#stale-outputs-and-reactive-notebooks)),3435 and then the sheet and the chart follow.
@@ -89,7 +90,7 @@ http get https://api.github.com/repos/nushell/nushell/issues | select number tit
8990 Sort by comments, filter by author, or make a pivot table of issues by9091 author, in the sheet. In a notebook, the same pipeline without9192 `| 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+Enter on its output works in it as a grid, to sort, filter and chart, and9394 `nu-timeout` stops a request that hangs.9495 9596 Nushell: [`http get`](https://www.nushell.sh/commands/docs/http_get.html),
M docs/nushell/notebooks.md +66 -12
@@ -16,7 +16,7 @@ files = ls | where type == file
1616 $files | where size > 1kb | sort-by size --reverse1717 ```1818 19-![A notebook: a cell reads a CSV as sales, a second reads it as $sales, its output is sent to a sheet and summed there, and with the notebook reactive, editing sales runs both again and the sum follows](../media/notebook.gif)19+![A notebook: a cell reads a CSV as sales, a second reads it as $sales, its output is a grid to select in and is sent to a sheet and summed there, and with the notebook reactive, editing sales runs both again and the sum follows](../media/notebook.gif)2020 2121 Open one from a shell with `012 nu`, or from nushell with `sheet nu`2222 (`sheet` comes from 012's nushell module: [Install the `sheet`
@@ -50,9 +50,9 @@ runs it at the right, its output under it, and note cells drawn as text:
5050 ▌ [2]: │ big = $files | where size > 1kb │ ▶5151 ▌ │ | sort-by size --reverse │5252 ▌ ╰────────────────────────────────────────────────────────────╯53-▌ Out[2]: name size54-▌ README.md 9.8 kB55-▌ 012 4.2 kB53+▌ Out[2]: name size54+▌ 1 README.md 9.8 kB55+▌ 2 012 4.2 kB5656 ```5757 5858 The prompt says how many runs came before this one (`[2]:`, `[*]:` while
@@ -87,8 +87,8 @@ Outputs are drawn by what they are, with values formatted as cells
8787 8888 | Output | Shows |8989 |---|---|90-| A table (a list of records) | Its columns fitted to their values, numbers right-aligned, under its header |91-| A record | Its fields, one a line: `key value` |90+| A table (a list of records) | 012's grid ([Outputs as grids](#outputs-as-grids)): its columns headed by their names and fitted to their values, its rows numbered from 1 |91+| A record | The same grid of two columns, `field` and `value`, a field a row |9292 | A list | Its items, numbered from 0, as nushell numbers them |9393 | Text | Its lines, wrapped |9494 | A value | As a cell shows it: `4.2 kB`, `9/27/2026 11:27:31` |
@@ -116,11 +116,65 @@ stateDiagram-v2
116116 hidden --> window: o117117 ```118118 119-**Enter** on an output, or a double click, opens it full-screen: arrows120-(or `h` `j` `k` `l`) move, `s` sorts by the pointer's column and `S` in121-descending order (again for the output's own order), `/` keeps the rows122-holding what's typed, and Esc (or `◀ Back`) goes back. The output itself123-doesn't change.119+**Enter** on any other output, or a double click, opens it full-screen,120+its lines scrolled with the arrows; Esc (or `◀ Back`) goes back.121+122+### Outputs as grids123+124+A table or a record is drawn as 012's own grid, the one a sheet has:125+the values are the cells [sending it to a sheet](#send-to-a-sheet)126+makes, each in the format of its type (sizes as `4.2 kB`, durations,127+dates), right-aligned numbers, fitted columns and the grid's row128+numbers, with the table's column names where a sheet has letters.129+130+**Enter** on the output, or a click in it, works in it (the mode131+indicator says `OUTPUT`, and the bar left of it turns green, as for a132+cell edited): an active cell moves with the arrows, and the grid's keys,133+menus and mouse work on it as on a sheet, in its window:134+135+![An output worked as a grid: its column of regions selected, the status line counting it](../media/notebook-grid.png)136+137+- Shift+arrows, Ctrl+A or a drag select a range, and the status line138+ shows its Sum, Avg and Count; Ctrl+C copies it, as TSV to the system139+ clipboard and with its formats for Ctrl+V on a sheet.140+- **Data > Sort sheet** (or the column's right-click menu) sorts by the141+ active column, **Data > Create a filter** puts `▾` on each column's142+ name, and Alt+Down (or a click on `▾`) opens the column's filter;143+ Ctrl+F finds.144+- Drag the right edge of a column's name, or **Format > Column width**,145+ to resize it; Shift+wheel scrolls a wide table sideways; the names146+ stay on top as the rows scroll.147+- Ctrl+Z undoes a sort, a filter or a width; typing, Del, paste and148+ formats are refused, as they'd change the output: `G` sends it to a149+ sheet, where its copy can change.150+- **Enter** shows the grid full-screen, where it all works the same;151+ **Esc** deselects, then goes back from full-screen, then back to the152+ notebook.153+154+```mermaid155+stateDiagram-v2156+ selected: output selected (NOTEBOOK)157+ window: its grid, in its window (OUTPUT)158+ full: its grid, full-screen (OUTPUT)159+ selected --> window: Enter, a click in it160+ window --> full: Enter, a double click161+ full --> window: Esc162+ window --> selected: Esc163+```164+165+Sorting and filtering act on the grid's copy: the output, what later166+cells read as `$name`, doesn't change, and running the cell again167+draws its new output afresh.168+169+**Insert > Chart**, **Data > Pivot table** and the frequency table170+(Alt+Shift+F) on the grid make them where charts and pivot tables live,171+on a sheet: the output is [sent to a sheet](#send-to-a-sheet) first (a new172+one named after the cell, unless it's on one already), and the command173+runs there on the columns selected in the grid, every row under the174+header. A chart drawn under the output would have to squeeze into the175+notebook's column and scroll with the cells; on the sheet it has room,176+its editor, images where the terminal draws them, and it follows the177+cell's next run, as the region it charts does.124178 125179 Note cells are Markdown: headings, **bold**, *italic*, `code`, links (the126180 terminal opens them), lists and quotes. They're drawn as text, without a
@@ -154,7 +208,7 @@ delete, copy, cut, move, make notes or code, hide or clear outputs.
154208 | Up, Down, `j`, `k` | Move between cells, stopping at each output; on an output, scroll its window first |155209 | Shift+Up, Shift+Down, `K`, `J` | Select the cells passed over too |156210 | Home, End, PgUp, PgDn | The first cell, the last, a screen up or down |157-| Enter | Edit the cell; on an output, open it full-screen |211+| Enter | Edit the cell; on a table or record output, work in its grid; on another, open it full-screen |158212 | Shift+Enter | Run the cells and select the next, adding one at the end |159213 | Ctrl+Enter, `r` | Run the cells, staying on them |160214 | Alt+Enter | Run the cells and add a code cell under them |
M docs/reference/README.md +1 -0
M docs/reference/_category_.json +1 -1
M docs/reference/command-line.md +14 -6
@@ -25,18 +25,21 @@ The flags are the options' flags, listed in [Configuration](config.md#options).
2525 | Command | Does |2626 |---|---|2727 | `012 get file.012 [ref]` | Writes a cell's value, or a range or sheet as a table: [Scripts](../files/scripts.md#get) |28-| `012 set file.012 ref input [ref input ...]` | Types entries into cells and saves: [Scripts](../files/scripts.md#set) |28+| `012 set file.012 ref input [ref input ...]` | Types entries into cells and saves, or with `--dry-run` prints the change: [Scripts](../files/scripts.md#set) |2929 | `012 recalc file.012` | Recalculates, saves and lists the cells showing errors: [Scripts](../files/scripts.md#recalc) |3030 | `012 export file.012 out [ref]` | Writes the workbook, a sheet or a range in another format: [Scripts](../files/scripts.md#export) |31+| `012 describe file.012` | Lists the sheets and what's on them: [Agents](../agents/README.md#with-a-shell) |32+| `012 mcp file.012` | Serves the workbook to MCP hosts over standard input and output: [MCP server](../agents/mcp.md) |3133 | `012 diff a.012 b.012` | Lists what changed, cell by cell: [Diff and merge in git](../files/git.md#012-diff) |3234 | `012 diff --textconv file.012` | Writes a workbook as lines, for git's textconv: [Diff and merge in git](../files/git.md#git) |3335 | `012 merge-driver base ours theirs [path]` | Merges theirs into ours, for git: [Diff and merge in git](../files/git.md#merging) |3436 | `012 nu --module`, `012 nu --install-module [--force] [path]` | Prints or installs the nushell module: [Nushell](../nushell/README.md#install-the-sheet-command) |37+| `012 agent --skill`, `012 agent --install-skill [--force] [dir]` | Prints or installs the Claude Code skill: [Agents](../agents/README.md#the-claude-code-skill) |3538 | `012 config [path\|edit\|default\|themes\|set-key\|delete-key]` | The settings: [Configuration](config.md#commands) |36-| `012 version` | Prints the version |39+| `012 version [--format text\|json\|nuon]` | Prints the version |3740 38-`get`, `set`, `recalc`, `export`, `diff` and `merge-driver` take their39-flags anywhere after the command's name, and `--help` prints their41+`get`, `set`, `recalc`, `export`, `describe`, `mcp`, `diff`,42+`merge-driver` and `agent` take their flags anywhere after the command's name, and `--help` prints their4043 usage. `--` ends the flags, so what follows is taken as it is4144 (`012 set book.012 -- A1 --`), and an argument such as `-5` is never a4245 flag.
@@ -47,10 +50,15 @@ flag.
4750 | `--input` | `get` | What was typed (a formula) rather than its value |4851 | `--no-header` | `get` | JSON and NUON columns named by their letters, the first row a record |4952 | `--force` | `set` | Sets cells in protected ranges |53+| `--dry-run` | `set` | Prints what would change, as `012 diff` would, and saves nothing |54+| `--format text\|json\|nuon` | `set`, `recalc`, `describe`, `merge-driver`, `version` | The result as text, or as [JSON or NUON](json.md) |55+| `--report json\|nuon` | `export` | Writes what was exported as [JSON or NUON](json.md#export) |5056 | `--format kind`, `--table name` | `export` | The format when the file's extension doesn't say; SQLite's table |51-| `--notebooks` | `get`, `recalc`, `export` | Runs the notebooks' cells first, when the file is trusted here |57+| `--chart n\|title` | `export` | One chart of the sheet as a web page, by its number or title |58+| `--notebooks` | `get`, `recalc`, `export`, `describe` | Runs the notebooks' cells first, when the file is trusted here |5259 | `--trust` | with `--notebooks` | Runs the cells of a file saved on another computer |53-| `--jev` | `get`, `recalc`, `export` | Asks JEV for the JEV functions' answers first |60+| `--read-only`, `--force`, `--notebooks`, `--jev` | `mcp` | The tools offered and what they may do: [MCP server](../agents/mcp.md#flags) |61+| `--jev` | `get`, `recalc`, `export`, `describe` | Asks JEV for the JEV functions' answers first |5462 | `--format text\|json\|nuon` | `diff` | The form of the changes; text by default |5563 | `--color auto\|always\|never` | `diff` | Colors the text; auto colors on a terminal or git's pager unless `NO_COLOR` is set |5664
M docs/reference/functions.md +11 -11
@@ -20,20 +20,20 @@ Aliases: `AVG` for `AVERAGE`.
2020 | `ABS(value)` | Absolute value |2121 | `AND(logical1, [logical2, ...])` | TRUE if all arguments are true |2222 | `AVERAGE(value1, [value2, ...])` | Average of numbers, ignoring text |23-| `COUNT(value1, [value2, ...])` | Count of numeric values |24-| `COUNTA(value1, [value2, ...])` | Count of non-empty values |23+| `COUNT(value1, [value2, ...])` | Count of numeric values, skipping errors |24+| `COUNTA(value1, [value2, ...])` | Count of non-empty values, errors included |2525 | `FALSE()` | The logical value FALSE |2626 | `IF(condition, value_if_true, [value_if_false])` | Choose a value by a condition |27-| `IFERROR(value, [value_if_error])` | A fallback when a value is an error |27+| `IFERROR(value, [value_if_error])` | A fallback when a value is an error; blank without one |2828 | `INT(value)` | Round down to the nearest integer |2929 | `MAX(value1, [value2, ...])` | Largest number |3030 | `MIN(value1, [value2, ...])` | Smallest number |31-| `MOD(dividend, divisor)` | Remainder, with the sign of the divisor |31+| `MOD(dividend, divisor)` | Remainder, with the sign of the divisor: MOD(0.3, 0.1) is 0.1 as in Excel, where Sheets gives -5.55E-17 |3232 | `NA()` | The #N/A error |3333 | `NOT(logical)` | The opposite of a logical value |3434 | `OR(logical1, [logical2, ...])` | TRUE if any argument is true |3535 | `PI()` | The number pi |36-| `ROUND(value, [places])` | Round to a number of decimal places, halves away from zero |36+| `ROUND(value, [places])` | Round to a number of decimal places, halves away from zero, on the digits a cell shows: ROUND(1.5, 14) is 1.5 |3737 | `SQRT(value)` | Square root |3838 | `SUM(value1, [value2, ...])` | Sum of numbers |3939 | `TRUE()` | The logical value TRUE |
@@ -48,7 +48,7 @@ Aliases: `AVG` for `AVERAGE`.
4848 | `LN(value)` | Natural logarithm |4949 | `LOG(value, [base])` | Logarithm, base 10 by default |5050 | `LOG10(value)` | Base-10 logarithm |51-| `POWER(base, exponent)` | A number raised to a power |51+| `POWER(base, exponent)` | A number raised to a power, odd roots of negatives included |5252 | `PRODUCT(factor1, [factor2, ...])` | Product of numbers |5353 | `QUOTIENT(dividend, divisor)` | Integer part of a division |5454 | `RAND()` | A random number from 0 up to 1, new on every change (recalculates on every change) |
@@ -58,7 +58,7 @@ Aliases: `AVG` for `AVERAGE`.
5858 | `SIGN(value)` | 1, 0 or -1 by the sign of a number |5959 | `SUMIF(range, criterion, [sum_range])` | Sum of the cells that meet a condition |6060 | `SUMIFS(sum_range, criteria_range1, criterion1, [criteria_range2, criterion2, ...])` | Sum of the cells that meet every condition |61-| `SUMPRODUCT(array1, [array2, ...])` | Sum of the products of matching entries |61+| `SUMPRODUCT(array1, [array2, ...])` | Sum of the products of matching entries, TRUE counting as 1 |6262 | `TRUNC(value, [places])` | Drop decimals past a number of places |6363 6464 ## Statistics
@@ -105,7 +105,7 @@ Aliases: `AVG` for `AVERAGE`.
105105 | `EXACT(string1, string2)` | TRUE if two texts are identical, case included |106106 | `FIND(search_for, text_to_search, [starting_at])` | Position of text, case-sensitive |107107 | `LEFT(string, [number_of_characters])` | The first characters of text |108-| `LEN(text)` | Number of characters in text |108+| `LEN(text)` | Number of characters in text: an emoji is one, where Sheets counts two |109109 | `LOWER(text)` | Text in lower case |110110 | `MID(string, starting_at, extract_length)` | Characters from the middle of text |111111 | `PROPER(text)` | Text with each word capitalized |
@@ -117,7 +117,7 @@ Aliases: `AVG` for `AVERAGE`.
117117 | `TEXT(number, format)` | A number as text in a format, e.g. "$#,##0.00" or "yyyy-mm-dd" |118118 | `TEXTJOIN(delimiter, ignore_empty, text1, [text2, ...])` | Join text with a delimiter |119119 | `TRIM(text)` | Text without leading, trailing and repeated spaces |120-| `UPPER(text)` | Text in upper case |120+| `UPPER(text)` | Text in upper case: ß is SS |121121 | `VALUE(text)` | Text as a number; dates and times too |122122 123123 ## Split and regular expressions
@@ -136,7 +136,7 @@ Aliases: `AVG` for `AVERAGE`.
136136 | `CHOOSE(index, choice1, [choice2, ...])` | The choice at a position |137137 | `COLUMNS(range)` | Number of columns in a range |138138 | `HLOOKUP(search_key, range, index, [is_sorted])` | Find a key in the first row and return a value from its column |139-| `INDEX(reference, [row], [column])` | The value at a row and column of a range |139+| `INDEX(reference, [row], [column])` | The value at a row and column of a range; row or column 0 for a whole column or row |140140 | `MATCH(search_key, range, [search_type])` | Position of a key in a row or column |141141 | `ROWS(range)` | Number of rows in a range |142142 | `VLOOKUP(search_key, range, index, [is_sorted])` | Find a key in the first column and return a value from its row |
@@ -164,7 +164,7 @@ Aliases: `AVG` for `AVERAGE`.
164164 | `BYCOL(array_or_range, LAMBDA)` | Each column of an array passed to a LAMBDA, one value per column |165165 | `BYROW(array_or_range, LAMBDA)` | Each row of an array passed to a LAMBDA, one value per row |166166 | `LAMBDA([name, ...], formula_expression)` | A function of names, called with values: LAMBDA(x, x*2)(3) |167-| `LET(name1, value_expression1, [name2, value_expression2, ...], formula_expression)` | Name values for use in a formula |167+| `LET(name1, value_expression1, [name2, value_expression2, ...], formula_expression)` | Name values for use in a formula; an error counts only where its name is used |168168 | `MAKEARRAY(rows, columns, LAMBDA)` | An array of a size, each entry a LAMBDA of its row and column |169169 | `MAP(array1, [array2, ...], LAMBDA)` | Each entry of arrays passed to a LAMBDA |170170 | `REDUCE(initial_value, array_or_range, LAMBDA)` | An array folded into one value by a LAMBDA of the total so far and each entry |
A docs/reference/json.md +169 -0
@@ -0,0 +1,169 @@
1+---2+title: "JSON output"3+sidebar_position: 74+---5+6+# JSON output7+8+Commands without the screen write their results as JSON with9+`--format json`, or as NUON (the same values, as nushell reads them)10+with `--format nuon`; `012 export` writes to a file, so its result11+comes with `--report json`. The schemas below are stable: a later 01212+may add fields, but never renames or removes one, or changes its type.13+Errors are not JSON: they go to standard error as text, with the exit14+statuses in [Command line](command-line.md#exit-status).15+16+## get17+18+`012 get file ref --format json` writes a cell's value alone (a number,19+a string, `true`, `null` for a blank cell), or a range as a list of20+records named by its first row (`--no-header`: by column letters), as21+[Scripts](../files/scripts.md#get) describes. Dates are strings in ISO22+8601, and in NUON dates, file sizes and durations keep their types.23+24+## set25+26+```json27+{28+ "file": "book.012",29+ "saved": true,30+ "changes": [31+ {"kind": "cell", "sheet": "Sheet1", "item": "B7", "field": "input", "old": "12", "new": "=SUM(B1:B6)"}32+ ],33+ "warnings": ["Sheet1!C2: Enter a number between 1 and 10"]34+}35+```36+37+| Field | Is |38+|---|---|39+| `file` | The workbook's path, as given |40+| `saved` | Whether the file was written: false with `--dry-run` |41+| `changes` | What changed, as [`diff`](#diff) lists it |42+| `warnings` | Entries a validation rule marks invalid but lets in |43+44+## recalc45+46+```json47+{48+ "file": "book.012",49+ "errors": [50+ {"cell": "Q3!B7", "sheet": "Q3", "addr": "B7", "value": "#DIV/0!", "why": "Division by zero in B6/C6", "jev": false}51+ ],52+ "circular": false,53+ "notebook_failures": []54+}55+```56+57+`errors` are the formulas showing errors, sheet by sheet and row by58+row; `why` is what the screen's context line says, or `""`; `jev` is59+set for a JEV function's error that `--jev` would answer. `circular` is60+set when a formula reads its own cell. `notebook_failures` are the61+lines `--notebooks` reported for cells that failed. The exit status is62+1 when there are errors, as without `--format`.63+64+## describe65+66+```json67+{68+ "sheets": [69+ {70+ "name": "Sales", "kind": "sheet", "shown": true, "hidden": false,71+ "used": "A1:F9", "rows": 9, "cols": 6, "cells": 54, "formulas": 9, "errors": 0,72+ "header_row": 1, "columns": ["Date", "Region", "Units", "Price", "Total", "Share"],73+ "frozen": [1, 0], "filter": "",74+ "tables": [{"name": "Orders", "range": "A1:F9", "columns": ["Date", "Region", "Units", "Price", "Total", "Share"]}],75+ "regions": [{"name": "files", "kind": "output", "range": "H1:J12"}],76+ "charts": [{"number": 1, "title": "Units by date", "type": "column", "data": "A1:C9", "at": "H2"}]77+ }78+ ],79+ "names": [{"name": "Rate", "range": "Sales!B12"}]80+}81+```82+83+| Field | Is |84+|---|---|85+| `kind` | `sheet`, `notebook` or `pivot` |86+| `shown`, `hidden` | The sheet shown when the file was saved; a hidden tab |87+| `used` | A1 to the last cell with contents, `""` for an empty sheet; `rows` and `cols` its size |88+| `cells`, `formulas`, `errors` | Cells with contents, formulas, and formulas showing errors; `formulas` and `errors` are -1 on sheets of over a million cells, which aren't counted |89+| `header_row`, `columns` | The row guessed to name the columns (1 for the first; 0 and `[]` when none) and its names, `""` for a blank cell |90+| `frozen` | Frozen rows and columns |91+| `filter` | The filtered range, or `""` |92+| `tables` | Named tables, header row included in `range` |93+| `regions` | Notebook outputs (`kind` `output`) and linked files (`linked`, with `file`) sent to the sheet, with the range their rows fill |94+| `charts` | Each chart's `number` (for `012 export --chart`), title (its type's name when it has none), `type`, `data` range and `at`, the cell under its top-left corner |95+| `pivot` | On a pivot table, `{"source": "Sales!A1:F9"}` |96+| `notebook_cells` | On a notebook, each cell: `number`, `kind` (`code` or `note`), `name` (its output's), `source`, and for code `state` (`ran`, `failed`, `not run`) and `error` |97+| `names` | Named ranges, `range` `#REF!` when its cells were deleted |98+99+## diff100+101+`012 diff a b --format json` writes a list of changes:102+103+| Field | Is |104+|---|---|105+| `kind` | `cell`, `sheet`, `region`, `table`, `layout` (another field of a sheet: widths, rules, charts), `name`, `macro`, `notebook` or `workbook` (its locale, its arithmetic) |106+| `sheet` | The sheet, by its name in the second workbook where it has one |107+| `item` | The cell, region, name, macro or field that changed |108+| `field` | What about it: for a cell `input`, `value`, `format` or `note`; for a sheet `added`, `removed`, `renamed` or `moved` |109+| `old`, `new` | Its values, `null` where it wasn't or isn't there |110+111+See [Diff and merge in git](../files/git.md#012-diff).112+113+## export114+115+`012 export file out --report json`:116+117+```json118+{"file": "out.csv", "format": "csv", "rows": 9, "notes": ["1 formula saved as values"]}119+```120+121+## merge-driver122+123+`012 merge-driver base ours theirs --format json` writes124+`{"conflicts": [...]}`, each with `where`, `field`, and the `base`,125+`ours` and `theirs` versions as text (`""` where it isn't there), and126+`what` for a conflict about a whole sheet. The merge and exit status127+are as without it.128+129+## MCP tools130+131+The [MCP server](../agents/mcp.md)'s tools return these, as structured132+content with the same JSON as text beside it. `describe` returns133+[describe's](#describe) schema, `list_errors` recalc's `errors` and134+`circular`.135+136+`read_range`, and the range resources:137+138+```json139+{140+ "range": "Sales!A1:C3", "rows": 3, "cols": 3,141+ "values": [["Region", "Units", "Price"], ["North", 3, 12.5], ["South", 5, null]],142+ "text": [["Region", "Units", "Price"], ["North", "3", "$12.50"], ["South", "5", ""]],143+ "formulas": {"C3": "=IF(B3>4, \"\", 9.75)"},144+ "truncated": false145+}146+```147+148+`values` are typed as [`get`](#get) types one cell (blank is `null`, an149+error its text); `text` comes only when asked for; `truncated` is set150+when the range held more cells than `max_cells`, and `rows` says how151+many came back.152+153+Writes (`write_cells`, `apply_operations`, `sort`, `filter`) return154+`{"saved", "changes", "warnings"}` as [`set`](#set) does, `saved` false155+for a dry run or a change that changed nothing; `create_chart` adds156+`"chart": {"sheet", "number", "title"}` and `create_pivot` `"sheet"`,157+the pivot's.158+159+| Tool | Returns |160+|---|---|161+| `evaluate` | `cell` where it was computed, `value`, `text` as shown, `error` explaining an error value, and `spill`, a `read_range` result, when the formula spilled |162+| `find` | `matches`, each `cell`, `text` and `input`, the first `limit` of them, and `total` |163+| `run_notebook_cell` | `notebook`, `cell`, `name`, `state` (`ran` or `failed`), `error`, `output` as NUON and `cut` when the output was longer than 64 KB |164+165+## version166+167+```json168+{"version": "v0.9.0", "go": "go1.27.1", "os": "darwin", "arch": "arm64"}169+```
M docs/reference/keys.md +15 -6
@@ -147,7 +147,7 @@ on a sheet, `!` starts an entry as any character does.
147147 | Up, Down, `j`, `k`, Home, End, PgUp, PgDn | Move between cells and their outputs; on an output, Up and Down scroll its window first |148148 | Shift+Up, Shift+Down, `K`, `J` | Select the cells passed over too, to run, delete, copy or move together |149149 | Alt+Up, Alt+Down, Ctrl+Shift+Up, Ctrl+Shift+Down | Move the selected cells up or down |150-| Enter | Edit the cell; on an output, open it full-screen |150+| Enter | Edit the cell; on a table or record output, work in its grid; on another output, open it full-screen |151151 | Shift+Enter, Ctrl+Enter, `r`, Alt+Enter | Run the cells and select the next; run them in place (`r` too); run them and add a cell under them |152152 | F9 | Run every cell |153153 | `a`, `b`, `!` | Add a code cell above, below; add one below and edit it |
@@ -168,11 +168,19 @@ on a sheet, `!` starts an entry as any character does.
168168 | Up, Down, Home, End, Ctrl+A, Ctrl+E | Move by the lines on screen; the start, the end of the line |169169 | Word keys | As [anywhere text is edited](#entering-data); Ctrl+U deletes to the start of the line, not the cell |170170 171-| Key | On an output full-screen |171+| Key | In a table's or record's output ([its grid](../nushell/notebooks.md#outputs-as-grids)) |172172 |---|---|173-| Arrows, `h`, `j`, `k`, `l`, PgUp, PgDn, `g`, `G` | Move |174-| `s`, `S` | Sort by the pointer's column, A to Z or Z to A; again for the output's order |175-| `/` | Keep the rows holding what's typed; Esc clears it |173+| Arrows, Shift+arrows, Ctrl+arrows, PgUp, PgDn, Ctrl+A | Move and select, as [on a sheet](#selecting); the status line shows Sum, Avg and Count |174+| Ctrl+C | Copy the selection, to paste on a sheet or elsewhere |175+| Ctrl+F | Find in the output |176+| Alt+Down | With a filter on (Data > Create a filter), the column's filter |177+| Ctrl+Z, Ctrl+Y | Undo, redo a sort, a filter or a column's width |178+| Enter | Show the grid full-screen |179+| Esc | Deselect; then back from full-screen, then back to the notebook |180+181+| Key | On any other output full-screen |182+|---|---|183+| Up, Down, `j`, `k`, PgUp, PgDn, `g`, `G` | Move |176184 | Esc, `q` | Back to the notebook |177185 178186 ## Keys the terminal has to tell apart
@@ -324,7 +332,8 @@ On a notebook's tab, as in JupyterLab:
324332 | Click a cell; Shift+click | Select it; select the cells between too |325333 | Click in a code cell's box; double-click a note | Edit it, the caret where you clicked |326334 | Click `▶` (`■` while it runs) | Run the cell (stop it) |327-| Click an output; double-click it | Select it; open it full-screen |335+| Click an output; double-click it | Select it (in a table's or record's grid, the cell clicked, to work in it); open it full-screen |336+| Drag in an output's grid; drag its column header's right edge | Select cells; resize the column |328337 | Click left of an output | Hide it, or show it again |329338 | Wheel over an output's window | Scroll the output, then the notebook |330339 | Click a toolbar button | Run, stop, restart, run all, add, cut, copy, paste, or pick the cell's kind |
M e2e/jupyter_test.go +33 -0
@@ -49,6 +49,39 @@ func (s *session) codes() []string {
4949 return out5050 }5151 52+// An output is 012's grid: Enter works in it, Shift+arrows select,53+// Ctrl+C copies, the palette's sort sorts it, a click moves the active54+// cell, Enter shows it full-screen and Esc goes back a level at a time.55+func TestNotebookOutputGrid(t *testing.T) {56+ s := startWith(t, options{cols: 100, rows: 40, startsOn: "EDIT", env: fakeNu}, "nu")57+ clip := s.watchClipboard()58+ s.keys("files = ls", "<ctrl+enter>")59+ s.waitFor("Out[1]:")60+ s.keys("<esc>", "<down>", "<enter>")61+ s.waitFor("OUTPUT")62+ s.keys("<shift+down>", "<shift+right>", "<ctrl+c>")63+ s.eventually("the rows copied", func() bool { return clip.get() == "012\tfile\nCLAUDE.md\tfile" })64+ s.waitFor("name to type, rows 1 to 2")65+ s.keys("<esc>", "<right>", "<right>", "<ctrl+k>", "Sort sheet Z to A", "<enter>")66+ s.eventually("sorted by size", func() bool {67+ _, first := s.rowOf("README.md")68+ _, last := s.rowOf("go.mod")69+ return first < last && strings.Contains(s.line(first), " 1 README.md")70+ })71+ col, row := s.rowOf("demos")72+ s.leftClick(col+1, row, 0)73+ s.keys("<ctrl+c>")74+ s.eventually("the cell clicked copied", func() bool { return clip.get() == "demos" })75+ s.keys("<enter>")76+ s.waitFor("files [1], full-screen")77+ s.keys("<esc>")78+ s.eventually("back in the window", func() bool {79+ return !strings.Contains(s.screen(), "full-screen") || strings.Contains(s.screen(), "[1]:")80+ })81+ s.keys("<esc>")82+ s.waitFor("NOTEBOOK")83+}84+5285 func TestNotebookMouseAndKeys(t *testing.T) {5386 s := startWith(t, options{cols: 100, rows: 40, startsOn: "EDIT", env: fakeNu}, "nu")5487 s.keys("files = ls", "<esc>")
M e2e/screennotebook_test.go +20 -6
@@ -10,10 +10,12 @@ import (
1010 // Golden screens for notebooks: cells with a note and table outputs, a1111 // cell edited with a long pipeline wrapped (at 80 and 60 columns), a1212 // failure, nu's highlighting and a problem nu found, a cell running and13-// one waiting, a cell running as a stream, stale outputs, an output14-// full-screen, and an output sent to a sheet. Each is recorded on a light terminal and in the15-// high-contrast theme too. nu is testdata/nu/nu, which answers what the16-// screens run, and what the code editor asks, with fixed outputs.13+// one waiting, a cell running as a stream, stale outputs, an output's14+// grid entered with a range selected, its filter open, and full-screen,15+// and an output sent to a sheet. Each is recorded on a light terminal16+// and in the high-contrast theme too. nu is testdata/nu/nu, which17+// answers what the screens run, and what the code editor asks, with18+// fixed outputs.1719 1820 // fakeNu puts the stand-in nu first on the PATH.1921 var fakeNu = func() []string {
@@ -91,8 +93,20 @@ var notebookScreens = []screen{
9193 }},9294 {name: "notebook-output", setup: func(s *session) {9395 filesNotebook(s)94- s.keys("<up>", "<up>", "<up>", "<enter>")95- s.waitFor("full-screen")96+ s.keys("<up>", "<up>", "<up>", "<enter>", "<enter>")97+ s.waitFor("◀ Back")98+ }},99+ {name: "notebook-grid", setup: func(s *session) {100+ filesNotebook(s)101+ s.keys("<up>", "<up>", "<up>", "<enter>", "<shift+down>", "<shift+right>", "<shift+right>")102+ s.waitFor("Count 6")103+ }},104+ {name: "notebook-grid-filter", setup: func(s *session) {105+ filesNotebook(s)106+ s.keys("<up>", "<up>", "<up>", "<enter>", "<ctrl+k>", "Create a filter", "<enter>")107+ s.waitFor("▾")108+ s.keys("<right>", "<alt+down>")109+ s.waitFor("Select all")96110 }},97111 {name: "notebook-nu-highlight", setup: func(s *session) {98112 filesNotebook(s)
M e2e/settings_test.go +2 -2
M e2e/testdata/screens/functions-light.html +1 -1
@@ -14,7 +14,7 @@
1414 <span style="color:var(--vt-palette-8)">│</span> AVERAGE<span style="color:var(--vt-palette-4);font-weight:bold">IF</span>(criteria_range, criterion, [average_range]) <span style="color:var(--vt-palette-0)">Average</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">the</span> <span style="color:var(--vt-palette-0)">cells</span> <span style="color:var(--vt-palette-0)">that</span> <span style="color:var(--vt-palette-0)">meet</span> <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="color:var(--vt-palette-8)">│</span> AVERAGE<span style="color:var(--vt-palette-4);font-weight:bold">IF</span>S(average_range, criteria_range1, criterion1, [c… <span style="color:var(--vt-palette-0)">Average</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">the</span> <span style="color:var(--vt-palette-0)">cells</span> <span style="color:var(--vt-palette-0)">that</span> <span style="color:var(--vt-palette-0)">meet</span> <span style="color:var(--vt-palette-0)">ev…</span> <span style="color:var(--vt-palette-8)">│</span>1616 <span style="color:var(--vt-palette-8)">│</span> JEV.CLASS<span style="color:var(--vt-palette-4);font-weight:bold">IF</span>Y(value, question, labels, [descriptions]) <span style="color:var(--vt-palette-0)">The</span> <span style="color:var(--vt-palette-0)">label</span> <span style="color:var(--vt-palette-0)">that</span> <span style="color:var(--vt-palette-0)">fits</span> <span style="color:var(--vt-palette-0)">best,</span> <span style="color:var(--vt-palette-0)">chosen</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">80</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">142</span> <span style="color:var(--vt-palette-8)">─┘</span>17+<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">81</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">142</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">14</span><span style="background:var(--vt-palette-7)"> </span>1919 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">15</span><span style="background:var(--vt-palette-7)"> </span>2020 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">16</span><span style="background:var(--vt-palette-7)"> </span>
M e2e/testdata/screens/functions.html +1 -1
@@ -14,7 +14,7 @@
1414 <span style="color:var(--vt-palette-8)">│</span> AVERAGE<span style="color:var(--vt-palette-3);font-weight:bold">IF</span>(criteria_range, criterion, [average_range]) <span style="color:var(--vt-palette-8)">Average</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">the</span> <span style="color:var(--vt-palette-8)">cells</span> <span style="color:var(--vt-palette-8)">that</span> <span style="color:var(--vt-palette-8)">meet</span> <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="color:var(--vt-palette-8)">│</span> AVERAGE<span style="color:var(--vt-palette-3);font-weight:bold">IF</span>S(average_range, criteria_range1, criterion1, [c… <span style="color:var(--vt-palette-8)">Average</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">the</span> <span style="color:var(--vt-palette-8)">cells</span> <span style="color:var(--vt-palette-8)">that</span> <span style="color:var(--vt-palette-8)">meet</span> <span style="color:var(--vt-palette-8)">ev…</span> <span style="color:var(--vt-palette-8)">│</span>1616 <span style="color:var(--vt-palette-8)">│</span> JEV.CLASS<span style="color:var(--vt-palette-3);font-weight:bold">IF</span>Y(value, question, labels, [descriptions]) <span style="color:var(--vt-palette-8)">The</span> <span style="color:var(--vt-palette-8)">label</span> <span style="color:var(--vt-palette-8)">that</span> <span style="color:var(--vt-palette-8)">fits</span> <span style="color:var(--vt-palette-8)">best,</span> <span style="color:var(--vt-palette-8)">chosen</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">80</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">142</span> <span style="color:var(--vt-palette-8)">─┘</span>17+<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">81</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">142</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>2020 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">16</span><span style="background:var(--vt-palette-8)"> </span>
M e2e/testdata/screens/menu-download.html +2 -2
@@ -12,8 +12,8 @@
1212 <span style="color:var(--vt-palette-8)">├─────────────────────┤│</span> SQLite database (.sqlite) <span style="color:var(--vt-palette-8)">│</span>1313 <span style="color:var(--vt-palette-8)">│</span> Quit <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+Q</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">││</span> JSON list of records (.json) <span style="color:var(--vt-palette-8)">│</span>1414 <span style="color:var(--vt-palette-8)">└─────────────────────┘│</span> Nushell table (.nuon) <span style="color:var(--vt-palette-8)">│</span>15-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└──────────────────────────────────┘</span>16-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span>15+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Web page (.html) <span style="color:var(--vt-palette-8)">│</span>16+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└──────────────────────────────────┘</span>1717 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>
M e2e/testdata/screens/notebook-cells-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>1919 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-cells-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-cells.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-error-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">failed</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>2626 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">lss</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">-a</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>
M e2e/testdata/screens/notebook-error-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3)">failed</span> <span style="color:var(--vt-palette-3)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>2626 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">lss</span> -a <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
M e2e/testdata/screens/notebook-error.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3)">failed</span> <span style="color:var(--vt-palette-3)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>2626 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-6)">lss</span> -a <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
A e2e/testdata/screens/notebook-grid-filter-high-contrast.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">FILTER</span><span style="background:#40e0ff"> </span>2+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">Files</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">What&#39;s</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">the</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">repo,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">from</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="color:#ffffff;background:#000000">.</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>9+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">▾</span><span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">type</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">▾</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">▾</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">┌─</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">Filter</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">type</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────┐</span><span style="background:#000000"> </span>12+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">If</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#3a3a3a">‹</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">None</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">›</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>13+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">├────────────────────────────────────┤</span><span style="background:#000000"> </span>14+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">›</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Search</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">values</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>15+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">├────────────────────────────────────┤</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">[x]</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">Select</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">all</span><span style="background:#40e0ff"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">[x]</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">1</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│──────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">si</span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">[x]</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>19+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────└───────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─┘──────────────────────────────╯</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>24+<span style="background:#000000"> </span>25+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>26+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>27+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>28+<span style="background:#000000"> </span>29+<span style="background:#000000"> </span>30+<span style="color:#959595;background:#1f1f1f">Type</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">to</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">the</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">values</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Space</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">check</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Tab</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">condition</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">apply</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">cancel</span><span style="background:#1f1f1f"> </span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-filter-light.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">FILTER</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">▾</span><span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">type</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">▾</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">▾</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span> 012 <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Filter</span> <span style="font-weight:bold">type</span> <span style="color:var(--vt-palette-8)">──────────────────────┐</span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">If</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">‹</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">None</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">›</span> <span style="color:var(--vt-palette-8)">│</span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos <span style="color:var(--vt-palette-8)">│</span> <span style="font-weight:bold">›</span> <span style="color:var(--vt-palette-0)">Search</span> <span style="color:var(--vt-palette-0)">values</span> <span style="color:var(--vt-palette-8)">│</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>16+ <span style="color:var(--vt-palette-8)">│</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">[x]</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">Select</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">all</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-8)">│</span>17+ <span style="color:var(--vt-palette-8)">╭──────────────────│</span> [x] dir <span style="color:var(--vt-palette-0)">1</span> <span style="color:var(--vt-palette-8)">│──────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> si<span style="color:var(--vt-palette-8)">│</span> [x] file <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────└───────────────────────────</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-8)">─┘──────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="color:var(--vt-palette-0)">Type</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">search</span> <span style="color:var(--vt-palette-0)">the</span> <span style="color:var(--vt-palette-0)">values</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Space</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">check</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Tab</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">condition</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">apply</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">cancel</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-filter.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">FILTER</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">▾</span><span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">type</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">▾</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">▾</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span> 012 <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Filter</span> <span style="font-weight:bold">type</span> <span style="color:var(--vt-palette-8)">──────────────────────┐</span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">If</span> <span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">‹</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">None</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">│</span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos <span style="color:var(--vt-palette-8)">│</span> <span style="font-weight:bold">›</span> <span style="color:var(--vt-palette-8)">Search</span> <span style="color:var(--vt-palette-8)">values</span> <span style="color:var(--vt-palette-8)">│</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>16+ <span style="color:var(--vt-palette-8)">│</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">[x]</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">Select</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">all</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-8)">│</span>17+ <span style="color:var(--vt-palette-8)">╭──────────────────│</span> [x] dir <span style="color:var(--vt-palette-8)">1</span> <span style="color:var(--vt-palette-8)">│──────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> si<span style="color:var(--vt-palette-8)">│</span> [x] file <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────└───────────────────────────</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">─┘──────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="color:var(--vt-palette-8)">Type</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">search</span> <span style="color:var(--vt-palette-8)">the</span> <span style="color:var(--vt-palette-8)">values</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Space</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">check</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Tab</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">condition</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">apply</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">cancel</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-high-contrast.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">OUTPUT</span><span style="background:#40e0ff"> </span>2+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Output</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+C</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">copy</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+F</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">find</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">full-screen</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">Files</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">What&#39;s</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">the</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">repo,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">from</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="color:#ffffff;background:#000000">.</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>9+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">type</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">size</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>11+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">file</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">4.2</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">kB</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>12+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">2</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">CLAUDE.md</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">file</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">1.0</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">kB</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>13+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>19+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>24+<span style="background:#000000"> </span>25+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>26+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>27+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>28+<span style="background:#000000"> </span>29+<span style="background:#000000"> </span>30+<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">name</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">to</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">size,</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">rows</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">1</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">to</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">2</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Sum</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">5200</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Avg</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">2600</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Count</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">6</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-light.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+ <span style="color:var(--vt-palette-0)">Output</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+C</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">copy</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+F</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">find</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">full-screen</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B16+17+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-0)">Sum</span> 5200 <span style="color:var(--vt-palette-0)">Avg</span> 2600 <span style="color:var(--vt-palette-0)">Count</span> 6</pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+ <span style="color:var(--vt-palette-8)">Output</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+C</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">copy</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+F</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">find</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">full-screen</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B16+17+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-8)">Sum</span> 5200 <span style="color:var(--vt-palette-8)">Avg</span> 2600 <span style="color:var(--vt-palette-8)">Count</span> 6</pre>\ No newline at end of file
M e2e/testdata/screens/notebook-nu-error-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2626 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sort-by</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;text-decoration:underline wavy #ff8080">--revrse</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-nu-error-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-error.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-highlight-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2626 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sort-by</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">--reverse</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000;font-style:italic">#</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000;font-style:italic">largest</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-nu-highlight-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">big</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> <span style="color:var(--vt-palette-5)">size</span> <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> --reverse <span style="color:var(--vt-palette-0);font-style:italic">#</span> <span style="color:var(--vt-palette-0);font-style:italic">largest</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-highlight.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">big</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> <span style="color:var(--vt-palette-5)">size</span> <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> --reverse <span style="color:var(--vt-palette-8);font-style:italic">#</span> <span style="color:var(--vt-palette-8);font-style:italic">largest</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-output-high-contrast.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">OUTPUT</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">◀</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Back</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">[1]</span><span style="color:#959595;background:#000000">,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">full-screen</span><span style="background:#000000"> </span>3-<span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">s</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sort</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">S</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">descending</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">/</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">filter</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span>4-<span style="background:#3a3a3a"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5-<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#000000"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Output</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Shift+arrows</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">select</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+C</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">copy</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+F</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">find</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span><span style="background:#000000"> </span>4+<span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5+<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1010 <span style="background:#000000"> </span>1111 <span style="background:#000000"> </span>1212 <span style="background:#000000"> </span>
M e2e/testdata/screens/notebook-output-light.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>22 ◀ Back <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="font-weight:bold">files</span> <span style="font-weight:bold">[1]</span><span style="color:var(--vt-palette-0)">,</span> <span style="color:var(--vt-palette-0)">full-screen</span>3-<span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-0)">[1]</span> <span style="color:var(--vt-palette-0)">5</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">s</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">sort</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">S</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">descending</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">filter</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5-<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span> CLAUDE.md file 1.0 kB7-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span> README.md file 9.8 kB8-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span> demos dir 3.1 kB9-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span> go.mod file 812 B3+ <span style="color:var(--vt-palette-0)">Output</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Shift+arrows</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">select</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+C</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">copy</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+F</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">find</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4+<span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB7+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB8+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB9+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1010 1111 1212
M e2e/testdata/screens/notebook-output.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>22 ◀ Back <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="font-weight:bold">files</span> <span style="font-weight:bold">[1]</span><span style="color:var(--vt-palette-8)">,</span> <span style="color:var(--vt-palette-8)">full-screen</span>3-<span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">[1]</span> <span style="color:var(--vt-palette-8)">5</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">s</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">sort</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">S</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">descending</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">filter</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5-<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span> CLAUDE.md file 1.0 kB7-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span> README.md file 9.8 kB8-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span> demos dir 3.1 kB9-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span> go.mod file 812 B3+ <span style="color:var(--vt-palette-8)">Output</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Shift+arrows</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">select</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+C</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">copy</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+F</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">find</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4+<span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB7+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB8+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB9+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1010 1111 1212
M e2e/testdata/screens/notebook-running-high-contrast.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>55 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>66 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>7-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>8-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1313 <span style="background:#000000"> </span>1414 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1515 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[4]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1616 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>17-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[4]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>18-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>19-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[4]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>19+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2121 <span style="background:#000000"> </span>2222 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">running</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>2323 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[*]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sleep</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">10min</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">■</span>
M e2e/testdata/screens/notebook-running-light.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>55 <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>66 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>7- <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>8- 012 file 4.2 kB9- CLAUDE.md file 1.0 kB10- README.md file 9.8 kB11- demos dir 3.1 kB12- go.mod file 812 B7+ <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>8+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB9+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB10+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1313 1414 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1515 <span style="color:var(--vt-palette-0)">[4]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1616 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>17- <span style="color:var(--vt-palette-0)">Out[4]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>18- 012 file 4.2 kB19- README.md file 9.8 kB20- demos dir 3.1 kB17+ <span style="color:var(--vt-palette-0)">Out[4]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>18+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB19+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB20+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2121 2222 <span style="color:var(--vt-palette-8)">╭────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">running</span> <span style="color:var(--vt-palette-8)">─╮</span>2323 <span style="color:var(--vt-palette-0)">[*]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-4)">sleep</span> <span style="color:var(--vt-palette-1)">10min</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">■</span>
M e2e/testdata/screens/notebook-running.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>55 <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>66 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>7- <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>8- 012 file 4.2 kB9- CLAUDE.md file 1.0 kB10- README.md file 9.8 kB11- demos dir 3.1 kB12- go.mod file 812 B7+ <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>8+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB9+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB10+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1313 1414 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1515 <span style="color:var(--vt-palette-8)">[4]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1616 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>17- <span style="color:var(--vt-palette-8)">Out[4]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>18- 012 file 4.2 kB19- README.md file 9.8 kB20- demos dir 3.1 kB17+ <span style="color:var(--vt-palette-8)">Out[4]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>18+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB19+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB20+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2121 2222 <span style="color:var(--vt-palette-8)">╭────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">running</span> <span style="color:var(--vt-palette-8)">─╮</span>2323 <span style="color:var(--vt-palette-8)">[*]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-6)">sleep</span> <span style="color:var(--vt-palette-3)">10min</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">■</span>
M e2e/testdata/screens/notebook-scroll-high-contrast.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">NOTEBOOK</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">table:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">columns</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">o</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">hide</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">O</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">whole</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">G</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sheet</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">table:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">columns</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">work</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">o</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">hide</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">O</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">whole</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">G</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sheet</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>66 <span style="background:#000000"> </span>77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1414 <span style="background:#000000"> </span>1515 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1..30</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">each</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">{</span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="color:#40e0ff;background:#000000">i</span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">{n:</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$i</span><span style="color:#ffffff;background:#000000">,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">square:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">(</span><span style="color:#ff80ff;background:#000000">$i</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">*</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$i</span><span style="color:#ffffff;background:#000000">)}}</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>18-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">n</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">square</span><span style="background:#000000"> </span>19-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">16</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">25</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">6</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">36</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">7</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">49</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">64</span><span style="background:#000000"> </span>24-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">81</span><span style="background:#000000"> </span>25-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">100</span><span style="background:#000000"> </span>26-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">11</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">121</span><span style="background:#000000"> </span>27-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">12</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">144</span><span style="background:#000000"> </span>28-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">169</span><span style="background:#000000"> </span>29-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">…</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">(O</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">shows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">all,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Enter</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">opens</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it)</span><span style="background:#000000"> </span>18+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">n</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">square</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>19+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">16</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">25</span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">6</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">6</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">36</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">7</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">7</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">49</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">8</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">64</span><span style="background:#000000"> </span>24+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">9</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">81</span><span style="background:#000000"> </span>25+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">10</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">100</span><span style="background:#000000"> </span>26+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">11</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">11</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">121</span><span style="background:#000000"> </span>27+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">12</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">12</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">144</span><span style="background:#000000"> </span>28+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">13</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">169</span><span style="background:#000000"> </span>29+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">…</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">(O</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">shows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">all,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Enter</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">works</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it)</span><span style="background:#000000"> </span>3030 <span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+K</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+/</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">shortcuts</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">F10</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-scroll-light.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3- <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">table:</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">rows,</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">columns</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">o</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">hide</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">O</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">whole</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">G</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">sheet</span>4- demos dir 3.1 kB5- go.mod file 812 B3+ <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">table:</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">rows,</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">columns</span> <span style="color:var(--vt-palette-8)">──────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">work</span> <span style="color:var(--vt-palette-0)">in</span> <span style="color:var(--vt-palette-0)">it</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">o</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">hide</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">O</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">whole</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">G</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">sheet</span>4+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B66 77 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- README.md file 9.8 kB13- demos dir 3.1 kB10+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1414 1515 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1616 <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-1)">1..30</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">each</span> {<span style="font-weight:bold">|</span><span style="color:var(--vt-palette-4)">i</span><span style="font-weight:bold">|</span> {n: <span style="color:var(--vt-palette-5)">$i</span>, square: (<span style="color:var(--vt-palette-5)">$i</span> <span style="font-weight:bold">*</span> <span style="color:var(--vt-palette-5)">$i</span>)}} <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1717 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>18-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">n</span> <span style="font-weight:bold;text-decoration:underline">square</span>19-<span style="color:var(--vt-palette-4)">▌</span> 4 1620-<span style="color:var(--vt-palette-4)">▌</span> 5 2521-<span style="color:var(--vt-palette-4)">▌</span> 6 3622-<span style="color:var(--vt-palette-4)">▌</span> 7 4923-<span style="color:var(--vt-palette-4)">▌</span> 8 6424-<span style="color:var(--vt-palette-4)">▌</span> 9 8125-<span style="color:var(--vt-palette-4)">▌</span> 10 10026-<span style="color:var(--vt-palette-4)">▌</span> 11 12127-<span style="color:var(--vt-palette-4)">▌</span> 12 14428-<span style="color:var(--vt-palette-4)">▌</span> 13 16929-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">13</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">(O</span> <span style="color:var(--vt-palette-0)">shows</span> <span style="color:var(--vt-palette-0)">all,</span> <span style="color:var(--vt-palette-0)">Enter</span> <span style="color:var(--vt-palette-0)">opens</span> <span style="color:var(--vt-palette-0)">it)</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">n</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">square</span><span style="background:var(--vt-palette-7)"> </span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> 4 1620+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> 5 2521+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">6</span><span style="background:var(--vt-palette-7)"> </span> 6 3622+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">7</span><span style="background:var(--vt-palette-7)"> </span> 7 4923+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">8</span><span style="background:var(--vt-palette-7)"> </span> 8 6424+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">9</span><span style="background:var(--vt-palette-7)"> </span> 9 8125+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">10</span><span style="background:var(--vt-palette-7)"> </span> 10 10026+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">11</span><span style="background:var(--vt-palette-7)"> </span> 11 12127+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">12</span><span style="background:var(--vt-palette-7)"> </span> 12 14428+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">13</span><span style="background:var(--vt-palette-7)"> </span> 13 16929+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">13</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">(O</span> <span style="color:var(--vt-palette-0)">shows</span> <span style="color:var(--vt-palette-0)">all,</span> <span style="color:var(--vt-palette-0)">Enter</span> <span style="color:var(--vt-palette-0)">works</span> <span style="color:var(--vt-palette-0)">in</span> <span style="color:var(--vt-palette-0)">it)</span>3030 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">shortcuts</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">F10</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-scroll.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3- <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">table:</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">rows,</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">columns</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">o</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">hide</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">O</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">whole</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">G</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">sheet</span>4- demos dir 3.1 kB5- go.mod file 812 B3+ <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">table:</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">rows,</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">columns</span> <span style="color:var(--vt-palette-8)">──────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">work</span> <span style="color:var(--vt-palette-8)">in</span> <span style="color:var(--vt-palette-8)">it</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">o</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">hide</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">O</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">whole</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">G</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">sheet</span>4+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B66 77 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- README.md file 9.8 kB13- demos dir 3.1 kB10+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1414 1515 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1616 <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-3)">1..30</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">each</span> {<span style="font-weight:bold">|</span><span style="color:var(--vt-palette-6)">i</span><span style="font-weight:bold">|</span> {n: <span style="color:var(--vt-palette-5)">$i</span>, square: (<span style="color:var(--vt-palette-5)">$i</span> <span style="font-weight:bold">*</span> <span style="color:var(--vt-palette-5)">$i</span>)}} <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1717 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>18-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">n</span> <span style="font-weight:bold;text-decoration:underline">square</span>19-<span style="color:var(--vt-palette-4)">▌</span> 4 1620-<span style="color:var(--vt-palette-4)">▌</span> 5 2521-<span style="color:var(--vt-palette-4)">▌</span> 6 3622-<span style="color:var(--vt-palette-4)">▌</span> 7 4923-<span style="color:var(--vt-palette-4)">▌</span> 8 6424-<span style="color:var(--vt-palette-4)">▌</span> 9 8125-<span style="color:var(--vt-palette-4)">▌</span> 10 10026-<span style="color:var(--vt-palette-4)">▌</span> 11 12127-<span style="color:var(--vt-palette-4)">▌</span> 12 14428-<span style="color:var(--vt-palette-4)">▌</span> 13 16929-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">13</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">(O</span> <span style="color:var(--vt-palette-8)">shows</span> <span style="color:var(--vt-palette-8)">all,</span> <span style="color:var(--vt-palette-8)">Enter</span> <span style="color:var(--vt-palette-8)">opens</span> <span style="color:var(--vt-palette-8)">it)</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">n</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">square</span><span style="background:var(--vt-palette-8)"> </span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> 4 1620+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> 5 2521+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">6</span><span style="background:var(--vt-palette-8)"> </span> 6 3622+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">7</span><span style="background:var(--vt-palette-8)"> </span> 7 4923+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">8</span><span style="background:var(--vt-palette-8)"> </span> 8 6424+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">9</span><span style="background:var(--vt-palette-8)"> </span> 9 8125+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> 10 10026+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> 11 12127+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> 12 14428+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> 13 16929+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">13</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">(O</span> <span style="color:var(--vt-palette-8)">shows</span> <span style="color:var(--vt-palette-8)">all,</span> <span style="color:var(--vt-palette-8)">Enter</span> <span style="color:var(--vt-palette-8)">works</span> <span style="color:var(--vt-palette-8)">in</span> <span style="color:var(--vt-palette-8)">it)</span>3030 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">shortcuts</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">F10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-select-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">──────────────────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>99 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-select-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▎</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▎</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▎</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-select.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▎</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▎</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▎</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-stale-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">──────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">stale</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">first</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>99 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">stale</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-stale-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-5);font-style:italic">stale</span> <span style="color:var(--vt-palette-5);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">first</span> <span style="color:var(--vt-palette-1)">4</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-5);font-style:italic">stale</span> <span style="color:var(--vt-palette-5);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-stale.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3);font-style:italic">stale</span> <span style="color:var(--vt-palette-3);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">first</span> <span style="color:var(--vt-palette-3)">4</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3);font-style:italic">stale</span> <span style="color:var(--vt-palette-3);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-wrap-high-contrast.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">EDIT</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>33 <span style="color:#757575;background:#000000">────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">done</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Tab</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">complete</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1010 <span style="background:#000000"> </span>1111 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1212 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1313 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>16-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span>1919 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2020 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">==</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-wrap-light.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>33 <span style="color:var(--vt-palette-8)">────────────────────────────────────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">done</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Tab</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">complete</span>4- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>5- 012 file 4.2 kB6- CLAUDE.md file 1.0 kB7- README.md file 9.8 kB8- demos dir 3.1 kB9- go.mod file 812 B4+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB6+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB7+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB8+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB9+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1010 1111 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1212 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1313 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>14- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>15- 012 file 4.2 kB16- README.md file 9.8 kB17- demos dir 3.1 kB14+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB16+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB17+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1818 1919 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2020 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> type <span style="font-weight:bold">==</span> file <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-wrap-narrow-high-contrast.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">NOTEBOOK</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>33 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">cell</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">reads</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">edit</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Shift+↑↓</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">select</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>77 <span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>99 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1010 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────╯</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1515 <span style="background:#000000"> </span>1616 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭──────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">select</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">first</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span>2121 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">rename</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">bytes</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span>2222 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────╯</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>2424 <span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+K</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap-narrow-light.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ ▶▶ <span style="color:var(--vt-palette-8)">│</span> + ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>33 <span style="color:var(--vt-palette-0)">cell</span> <span style="color:var(--vt-palette-0)">4:</span> <span style="color:var(--vt-palette-0)">reads</span> <span style="color:var(--vt-palette-0)">$files</span> <span style="color:var(--vt-palette-8)">─────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">edit</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Shift+↑↓</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">select</span>4- README.md file 9.8 kB5- demos dir 3.1 kB6- go.mod file 812 B4+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB6+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B77 88 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>99 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1010 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────╯</span>11- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>12- 012 file 4.2 kB13- README.md file 9.8 kB14- demos dir 3.1 kB11+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1515 1616 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">select</span> name size <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">first</span> <span style="color:var(--vt-palette-1)">10</span> <span style="color:var(--vt-palette-4)">│</span>2121 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">rename</span> file bytes <span style="color:var(--vt-palette-4)">│</span>2222 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────╯</span>23-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>23+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>2424 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap-narrow.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ ▶▶ <span style="color:var(--vt-palette-8)">│</span> + ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>33 <span style="color:var(--vt-palette-8)">cell</span> <span style="color:var(--vt-palette-8)">4:</span> <span style="color:var(--vt-palette-8)">reads</span> <span style="color:var(--vt-palette-8)">$files</span> <span style="color:var(--vt-palette-8)">─────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">edit</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Shift+↑↓</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">select</span>4- README.md file 9.8 kB5- demos dir 3.1 kB6- go.mod file 812 B4+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB6+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B77 88 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>99 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1010 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────╯</span>11- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>12- 012 file 4.2 kB13- README.md file 9.8 kB14- demos dir 3.1 kB11+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1515 1616 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">select</span> name size <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">first</span> <span style="color:var(--vt-palette-3)">10</span> <span style="color:var(--vt-palette-4)">│</span>2121 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">rename</span> file bytes <span style="color:var(--vt-palette-4)">│</span>2222 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────╯</span>23-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>23+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>2424 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>33 <span style="color:var(--vt-palette-8)">────────────────────────────────────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">done</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Tab</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">complete</span>4- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>5- 012 file 4.2 kB6- CLAUDE.md file 1.0 kB7- README.md file 9.8 kB8- demos dir 3.1 kB9- go.mod file 812 B4+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB6+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB7+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB8+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB9+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1010 1111 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1212 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1313 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>14- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>15- 012 file 4.2 kB16- README.md file 9.8 kB17- demos dir 3.1 kB14+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB16+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB17+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1818 1919 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2020 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> type <span style="font-weight:bold">==</span> file <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/palette.html +1 -1
@@ -13,7 +13,7 @@
1313 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">9</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as SQLite <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1414 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as JSON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as NUON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>16-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Decimal arithmetic <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Settings</span> <span style="color:var(--vt-palette-8)">│</span>16+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as HTML <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1717 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>
M go.mod +7 -0
M go.sum +16 -0
@@ -56,8 +56,12 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
5656 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=5757 github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=5858 github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=59+github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=60+github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=5961 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=6062 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=63+github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=64+github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=6165 github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=6266 github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=6367 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -78,6 +82,8 @@ github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsRe
7882 github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=7983 github.com/mattn/go-runewidth v0.0.30 h1:+KUuiDA4fF0R1p5FeueHefjDm+GIM+kWfFnDjybOPgk=8084 github.com/mattn/go-runewidth v0.0.30/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8=85+github.com/modelcontextprotocol/go-sdk v1.8.0 h1:KIvahhYqwtbeniWVPs3TcXEA7b8jEtwfBpOTAI+Urx4=86+github.com/modelcontextprotocol/go-sdk v1.8.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=8187 github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=8288 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=8389 github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
@@ -104,6 +110,10 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
104110 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=105111 github.com/sahilm/fuzzy v0.1.3 h1:juByESSS32nVD81vr6tHmKmA/8zde7gE+x5CLxrzXPU=106112 github.com/sahilm/fuzzy v0.1.3/go.mod h1:au6//VbVSqu6DFrkL2CfjlJ5iURpNCPeE+1GwY3XsT8=113+github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=114+github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=115+github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=116+github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=107117 github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=108118 github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=109119 github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44=
@@ -120,6 +130,8 @@ github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBL
120130 github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=121131 github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=122132 github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=133+github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=134+github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=123135 go.starlark.net v0.0.0-20260908191801-89a6a09411d5 h1:X8HyonnLxrmAbdeMIEGEJVZ/yg6WykLZyAZmpCLSfMA=124136 go.starlark.net v0.0.0-20260908191801-89a6a09411d5/go.mod h1:Iue6g6iirlfLoVi/DYCi5/x0h/bAOuWF3dULTKpt2Vo=125137 golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
@@ -132,6 +144,8 @@ golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
132144 golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=133145 golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=134146 golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=147+golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=148+golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=135149 golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=136150 golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=137151 golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
@@ -140,6 +154,8 @@ golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
140154 golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=141155 golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=142156 golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=157+golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=158+golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=143159 golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=144160 golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=145161 google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
M internal/chart/image.go +23 -0
@@ -46,6 +46,9 @@ type canvas struct {
4646 *image.RGBA4747 cw, ch float644848 pal Palette49+ // vec, when set, takes the shapes as SVG instead of pixels, and50+ // RGBA has no pixels, only its bounds (see SVG).51+ vec *vector4952 }5053 5154 // blend paints c over the pixel at x, y with coverage a.
@@ -65,6 +68,10 @@ func (cv *canvas) blend(x, y int, c color.RGBA, a float64) {
6568 6669 // rect fills x0..x1, y0..y1 in pixels, antialiasing fractional edges.6770 func (cv *canvas) rect(x0, y0, x1, y1 float64, c color.RGBA) {71+ if cv.vec != nil {72+ cv.vec.rect(x0, y0, x1, y1, c)73+ return74+ }6875 for y := int(math.Floor(y0)); float64(y) < y1; y++ {6976 cy := min(y1, float64(y+1)) - max(y0, float64(y))7077 for x := int(math.Floor(x0)); float64(x) < x1; x++ {
@@ -76,6 +83,10 @@ func (cv *canvas) rect(x0, y0, x1, y1 float64, c color.RGBA) {
7683 7784 // hline draws a one pixel horizontal line at y.7885 func (cv *canvas) hline(y int, c color.RGBA) {86+ if cv.vec != nil {87+ cv.vec.line(float64(cv.Rect.Min.X), float64(y)+0.5, float64(cv.Rect.Max.X), float64(y)+0.5, c)88+ return89+ }7990 for x := cv.Rect.Min.X; x < cv.Rect.Max.X; x++ {8091 cv.blend(x, y, c, 1)8192 }
@@ -83,6 +94,10 @@ func (cv *canvas) hline(y int, c color.RGBA) {
8394 8495 // vline draws a one pixel vertical line at x.8596 func (cv *canvas) vline(x int, c color.RGBA) {97+ if cv.vec != nil {98+ cv.vec.line(float64(x)+0.5, float64(cv.Rect.Min.Y), float64(x)+0.5, float64(cv.Rect.Max.Y), c)99+ return100+ }86101 for y := cv.Rect.Min.Y; y < cv.Rect.Max.Y; y++ {87102 cv.blend(x, y, c, 1)88103 }
@@ -91,6 +106,10 @@ func (cv *canvas) vline(x int, c color.RGBA) {
91106 // polyline strokes the points with a round-capped line width px wide.92107 // Coverage is kept per pixel, so joints aren't painted twice.93108 func (cv *canvas) polyline(pts [][2]float64, width float64, c color.RGBA) {109+ if cv.vec != nil {110+ cv.vec.polyline(pts, width, c)111+ return112+ }94113 b := cv.Rect95114 cover := make([]float64, b.Dx()*b.Dy())96115 r := width / 2
@@ -213,6 +232,10 @@ func (p *barPlan) image(cv *canvas) {
213232 214233 // image draws the pie, supersampled, with a thin gap between slices.215234 func (p *piePlan) image(cv *canvas) {235+ if cv.vec != nil {236+ p.vector(cv)237+ return238+ }216239 b := cv.Rect217240 cx, cy := float64(b.Dx())/2, float64(b.Dy())/2218241 pr := newPieRaster(p, cx, cy, min(cx, cy)-1, 1)
M internal/chart/scatter.go +4 -0
A internal/chart/svg.go +311 -0
@@ -0,0 +1,311 @@
1+package chart2+3+import (4+ "fmt"5+ "html"6+ "image"7+ "image/color"8+ "math"9+ "strings"10+11+ "github.com/FelineStateMachine/012/internal/sheet"12+)13+14+// SVG charts are the text chart and the image in one vector drawing,15+// for the HTML export: the axes, labels and legend Draw lays out, as16+// text on a grid of SVGCellW by SVGCellH pixels, and the plot area as17+// the shapes Image paints, as SVG shapes rather than pixels. Colors are18+// classes the page styles, so a chart follows the page's light or dark19+// palette:20+//21+// ct-ax, ct-lb, ct-mu text of the axes, the labels and messages22+// ct-s0 .. ct-s5 text in a series' color23+// cf-0 .. cf-5 shapes filled in a series' color24+// cs-0 .. cs-5 lines stroked in a series' color25+// cs-gl gridlines26+// cs-box axes, in their text class's color27+// cs-gap the gaps between a pie's slices28+const (29+ SVGCellW = 930+ SVGCellH = 2131+)32+33+// vecGrid and vecSeries stand for the colors in the palette a vector34+// canvas paints with, so each shape finds its class again: the red35+// channel is the series and the blue one says it's a gridline.36+var vecGrid = color.RGBA{B: 1, A: 255}37+38+func vecSeries(i int) color.RGBA { return color.RGBA{R: uint8(i), A: 255} }39+40+// SVG draws d as a chart of type t in w by h cells, as an svg element41+// of w*SVGCellW by h*SVGCellH pixels whose title is title.42+func SVG(t sheet.ChartType, d sheet.ChartData, w, h int, o Options, title string) string {43+ w, h = max(w, 0), max(h, 0)44+ o.Image, o.CellW, o.CellH = true, SVGCellW, SVGCellH45+ g := Draw(t, d, w, h, o)46+ var b strings.Builder47+ fmt.Fprintf(&b, `<svg xmlns="http://www.w3.org/2000/svg" class="chart" width="%d" height="%d" viewBox="0 0 %d %d" role="img">`,48+ w*SVGCellW, h*SVGCellH, w*SVGCellW, h*SVGCellH)49+ if title != "" {50+ b.WriteString("<title>" + html.EscapeString(title) + "</title>")51+ }52+ if !g.Plot.Empty() {53+ b.WriteString(plotSVG(t, d, w, h, o, g.Plot))54+ }55+ gridText(&b, g)56+ b.WriteString("</svg>")57+ return b.String()58+}59+60+// plotSVG is the plot area's shapes, placed over its cells.61+func plotSVG(t sheet.ChartType, d sheet.ChartData, w, h int, o Options, plot image.Rectangle) string {62+ p, _ := planFor(t, d, w, h, o)63+ pal := Palette{Grid: vecGrid}64+ for i := range pal.Series {65+ pal.Series[i] = vecSeries(i)66+ }67+ v := &vector{}68+ cv := &canvas{69+ RGBA: &image.RGBA{Rect: image.Rect(0, 0, plot.Dx()*SVGCellW, plot.Dy()*SVGCellH)},70+ cw: SVGCellW, ch: SVGCellH, pal: pal, vec: v,71+ }72+ p.image(cv)73+ v.flush()74+ return fmt.Sprintf(`<g transform="translate(%d %d)">%s</g>`, plot.Min.X*SVGCellW, plot.Min.Y*SVGCellH, v.b.String())75+}76+77+// gridText writes the text chart's cells, a run of one role at a time.78+func gridText(b *strings.Builder, g *Grid) {79+ for y := range g.H {80+ x := 081+ for x < g.W {82+ c := g.At(x, y)83+ if c.Text == " " || c.Text == "" || c.Fg == None {84+ x++85+ continue86+ }87+ if arms, ok := boxArms[c.Text]; ok {88+ boxLines(b, x, y, arms, textClass(c.Fg))89+ x++90+ continue91+ }92+ start, role := x, c.Fg93+ var run strings.Builder94+ for x < g.W && g.At(x, y).Fg == role && !isBox(g.At(x, y).Text) {95+ run.WriteString(g.At(x, y).Text)96+ x++97+ }98+ fmt.Fprintf(b, `<text x="%d" y="%.1f" class="%s" xml:space="preserve">%s</text>`, start*SVGCellW,99+ float64(y)*SVGCellH+SVGCellH*0.72, textClass(role), html.EscapeString(strings.TrimRight(run.String(), " ")))100+ }101+ }102+}103+104+// boxArms are the box-drawing characters the axes use, as the arms105+// each draws from the middle of its cell: up, down, left, right. They106+// are drawn as lines, which meet whatever font the page has.107+var boxArms = map[string][4]bool{108+ "│": {true, true, false, false}, "─": {false, false, true, true},109+ "└": {true, false, false, true}, "┘": {true, false, true, false},110+ "┌": {false, true, false, true}, "┐": {false, true, true, false},111+ "├": {true, true, false, true}, "┤": {true, true, true, false},112+ "┬": {false, true, true, true}, "┴": {true, false, true, true},113+ "┼": {true, true, true, true},114+}115+116+func isBox(s string) bool { _, ok := boxArms[s]; return ok }117+118+// boxLines draws a box-drawing character's arms in cell x, y.119+func boxLines(b *strings.Builder, x, y int, arms [4]bool, class string) {120+ cx, cy := float64(x)*SVGCellW+SVGCellW/2, float64(y)*SVGCellH+SVGCellH/2121+ ends := [4][2]float64{{cx, float64(y) * SVGCellH}, {cx, float64(y+1) * SVGCellH},122+ {float64(x) * SVGCellW, cy}, {float64(x+1) * SVGCellW, cy}}123+ for i, on := range arms {124+ if on {125+ fmt.Fprintf(b, `<line x1="%s" y1="%s" x2="%s" y2="%s" class="%s cs-box"/>`, num(cx), num(cy), num(ends[i][0]), num(ends[i][1]), class)126+ }127+ }128+}129+130+func textClass(r Role) string {131+ switch {132+ case r == Axis, r == Gridline:133+ return "ct-ax"134+ case r == Label:135+ return "ct-lb"136+ case r >= Series:137+ return fmt.Sprintf("ct-s%d", int(r-Series)%Colors)138+ }139+ return "ct-mu"140+}141+142+// vector collects a canvas's shapes as SVG. Area charts paint a pixel143+// column at a time; those columns are joined into one polygon per color144+// for as long as they run on without a gap.145+type vector struct {146+ b strings.Builder147+ strips map[color.RGBA]*strip148+ order []color.RGBA149+}150+151+// strip is a run of one-pixel columns of one color: their tops and152+// bottoms, left to right.153+type strip struct {154+ x0, x1 float64155+ top, below [][2]float64156+}157+158+func paint(c color.RGBA) (series int, grid bool, opacity string) {159+ if c.A < 255 {160+ opacity = fmt.Sprintf(` fill-opacity="%.2f"`, float64(c.A)/255)161+ }162+ return int(c.R) % Colors, c.B == 1, opacity163+}164+165+func (v *vector) rect(x0, y0, x1, y1 float64, c color.RGBA) {166+ if x1 <= x0 || y1 <= y0 {167+ return168+ }169+ if x1-x0 <= 1.001 {170+ v.column(x0, y0, x1, y1, c)171+ return172+ }173+ v.flush()174+ s, _, op := paint(c)175+ fmt.Fprintf(&v.b, `<rect x="%s" y="%s" width="%s" height="%s" class="cf-%d"%s/>`, num(x0), num(y0), num(x1-x0), num(y1-y0), s, op)176+}177+178+// column adds a pixel column to its color's strip, starting a new strip179+// when it doesn't continue the last one.180+func (v *vector) column(x0, y0, x1, y1 float64, c color.RGBA) {181+ if v.strips == nil {182+ v.strips = map[color.RGBA]*strip{}183+ }184+ st := v.strips[c]185+ if st != nil && math.Abs(st.x1-x0) > 0.001 {186+ v.emitStrip(c, st)187+ st = nil188+ }189+ if st == nil {190+ st = &strip{x0: x0}191+ v.strips[c] = st192+ v.order = append(v.order, c)193+ }194+ st.x1 = x1195+ st.top = append(st.top, [2]float64{x0, y0}, [2]float64{x1, y0})196+ st.below = append(st.below, [2]float64{x0, y1}, [2]float64{x1, y1})197+}198+199+// flush writes the strips still open, in the order they started, so200+// they're under whatever is drawn next.201+func (v *vector) flush() {202+ for _, c := range v.order {203+ if st := v.strips[c]; st != nil {204+ v.emitStrip(c, st)205+ }206+ }207+ v.order = v.order[:0]208+}209+210+func (v *vector) emitStrip(c color.RGBA, st *strip) {211+ delete(v.strips, c)212+ pts := simplify(st.top)213+ below := simplify(st.below)214+ for i := len(below) - 1; i >= 0; i-- {215+ pts = append(pts, below[i])216+ }217+ s, _, op := paint(c)218+ fmt.Fprintf(&v.b, `<polygon points="%s" class="cf-%d"%s/>`, points(pts), s, op)219+}220+221+func (v *vector) line(x0, y0, x1, y1 float64, c color.RGBA) {222+ v.flush()223+ class := "cs-gl"224+ if s, grid, _ := paint(c); !grid {225+ class = fmt.Sprintf("cs-%d", s)226+ }227+ fmt.Fprintf(&v.b, `<line x1="%s" y1="%s" x2="%s" y2="%s" class="%s"/>`, num(x0), num(y0), num(x1), num(y1), class)228+}229+230+func (v *vector) polyline(pts [][2]float64, width float64, c color.RGBA) {231+ v.flush()232+ s, _, _ := paint(c)233+ if len(pts) == 1 {234+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-%d"/>`, num(pts[0][0]), num(pts[0][1]), num(width/2), s)235+ return236+ }237+ fmt.Fprintf(&v.b, `<polyline points="%s" fill="none" stroke-width="%s" stroke-linecap="round" stroke-linejoin="round" class="cs-%d"/>`,238+ points(pts), num(width), s)239+}240+241+func (v *vector) disc(cx, cy, r float64, c color.RGBA) {242+ v.flush()243+ s, _, _ := paint(c)244+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-%d"/>`, num(cx), num(cy), num(r), s)245+}246+247+// vector draws the pie as one path a slice, with the page's background248+// stroked between them as the image leaves a gap.249+func (p *piePlan) vector(cv *canvas) {250+ v := cv.vec251+ b := cv.Rect252+ cx, cy := float64(b.Dx())/2, float64(b.Dy())/2253+ r := min(cx, cy) - 1254+ if len(p.slices) == 1 {255+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-0"/>`, num(cx), num(cy), num(r))256+ return257+ }258+ at := func(f float64) string {259+ a := f * 2 * math.Pi260+ return num(cx+r*math.Sin(a)) + " " + num(cy-r*math.Cos(a))261+ }262+ for i, s := range p.slices {263+ if s.to <= s.from {264+ continue265+ }266+ large := 0267+ if s.to-s.from > 0.5 {268+ large = 1269+ }270+ fmt.Fprintf(&v.b, `<path d="M%s %s L%s A%s %s 0 %d 1 %s Z" class="cf-%d cs-gap"/>`,271+ num(cx), num(cy), at(s.from), num(r), num(r), large, at(s.to), i%Colors)272+ }273+}274+275+// simplify drops the points of a path that lie on the line between276+// their neighbors.277+func simplify(pts [][2]float64) [][2]float64 {278+ if len(pts) < 3 {279+ return pts280+ }281+ out := [][2]float64{pts[0]}282+ for i := 1; i < len(pts)-1; i++ {283+ a, b, c := out[len(out)-1], pts[i], pts[i+1]284+ if math.Abs((b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])) > 0.25 {285+ out = append(out, b)286+ }287+ }288+ return append(out, pts[len(pts)-1])289+}290+291+func points(pts [][2]float64) string {292+ var b strings.Builder293+ for i, p := range pts {294+ if i > 0 {295+ b.WriteByte(' ')296+ }297+ b.WriteString(num(p[0]) + "," + num(p[1]))298+ }299+ return b.String()300+}301+302+// num writes a coordinate to a tenth of a pixel, without trailing303+// zeros.304+func num(f float64) string {305+ s := fmt.Sprintf("%.1f", f)306+ s = strings.TrimSuffix(s, ".0")307+ if s == "-0" {308+ return "0"309+ }310+ return s311+}
A internal/chart/svg_test.go +71 -0
@@ -0,0 +1,71 @@
1+package chart2+3+import (4+ "encoding/xml"5+ "io"6+ "strings"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// TestSVGEveryType draws each type as SVG, checking it's well-formed13+// XML with the chart's labels as text and shapes of its own kind.14+func TestSVGEveryType(t *testing.T) {15+ cases := []struct {16+ typ sheet.ChartType17+ data sheet.ChartData18+ opts sheet.ChartOptions19+ shape string20+ }{21+ {sheet.ChartColumn, budget, sheet.ChartOptions{}, "<rect"},22+ {sheet.ChartBar, single, sheet.ChartOptions{}, "<rect"},23+ {sheet.ChartLine, budget, sheet.ChartOptions{}, "<polyline"},24+ {sheet.ChartArea, budget, sheet.ChartOptions{}, "<polygon"},25+ {sheet.ChartArea, budget, sheet.ChartOptions{Stack: sheet.StackNormal}, "<polygon"},26+ {sheet.ChartPie, single, sheet.ChartOptions{}, "<path"},27+ {sheet.ChartScatter, xy, sheet.ChartOptions{Trend: true}, "<circle"},28+ {sheet.ChartColumn, signs, sheet.ChartOptions{Stack: sheet.StackNormal}, "<rect"},29+ }30+ for _, c := range cases {31+ t.Run(c.typ.String(), func(t *testing.T) {32+ svg := SVG(c.typ, c.data, 60, 18, Options{Chart: c.opts}, "Budget & more")33+ d := xml.NewDecoder(strings.NewReader(svg))34+ for {35+ if _, err := d.Token(); err == io.EOF {36+ break37+ } else if err != nil {38+ t.Fatalf("not XML: %v\n%s", err, svg)39+ }40+ }41+ if !strings.Contains(svg, c.shape) {42+ t.Errorf("no %s in\n%s", c.shape, svg)43+ }44+ if !strings.Contains(svg, "<title>Budget &amp; more</title>") {45+ t.Errorf("no title")46+ }47+ if c.typ != sheet.ChartPie && !strings.Contains(svg, `class="ct-lb"`) {48+ t.Errorf("no labels")49+ }50+ })51+ }52+}53+54+// TestSVGAreaIsFewShapes joins an area's pixel columns into polygons.55+func TestSVGAreaIsFewShapes(t *testing.T) {56+ svg := SVG(sheet.ChartArea, single, 80, 20, Options{}, "")57+ if n := strings.Count(svg, "<polygon"); n == 0 || n > 3 {58+ t.Errorf("%d polygons", n)59+ }60+ if strings.Contains(svg, "<rect") {61+ t.Errorf("area columns drawn as rects")62+ }63+}64+65+// TestSVGNothingToPlot shows the text chart's message alone.66+func TestSVGNothingToPlot(t *testing.T) {67+ svg := SVG(sheet.ChartColumn, sheet.ChartData{}, 40, 10, Options{}, "")68+ if !strings.Contains(svg, "No numbers to chart") || strings.Contains(svg, "<g ") {69+ t.Errorf("got %s", svg)70+ }71+}
A internal/fileio/fonts/OFL.txt +93 -0
@@ -0,0 +1,93 @@
1+Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ThinItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLight.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Light.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-LightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Regular.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Italic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Medium.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-MediumItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Bold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-BoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved.2+3+This Font Software is licensed under the SIL Open Font License, Version 1.1.4+This license is copied below, and is also available with a FAQ at:5+http://scripts.sil.org/OFL6+7+8+-----------------------------------------------------------9+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200710+-----------------------------------------------------------11+12+PREAMBLE13+The goals of the Open Font License (OFL) are to stimulate worldwide14+development of collaborative font projects, to support the font creation15+efforts of academic and linguistic communities, and to provide a free and16+open framework in which fonts may be shared and improved in partnership17+with others.18+19+The OFL allows the licensed fonts to be used, studied, modified and20+redistributed freely as long as they are not sold by themselves. The21+fonts, including any derivative works, can be bundled, embedded,22+redistributed and/or sold with any software provided that any reserved23+names are not used by derivative works. The fonts and derivatives,24+however, cannot be released under any other type of license. The25+requirement for fonts to remain under this license does not apply26+to any document created using the fonts or their derivatives.27+28+DEFINITIONS29+"Font Software" refers to the set of files released by the Copyright30+Holder(s) under this license and clearly marked as such. This may31+include source files, build scripts and documentation.32+33+"Reserved Font Name" refers to any names specified as such after the34+copyright statement(s).35+36+"Original Version" refers to the collection of Font Software components as37+distributed by the Copyright Holder(s).38+39+"Modified Version" refers to any derivative made by adding to, deleting,40+or substituting -- in part or in whole -- any of the components of the41+Original Version, by changing formats or by porting the Font Software to a42+new environment.43+44+"Author" refers to any designer, engineer, programmer, technical45+writer or other person who contributed to the Font Software.46+47+PERMISSION & CONDITIONS48+Permission is hereby granted, free of charge, to any person obtaining49+a copy of the Font Software, to use, study, copy, merge, embed, modify,50+redistribute, and sell modified and unmodified copies of the Font51+Software, subject to the following conditions:52+53+1) Neither the Font Software nor any of its individual components,54+in Original or Modified Versions, may be sold by itself.55+56+2) Original or Modified Versions of the Font Software may be bundled,57+redistributed and/or sold with any software, provided that each copy58+contains the above copyright notice and this license. These can be59+included either as stand-alone text files, human-readable headers or60+in the appropriate machine-readable metadata fields within text or61+binary files as long as those fields can be easily viewed by the user.62+63+3) No Modified Version of the Font Software may use the Reserved Font64+Name(s) unless explicit written permission is granted by the corresponding65+Copyright Holder. This restriction only applies to the primary font name as66+presented to the users.67+68+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font69+Software shall not be used to promote, endorse or advertise any70+Modified Version, except to acknowledge the contribution(s) of the71+Copyright Holder(s) and the Author(s) or with their explicit written72+permission.73+74+5) The Font Software, modified or unmodified, in part or in whole,75+must be distributed entirely under this license, and must not be76+distributed under any other license. The requirement for fonts to77+remain under this license does not apply to any document created78+using the Font Software.79+80+TERMINATION81+This license becomes null and void if any of the above conditions are82+not met.83+84+DISCLAIMER85+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,86+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF87+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT88+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE89+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,90+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL91+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING92+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM93+OTHER DEALINGS IN THE FONT SOFTWARE.
A internal/fileio/fonts/ibm-plex-mono-latin-400-italic.woff2 +0 -0

Binary file.

A internal/fileio/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0

Binary file.

A internal/fileio/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0

Binary file.

M internal/fileio/formats.go +19 -1
@@ -19,6 +19,7 @@ const (
1919 WK12020 JSON2121 NUON22+ HTML2223 )2324 2425 // A fileFormat is everything about a Kind: its names, its extensions,
@@ -95,6 +96,10 @@ var kinds = []fileFormat{{
9596 kind: NUON, name: "NUON", noun: "NUON", label: "Nushell table (NUON)", exts: []string{".nuon"},9697 read: importNUON, write: exportNUON, menu: "Nushell table", encode: encodeNUON,9798 about: "Save the sheet as a nushell table that keeps its types, named by its first row",99+}, {100+ kind: HTML, name: "HTML", noun: "HTML", label: "Web page", exts: []string{".html", ".htm"},101+ write: exportHTML, menu: "Web page",102+ about: "Save the sheet as a web page in 012's look, with its charts, to share with anyone",98103 }}99104 100105 // unknownFormat is what an invalid Kind reports.
@@ -117,8 +122,18 @@ func Kinds() []Kind {
117122 return out118123 }119124 120-// KindOf recognizes a file's format by its extension.125+// KindOf recognizes a file 012 imports by its extension.121126 func KindOf(name string) (Kind, bool) {127+ k, ok := ExportKindOf(name)128+ if !ok || !k.CanImport() {129+ return 0, false130+ }131+ return k, true132+}133+134+// ExportKindOf recognizes a file's format by its extension, including135+// formats 012 only writes (HTML).136+func ExportKindOf(name string) (Kind, bool) {122137 ext := strings.ToLower(filepath.Ext(name))123138 for _, k := range kinds {124139 for _, e := range k.exts {
@@ -130,6 +145,9 @@ func KindOf(name string) (Kind, bool) {
130145 return 0, false131146 }132147 148+// CanImport reports whether 012 reads files of this kind.149+func (k Kind) CanImport() bool { return k.format().read != nil }150+133151 // String is the format's short name, e.g. "XLSX".134152 func (k Kind) String() string { return k.format().name }135153
M internal/fileio/formats_test.go +16 -6
A internal/fileio/html.go +125 -0
@@ -0,0 +1,125 @@
1+package fileio2+3+import (4+ "context"5+ "fmt"6+ "html"7+ "io"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// HTML exports are static pages in 012's look (see htmlstyle.go): the13+// control panel's lines above the grid, the grid with its headers and14+// charts, and a small script that puts the pointer on a cell clicked or15+// moved to with the arrow keys, showing its address in the name box and16+// what it holds in the formula bar, as the screen does. The page needs17+// nothing beyond itself: fonts, styles, SVG charts and script are in18+// the file.19+20+// HTMLPage is what an HTML page shows: a sheet or range, or one chart.21+type HTMLPage struct {22+ Title string // the page's title, and the first line's23+ Snap *Snapshot // the cells, when Chart is nil24+ Chart *SnapChart25+}26+27+// WriteHTML writes p as a page. The note, when there is one, says what28+// the page left out.29+func WriteHTML(w io.Writer, p HTMLPage) (note string, err error) {30+ body, name, where := "", "", ""31+ switch {32+ case p.Chart != nil:33+ body, name, where = HTMLChart(*p.Chart), p.Chart.Data.String(), p.Chart.Type.Title()+" chart of "+p.Chart.Data.String()34+ case p.Snap != nil:35+ body, note = HTMLGrid(p.Snap)36+ where = p.Snap.Name + "!" + p.Snap.Range.String()37+ }38+ _, err = io.WriteString(w, HTMLDocument(p.Title, HTMLPanel(p.Title, name, where)+body, ""))39+ return note, err40+}41+42+// HTMLDocument is a whole page: title, style sheet, body and script,43+// with extra added to the script (the MCP view's messages).44+func HTMLDocument(title, body, extra string) string {45+ return "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">" +46+ "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">" +47+ "<meta name=\"generator\" content=\"012\"><title>" + html.EscapeString(title) + "</title>\n<style>\n" +48+ HTMLStyle() + "</style></head>\n<body><div class=\"o12\">" + body +49+ "</div>\n<script>\n" + htmlScript + extra + "</script></body></html>\n"50+}51+52+// HTMLPanel is the control panel's three lines: the title with the53+// mode indicator, the name box (holding name until a cell is pointed54+// at) and formula bar, and the context line saying what the page55+// shows.56+func HTMLPanel(title, name, where string) string {57+ return fmt.Sprintf(`<header class="panel"><div><span class="book">%s</span><span class="mode">READY</span></div>`+58+ `<div><span class="namebox" id="o12-name">%s</span><span class="input" id="o12-input"></span></div>`+59+ `<div class="context" id="o12-context">%s</div></header>`, html.EscapeString(title), html.EscapeString(name), html.EscapeString(where))60+}61+62+// exportHTML writes a sheet or range as a page.63+func exportHTML(_ context.Context, name string, snap *Snapshot, _ ExportOptions) (*ExportResult, error) {64+ var note string65+ err := writeFile(name, func(w io.Writer) error {66+ var err error67+ note, err = WriteHTML(w, HTMLPage{Title: snap.Name, Snap: snap})68+ return err69+ })70+ if err != nil {71+ return nil, err72+ }73+ res := &ExportResult{Rows: snap.Range.To.Row - snap.Range.From.Row + 1}74+ if len(snap.Cells) == 0 {75+ res.Rows = 076+ }77+ if note != "" {78+ res.Notes = append(res.Notes, note)79+ }80+ return res, nil81+}82+83+// ChartSnap is chart i of s with the values it draws, for a page of84+// its own.85+func ChartSnap(s *sheet.Sheet, i int) (SnapChart, bool) {86+ charts := s.Charts()87+ if i < 0 || i >= len(charts) {88+ return SnapChart{}, false89+ }90+ return SnapChart{Chart: charts[i], Values: s.ChartData(charts[i])}, true91+}92+93+// htmlScript moves the pointer: a click or an arrow key puts it on a94+// cell, whose address goes in the name box, what was typed in it in95+// the formula bar, and whose row and column headers light up. It works96+// on grids added to the page later, as the MCP view adds them.97+const htmlScript = `(function(){98+var cur=null;99+function col(s){var n=0;for(var i=0;i<s.length;i++)n=n*26+s.charCodeAt(i)-64;return n}100+function name(n){var s="";while(n>0){n--;s=String.fromCharCode(65+n%26)+s;n=Math.floor(n/26)}return s}101+function split(a){var m=/^([A-Z]+)(\d+)$/.exec(a);return m?[col(m[1]),+m[2]]:null}102+function point(td){103+ if(cur){cur.classList.remove("ptr")}104+ document.querySelectorAll("th.on").forEach(function(t){t.classList.remove("on")});105+ cur=td;if(!td)return;106+ td.classList.add("ptr");107+ var a=td.getAttribute("data-a"),p=split(a),g=td.closest("table");108+ var nb=document.getElementById("o12-name"),inp=document.getElementById("o12-input");109+ if(nb)nb.textContent=a;110+ if(inp)inp.textContent=td.hasAttribute("data-f")?td.getAttribute("data-f"):td.textContent;111+ if(p&&g){var c=g.querySelector('th[data-c="'+name(p[0])+'"]'),r=g.querySelector('th[data-r="'+p[1]+'"]');112+ if(c)c.classList.add("on");if(r)r.classList.add("on")}113+}114+document.addEventListener("click",function(e){var td=e.target.closest&&e.target.closest("td[data-a]");if(td)point(td)});115+document.addEventListener("keydown",function(e){116+ if(!cur)return;var d={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]}[e.key];if(!d)return;117+ var p=split(cur.getAttribute("data-a")),g=cur.closest("table");if(!p||!g)return;118+ for(var k=1;k<64;k++){var n=g.querySelector('td[data-a="'+name(p[0]+d[0]*k)+(p[1]+d[1]*k)+'"]');119+ if(n){point(n);n.scrollIntoView({block:"nearest",inline:"nearest"});e.preventDefault();return}120+ if(p[0]+d[0]*k<1||p[1]+d[1]*k<1)return}121+});122+window.o12point=point;123+var first=document.querySelector("td[data-a]");if(first)point(first);124+})();125+`
A internal/fileio/html_test.go +139 -0
@@ -0,0 +1,139 @@
1+package fileio2+3+import (4+ "bytes"5+ "context"6+ "os"7+ "path/filepath"8+ "regexp"9+ "strings"10+ "testing"11+12+ "github.com/FelineStateMachine/012/internal/sheet"13+)14+15+// htmlBook is a sheet with a header, numbers, a formula, a style, a16+// merge, a note and a chart.17+func htmlBook(t *testing.T) *sheet.Sheet {18+ t.Helper()19+ s := sheet.New()20+ for a, in := range map[string]string{21+ "A1": "Month", "B1": "Sales", "A2": "Jan", "B2": "$1,200", "A3": "Feb", "B3": "900",22+ "A4": "Total", "B4": "=SUM(B2:B3)", "A6": "<b>not markup</b>",23+ } {24+ addr, _ := sheet.ParseAddr(a)25+ if err := s.Set(addr, in); err != nil {26+ t.Fatal(err)27+ }28+ }29+ s.SetStyle(sheet.Rect{To: sheet.Addr{Col: 1}}, func(st *sheet.Style) { st.Bold = true })30+ if err := s.SetNote(sheet.Addr{Row: 3}, "adds up"); err != nil {31+ t.Fatal(err)32+ }33+ if err := s.Merge(sheet.Rect{From: sheet.Addr{Row: 5}, To: sheet.Addr{Col: 1, Row: 5}}, sheet.MergeAll); err != nil {34+ t.Fatal(err)35+ }36+ s.AddChart(sheet.Chart{Type: sheet.ChartColumn, Data: sheet.Rect{To: sheet.Addr{Col: 1, Row: 2}}, Header: true, Labels: true,37+ Title: "Sales by month", At: sheet.Addr{Col: 3, Row: 1}, W: 40, H: 14})38+ return s39+}40+41+// TestHTMLPage exports a sheet as a page that holds everything it42+// needs: fonts, styles, the cells as shown, the chart as SVG.43+func TestHTMLPage(t *testing.T) {44+ s := htmlBook(t)45+ path := filepath.Join(t.TempDir(), "sales.html")46+ k, ok := ExportKindOf(path)47+ if !ok || k != HTML || k.CanImport() {48+ t.Fatalf("ExportKindOf = %v, %v", k, ok)49+ }50+ if _, ok := KindOf(path); ok {51+ t.Errorf("an HTML file is offered for import")52+ }53+ res, err := Export(context.Background(), path, HTML, Snap(s, sheet.Rect{}, "Sales"), ExportOptions{})54+ if err != nil {55+ t.Fatal(err)56+ }57+ if res.Rows != 6 || len(res.Notes) != 0 {58+ t.Errorf("rows %d, notes %q", res.Rows, res.Notes)59+ }60+ data, err := os.ReadFile(path)61+ if err != nil {62+ t.Fatal(err)63+ }64+ page := string(data)65+ for _, want := range []string{66+ "<title>Sales</title>", "@font-face{font-family:'IBM Plex Mono'", "data:font/woff2;base64,",67+ `<th data-c="A">A</th>`, `data-a="B1" class="b">Sales<`, `data-a="A2" class="clip">Jan<`, `data-a="B2" class="r">$1,200<`,68+ `data-f="=SUM(B2:B3)">$2,100<`, `class="clip note" title="adds up"`, `colspan="2" rowspan="1"`, "&lt;b&gt;not markup&lt;/b&gt;",69+ `<figure class="chart"`, "<svg", "<figcaption>Sales by month</figcaption>", `class="range">A1:B3<`,70+ "prefers-color-scheme:light", "READY",71+ } {72+ if !strings.Contains(page, want) {73+ t.Errorf("page lacks %q", want)74+ }75+ }76+ // Nothing is fetched from elsewhere.77+ if m := regexp.MustCompile(`(src|href)="?https?:`).FindString(page); m != "" {78+ t.Errorf("page loads %s", m)79+ }80+}81+82+// TestHTMLRange exports a range, with the charts anchored in it.83+func TestHTMLRange(t *testing.T) {84+ s := htmlBook(t)85+ var b bytes.Buffer86+ snap := Snap(s, sheet.Rect{From: sheet.Addr{Row: 1}, To: sheet.Addr{Col: 1, Row: 2}}, "Sales")87+ if _, err := WriteHTML(&b, HTMLPage{Title: "Sales", Snap: snap}); err != nil {88+ t.Fatal(err)89+ }90+ page := b.String()91+ if strings.Contains(page, `data-a="A1"`) || !strings.Contains(page, `data-a="B3"`) || strings.Contains(page, "<svg") {92+ t.Errorf("range page wrong:\n%s", page[strings.Index(page, "<body>"):])93+ }94+ if !strings.Contains(page, `id="o12-context">Sales!A2:B3<`) {95+ t.Errorf("context line doesn't name the range")96+ }97+}98+99+// TestHTMLChartPage draws one chart on its own page.100+func TestHTMLChartPage(t *testing.T) {101+ s := htmlBook(t)102+ c, ok := ChartSnap(s, 0)103+ if !ok {104+ t.Fatal("no chart")105+ }106+ if _, ok := ChartSnap(s, 1); ok {107+ t.Error("chart 1 found")108+ }109+ var b bytes.Buffer110+ if _, err := WriteHTML(&b, HTMLPage{Title: "Sales by month", Chart: &c}); err != nil {111+ t.Fatal(err)112+ }113+ page := b.String()114+ if !strings.Contains(page, `<figure class="chart solo"`) || !strings.Contains(page, "<rect") || strings.Contains(page, "<table") {115+ t.Errorf("chart page wrong")116+ }117+}118+119+// TestHTMLLooks draws a rule's fill and text color.120+func TestHTMLLooks(t *testing.T) {121+ s := sheet.New()122+ for i, in := range []string{"5", "50"} {123+ if err := s.Set(sheet.Addr{Row: i}, in); err != nil {124+ t.Fatal(err)125+ }126+ }127+ err := s.AddCondFormat(sheet.CondFormat{Ranges: []sheet.Rect{{To: sheet.Addr{Row: 1}}}, Op: sheet.RuleGreater, Args: [2]string{"10"},128+ Style: sheet.RuleStyle{Fill: sheet.ColorGreen, Bold: true}})129+ if err != nil {130+ t.Fatal(err)131+ }132+ grid, _ := HTMLGrid(Snap(s, sheet.Rect{}, "S"))133+ if !strings.Contains(grid, `data-a="A2" class="r b" style="background:var(--r3);color:var(--i3)"`) {134+ t.Errorf("rule not drawn:\n%s", grid)135+ }136+ if strings.Contains(grid, `data-a="A1" class="r b"`) {137+ t.Errorf("rule drawn where it doesn't apply")138+ }139+}
A internal/fileio/htmlcell.go +221 -0
@@ -0,0 +1,221 @@
1+package fileio2+3+import (4+ "fmt"5+ "html"6+ "strings"7+8+ "github.com/FelineStateMachine/012/internal/sheet"9+)10+11+// htmlCell is what a td says about its cell: classes, inline styles,12+// attributes and the text shown.13+type htmlCell struct {14+ class []string15+ style []string16+ attrs string17+ text string18+ icon string // an icon set's glyph, before the text19+}20+21+// writeCell writes the td of the cell at a: spanning a merge, with the22+// text as the grid shows it at the cell's width.23+func (l *htmlLayout) writeCell(b *strings.Builder, a sheet.Addr) {24+ snap := l.snap25+ var h htmlCell26+ width := htmlColWidth(snap, a.Col)27+ if m, ok := l.merged[a]; ok {28+ width = 029+ for col := m.From.Col; col <= m.To.Col; col++ {30+ width += htmlColWidth(snap, col)31+ }32+ h.attrs += fmt.Sprintf(` colspan="%d" rowspan="%d"`, m.To.Col-m.From.Col+1, l.visibleRows(m))33+ }34+ c, filled := snap.Cells[a]35+ if filled {36+ h.content(snap, c, width)37+ h.textStyle(c.Style)38+ h.borders(c.Style.Borders)39+ if c.Style.Wrap == sheet.WrapOverflow && h.text != "" && l.nextFilled(a) {40+ h.class = append(h.class, "clip")41+ }42+ }43+ if look, ok := snap.Looks[a]; ok {44+ h.look(look)45+ }46+ if role := l.tableRole[a]; role != "" {47+ h.class = append(h.class, role)48+ }49+ if note, ok := snap.Notes[a]; ok {50+ h.class = append(h.class, "note")51+ h.attrs += ` title="` + html.EscapeString(note) + `"`52+ }53+ fmt.Fprintf(b, `<td data-a="%s"`, a)54+ if len(h.class) > 0 {55+ b.WriteString(` class="` + strings.Join(h.class, " ") + `"`)56+ }57+ if len(h.style) > 0 {58+ b.WriteString(` style="` + html.EscapeString(strings.Join(h.style, ";")) + `"`)59+ }60+ b.WriteString(h.attrs + ">")61+ if h.icon != "" {62+ b.WriteString(h.icon)63+ }64+ b.WriteString(html.EscapeString(h.text) + "</td>")65+}66+67+// visibleRows is how many drawn rows a merge spans.68+func (l *htmlLayout) visibleRows(m sheet.Rect) int {69+ n := 070+ for row := m.From.Row; row <= m.To.Row; row++ {71+ if !l.snap.HiddenRows[row] {72+ n++73+ }74+ }75+ return max(n, 1)76+}77+78+// nextFilled reports whether the cell right of a holds something, which79+// a's text stops at rather than running on, as in Sheets.80+func (l *htmlLayout) nextFilled(a sheet.Addr) bool {81+ next := sheet.Addr{Col: a.Col + 1, Row: a.Row}82+ c, ok := l.snap.Cells[next]83+ return ok && (c.Input != "" || c.Value.Kind != sheet.Empty) || l.covered[next]84+}85+86+// content is the cell's text as the grid shows it in width columns,87+// where it goes, and what was typed when that isn't the text.88+func (h *htmlCell) content(snap *Snapshot, c SnapCell, width int) {89+ text, align := sheet.DisplayIn(c.Value, c.Format, width, snap.Locale)90+ h.text = text91+ switch c.Style.Align {92+ case sheet.AlignLeft:93+ align = sheet.AlignLeft94+ case sheet.AlignCenter:95+ align = sheet.AlignCenter96+ case sheet.AlignRight:97+ align = sheet.AlignRight98+ }99+ switch align {100+ case sheet.AlignRight:101+ h.class = append(h.class, "r")102+ case sheet.AlignCenter:103+ h.class = append(h.class, "c")104+ }105+ if c.Value.Kind == sheet.Error {106+ h.class = append(h.class, "err")107+ }108+ if c.Input != "" && c.Input != text {109+ h.attrs += ` data-f="` + html.EscapeString(c.Input) + `"`110+ }111+ switch c.Style.Wrap {112+ case sheet.WrapOn:113+ h.class = append(h.class, "wrap")114+ case sheet.WrapClip:115+ h.class = append(h.class, "clip")116+ }117+ switch c.Style.VAlign {118+ case sheet.VAlignTop:119+ h.class = append(h.class, "t")120+ case sheet.VAlignMiddle:121+ h.class = append(h.class, "m")122+ }123+}124+125+// textStyle adds bold, italic, underline and strikethrough.126+func (h *htmlCell) textStyle(st sheet.Style) {127+ for _, f := range []struct {128+ on bool129+ class string130+ }{{st.Bold, "b"}, {st.Italic, "i"}, {st.Underline, "u"}, {st.Strikethrough, "s"}} {131+ if f.on {132+ h.class = append(h.class, f.class)133+ }134+ }135+}136+137+// borders draws each edge's line in its color, or the border role's138+// when it has none.139+func (h *htmlCell) borders(b sheet.Borders) {140+ if b.IsZero() {141+ return142+ }143+ for _, e := range []struct {144+ edge sheet.Edge145+ side string146+ }{{sheet.EdgeTop, "top"}, {sheet.EdgeBottom, "bottom"}, {sheet.EdgeLeft, "left"}, {sheet.EdgeRight, "right"}} {147+ st := b.Stroke(e.edge)148+ line := ""149+ switch st.Line {150+ case sheet.LineThin:151+ line = "1px solid"152+ case sheet.LineThick:153+ line = "2px solid"154+ case sheet.LineDouble:155+ line = "3px double"156+ default:157+ continue158+ }159+ color := "var(--border)"160+ if st.Color != sheet.ColorNone {161+ color = ruleVar(st.Color)162+ }163+ h.style = append(h.style, "border-"+e.side+":"+line+" "+color)164+ }165+}166+167+func ruleVar(c sheet.Color) string { return fmt.Sprintf("var(--r%d)", int(c)) }168+func inkVar(c sheet.Color) string { return fmt.Sprintf("var(--i%d)", int(c)) }169+170+// look draws what the sheet's rules show: a conditional format's171+// colors and text style, a color scale, a data bar, an icon, a172+// checkbox, a dropdown's marker and an invalid entry's underline.173+func (h *htmlCell) look(l sheet.Look) {174+ if l.Styled {175+ h.ruleStyle(l.Style)176+ }177+ if l.Scaled {178+ pct := int(l.Pos*100 + 0.5)179+ h.style = append(h.style, fmt.Sprintf("background:color-mix(in srgb,%s %d%%,%s)", ruleVar(l.To), pct, ruleVar(l.From)))180+ ink := l.From181+ if l.Pos >= 0.5 {182+ ink = l.To183+ }184+ h.style = append(h.style, "color:"+inkVar(ink))185+ }186+ if l.Bar {187+ pct := int(l.BarLen*100 + 0.5)188+ h.style = append(h.style, fmt.Sprintf("background:linear-gradient(to right,color-mix(in srgb,%s 55%%,transparent) %d%%,transparent %d%%)",189+ ruleVar(l.BarColor), pct, pct))190+ }191+ if l.ValueHidden {192+ h.text = ""193+ }194+ if l.Icon != "" {195+ h.icon = fmt.Sprintf(`<span class="icon" style="color:%s">%s</span>`, ruleVar(l.IconColor), html.EscapeString(l.Icon))196+ }197+ switch {198+ case l.Checkbox && l.Checked:199+ h.text, h.class = "[✓]", append(h.class, "c")200+ case l.Checkbox:201+ h.text, h.class = "[ ]", append(h.class, "c")202+ case l.Dropdown:203+ h.text += " ▾"204+ }205+ if l.Invalid {206+ h.class = append(h.class, "bad")207+ }208+}209+210+// ruleStyle is a single-color rule's fill, text color and text style.211+func (h *htmlCell) ruleStyle(st sheet.RuleStyle) {212+ switch {213+ case st.Fill != sheet.ColorNone && (st.Text == sheet.ColorNone || st.Text == st.Fill):214+ h.style = append(h.style, "background:"+ruleVar(st.Fill), "color:"+inkVar(st.Fill))215+ case st.Fill != sheet.ColorNone:216+ h.style = append(h.style, "background:"+ruleVar(st.Fill), "color:"+ruleVar(st.Text))217+ case st.Text != sheet.ColorNone:218+ h.style = append(h.style, "color:"+ruleVar(st.Text))219+ }220+ h.textStyle(sheet.Style{Bold: st.Bold, Italic: st.Italic, Underline: st.Underline, Strikethrough: st.Strikethrough})221+}
A internal/fileio/htmlgrid.go +239 -0
@@ -0,0 +1,239 @@
1+package fileio2+3+import (4+ "fmt"5+ "html"6+ "sort"7+ "strconv"8+ "strings"9+10+ "github.com/FelineStateMachine/012/internal/chart"11+ "github.com/FelineStateMachine/012/internal/sheet"12+)13+14+// maxHTMLCells bounds the cells a page draws, blank ones included: a15+// browser shows a table of about this many at once without trouble.16+// Past it the page draws the first rows and says so.17+const maxHTMLCells = 200_00018+19+// htmlLayout is where the grid's rows and columns go: the columns and20+// rows drawn, in order, and the pixel offset of each from the grid's21+// top-left corner, headers included.22+type htmlLayout struct {23+ snap *Snapshot24+ cols, rows []int25+ x, y map[int]int // left edge of a column, top edge of a row26+ headW int // the row numbers' width27+ cut int // rows left out past maxHTMLCells28+ merged map[sheet.Addr]sheet.Rect29+ covered map[sheet.Addr]bool30+ tableRole map[sheet.Addr]string31+}32+33+// layout places the snapshot's range, grown to hold its charts.34+func layout(snap *Snapshot) *htmlLayout {35+ r := snap.Range36+ colsTo, rowsTo := r.To.Col, r.To.Row37+ for _, c := range snap.Charts {38+ colsTo = max(colsTo, chartEndCol(snap, c))39+ rowsTo = max(rowsTo, chartEndRow(snap, c))40+ }41+ l := &htmlLayout{snap: snap, x: map[int]int{}, y: map[int]int{}}42+ for col := r.From.Col; col <= min(colsTo, sheet.MaxCols-1); col++ {43+ l.cols = append(l.cols, col)44+ }45+ maxRows := max(maxHTMLCells/max(len(l.cols), 1), 100)46+ for row := r.From.Row; row <= min(rowsTo, sheet.MaxRows-1); row++ {47+ if snap.HiddenRows[row] {48+ continue49+ }50+ if len(l.rows) == maxRows {51+ l.cut = rowsTo - row + 152+ break53+ }54+ l.rows = append(l.rows, row)55+ }56+ last := r.From.Row + 157+ if len(l.rows) > 0 {58+ last = l.rows[len(l.rows)-1] + 159+ }60+ l.headW = (max(len(strconv.Itoa(last)), 3) + 2) * htmlCellW61+ x := l.headW62+ for _, col := range l.cols {63+ l.x[col] = x64+ x += htmlColWidth(snap, col) * htmlCellW65+ }66+ y := htmlCellH67+ for _, row := range l.rows {68+ l.y[row] = y69+ y += htmlRowHeight(snap, row) * htmlCellH70+ }71+ l.mergesAndTables()72+ return l73+}74+75+func htmlColWidth(snap *Snapshot, col int) int {76+ if w, ok := snap.Widths[col]; ok {77+ return w78+ }79+ return sheet.DefaultWidth80+}81+82+func htmlRowHeight(snap *Snapshot, row int) int {83+ if h, ok := snap.Heights[row]; ok && h > 0 {84+ return h85+ }86+ return 187+}88+89+// chartEndCol is the last column a chart covers.90+func chartEndCol(snap *Snapshot, c SnapChart) int {91+ col, w := c.At.Col, c.W92+ for w > htmlColWidth(snap, col) && col < sheet.MaxCols-1 {93+ w -= htmlColWidth(snap, col)94+ col++95+ }96+ return col97+}98+99+// chartEndRow is the last row a chart covers.100+func chartEndRow(snap *Snapshot, c SnapChart) int {101+ row, h := c.At.Row, c.H102+ for h > htmlRowHeight(snap, row) && row < sheet.MaxRows-1 {103+ h -= htmlRowHeight(snap, row)104+ row++105+ }106+ return row107+}108+109+// mergesAndTables notes the merged cells and the cells tables style.110+func (l *htmlLayout) mergesAndTables() {111+ l.merged, l.covered, l.tableRole = map[sheet.Addr]sheet.Rect{}, map[sheet.Addr]bool{}, map[sheet.Addr]string{}112+ for _, m := range l.snap.Merges {113+ l.merged[m.From] = m114+ for row := m.From.Row; row <= m.To.Row; row++ {115+ for col := m.From.Col; col <= m.To.Col; col++ {116+ if a := (sheet.Addr{Col: col, Row: row}); a != m.From {117+ l.covered[a] = true118+ }119+ }120+ }121+ }122+ for _, t := range l.snap.Tables {123+ for col := t.Range.From.Col; col <= t.Range.To.Col; col++ {124+ if t.Header {125+ l.tableRole[sheet.Addr{Col: col, Row: t.Range.From.Row}] = "th"126+ }127+ for row := t.Range.From.Row + 2; t.Banded && row <= t.Range.To.Row; row += 2 {128+ l.tableRole[sheet.Addr{Col: col, Row: row}] = "band"129+ }130+ }131+ }132+}133+134+// HTMLGrid draws the snapshot as 012's grid: column letters and row135+// numbers, the cells as they show with their styles, borders and the136+// looks of rules, and the charts over them. It returns the fragment and137+// a note when rows were left out.138+func HTMLGrid(snap *Snapshot) (string, string) {139+ l := layout(snap)140+ var b strings.Builder141+ b.WriteString(`<div class="sheet"><table class="grid"><colgroup>`)142+ fmt.Fprintf(&b, `<col style="width:%dpx">`, l.headW)143+ for _, col := range l.cols {144+ fmt.Fprintf(&b, `<col style="width:%dpx">`, htmlColWidth(snap, col)*htmlCellW)145+ }146+ b.WriteString(`</colgroup><thead><tr><th class="corner"></th>`)147+ for _, col := range l.cols {148+ fmt.Fprintf(&b, `<th data-c="%s">%s</th>`, sheet.ColName(col), sheet.ColName(col))149+ }150+ b.WriteString("</tr></thead><tbody>")151+ for _, row := range l.rows {152+ l.writeRow(&b, row)153+ }154+ b.WriteString("</tbody></table>")155+ for _, c := range snap.Charts {156+ l.writeChart(&b, c)157+ }158+ b.WriteString("</div>")159+ note := ""160+ if l.cut > 0 {161+ note = fmt.Sprintf("HTML pages show the first %d rows: %d more are left out", len(l.rows), l.cut)162+ }163+ return b.String(), note164+}165+166+func (l *htmlLayout) writeRow(b *strings.Builder, row int) {167+ style := ""168+ if h := htmlRowHeight(l.snap, row); h > 1 {169+ style = fmt.Sprintf(` style="height:%dpx"`, h*htmlCellH)170+ }171+ fmt.Fprintf(b, `<tr%s><th data-r="%d">%d</th>`, style, row+1, row+1)172+ for _, col := range l.cols {173+ a := sheet.Addr{Col: col, Row: row}174+ if l.covered[a] {175+ continue176+ }177+ l.writeCell(b, a)178+ }179+ b.WriteString("</tr>")180+}181+182+// writeChart draws a chart in its frame over the cells under it, as183+// the screen does: the title in the top border, the range in the184+// bottom one.185+func (l *htmlLayout) writeChart(b *strings.Builder, c SnapChart) {186+ x, y := l.at(c.At)187+ fmt.Fprintf(b, `<figure class="chart" style="left:%dpx;top:%dpx;width:%dpx;height:%dpx">`,188+ x, y, c.W*htmlCellW, c.H*htmlCellH)189+ writeChartBody(b, c)190+ b.WriteString("</figure>")191+}192+193+// writeChartBody is a chart's frame labels and drawing, inside its194+// figure.195+func writeChartBody(b *strings.Builder, c SnapChart) {196+ fmt.Fprintf(b, `<figcaption>%s</figcaption>`, html.EscapeString(chartTitle(c.Chart)))197+ b.WriteString(chart.SVG(c.Type, c.Values, c.W-4, c.H-2, chart.Options{Chart: c.ChartOptions}, chartTitle(c.Chart)))198+ fmt.Fprintf(b, `<span class="range">%s</span>`, c.Data.String())199+}200+201+// chartTitle is a chart's title, or its type's name when it has none.202+func chartTitle(c sheet.Chart) string {203+ if c.Title != "" {204+ return c.Title205+ }206+ return c.Type.Title() + " chart"207+}208+209+// at is the pixel offset of a cell's top-left corner; a cell in a210+// hidden row or past the drawn ones sits where the next drawn one does.211+func (l *htmlLayout) at(a sheet.Addr) (int, int) {212+ x, ok := l.x[a.Col]213+ if !ok {214+ x = l.headW215+ }216+ y, ok := l.y[a.Row]217+ if !ok {218+ i := sort.SearchInts(l.rows, a.Row)219+ switch {220+ case i < len(l.rows):221+ y = l.y[l.rows[i]]222+ case len(l.rows) > 0:223+ last := l.rows[len(l.rows)-1]224+ y = l.y[last] + htmlRowHeight(l.snap, last)*htmlCellH225+ default:226+ y = htmlCellH227+ }228+ }229+ return x, y230+}231+232+// HTMLChart draws one chart alone, in its frame.233+func HTMLChart(c SnapChart) string {234+ var b strings.Builder235+ fmt.Fprintf(&b, `<figure class="chart solo" style="width:%dpx;height:%dpx">`, c.W*htmlCellW, c.H*htmlCellH)236+ writeChartBody(&b, c)237+ b.WriteString("</figure>")238+ return b.String()239+}
A internal/fileio/htmlstyle.go +169 -0
@@ -0,0 +1,169 @@
1+package fileio2+3+import (4+ "embed"5+ "encoding/base64"6+ "fmt"7+ "math"8+ "strings"9+ "sync"10+11+ "github.com/FelineStateMachine/012/internal/chart"12+ "github.com/FelineStateMachine/012/internal/sheet"13+)14+15+// HTML pages are drawn in 012's look: the 16 ANSI colors of the16+// reference palettes the golden screens use (e2e/palette_test.go),17+// mapped to the roles the terminal theme gives them18+// (internal/ui/theme), dark or light as the reader's system prefers,19+// in IBM Plex Mono, the docs site's font, embedded so the page needs20+// nothing else. One cell is htmlCellW by htmlCellH pixels, the size of21+// a cell of an SVG chart, so charts sit on the grid as on the screen.22+23+const (24+ htmlCellW = chart.SVGCellW25+ htmlCellH = chart.SVGCellH26+)27+28+//go:embed fonts/*.woff229+var fonts embed.FS30+31+// htmlPalette is a reference palette and the roles drawn in it.32+type htmlPalette struct {33+ ansi [16]uint3234+ bg, fg uint3235+ grid uint32 // the faint lines between cells36+ // ANSI slots of the roles.37+ headerBg, headerFg, bar, muted, border, note, link int38+ series [chart.Colors]int39+}40+41+var htmlPalettes = [2]htmlPalette{{42+ ansi: [16]uint32{0x1d1f21, 0xcc6666, 0xb5bd68, 0xf0c674, 0x81a2be, 0xb294bb, 0x8abeb7, 0xc5c8c6,43+ 0x666666, 0xd54e53, 0xb9ca4a, 0xe7c547, 0x7aa6da, 0xc397d8, 0x70c0b1, 0xeaeaea},44+ bg: 0x1d1f21, fg: 0xc5c8c6, grid: 0x2c2e30,45+ headerBg: 8, headerFg: 15, bar: 6, muted: 8, border: 7, note: 3, link: 12,46+ series: [chart.Colors]int{6, 5, 3, 2, 12, 9},47+}, {48+ ansi: [16]uint32{0x1d1f21, 0xc82829, 0x718c00, 0xb58900, 0x4271ae, 0x8959a8, 0x3e999f, 0xd6d6d6,49+ 0x8e908c, 0xc82829, 0x718c00, 0xb58900, 0x4271ae, 0x8959a8, 0x3e999f, 0xffffff},50+ bg: 0xfafafa, fg: 0x1d1f21, grid: 0xe8e8e8,51+ headerBg: 7, headerFg: 0, bar: 4, muted: 0, border: 0, note: 5, link: 4,52+ series: [chart.Colors]int{4, 5, 2, 1, 6, 8},53+}}54+55+// ruleSlots are the ANSI slots of sheet.Color, as the theme maps them.56+var ruleSlots = [sheet.NumColors]int{0, 1, 3, 2, 6, 4, 5}57+58+// vars writes the palette's CSS variables.59+func (p htmlPalette) vars() string {60+ var b strings.Builder61+ hex := func(v uint32) string { return fmt.Sprintf("#%06x", v) }62+ slot := func(i int) string { return hex(p.ansi[i]) }63+ fmt.Fprintf(&b, "--bg:%s;--fg:%s;--grid:%s;--hbg:%s;--hfg:%s;--bar:%s;--muted:%s;--border:%s;--note:%s;--link:%s;--axis:%s;--acc:%s;--accfg:%s;",64+ hex(p.bg), hex(p.fg), hex(p.grid), slot(p.headerBg), slot(p.headerFg), slot(p.bar), slot(p.muted),65+ slot(p.border), slot(p.note), slot(p.link), slot(8), slot(6), slot(0))66+ for i, s := range p.series {67+ fmt.Fprintf(&b, "--s%d:%s;", i, slot(s))68+ }69+ for c := 1; c < sheet.NumColors; c++ {70+ fill := p.ansi[ruleSlots[c]]71+ fmt.Fprintf(&b, "--r%d:%s;--i%d:%s;", c, hex(fill), c, hex(p.ink(fill)))72+ }73+ return b.String()74+}75+76+// ink is black or bright white, whichever reads better on bg.77+func (p htmlPalette) ink(bg uint32) uint32 {78+ if contrast(p.ansi[0], bg) >= contrast(p.ansi[15], bg) {79+ return p.ansi[0]80+ }81+ return p.ansi[15]82+}83+84+// contrast is the WCAG contrast ratio of two colors.85+func contrast(a, b uint32) float64 {86+ la, lb := luminance(a), luminance(b)87+ return (max(la, lb) + 0.05) / (min(la, lb) + 0.05)88+}89+90+func luminance(c uint32) float64 {91+ ch := func(v uint32) float64 {92+ s := float64(v&0xff) / 25593+ if s <= 0.03928 {94+ return s / 12.9295+ }96+ return math.Pow((s+0.055)/1.055, 2.4)97+ }98+ return 0.2126*ch(c>>16) + 0.7152*ch(c>>8) + 0.0722*ch(c)99+}100+101+// htmlCSS is the style sheet every page and view shares, fonts102+// included.103+var htmlCSS = sync.OnceValue(func() string {104+ var b strings.Builder105+ for _, f := range []struct{ file, weight, style string }{106+ {"ibm-plex-mono-latin-400-normal.woff2", "400", "normal"},107+ {"ibm-plex-mono-latin-600-normal.woff2", "600", "normal"},108+ {"ibm-plex-mono-latin-400-italic.woff2", "400", "italic"},109+ } {110+ data, _ := fonts.ReadFile("fonts/" + f.file)111+ fmt.Fprintf(&b, "@font-face{font-family:'IBM Plex Mono';font-weight:%s;font-style:%s;src:url(data:font/woff2;base64,%s) format('woff2')}\n",112+ f.weight, f.style, base64.StdEncoding.EncodeToString(data))113+ }114+ dark, light := htmlPalettes[0].vars(), htmlPalettes[1].vars()115+ fmt.Fprintf(&b, ":root{%s}\n@media (prefers-color-scheme:light){:root:not(.dark){%s}}\n:root.light{%s}\n", dark, light, light)116+ b.WriteString(htmlRules)117+ return b.String()118+})119+120+// HTMLStyle is the style sheet of 012's HTML pages, for a page built121+// around HTMLGrid or HTMLChart; the root element takes the class dark122+// or light to choose a palette over the reader's preference.123+func HTMLStyle() string { return htmlCSS() }124+125+// htmlRules are the page's rules, after its fonts and palettes.126+const htmlRules = `*{box-sizing:border-box}127+html,body{margin:0;background:var(--bg);color:var(--fg)}128+body{font:15px/21px 'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;font-variant-ligatures:none}129+.o12{min-width:100%;width:max-content}130+.panel{position:sticky;left:0;top:0;z-index:3;background:var(--bg);white-space:pre;width:100vw;max-width:100%}131+.panel>div{height:21px;display:flex;gap:9px;overflow:hidden}132+.panel .book{flex:1;overflow:hidden;text-overflow:ellipsis}133+.mode{background:var(--acc);color:var(--accfg);font-weight:600;padding:0 9px}134+.namebox{background:var(--hbg);color:var(--hfg);min-width:90px;padding:0 9px}135+.input{flex:1;overflow:hidden;text-overflow:ellipsis}136+.context{color:var(--muted)}137+.sheet{position:relative}138+table.grid{border-collapse:collapse;table-layout:fixed;width:max-content}139+.grid th{background:var(--hbg);color:var(--hfg);font-weight:400;height:21px;padding:0;text-align:center;position:sticky;z-index:1}140+.grid thead th{top:63px}141+.grid tbody th{left:0;text-align:right;padding-right:9px;vertical-align:bottom}142+.grid thead th.corner{left:0;z-index:2}143+.grid th.on{background:var(--acc);color:var(--accfg);font-weight:600}144+.grid td{height:21px;padding:0 4px;white-space:pre;overflow:visible;box-shadow:inset -1px -1px 0 var(--grid);vertical-align:bottom;position:relative}145+.grid td.clip{overflow:hidden}146+.grid td.wrap{white-space:pre-wrap;overflow-wrap:anywhere}147+.grid td.r{text-align:right}.grid td.c{text-align:center}.grid td.l{text-align:left}148+.grid td.t{vertical-align:top}.grid td.m{vertical-align:middle}149+.grid td.b{font-weight:600}.grid td.i{font-style:italic}150+.grid td.u{text-decoration:underline}.grid td.s{text-decoration:line-through}.grid td.u.s{text-decoration:underline line-through}151+.grid td.err{text-decoration:underline wavy var(--r1)}152+.grid td.bad{text-decoration:underline dotted var(--r2)}153+.grid td.th{font-weight:600;text-decoration:underline;color:var(--bar)}154+.grid td.band{background:var(--hbg);color:var(--hfg)}155+.grid td.note::after{content:'\259D';position:absolute;right:0;top:-3px;color:var(--note);font-size:12px}156+.grid td.ptr{outline:2px solid var(--acc);outline-offset:-2px}157+.grid a{color:var(--link)}158+.grid .icon{margin-right:9px}159+figure.chart{position:absolute;margin:0;border:1px solid var(--axis);background:var(--bg);padding:20px 17px;z-index:1}160+figure.chart figcaption{position:absolute;top:-11px;left:9px;background:var(--bg);padding:0 9px;font-weight:600;white-space:pre}161+figure.chart .range{position:absolute;bottom:-11px;right:9px;background:var(--bg);padding:0 9px;color:var(--muted);white-space:pre}162+figure.solo{position:relative;display:inline-block;margin:21px 18px}163+svg.chart{display:block;overflow:visible;font:15px 'IBM Plex Mono',ui-monospace,monospace}164+.ct-ax{fill:var(--axis);color:var(--axis)}.ct-lb{fill:var(--muted);color:var(--muted)}.ct-mu{fill:var(--muted);color:var(--muted)}165+.cs-box{stroke:currentColor;stroke-width:1}.cs-gl{stroke:var(--grid);stroke-width:1}.cs-gap{stroke:var(--bg);stroke-width:1.5}166+.ct-s0,.cf-0{fill:var(--s0)}.ct-s1,.cf-1{fill:var(--s1)}.ct-s2,.cf-2{fill:var(--s2)}.ct-s3,.cf-3{fill:var(--s3)}.ct-s4,.cf-4{fill:var(--s4)}.ct-s5,.cf-5{fill:var(--s5)}167+.cs-0{stroke:var(--s0)}.cs-1{stroke:var(--s1)}.cs-2{stroke:var(--s2)}.cs-3{stroke:var(--s3)}.cs-4{stroke:var(--s4)}.cs-5{stroke:var(--s5)}168+.status{white-space:pre;color:var(--muted);padding:0 9px;height:21px}169+`
M internal/fileio/sheetscorpus_xlsx_test.go +14 -4
@@ -6,6 +6,7 @@ import (
66 "os"77 "slices"88 "strconv"9+ "strings"910 "testing"1011 1112 "github.com/FelineStateMachine/012/internal/sheet"
@@ -59,8 +60,8 @@ func excelKeeps(formula string) bool {
5960 6061 // foldSheets records Sheets' results from name, a CSV download of the6162 // corpus sheet after importing the XLSX workbook into Sheets. Rows left62-// out of the download, and formulas saved as values that weren't typed63-// in, stay as they are.63+// out of the download, formulas saved as values that weren't typed in,64+// and functions the import didn't recognize stay as they are.6465 func foldSheets(t *testing.T, rows []*corpusLine, name string) {6566 t.Helper()6667 f, err := os.Open(name)
@@ -78,13 +79,22 @@ func foldSheets(t *testing.T, rows []*corpusLine, name string) {
7879 sheets := map[string]string{}7980 for _, rec := range recs[1:] {8081 if len(rec) > colKind {81- sheets[rec[colFormula]] = encodeResult(rec[colText], rec[colKind])82+ text := rec[colText]83+ if rec[colKind] == "number" {84+ // Sheets writes a number a hair off a whole one, such as85+ // 100*1.1, as "110." when it rounds to 15 digits.86+ text = strings.TrimSuffix(text, ".")87+ }88+ sheets[rec[colFormula]] = encodeResult(text, rec[colKind])8289 }8390 }8491 skipped := 08592 for _, r := range rows {8693 got, ok := sheets[r.formula]87- if !ok || (got == "(blank)" && !excelKeeps(r.formula)) {94+ // #NAME? where 012 knows every name means the import didn't95+ // recognize a function (Sheets reads Excel's _xlfn._xlws.FILTER96+ // so): the formula wasn't computed.97+ if !ok || (got == "(blank)" && !excelKeeps(r.formula)) || (got == "#NAME?" && r.ours != got) {8898 skipped++8999 continue90100 }
A internal/fileio/snapdrawn.go +32 -0
M internal/fileio/snapshot.go +7 -0
M internal/fileio/testdata/sheets_corpus.tsv +290 -290
@@ -6,315 +6,315 @@
66 # Every formula computes one value; array results are measured with ROWS,77 # COLUMNS, INDEX or TEXTJOIN. Data! is the fixture sheet (sheetscorpus_test.go).88 ## Dates and times9-=DATE(2026, 9, 26) 46291 unconfirmed10-=DATE(2026, 14, 1) 46419 unconfirmed11-=DATE(2026, 1, 0) 46022 unconfirmed12-=DATE(26, 1, 1) 9498 unconfirmed13-=DATE(1899, 12, 30) 693961 unconfirmed14-=DATE(1900, 1, 1) 2 unconfirmed15-=DATE(1900, 2, 29) 61 unconfirmed16-=DATE(-1, 1, 1) #NUM! unconfirmed17-=DATE("2026", "9", "26") 46291 unconfirmed18-=TIME(14, 30, 0) 0.604166666666667 unconfirmed19-=TIME(25, 0, 0) 0.0416666666666667 unconfirmed20-=TIME(0, -1, 0) #NUM! unconfirmed21-=YEAR(0) 1899 unconfirmed22-=DAY(Data!A5) 30 unconfirmed23-=YEAR(Data!A4) #VALUE! unconfirmed24-=WEEKDAY(Data!F1) 7 unconfirmed25-=WEEKDAY(Data!F1, 2) 6 unconfirmed26-=WEEKDAY(Data!F1, 4) #NUM! unconfirmed27-=HOUR(0.99999999) 0 unconfirmed28-=HOUR(1.75) 18 unconfirmed29-=MINUTE("14:30:59") 30 unconfirmed30-=SECOND(59.6/86400) 0 unconfirmed31-=EDATE(DATE(2024, 2, 29), 12) 45716 unconfirmed32-=EDATE(Data!F1, 1.9) 46321 unconfirmed33-=EOMONTH(DATE(2026, 1, 31), 1) 46081 unconfirmed34-=DATEDIF(Data!F4, Data!F1, "MD") 28 unconfirmed35-=DATEDIF(Data!F4, Data!F1, "YD") 210 unconfirmed36-=DATEDIF(DATE(2024, 1, 31), DATE(2024, 3, 1), "MD") -1 unconfirmed37-=DATEDIF(Data!F2, Data!F5, "D") #NUM! unconfirmed38-=DAYS(Data!F1, Data!F2) 238 unconfirmed39-=NETWORKDAYS(Data!F5, Data!F2, Data!F5) 22 unconfirmed40-=NETWORKDAYS(Data!F1, Data!F1) 0 unconfirmed41-=DATEVALUE("9/26/2026") 46291 unconfirmed42-=DATEVALUE("Sep 26, 2026") 46291 unconfirmed43-=DATEVALUE("9/26/2026 18:00") 46291 unconfirmed44-=DATEVALUE("2/30/2026") #VALUE! unconfirmed45-=DATEVALUE(46291) #VALUE! unconfirmed46-=TIMEVALUE("2:30 PM") 0.604166666666667 unconfirmed47-=TIMEVALUE("9/26/2026 6:00") 0.25 unconfirmed48-=TIMEVALUE("noon") #VALUE! unconfirmed49-="2026-09-27"-Data!F1 1 unconfirmed50-=Data!F1+Data!F3 46291.6041666667 unconfirmed51-=Data!F1="2026-09-26" FALSE unconfirmed9+=DATE(2026, 9, 26) 46291 4629110+=DATE(2026, 14, 1) 46419 4641911+=DATE(2026, 1, 0) 46022 4602212+=DATE(26, 1, 1) 9498 949813+=DATE(1899, 12, 30) 693961 69396114+=DATE(1900, 1, 1) 2 215+=DATE(1900, 2, 29) 61 6116+=DATE(-1, 1, 1) #NUM! #NUM!17+=DATE("2026", "9", "26") 46291 4629118+=TIME(14, 30, 0) 0.604166666666667 0.60416666666666719+=TIME(25, 0, 0) 0.0416666666666667 0.041666666666666720+=TIME(0, -1, 0) #NUM! #NUM!21+=YEAR(0) 1899 189922+=DAY(Data!A5) 30 3023+=YEAR(Data!A4) #VALUE! #VALUE!24+=WEEKDAY(Data!F1) 7 725+=WEEKDAY(Data!F1, 2) 6 626+=WEEKDAY(Data!F1, 4) #NUM! #NUM!27+=HOUR(0.99999999) 0 028+=HOUR(1.75) 18 1829+=MINUTE("14:30:59") 30 3030+=SECOND(59.6/86400) 0 031+=EDATE(DATE(2024, 2, 29), 12) 45716 4571632+=EDATE(Data!F1, 1.9) 46321 4632133+=EOMONTH(DATE(2026, 1, 31), 1) 46081 4608134+=DATEDIF(Data!F4, Data!F1, "MD") 28 2835+=DATEDIF(Data!F4, Data!F1, "YD") 210 21036+=DATEDIF(DATE(2024, 1, 31), DATE(2024, 3, 1), "MD") -1 -137+=DATEDIF(Data!F2, Data!F5, "D") #NUM! #NUM!38+=DAYS(Data!F1, Data!F2) 238 23839+=NETWORKDAYS(Data!F5, Data!F2, Data!F5) 22 2240+=NETWORKDAYS(Data!F1, Data!F1) 0 041+=DATEVALUE("9/26/2026") 46291 4629142+=DATEVALUE("Sep 26, 2026") 46291 4629143+=DATEVALUE("9/26/2026 18:00") 46291 4629144+=DATEVALUE("2/30/2026") #VALUE! #VALUE!45+=DATEVALUE(46291) #VALUE! #VALUE!46+=TIMEVALUE("2:30 PM") 0.604166666666667 0.60416666666666747+=TIMEVALUE("9/26/2026 6:00") 0.25 0.2548+=TIMEVALUE("noon") #VALUE! #VALUE!49+="2026-09-27"-Data!F1 1 150+=Data!F1+Data!F3 46291.6041666667 46291.604166666751+=Data!F1="2026-09-26" FALSE FALSE5252 ## Text53-=CONCATENATE("a", 1, TRUE) "a1TRUE" unconfirmed54-=CONCATENATE(Data!A1:A3) "102030" unconfirmed55-=TEXTJOIN(", ", TRUE, Data!A3:A5) "30, apple" unconfirmed56-=TEXTJOIN(",", FALSE, Data!B5:B7) "north,,Ab*d" unconfirmed57-=LEFT("hi", -1) #VALUE! unconfirmed58-=LEFT(12345, 2) "12" unconfirmed59-=LEFT(TRUE, 1) "T" unconfirmed60-=MID("abc", 5, 2) "" unconfirmed61-=MID("abc", 0, 2) #VALUE! unconfirmed62-=LEN(Data!F1) 5 unconfirmed63-=LEN(1/4) 4 unconfirmed64-=LEN("héllo") 5 unconfirmed65-=LEN("😀") 1 unconfirmed66-=LEFT("日本語", 2) "日本" unconfirmed67-=UPPER("straße") "STRAßE" unconfirmed68-=UPPER(1.5) "1.5" unconfirmed69-=PROPER("hello wORLD it's") "Hello World It'S" unconfirmed70-=PROPER("o'neil mcdonald 3rd") "O'Neil Mcdonald 3Rd" unconfirmed71-=TRIM(" a b ") "a b" unconfirmed72-=SUBSTITUTE("aaa", "aa", "b") "ba" unconfirmed73-=SUBSTITUTE("abc", "", "x") "abc" unconfirmed74-=REPLACE("abc", 10, 1, "X") "abcX" unconfirmed75-=FIND("B", "abc") #VALUE! unconfirmed76-=FIND("", "abc") 1 unconfirmed77-=SEARCH("b?d", "abcbxd") 4 unconfirmed78-=SEARCH("~*", "a*b") 2 unconfirmed79-=REPT("ab", 2.9) "abab" unconfirmed80-=REPT("ab", -1) #VALUE! unconfirmed81-=EXACT(1, "1") TRUE unconfirmed82-=EXACT(TRUE, "TRUE") TRUE unconfirmed83-="a"&Data!A5 "a" unconfirmed84-=1&2 "12" unconfirmed85-=VALUE("1,234.5") 1234.5 unconfirmed86-=VALUE(" 42 ") 42 unconfirmed87-=VALUE("") 0 unconfirmed88-=VALUE("abc") #VALUE! unconfirmed89-=VALUE("9/26/2026") 46291 unconfirmed90-=VALUE(TRUE) #VALUE! unconfirmed53+=CONCATENATE("a", 1, TRUE) "a1TRUE" "a1TRUE"54+=CONCATENATE(Data!A1:A3) "102030" "102030"55+=TEXTJOIN(", ", TRUE, Data!A3:A5) "30, apple" "30, apple"56+=TEXTJOIN(",", FALSE, Data!B5:B7) "north,,Ab*d" "north,,Ab*d"57+=LEFT("hi", -1) #VALUE! #VALUE!58+=LEFT(12345, 2) "12" "12"59+=LEFT(TRUE, 1) "T" "T"60+=MID("abc", 5, 2) "" ""61+=MID("abc", 0, 2) #NUM! #NUM!62+=LEN(Data!F1) 5 9 on purpose: F1 is a date, stored in the XLSX as its serial with a m/d/yyyy format; Sheets' text functions read a date cell as it shows (9/26/2026), 012 reads its serial, as Excel does63+=LEN(1/4) 4 464+=LEN("héllo") 5 565+=LEN("😀") 1 2 on purpose: LEN counts characters (code points), where Sheets counts UTF-16 units66+=LEFT("日本語", 2) "日本" "日本"67+=UPPER("straße") "STRASSE" "STRASSE"68+=UPPER(1.5) "1.5" "1.5"69+=PROPER("hello wORLD it's") "Hello World It'S" "Hello World It'S"70+=PROPER("o'neil mcdonald 3rd") "O'Neil Mcdonald 3Rd" "O'Neil Mcdonald 3Rd"71+=TRIM(" a b ") "a b" "a b"72+=SUBSTITUTE("aaa", "aa", "b") "ba" "ba"73+=SUBSTITUTE("abc", "", "x") "abc" "abc"74+=REPLACE("abc", 10, 1, "X") "abcX" "abcX"75+=FIND("B", "abc") #VALUE! #VALUE!76+=FIND("", "abc") 1 177+=SEARCH("b?d", "abcbxd") 4 478+=SEARCH("~*", "a*b") 2 279+=REPT("ab", 2.9) "abab" "abab"80+=REPT("ab", -1) #VALUE! #VALUE!81+=EXACT(1, "1") TRUE TRUE82+=EXACT(TRUE, "TRUE") TRUE TRUE83+="a"&Data!A5 "a" "a"84+=1&2 "12" "12"85+=VALUE("1,234.5") 1234.5 1234.586+=VALUE(" 42 ") 42 4287+=VALUE("") 0 088+=VALUE("abc") #VALUE! #VALUE!89+=VALUE("9/26/2026") 46291 4629190+=VALUE(TRUE) #VALUE! #VALUE!9191 ## Regular expressions and SPLIT9292 =REGEXMATCH("ABC", "(?i)abc") TRUE unconfirmed9393 =REGEXMATCH(123, "1") #VALUE! unconfirmed9494 =REGEXEXTRACT("abc", "\d+") #N/A unconfirmed95-=TEXTJOIN("|", TRUE, REGEXEXTRACT("a1b2", "(\d)b(\d)")) "1" unconfirmed96-=REGEXREPLACE("john smith", "(\w+) (\w+)", "$2, $1") "smith, john" unconfirmed95+=TEXTJOIN("|", TRUE, REGEXEXTRACT("a1b2", "(\d)b(\d)")) "1|2" unconfirmed96+=REGEXREPLACE("john smith", "(\w+) (\w+)", "$2, $1") "smith, john" "smith, john"9797 =COLUMNS(SPLIT("a,b,,c", ",", TRUE, FALSE)) 4 unconfirmed9898 =SUM(SPLIT("1,2,3", ",")) 6 unconfirmed9999 =COLUMNS(SPLIT("a-b_c", "-_")) 3 unconfirmed100100 ## TEXT and number formats101-=TEXT(1234.567, "$#,##0.00") "$1,234.57" unconfirmed102-=TEXT(1234567.891, "#,##0,") "1,235" unconfirmed103-=TEXT(1234.5, "0.00E+00") "1.23E+03" unconfirmed104-=TEXT(0.0000000001, "0.00E+00") "1.00E-10" unconfirmed105-=TEXT(-1234.5, "#,##0.00;(#,##0.00)") "(1,234.50)" unconfirmed106-=TEXT(0, "0;-0;\z\e\r\o") "zero" unconfirmed107-=TEXT(3, "0.###") "3." unconfirmed108-=TEXT(2.5, "0") "3" unconfirmed109-=TEXT(-0.5, "0") "-1" unconfirmed110-=TEXT(1.005, "0.00") "1.01" unconfirmed111-=TEXT(0.75, "# ?/?") " /1" unconfirmed112-=TEXT("abc", "0") "abc" unconfirmed113-=TEXT("12", "0.00") "12.00" unconfirmed114-=TEXT(TRUE, "0") "1" unconfirmed115-=TEXT(Data!F1, "dddd") "Saturday" unconfirmed116-=TEXT(Data!F1, "mmm d, yyyy") "Sep 26, 2026" unconfirmed117-=TEXT(Data!F1, "dddd, mmmm d, yyyy") "Saturday, September 26, 2026" unconfirmed118-=TEXT(Data!F3, "h:mm AM/PM") "2:30 PM" unconfirmed119-=TEXT(0.75, "h AM/PM") "6 PM" unconfirmed120-=TEXT(Data!F1+Data!F3, "yyyy-mm-dd hh:mm") "2026-09-26 14:30" unconfirmed121-=TEXT(1.5, "[h]:mm") "36:00" unconfirmed122-=TEXT(90/1440, "[mm]:ss") "90:00" unconfirmed101+=TEXT(1234.567, "$#,##0.00") "$1,234.57" "$1,234.57"102+=TEXT(1234567.891, "#,##0,") "1,235" "1,235"103+=TEXT(1234.5, "0.00E+00") "1.23E+03" "1.23E+03"104+=TEXT(0.0000000001, "0.00E+00") "1.00E-10" "1.00E-10"105+=TEXT(-1234.5, "#,##0.00;(#,##0.00)") "(1,234.50)" "(1,234.50)"106+=TEXT(0, "0;-0;\z\e\r\o") "zero" "zero"107+=TEXT(3, "0.###") "3." "3."108+=TEXT(2.5, "0") "3" "3"109+=TEXT(-0.5, "0") "-1" "-1"110+=TEXT(1.005, "0.00") "1.01" "1.01"111+=TEXT(0.75, "# ?/?") "3/4" "3/4"112+=TEXT("abc", "0") "abc" "abc"113+=TEXT("12", "0.00") "12.00" "12.00"114+=TEXT(TRUE, "0") "TRUE" "TRUE"115+=TEXT(Data!F1, "dddd") "Saturday" "Saturday"116+=TEXT(Data!F1, "mmm d, yyyy") "Sep 26, 2026" "Sep 26, 2026"117+=TEXT(Data!F1, "dddd, mmmm d, yyyy") "Saturday, September 26, 2026" "Saturday, September 26, 2026"118+=TEXT(Data!F3, "h:mm AM/PM") "2:30 PM" "2:30 PM"119+=TEXT(0.75, "h AM/PM") "6 PM" "6 PM"120+=TEXT(Data!F1+Data!F3, "yyyy-mm-dd hh:mm") "2026-09-26 14:30" "2026-09-26 14:30"121+=TEXT(1.5, "[h]:mm") "36:00" "36:00"122+=TEXT(90/1440, "[mm]:ss") "90:00" "90:00"123123 ## Rounding and floating point124-=ROUND(1.005, 2) 1.01 unconfirmed125-=ROUND(2.675, 2) 2.68 unconfirmed126-=ROUND(0.285, 2) 0.29 unconfirmed127-=ROUND(-2.5) -3 unconfirmed128-=ROUND(1.5, 0.9) 2 unconfirmed129-=ROUND(1.23456789012345, 14) 1.23456789012345 unconfirmed130-=ROUNDUP(0.1+0.2, 1) 0.3 unconfirmed131-=ROUNDDOWN(1-0.9, 1) 0.1 unconfirmed132-=TRUNC(1234, -2) 1200 unconfirmed133-=INT(-1.5) -2 unconfirmed134-=INT(1-0.9+0.9) 1 unconfirmed135-=CEILING(0.3, 0.1) 0.3 unconfirmed136-=CEILING(-2.5, 1) -2 unconfirmed137-=CEILING(-2.5, -1) -3 unconfirmed138-=CEILING(2.5, -1) #NUM! unconfirmed139-=CEILING(2.5, 0) 0 unconfirmed140-=FLOOR(-2.5, 1) -3 unconfirmed141-=FLOOR(-2.5, -1) -2 unconfirmed142-=MOD(-7, 3) 2 unconfirmed143-=MOD(10, 0) #DIV/0! unconfirmed144-=MOD(0.3, 0.1) 0.1 unconfirmed145-=QUOTIENT(-7, 2) -3 unconfirmed146-=0.1+0.2 0.3 unconfirmed147-=0.1+0.2=0.3 FALSE unconfirmed148-=0.1+0.2-0.3 5.55111512312578E-17 unconfirmed149-=1-0.9 0.1 unconfirmed150-=(1-0.9)=0.1 FALSE unconfirmed151-=SUM(0.1, 0.2, 0.3)=0.6 FALSE unconfirmed152-=1/3 0.333333333333333 unconfirmed153-=100*1.1 110 unconfirmed154-=1E+21 1E+21 unconfirmed155-=123456789012345678 123456789012346000 unconfirmed156-=9007199254740993 9007199254740990 unconfirmed157-=0.000001 0.000001 unconfirmed158-=-0 0 unconfirmed159-=-2^2 4 unconfirmed160-=0^0 1 unconfirmed161-=POWER(0, 0) 1 unconfirmed162-=POWER(-8, 1/3) #NUM! unconfirmed163-=(-8)^(1/3) #NUM! unconfirmed164-=1E+308*10 #NUM! unconfirmed165-=LOG(10, 1) #DIV/0! unconfirmed124+=ROUND(1.005, 2) 1.01 1.01125+=ROUND(2.675, 2) 2.68 2.68126+=ROUND(0.285, 2) 0.29 0.29127+=ROUND(-2.5) -3 -3128+=ROUND(1.5, 0.9) 2 2129+=ROUND(1.23456789012345, 14) 1.23456789012345 1.23456789012346 on purpose: 012 rounds the shortest decimal half away from zero, so an exact input stays exact; Sheets' ...346 fits only a rule that also turns ROUND(1.5, 14) into 1.50000000000001130+=ROUNDUP(0.1+0.2, 1) 0.3 0.3131+=ROUNDDOWN(1-0.9, 1) 0.1 0.1132+=TRUNC(1234, -2) 1200 1200133+=INT(-1.5) -2 -2134+=INT(1-0.9+0.9) 1 1135+=CEILING(0.3, 0.1) 0.3 0.3136+=CEILING(-2.5, 1) -2 -2137+=CEILING(-2.5, -1) -3 -3138+=CEILING(2.5, -1) #NUM! #NUM!139+=CEILING(2.5, 0) 0 0140+=FLOOR(-2.5, 1) -3 -3141+=FLOOR(-2.5, -1) -2 -2142+=MOD(-7, 3) 2 2143+=MOD(10, 0) #DIV/0! #DIV/0!144+=MOD(0.3, 0.1) 0.1 -5.55111512312578E-17 on purpose: 012 computes n - d*INT(n/d) as Excel does, keeping the divisor's sign; Sheets' -5.55E-17 is a floating artefact145+=QUOTIENT(-7, 2) -3 -3146+=0.1+0.2 0.3 0.3147+=0.1+0.2=0.3 TRUE TRUE148+=0.1+0.2-0.3 5.55111512312578E-17 5.55111512312578E-17149+=1-0.9 0.1 0.1150+=(1-0.9)=0.1 TRUE TRUE151+=SUM(0.1, 0.2, 0.3)=0.6 TRUE TRUE152+=1/3 0.333333333333333 0.333333333333333153+=100*1.1 110 110154+=1E+21 1E+21 1E+21155+=123456789012345678 123456789012345000 123456789012345000156+=9007199254740993 9007199254740990 9007199254740990157+=0.000001 0.000001 0.000001158+=-0 0 0159+=-2^2 4 4160+=0^0 1 1161+=POWER(0, 0) 1 1162+=POWER(-8, 1/3) -2 -2163+=(-8)^(1/3) -2 -2164+=1E+308*10 #NUM! #NUM!165+=LOG(10, 1) #DIV/0! #DIV/0!166166 ## Errors and their propagation167-=0/0 #DIV/0! unconfirmed168-=Data!J2+1 #DIV/0! unconfirmed169-=SUM(Data!J2, 1) #DIV/0! unconfirmed170-=SUM(1, NA()) #N/A unconfirmed171-=NA()+1/0 #N/A unconfirmed172-=1/0+NA() #DIV/0! unconfirmed173-=IFERROR(1/0, "x") "x" unconfirmed174-=IFERROR(NA()) "" unconfirmed175-=IFERROR(Data!J2, Data!J4) #N/A unconfirmed176-=IFNA(1/0, 0) #DIV/0! unconfirmed177-=ISERR(NA()) FALSE unconfirmed178-=IF(1/0, 1, 2) #DIV/0! unconfirmed179-=IF("abc", 1, 2) #VALUE! unconfirmed180-=AND(TRUE, 1/0) #DIV/0! unconfirmed181-=OR(TRUE, NA()) #N/A unconfirmed182-=Data!A1+nosuchname #NAME? unconfirmed183-=CHOOSE(0, "a") #VALUE! unconfirmed184-=INDEX(Data!A1:A3, 5) #REF! unconfirmed185-=AVERAGEIF(Data!A1:A7, ">100") #DIV/0! unconfirmed186-=SWITCH(Data!B4, "north", 1) #N/A unconfirmed187-=PMT(0, 0, 1000) #NUM! unconfirmed188-=COUNT(Data!J1:J4) #DIV/0! unconfirmed189-=COUNTA(Data!J1:J4) #DIV/0! unconfirmed167+=0/0 #DIV/0! #DIV/0!168+=Data!J2+1 #DIV/0! #DIV/0!169+=SUM(Data!J2, 1) #DIV/0! #DIV/0!170+=SUM(1, NA()) #N/A #N/A171+=NA()+1/0 #N/A #N/A172+=1/0+NA() #DIV/0! #DIV/0!173+=IFERROR(1/0, "x") "x" "x"174+=IFERROR(NA()) (blank) (blank)175+=IFERROR(Data!J2, Data!J4) #N/A #N/A176+=IFNA(1/0, 0) #DIV/0! #DIV/0!177+=ISERR(NA()) FALSE FALSE178+=IF(1/0, 1, 2) #DIV/0! #DIV/0!179+=IF("abc", 1, 2) #VALUE! #VALUE!180+=AND(TRUE, 1/0) #DIV/0! #DIV/0!181+=OR(TRUE, NA()) #N/A #N/A182+=Data!A1+nosuchname #NAME? #NAME?183+=CHOOSE(0, "a") #NUM! #NUM!184+=INDEX(Data!A1:A3, 5) #NUM! #NUM!185+=AVERAGEIF(Data!A1:A7, ">100") #DIV/0! #DIV/0!186+=SWITCH(Data!B4, "north", 1) #N/A #N/A187+=PMT(0, 0, 1000) #NUM! #NUM!188+=COUNT(Data!J1:J4) 0 0189+=COUNTA(Data!J1:J4) 4 4190190 ## Coercion191-=" 3 "*1 3 unconfirmed192-="1,000"*1 1000 unconfirmed193-="$5"*2 10 unconfirmed194-="50%"*2 1 unconfirmed195-="9/26/2026"*1 46291 unconfirmed196-="TRUE"*1 #VALUE! unconfirmed197-=-TRUE -1 unconfirmed198-=Data!A5&"x" "x" unconfirmed199-=Data!A5="" TRUE unconfirmed200-=Data!B6=0 FALSE unconfirmed201-=ISBLANK(Data!B6) FALSE unconfirmed202-=Data!J1+1 4 unconfirmed203-=SUM(Data!J1) 0 unconfirmed204-=SUM("3", 1) 4 unconfirmed205-=SUM(Data!E6, 1) 1 unconfirmed206-=AVERAGE(Data!E6, 3) 3 unconfirmed207-=COUNT("1", 2) 2 unconfirmed208-=COUNT(TRUE) 1 unconfirmed209-=COUNTBLANK(Data!B1:B7) 1 unconfirmed210-="10"<9 FALSE unconfirmed211-=1<"a" TRUE unconfirmed212-=TRUE>1 TRUE unconfirmed213-=TRUE="TRUE" FALSE unconfirmed214-=Data!A5<"a" TRUE unconfirmed215-=""=0 FALSE unconfirmed216-=IF("TRUE", 1, 2) #VALUE! unconfirmed217-=IF(Data!A5, "y", "n") "n" unconfirmed218-=AND("abc") #VALUE! unconfirmed219-=AND(Data!A4) #VALUE! unconfirmed220-=NOT("") #VALUE! unconfirmed221-=ROUND("2.5") 3 unconfirmed222-=LEFT(Data!F1, 3) "462" unconfirmed191+=" 3 "*1 3 3192+="1,000"*1 1000 1000193+="$5"*2 10 10194+="50%"*2 1 1195+="9/26/2026"*1 46291 46291196+="TRUE"*1 #VALUE! #VALUE!197+=-TRUE -1 -1198+=Data!A5&"x" "x" "x"199+=Data!A5="" TRUE TRUE200+=Data!B6=0 FALSE FALSE201+=ISBLANK(Data!B6) FALSE FALSE202+=Data!J1+1 4 4203+=SUM(Data!J1) 0 0204+=SUM("3", 1) 4 4205+=SUM(Data!E6, 1) 1 1206+=AVERAGE(Data!E6, 3) 3 3207+=COUNT("1", 2) 2 2208+=COUNT(TRUE) 1 1209+=COUNTBLANK(Data!B1:B7) 1 1210+="10"<9 FALSE FALSE211+=1<"a" TRUE TRUE212+=TRUE>1 TRUE TRUE213+=TRUE="TRUE" FALSE FALSE214+=Data!A5<"a" TRUE TRUE215+=""=0 FALSE FALSE216+=IF("TRUE", 1, 2) 1 1217+=IF(Data!A5, "y", "n") "n" "n"218+=AND("abc") #VALUE! #VALUE!219+=AND(Data!A4) #VALUE! #VALUE!220+=NOT("") TRUE TRUE221+=ROUND("2.5") 3 3222+=LEFT(Data!F1, 3) "462" "9/2" on purpose: F1 is a date, stored in the XLSX as its serial with a m/d/yyyy format; Sheets' text functions read a date cell as it shows (9/26/2026), 012 reads its serial, as Excel does223223 ## Lookups and criteria224-=VLOOKUP("B*", Data!D1:E3, 2, FALSE) 2.5 unconfirmed225-=VLOOKUP("Blueberry", Data!D1:E3, 2) 2.5 unconfirmed226-=VLOOKUP("Aardvark", Data!D1:E3, 2, TRUE) #N/A unconfirmed227-=VLOOKUP(2.5, Data!C1:D5, 2) "Banana" unconfirmed228-=VLOOKUP("1", Data!C1:D5, 2, FALSE) #N/A unconfirmed229-=VLOOKUP("Apple", Data!D1:E3, 3, FALSE) #REF! unconfirmed230-=VLOOKUP("Apple", Data!D1:E3, 0, FALSE) #VALUE! unconfirmed231-=HLOOKUP("Apple", Data!D1:E2, 2, FALSE) "Banana" unconfirmed232-=MATCH("cherry", Data!D1:D3, 0) 3 unconfirmed233-=MATCH("B*", Data!D1:D3, 0) 2 unconfirmed234-=MATCH(3.2, Data!C1:C7) 3 unconfirmed235-=MATCH(0, Data!C1:C7) #N/A unconfirmed236-=MATCH(35, Data!I1:I3, -1) #N/A unconfirmed237-=MATCH(3, {1, 3, 5}, 0) 2 unconfirmed238-=INDEX(Data!C1:E1, 2) "Apple" unconfirmed239-=INDEX(Data!D1:E3, 4, 1) #REF! unconfirmed240-=ROWS(INDEX(Data!A1:C3, 0, 1)) 1 unconfirmed241-=SUM(INDEX(Data!C1:E3, 0, 1)) 1 unconfirmed242-=XLOOKUP("kiwi", Data!D1:D3, Data!E1:E3) #N/A unconfirmed243-=XLOOKUP("Apple", Data!D1:D5, Data!E1:E5, , 0, -1) 9 unconfirmed244-=XLOOKUP(3.2, Data!C1:C7, Data!D1:D7, , -1) "Cherry" unconfirmed245-=XLOOKUP(3.2, Data!C1:C7, Data!D1:D7, , 1) "date" unconfirmed246-=XLOOKUP("Ch*", Data!D1:D3, Data!E1:E3, , 2) 3.5 unconfirmed247-=XLOOKUP(2, Data!G1:G4, Data!H1:H4, , 0, -1) 400 unconfirmed248-=CHOOSE(2.9, "a", "b", "c") "b" unconfirmed249-=SUMIF(Data!A1:A7, "<>10") 45 unconfirmed250-=SUMIF(Data!C1:C7, ">=" & Data!C5) 18 unconfirmed251-=SUMIFS(Data!C1:C5, Data!B1:B5, "north", Data!A1:A5, ">10") 3 unconfirmed252-=COUNTIF(Data!B1:B7, "?o*") 4 unconfirmed253-=COUNTIF(Data!B1:B7, "Ab~*d") 1 unconfirmed254-=COUNTIF(Data!B1:B7, "<>north") 4 unconfirmed255-=COUNTIF(Data!A1:A7, "") 2 unconfirmed256-=COUNTIF(Data!A1:A7, "10") 1 unconfirmed257-=COUNTIF(Data!J1:J4, 3) 0 unconfirmed258-=COUNTIF(Data!E1:E7, TRUE) 1 unconfirmed259-=COUNTIF(Data!F1:F5, ">" & DATE(2026, 1, 1)) 2 unconfirmed224+=VLOOKUP("B*", Data!D1:E3, 2, FALSE) 2.5 2.5225+=VLOOKUP("Blueberry", Data!D1:E3, 2) 2.5 2.5226+=VLOOKUP("Aardvark", Data!D1:E3, 2, TRUE) #N/A #N/A227+=VLOOKUP(2.5, Data!C1:D5, 2) "Banana" "Banana"228+=VLOOKUP("1", Data!C1:D5, 2, FALSE) #N/A #N/A229+=VLOOKUP("Apple", Data!D1:E3, 3, FALSE) #REF! #REF!230+=VLOOKUP("Apple", Data!D1:E3, 0, FALSE) #VALUE! #VALUE!231+=HLOOKUP("Apple", Data!D1:E2, 2, FALSE) "Banana" "Banana"232+=MATCH("cherry", Data!D1:D3, 0) 3 3233+=MATCH("B*", Data!D1:D3, 0) 2 2234+=MATCH(3.2, Data!C1:C7) 3 3235+=MATCH(0, Data!C1:C7) #N/A #N/A236+=MATCH(35, Data!I1:I3, -1) #N/A #N/A237+=MATCH(3, {1, 3, 5}, 0) 2 2238+=INDEX(Data!C1:E1, 2) "Apple" "Apple"239+=INDEX(Data!D1:E3, 4, 1) #NUM! #NUM!240+=ROWS(INDEX(Data!A1:C3, 0, 1)) 3 3241+=SUM(INDEX(Data!C1:E3, 0, 1)) 6 6242+=XLOOKUP("kiwi", Data!D1:D3, Data!E1:E3) #N/A #N/A243+=XLOOKUP("Apple", Data!D1:D5, Data!E1:E5, , 0, -1) 9 9244+=XLOOKUP(3.2, Data!C1:C7, Data!D1:D7, , -1) "Cherry" "Cherry"245+=XLOOKUP(3.2, Data!C1:C7, Data!D1:D7, , 1) "date" "date"246+=XLOOKUP("Ch*", Data!D1:D3, Data!E1:E3, , 2) 3.5 3.5247+=XLOOKUP(2, Data!G1:G4, Data!H1:H4, , 0, -1) 400 400248+=CHOOSE(2.9, "a", "b", "c") "b" "b"249+=SUMIF(Data!A1:A7, "<>10") 45 45250+=SUMIF(Data!C1:C7, ">=" & Data!C5) 18 18251+=SUMIFS(Data!C1:C5, Data!B1:B5, "north", Data!A1:A5, ">10") 3 3252+=COUNTIF(Data!B1:B7, "?o*") 4 4253+=COUNTIF(Data!B1:B7, "Ab~*d") 1 1254+=COUNTIF(Data!B1:B7, "<>north") 4 4255+=COUNTIF(Data!A1:A7, "") 2 2256+=COUNTIF(Data!A1:A7, "10") 1 1257+=COUNTIF(Data!J1:J4, 3) 1 1258+=COUNTIF(Data!E1:E7, TRUE) 1 1259+=COUNTIF(Data!F1:F5, ">" & DATE(2026, 1, 1)) 2 2260260 ## Arrays and spills261-=SUM(SEQUENCE(3, 3, 0, 2)) 72 unconfirmed262-=INDEX(SEQUENCE(3, 2, 10, 5), 3, 2) 35 unconfirmed263-=ROWS(SEQUENCE(0)) 1 unconfirmed264-=ROWS(FILTER(Data!A1:A7, Data!C1:C7>3)) 4 unconfirmed265-=TEXTJOIN(",", TRUE, FILTER(Data!D1:D5, Data!B1:B5="north")) "Apple,Cherry,Apple" unconfirmed266-=FILTER(Data!A1:A3, Data!A1:A3>100) #N/A unconfirmed267-=TEXTJOIN(",", TRUE, SORT(Data!C1:C5, 1, FALSE)) "5,4,3,2,1" unconfirmed268-=INDEX(SORT(Data!D1:E5, 2, FALSE), 1, 1) "date" unconfirmed269-=TEXTJOIN(",", TRUE, SORT(Data!D1:D5)) "Apple,Apple,Banana,Cherry,date" unconfirmed270-=TEXTJOIN(",", TRUE, UNIQUE(Data!B1:B5)) "north,south,east" unconfirmed271-=TEXTJOIN(",", TRUE, UNIQUE(Data!G1:G4, FALSE, TRUE)) "1,3" unconfirmed261+=SUM(SEQUENCE(3, 3, 0, 2)) 72 72262+=INDEX(SEQUENCE(3, 2, 10, 5), 3, 2) 35 35263+=ROWS(SEQUENCE(0)) #NUM! #NUM!264+=ROWS(FILTER(Data!A1:A7, Data!C1:C7>3)) 4 unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import265+=TEXTJOIN(",", TRUE, FILTER(Data!D1:D5, Data!B1:B5="north")) "Apple,Cherry,Apple" unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import266+=FILTER(Data!A1:A3, Data!A1:A3>100) #N/A unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import267+=TEXTJOIN(",", TRUE, SORT(Data!C1:C5, 1, FALSE)) "5,4,3,2,1" unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import268+=INDEX(SORT(Data!D1:E5, 2, FALSE), 1, 1) "date" unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import269+=TEXTJOIN(",", TRUE, SORT(Data!D1:D5)) "Apple,Apple,Banana,Cherry,date" unconfirmed Sheets read _xlfn._xlws.FILTER and _xlfn._xlws.SORT, which is how Excel writes them, as #NAME?: confirm on the next import270+=TEXTJOIN(",", TRUE, UNIQUE(Data!B1:B5)) "north,south,east" "north,south,east"271+=TEXTJOIN(",", TRUE, UNIQUE(Data!G1:G4, FALSE, TRUE)) "1,3" "1,3"272272 =TEXTJOIN(",", TRUE, FLATTEN(Data!C1:D2)) "1,Apple,2,Banana" unconfirmed273273 =ROWS(FLATTEN(Data!C1:D2, Data!G1:G2)) 6 unconfirmed274274 =TEXTJOIN(",", TRUE, SORTN(Data!C1:C7, 3, 0, 1, FALSE)) "7,6,5" unconfirmed275275 =ROWS(SORTN(Data!G1:G4, 2, 1, 1, TRUE)) 3 unconfirmed276-=TEXTJOIN(",", TRUE, CHOOSECOLS(Data!C1:E1, -1, 1)) "1.5,1" unconfirmed277-=ROWS(CHOOSEROWS(Data!A1:A7, 1, 3)) 2 unconfirmed276+=TEXTJOIN(",", TRUE, CHOOSECOLS(Data!C1:E1, -1, 1)) "1.5,1" "1.5,1"277+=ROWS(CHOOSEROWS(Data!A1:A7, 1, 3)) 2 2278278 =SUM(ARRAYFORMULA(Data!C1:C3*Data!G1:G3)) 11 unconfirmed279-=ARRAYFORMULA(SUM(Data!C1:C3^2)) 14 unconfirmed280-=SUM(Data!C1:C3*2) 12 unconfirmed281-=SUMPRODUCT(Data!C1:C3>1) 0 unconfirmed282-=SUMPRODUCT(Data!A1:A4, Data!C1:C4) 140 unconfirmed283-=SUM({1, 2; 3, 4}) 10 unconfirmed284-=INDEX({1, 2; 3, 4}, 2, 1) 3 unconfirmed279+=ARRAYFORMULA(SUM(Data!C1:C3^2)) 14 14280+=SUM(Data!C1:C3*2) 12 #VALUE! on purpose: 012 computes the arguments of functions that take ranges as arrays, as Excel 365 does; Sheets needs ARRAYFORMULA281+=SUMPRODUCT(Data!C1:C3>1) 2 2282+=SUMPRODUCT(Data!A1:A4, Data!C1:C4) 140 140283+=SUM({1, 2; 3, 4}) 10 10284+=INDEX({1, 2; 3, 4}, 2, 1) 3 3285285 ## LET and LAMBDA286-=LET(x, 2, y, x+1, x*y) 6 unconfirmed287-=LET(x, SEQUENCE(3), SUM(x)) 6 unconfirmed288-=LET(x, 1/0, 5) #DIV/0! unconfirmed289-=LAMBDA(x, x+1)() #N/A unconfirmed290-=LET(f, LAMBDA(x, x+1), f(f(1))) 3 unconfirmed291-=SUM(MAP({1, 2, 3}, LAMBDA(x, x*10))) 60 unconfirmed292-=SUM(MAP(Data!A1:A3, Data!C1:C3, LAMBDA(a, b, a+b))) 66 unconfirmed293-=REDUCE(0, Data!C1:C5, LAMBDA(a, b, a+b)) 15 unconfirmed294-=TEXTJOIN(",", TRUE, SCAN(0, {1, 2, 3}, LAMBDA(a, b, a+b))) "1,3,6" unconfirmed295-=SUM(BYROW(Data!C1:E3, LAMBDA(r, COUNT(r)))) 6 unconfirmed296-=TEXTJOIN(",", TRUE, BYCOL(Data!C1:E3, LAMBDA(c, COUNTA(c)))) "3,3,3" unconfirmed297-=SUM(MAKEARRAY(3, 3, LAMBDA(r, c, r*c))) 36 unconfirmed286+=LET(x, 2, y, x+1, x*y) 6 6287+=LET(x, SEQUENCE(3), SUM(x)) 6 6288+=LET(x, 1/0, 5) 5 5289+=LAMBDA(x, x+1)() #N/A #N/A290+=LET(f, LAMBDA(x, x+1), f(f(1))) 3 3291+=SUM(MAP({1, 2, 3}, LAMBDA(x, x*10))) 60 60292+=SUM(MAP(Data!A1:A3, Data!C1:C3, LAMBDA(a, b, a+b))) 66 66293+=REDUCE(0, Data!C1:C5, LAMBDA(a, b, a+b)) 15 15294+=TEXTJOIN(",", TRUE, SCAN(0, {1, 2, 3}, LAMBDA(a, b, a+b))) "1,3,6" "1,3,6"295+=SUM(BYROW(Data!C1:E3, LAMBDA(r, COUNT(r)))) 6 6296+=TEXTJOIN(",", TRUE, BYCOL(Data!C1:E3, LAMBDA(c, COUNTA(c)))) "3,3,3" "3,3,3"297+=SUM(MAKEARRAY(3, 3, LAMBDA(r, c, r*c))) 36 36298298 ## Logic299-=IFS(Data!A1>20, "big", Data!A1>5, "medium") "medium" unconfirmed300-=SWITCH(Data!B2, "north", 1, "south", 2) 2 unconfirmed301-=SWITCH(Data!B4, "north", 1, "south", 2, 0) 0 unconfirmed302-=XOR(Data!A1:A3) TRUE unconfirmed299+=IFS(Data!A1>20, "big", Data!A1>5, "medium") "medium" "medium"300+=SWITCH(Data!B2, "north", 1, "south", 2) 2 2301+=SWITCH(Data!B4, "north", 1, "south", 2, 0) 0 0302+=XOR(Data!A1:A3) TRUE TRUE303303 ## Math, statistics and finance304-=PRODUCT(2, "3") 6 unconfirmed305-=MEDIAN(1, 2, 3, 4) 2.5 unconfirmed306-=MODE(Data!G1:G4) 2 unconfirmed307-=MODE(Data!C1:C5) #N/A unconfirmed308-=STDEV(Data!A1:A7) 14.9303940559741 unconfirmed309-=VAR(Data!A1:A7) 222.916666666667 unconfirmed310-=RANK(2, Data!G1:G4) 2 unconfirmed311-=RANK(99, Data!A1:A7) #N/A unconfirmed312-=ROUND(PMT(0.05/12, 360, 200000), 6) -1073.643246 unconfirmed313-=PMT(0, 10, 1000) -100 unconfirmed314-=ROUND(PV(0.05/12, 360, -1000), 6) 186281.617046 unconfirmed315-=ROUND(NPER(0.01, -1000, 10000), 9) 10.588644459 unconfirmed316-=NPER(0.01, 100, 10000) -69.6607168935748 unconfirmed317-=ROUND(RATE(48, -200, 8000), 9) 0.007701472 unconfirmed318-=ROUND(NPV(0.1, Data!H1:H4), 6) -19.124377 unconfirmed319-=ROUND(IRR(Data!H1:H4), 9) 0.088963395 unconfirmed320-=IRR(Data!C1:C5) #NUM! unconfirmed304+=PRODUCT(2, "3") 6 6305+=MEDIAN(1, 2, 3, 4) 2.5 2.5306+=MODE(Data!G1:G4) 2 2307+=MODE(Data!C1:C5) #N/A #N/A308+=STDEV(Data!A1:A7) 14.9303940559741 14.9303940559741309+=VAR(Data!A1:A7) 222.916666666667 222.916666666667310+=RANK(2, Data!G1:G4) 2 2311+=RANK(99, Data!A1:A7) #N/A #N/A312+=ROUND(PMT(0.05/12, 360, 200000), 6) -1073.643246 -1073.643246313+=PMT(0, 10, 1000) -100 -100314+=ROUND(PV(0.05/12, 360, -1000), 6) 186281.617046 186281.617046315+=ROUND(NPER(0.01, -1000, 10000), 9) 10.588644459 10.588644459316+=NPER(0.01, 100, 10000) -69.6607168935748 -69.6607168935748317+=ROUND(RATE(48, -200, 8000), 9) 0.007701472 0.007701472318+=ROUND(NPV(0.1, Data!H1:H4), 6) -19.124377 -19.124377319+=ROUND(IRR(Data!H1:H4), 9) 0.088963395 0.088963395320+=IRR(Data!C1:C5) #NUM! #NUM!
M internal/formula/parse.go +3 -1
M internal/functions/args.go +17 -8
M internal/functions/dynamic.go +4 -1
M internal/functions/eval.go +2 -4
M internal/functions/everyday.go +45 -21
@@ -119,10 +119,10 @@ func init() {
119119 }120120 return num(s.sum / float64(s.nums))121121 }), format: inherit},122- &FuncDef{Name: "COUNT", Args: "value1, [value2, ...]", Desc: "Count of numeric values", Min: 1, Max: -1,123- eval: aggregate(func(s Agg) Value { return num(float64(s.nums)) })},124- &FuncDef{Name: "COUNTA", Args: "value1, [value2, ...]", Desc: "Count of non-empty values", Min: 1, Max: -1,125- eval: aggregate(func(s Agg) Value { return num(float64(s.count)) })},122+ &FuncDef{Name: "COUNT", Args: "value1, [value2, ...]", Desc: "Count of numeric values, skipping errors", Min: 1, Max: -1,123+ eval: counter(func(s Agg) Value { return num(float64(s.nums)) })},124+ &FuncDef{Name: "COUNTA", Args: "value1, [value2, ...]", Desc: "Count of non-empty values, errors included", Min: 1, Max: -1,125+ eval: counter(func(s Agg) Value { return num(float64(s.count + s.errs)) })},126126 &FuncDef{Name: "MIN", Args: "value1, [value2, ...]", Desc: "Smallest number", Min: 1, Max: -1,127127 eval: aggregate(func(s Agg) Value {128128 if s.nums == 0 {
@@ -140,9 +140,9 @@ func init() {
140140 &FuncDef{Name: "ABS", Args: "value", Desc: "Absolute value", Min: 1, Max: 1, eval: math1(math.Abs), format: inherit},141141 &FuncDef{Name: "INT", Args: "value", Desc: "Round down to the nearest integer", Min: 1, Max: 1, eval: math1(math.Floor), format: inherit},142142 &FuncDef{Name: "SQRT", Args: "value", Desc: "Square root", Min: 1, Max: 1, eval: math1(math.Sqrt)},143- &FuncDef{Name: "ROUND", Args: "value, [places]", Desc: "Round to a number of decimal places, halves away from zero", Min: 1, Max: 2,143+ &FuncDef{Name: "ROUND", Args: "value, [places]", Desc: "Round to a number of decimal places, halves away from zero, on the digits a cell shows: ROUND(1.5, 14) is 1.5", Min: 1, Max: 2,144144 eval: rounder(numfmt.HalfUp), format: inheritFrom(0)},145- &FuncDef{Name: "MOD", Args: "dividend, divisor", Desc: "Remainder, with the sign of the divisor", Min: 2, Max: 2,145+ &FuncDef{Name: "MOD", Args: "dividend, divisor", Desc: "Remainder, with the sign of the divisor: MOD(0.3, 0.1) is 0.1 as in Excel, where Sheets gives -5.55E-17", Min: 2, Max: 2,146146 eval: numeric(func(x []float64) Value {147147 if x[1] == 0 {148148 return value.ErrDiv0
@@ -155,15 +155,11 @@ func init() {
155155 &FuncDef{Name: "NA", Desc: "The #N/A error", Max: 0, eval: constant(value.ErrNA)},156156 &FuncDef{Name: "IF", Args: "condition, value_if_true, [value_if_false]", Desc: "Choose a value by a condition", Min: 2, Max: 3, arrays: liftPass,157157 eval: func(args []Node, get lookup) Value {158- c := eval1(args[0], get)159- if c.Kind == value.Error {160- return c161- }162- f, err := toNum(c)158+ t, err := truth(eval1(args[0], get))163159 if err != nil {164160 return *err165161 }166- if f != 0 {162+ if t {167163 return eval(args[1], get)168164 }169165 if len(args) < 3 {
@@ -171,14 +167,14 @@ func init() {
171167 }172168 return eval(args[2], get)173169 }, format: func(args []Node, infer func(Node) Format) Format { return inherit(args[1:], infer) }},174- &FuncDef{Name: "IFERROR", Args: "value, [value_if_error]", Desc: "A fallback when a value is an error", Min: 1, Max: 2, arrays: liftPass,170+ &FuncDef{Name: "IFERROR", Args: "value, [value_if_error]", Desc: "A fallback when a value is an error; blank without one", Min: 1, Max: 2, arrays: liftPass,175171 eval: func(args []Node, get lookup) Value {176172 v := eval(args[0], get)177173 if v.Kind != value.Error {178174 return v179175 }180176 if len(args) < 2 {181- return Value{Kind: value.Text}177+ return Value{} // blank, as in Sheets182178 }183179 return eval(args[1], get)184180 }},
@@ -187,7 +183,13 @@ func init() {
187183 &FuncDef{Name: "OR", Args: "logical1, [logical2, ...]", Desc: "TRUE if any argument is true", Min: 1, Max: -1,188184 eval: logical(func(t, _ int) bool { return t > 0 })},189185 &FuncDef{Name: "NOT", Args: "logical", Desc: "The opposite of a logical value", Min: 1, Max: 1,190- eval: numeric(func(x []float64) Value { return boolean(x[0] == 0) })},186+ eval: func(args []Node, get lookup) Value {187+ t, err := truth(eval(args[0], get))188+ if err != nil {189+ return *err190+ }191+ return boolean(!t)192+ }},191193 )192194 }193195
@@ -198,9 +200,13 @@ func init() {
198200 type Agg struct {199201 sum float64200202 prod float64201- count int // non-empty values203+ count int // non-empty values other than errors202204 nums int203205 min, max float64206+ // counting is set for COUNT and COUNTA, which count errors (errs)207+ // where the others stop at the first.208+ counting bool209+ errs int204210 }205211 206212 // each calls fn for every value in args: every cell of a range that
@@ -264,10 +270,15 @@ func eachEntry(a *Array, fn func(v Value, direct bool) *Value) *Value {
264270 }265271 266272 // Add counts v into the aggregate, with SUM's rules: blanks are skipped,267-// errors returned, and text counts only when given directly.273+// errors returned (counted, when counting), and text counts only when274+// given directly.268275 func (s *Agg) Add(v Value, direct bool) *Value {269276 switch v.Kind {270277 case value.Error:278+ if s.counting {279+ s.errs++280+ return nil281+ }271282 return errOf(v)272283 case value.Empty:273284 return nil
@@ -298,8 +309,21 @@ func NewAgg() Agg { return Agg{prod: 1, min: math.Inf(1), max: math.Inf(-1)} }
298309 // read each cell once; other ranges the engine adds up itself299310 // (Book.Fold), as it reads them.300311 func aggregate(done func(Agg) Value) func([]Node, lookup) Value {312+ return aggregateFrom(NewAgg(), done)313+}314+315+// counter builds COUNT and COUNTA, which read past errors, as Sheets316+// does: COUNT skips them and COUNTA counts them. Their ranges are read317+// directly, as the shared aggregates stop at an error.318+func counter(done func(Agg) Value) func([]Node, lookup) Value {319+ s := NewAgg()320+ s.counting = true321+ return aggregateFrom(s, done)322+}323+324+func aggregateFrom(start Agg, done func(Agg) Value) func([]Node, lookup) Value {301325 return func(args []Node, get lookup) Value {302- s := NewAgg()326+ s := start303327 for _, arg := range args {304328 if rn, ok := get.refOf(arg).(formula.Range); ok {305329 var e *Value
@@ -319,7 +343,7 @@ func aggregate(done func(Agg) Value) func([]Node, lookup) Value {
319343 // rangeAgg adds the range rn to s: from the running aggregates when s is320344 // empty and the range is shared, and otherwise as the engine reads it.321345 func rangeAgg(rn formula.Range, s Agg, get lookup) (Agg, *Value) {322- if s.count == 0 {346+ if s.count == 0 && !s.counting {323347 if a, e, ok := get.book.RangeAgg(rn.Sheet, rn.Rect); ok {324348 return a, e325349 }
@@ -337,12 +361,12 @@ func logical(test func(trues, n int) bool) func([]Node, lookup) Value {
337361 case v.Kind == value.Empty, v.Kind == value.Text && !direct:338362 return nil339363 }340- f, err := toNum(v)364+ t, err := truth(v)341365 if err != nil {342366 return err343367 }344368 n++345- if f != 0 {369+ if t {346370 trues++347371 }348372 return nil
M internal/functions/lambda.go +4 -6

Not shown: this page already shows 6000 lines of diff.

M internal/functions/lift.go +5 -1

Not shown: this page already shows 6000 lines of diff.

M internal/functions/logic.go +26 -3

Not shown: this page already shows 6000 lines of diff.

M internal/functions/lookup.go +18 -5

Not shown: this page already shows 6000 lines of diff.

M internal/functions/masked.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/functions/math.go +17 -3

Not shown: this page already shows 6000 lines of diff.

M internal/functions/text.go +26 -4

Not shown: this page already shows 6000 lines of diff.

A internal/headless/build.go +151 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/charts.go +47 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/describe.go +241 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/describe_test.go +86 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/describetext.go +107 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/encode.go +33 -0

Not shown: this page already shows 6000 lines of diff.

M internal/headless/jev.go +7 -1

Not shown: this page already shows 6000 lines of diff.

A internal/headless/ops.go +182 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/read.go +87 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/results.go +108 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/runcell.go +55 -0

Not shown: this page already shows 6000 lines of diff.

M internal/headless/set.go +2 -1

Not shown: this page already shows 6000 lines of diff.

A internal/headless/tools.go +177 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/backend.go +100 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/prompts.go +60 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/read.go +103 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/resources.go +225 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/server.go +96 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/server_test.go +340 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/views.go +119 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/views_test.go +74 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/write.go +169 -0

Not shown: this page already shows 6000 lines of diff.

A internal/numfmt/entered.go +35 -0

Not shown: this page already shows 6000 lines of diff.

A internal/numfmt/fraction.go +166 -0

Not shown: this page already shows 6000 lines of diff.

M internal/numfmt/numfmt_test.go +58 -0

Not shown: this page already shows 6000 lines of diff.

M internal/numfmt/pattern.go +3 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/cyclefind.go +377 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/cyclefind_test.go +116 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/decimal_test.go +5 -4

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/evaluate.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/functions_array_test.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/functions_lookup_test.go +4 -3

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/functions_math_test.go +6 -1

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/functions_sheets_test.go +71 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/functions_text_test.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/merge.go +17 -11

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/merge_undo_test.go +17 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/randedit_ops_test.go +1 -2

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/randedit_shared_test.go +5 -4

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/randedit_test.go +23 -24

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/recalc.go +7 -5

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/region.go +4 -3

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/regionclash.go +134 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/regionclash_test.go +103 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/regionshape.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/regionwrite.go +41 -40

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/sheet.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/spill.go +17 -7

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/spill_test.go +22 -5

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/spillblock.go +107 -1

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/spillcycle_test.go +66 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/tablebind.go +1 -1

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/plain.012 +10 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/single.012 +21 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/workbook.012 +169 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/0cef393ee02403d8 +2 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/52d14ae960ebe41a +2 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/5b93384d423fd67f +2 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/7bd353237853b747 +2 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/a1b814ebfaeff4cb +2 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fuzz/FuzzRandomEdits/d2d49b6d88d8d44d +2 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/workbook.go +11 -0

Not shown: this page already shows 6000 lines of diff.

M internal/sheet/workbook_test.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/cmdline.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/commands.go +20 -5

Not shown: this page already shows 6000 lines of diff.

M internal/ui/context.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/filter.go +12 -7

Not shown: this page already shows 6000 lines of diff.

M internal/ui/grid.go +5 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/gridlines.go +3 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/menuoverlay.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/model.go +6 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/monochrome_test.go +10 -7

Not shown: this page already shows 6000 lines of diff.

M internal/ui/mouse.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbcommands.go +6 -2

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgrid.go +287 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgrid_test.go +200 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgridcmd.go +215 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgridin.go +275 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbrun.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbscreen.go +16 -6

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/draw.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/full.go +40 -231

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbview/grid.go +199 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/keys.go +6 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/mouse.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/output.go +33 -125

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/outwin.go +27 -86

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/panel.go +5 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/view.go +7 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/view_test.go +84 -24

Not shown: this page already shows 6000 lines of diff.

M internal/ui/notebook.go +7 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/panel.go +20 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/pivot.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/settings_test.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/sort.go +4 -3

Not shown: this page already shows 6000 lines of diff.

M internal/ui/speed_test.go +22 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/testdata/speed.json +5 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/view.go +8 -4

Not shown: this page already shows 6000 lines of diff.

M internal/value/value.go +27 -0

Not shown: this page already shows 6000 lines of diff.

M oracle/go.mod +5 -0

Not shown: this page already shows 6000 lines of diff.

M oracle/go.sum +10 -0

Not shown: this page already shows 6000 lines of diff.

M oracle/oracle_test.go +4 -1

Not shown: this page already shows 6000 lines of diff.