012

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: MIT

README

012

A spreadsheet for the terminal with a Lotus 1-2-3 look and Google Sheets behavior, built on Bubble Tea v2.

Inside the grid it works the way Sheets does: typing replaces a cell, = starts a formula, Enter and Tab move you on, Shift+arrows and the mouse select, and Sheets' shortcuts do what you expect. Around the grid, the control panel, the mode indicator and the character grid keep 1-2-3's look. It is one pure-Go binary.

Typing a small budget, pointing at cells in a formula, and watching totals recalculate

Install

go install github.com/FelineStateMachine/012/cmd/012@latest

Requires Go 1.27. Or from a clone: make build puts the binary in bin/012.

012                  # a new sheet
012 budget.012       # open or create a sheet
012 sales.xlsx       # import .xlsx, .csv, .tsv, .sqlite, .parquet or Lotus .wk1
012 serve ~/sheets   # serve a directory over SSH, a 012 per session

F1 shows every shortcut, F10 or Alt+letter opens the menus, and Ctrl+K searches every command. 012 config edit opens the settings file.

What it does

  • Sheets-style editing. Formulas with 120 Sheets-compatible functions, autocomplete and argument hints, pointing at cells with the arrows or the mouse, named ranges, undo and redo for everything, copy and paste with reference adjustment and the system clipboard, fill series, insert and delete rows and columns.
  • Formats and styles. Currency, percent, dates and times detected as you type; number formats, bold, italic, underline, strikethrough, alignment.
  • Several sheets. Sheet tabs on the status line, references between sheets (=Sheet2!A1) that follow renames, pointing into another sheet while typing a formula, hiding sheets, and Sheets' keys for moving between them.
  • Data tools. Freeze rows and columns, multi-column sort, filters with value pickers and conditions, find and replace with regular expressions, tracing precedents and dependents, live pivot tables and frequency tables on sheets of their own.
  • Charts. Column, bar, line and pie charts that float over the grid and update live; real images in terminals with the kitty graphics protocol (kitty, Ghostty, WezTerm), text elsewhere.
  • Files. A diff-friendly JSON format, plus import from CSV, TSV, XLSX, SQLite, Parquet and Lotus 1-2-3 .wk1, and export to CSV, TSV, XLSX and SQLite.
  • Macros. Record what you do with absolute or relative references and replay it with Ctrl+Alt+Shift+digit, as one undo step; macros are readable Starlark scripts saved in the file, with step limits and no file or network access (docs).
  • JEV functions. JEV.TEST, JEV.PROB, JEV.CLASSIFY and JEV.SCORE ask TypeSafe's hosted JEV model about your data, answered in the background and cached (docs).
  • Made for terminals. Mouse with hover and resize handles, hyperlinks, light and dark themes that follow the terminal, desktop notifications, menus and a command palette styled like terminal software, not a GUI, and optional vim keys (hjkl, counts, dd/yy/p, visual selection, : commands) in File > Settings.
  • Themes and a config file. Your terminal's colors by default, or any of 349 color schemes (or your own Ghostty theme) with solid menu and status bars; one Ghostty-style config file for every setting, and the JEV API key kept in the OS keychain (config, themes).

Demos

Menus and the command palette Inserting a chart that follows its data
Menus and the command palette (Ctrl+K) Charts that float over the grid and follow their data
Freezing, sorting and filtering Find and replace
Freeze, sort and filter Find and replace
JEV functions classifying reviews Currency formats and totals
JEV functions in formulas Formats detected as you type

The recordings are VHS tapes in demos/; make demos renders them in a terminal using the Catppuccin Mocha palette, which 012 follows by default (themes). Charts show as text here; in kitty, Ghostty and WezTerm they are real images.

Documentation

Development

make build    # pure Go, CGO_ENABLED=0
make test     # unit tests
make e2e      # the real binary in libghostty, Ghostty's terminal core (needs Zig 0.16+ and pkg-config)
make screens  # golden screens and the review gallery
make oracle   # formulas and formats against excelize
make stress   # benchmarks on synthetic and real data; make stress-report compares runs

See docs/testing.md.

Status

Young and moving quickly. The file format is versioned and older files keep loading; the Go packages are internal and may change at any time.

License

MIT

Directories

Path Synopsis
cmd
012 command
Command 012 is a Lotus 1-2-3 style spreadsheet for the terminal.
Command 012 is a Lotus 1-2-3 style spreadsheet for the terminal.
demos
fakejev command
Command fakejev is a stand-in for the TypeSafe JEV service, for demo recordings: it answers every question about a value by looking for complaint words in the value, so a demo never needs a real key and always records the same answers.
Command fakejev is a stand-in for the TypeSafe JEV service, for demo recordings: it answers every question about a value by looking for complaint words in the value, so a demo never needs a real key and always records the same answers.
internal
chart
Package chart draws a sheet's charts: as text for any terminal (block elements for bars, braille for lines, half blocks for pies), and the plot area as an image for terminals with kitty graphics.
Package chart draws a sheet's charts: as text for any terminal (block elements for bars, braille for lines, half blocks for pies), and the plot area as an image for terminals with kitty graphics.
config
Package config is 012's settings file: a Ghostty-style list of "key = value" lines in <user config dir>/012/config, with # comments and config-file includes.
Package config is 012's settings file: a Ghostty-style list of "key = value" lines in <user config dir>/012/config, with # comments and config-file includes.
confine
Package confine maps the file names a user types to paths on disk, keeping them inside one directory when 012 serves sessions over SSH.
Package confine maps the file names a user types to paths on disk, keeping them inside one directory when 012 serves sessions over SSH.
fileio
Package fileio moves data between sheets and other file formats: CSV and TSV, Excel workbooks, SQLite databases, Parquet files and Lotus 1-2-3 worksheets.
Package fileio moves data between sheets and other file formats: CSV and TSV, Excel workbooks, SQLite databases, Parquet files and Lotus 1-2-3 worksheets.
formula
Package formula is the formula language: A1 references and ranges, sheet names in references, the lexer and Pratt parser, the syntax tree, the printer that writes trees back in Sheets' spelling, and the rewriting of references when cells are copied, moved, inserted or deleted.
Package formula is the formula language: A1 references and ranges, sheet names in references, the lexer and Pratt parser, the syntax tree, the printer that writes trees back in Sheets' spelling, and the rewriting of references when cells are copied, moved, inserted or deleted.
functions
Package functions is 012's function library: the FuncDef table, the evaluation of formulas (operators and calls), the argument, range and criteria helpers functions share, decimal arithmetic, and the questions JEV functions ask.
Package functions is 012's function library: the FuncDef table, the evaluation of formulas (operators and calls), the argument, range and criteria helpers functions share, decimal arithmetic, and the questions JEV functions ask.
jev
Package jev answers the spreadsheet's JEV functions with TypeSafe's hosted model.
Package jev answers the spreadsheet's JEV functions with TypeSafe's hosted model.
keyring
Package keyring keeps the JEV API key in the operating system's credential store: the macOS Keychain, the Windows Credential Manager, or the freedesktop Secret Service on Linux and the BSDs (GNOME Keyring, KWallet, KeePassXC).
Package keyring keeps the JEV API key in the operating system's credential store: the macOS Keychain, the Windows Credential Manager, or the freedesktop Secret Service on Linux and the BSDs (GNOME Keyring, KWallet, KeePassXC).
macro
Package macro runs macros: Starlark scripts that act on a spreadsheet through a small API, as Google Sheets macros are Apps Script.
Package macro runs macros: Starlark scripts that act on a spreadsheet through a small API, as Google Sheets macros are Apps Script.
numfmt
Package numfmt renders numbers the way spreadsheets show them: number format patterns as in Sheets' custom number formats and TEXT(), General's shortest form, rounding on the 15 significant digits users see, and the serial day numbers dates and times are stored as.
Package numfmt renders numbers the way spreadsheets show them: number format patterns as in Sheets' custom number formats and TEXT(), General's shortest form, rounding on the 15 significant digits users see, and the serial day numbers dates and times are stored as.
serve
Package serve runs 012 as an SSH server: each session gets its own spreadsheet over its own terminal, confined to one directory.
Package serve runs 012 as an SSH server: each session gets its own spreadsheet over its own terminal, confined to one directory.
sheet
Package sheet is the spreadsheet engine: cell storage, formula parsing and dependency-ordered recalculation.
Package sheet is the spreadsheet engine: cell storage, formula parsing and dependency-ordered recalculation.
stress
Package stress builds synthetic worst-case sheets for the stress benchmarks (see docs/limits.md and `make stress`).
Package stress builds synthetic worst-case sheets for the stress benchmarks (see docs/limits.md and `make stress`).
stress/benchrec command
Command benchrec turns `go test -bench` output into run records, one JSON line per benchmark, appended to a results file that DuckDB (and ClickHouse) read; see scripts/stress and docs/observability.md.
Command benchrec turns `go test -bench` output into run records, one JSON line per benchmark, appended to a results file that DuckDB (and ClickHouse) read; see scripts/stress and docs/observability.md.
telemetry
Package telemetry records what 012 spends its time on, as structured events written with log/slog.
Package telemetry records what 012 spends its time on, as structured events written with log/slog.
ui
Package ui is the Bubble Tea front end.
Package ui is the Bubble Tea front end.
ui/cmdline
Package cmdline is the command line (: with vim keys, or from the palette): what's typed on the context line, with completions from the command registry in a box under it.
Package cmdline is the command line (: with vim keys, or from the palette): what's typed on the context line, with completions from the command registry in a box under it.
ui/findbar
Package findbar is find and replace: a bar on the context line rather than a dialog, in the spirit of less and vim.
Package findbar is find and replace: a bar on the context line rather than a dialog, in the spirit of less and vim.
ui/formula
Package formula reads the formula being typed in the UI: the reference F4 cycles through absolute markers, and the word and function call around the caret that formula assistance follows.
Package formula reads the formula being typed in the UI: the reference F4 cycles through absolute markers, and the word and function call around the caret that formula assistance follows.
ui/lineedit
Package lineedit is the one-line text editor behind every text field of the UI.
Package lineedit is the one-line text editor behind every text field of the UI.
ui/overlay
Package overlay is the contract between the UI's root model and the components that take over input while open: menus, pickers, bars on the context line and dialogs.
Package overlay is the contract between the UI's root model and the components that take over input while open: menus, pickers, bars on the context line and dialogs.
ui/picker
Package picker is the searchable list behind the command palette and every other picker of the UI (functions, sheets, named ranges, macros, themes, files to import): a search field on top, results below with matched characters highlighted, in the manner of fzf.
Package picker is the searchable list behind the command palette and every other picker of the UI (functions, sheets, named ranges, macros, themes, files to import): a search field on top, results below with matched characters highlighted, in the manner of fzf.
ui/rowtext
Package rowtext lays out the text of one row of cells across the columns on screen, as Sheets does: values formatted and aligned, text running on into blank neighbors, cut to column boundaries in a single pass.
Package rowtext lays out the text of one row of cells across the columns on screen, as Sheets does: values formatted and aligned, text running on into blank neighbors, cut to column boundaries in a single pass.
ui/tabstrip
Package tabstrip is the sheet tabs at the left of the status line, the way tmux lists windows: the sheet shown is highlighted, a + adds a sheet, and when the tabs don't all fit, ‹ and › step through them.
Package tabstrip is the sheet tabs at the left of the status line, the way tmux lists windows: the sheet shown is highlighted, a + adds a sheet, and when the tabs don't all fit, ‹ and › step through them.
ui/theme
Package theme is the look of the UI: the style roles every view draws with, and the small widgets built from them (framed boxes, key chips, key hints).
Package theme is the look of the UI: the style roles every view draws with, and the small widgets built from them (framed boxes, key chips, key hints).
ui/themepicker
Package themepicker is File > Settings > Theme: every theme in a picker, fuzzy searched by name, "dark" or "light".
Package themepicker is File > Settings > Theme: every theme in a picker, fuzzy searched by name, "dark" or "light".
ui/transfer
Package transfer runs imports in the background and draws their progress: the mode indicator says WAIT, the context line offers Esc, the status line counts rows with a progress bar, and the terminal shows its own progress indicator.
Package transfer runs imports in the background and draws their progress: the mode indicator says WAIT, the context line offers Esc, the status line counts rows with a progress bar, and the terminal shows its own progress indicator.
value
Package value holds what a cell computes to and how it is shown: the Value of a cell, its number Format, and the parsing of typed text into numbers, dates and times.
Package value holds what a cell computes to and how it is shown: the Value of a cell, its number Format, and the parsing of typed text into numbers, dates and times.
scripts
doclint command
Command doclint keeps documentation about the code as it is.
Command doclint keeps documentation about the code as it is.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL