cell
A terminal spreadsheet editor with Vim keybindings, written in Rust.

Install
From crates.io:
Pre-built binaries for Linux, macOS, and Windows are available on the GitHub Releases page.
Build from source
# Binary at target/release/cell
Usage
|
To explore an example sheet with formulas, ranges, and IF logic:
The CSV/TSV delimiter is auto-detected from file content; pass
--delimiter to override. The native .cell format is auto-detected
via its # cell v magic header.
Headless mode
For shell pipelines, Makefiles, and CI, cell can read from and write to a
file without launching the TUI:
|
- Cell references are 1-indexed and Excel-style (
A1,AA10,A1:B3). - The
=prefix on--evalis optional. - Writes whose value starts with
=are stored as formulas; others are auto-typed (number vs text). - Operations apply in a fixed order per invocation: writes → save → reads → evals.
- Errors print to stderr; the process exits non-zero on bad refs, parse errors, or missing files.
- Stdin input supports CSV, TSV, and the native
.cellformat. The delimiter is auto-detected; pass--delimiterto override (CSV/TSV only).--writerequires a file argument when reading from stdin.
Keybindings
If you know Vim, you know cell.
All motions and operators accept a [count] prefix (5j, 10G, 3dd,
4yy, 2w). Counts also work between an operator and its motion (d3j,
y2k); outer and inner counts multiply (5d2j clears 10 rows). The
in-progress count and operator render in the status line as you type.
Normal Mode
Motion
| Key | Action |
|---|---|
h j k l |
Move cursor (one cell) |
gg |
First row (or row N with [count]gg) |
G |
Last row (or row N with [count]G) |
0 |
First column |
$ |
Last column |
w / b |
Next / previous non-empty cell in row |
Ctrl-D / Ctrl-U |
Half-page down / up |
Ctrl-F / Ctrl-B |
Full page down / up |
{ / } |
Previous / next block boundary in column |
H / M / L |
Cursor to top / middle / bottom of viewport |
zz / zt / zb |
Recenter / scroll-to-top / scroll-to-bottom around cursor |
Ctrl-e / Ctrl-y |
Scroll viewport one row without moving cursor |
Ctrl-o / Ctrl-i (or Tab) |
Jump back / forward in jump list |
Marks
| Key | Action |
|---|---|
m{a-z} |
Set mark at cursor |
'{a-z} |
Jump to marked row (column 0) |
`{a-z} |
Jump to exact marked cell |
Editing
| Key | Action |
|---|---|
i / a / Enter |
Edit cell (Insert mode) |
x |
Clear cell |
dd |
Delete row ([count]dd for N rows) |
d{motion} |
Clear cells along motion (dj, d3l, dh, dk) |
yy |
Yank row ([count]yy for N rows) |
y{motion} |
Yank cells along motion (yj, y3l, yh, yk) |
p / P |
Paste below / above |
Ctrl-A / Ctrl-X |
Increment / decrement number in cell ([count] accepted) |
~ |
Toggle case of first character, advance cursor |
guu / gUU |
Lowercase / uppercase entire cell |
g~~ |
Toggle case of every character in cell |
. |
Repeat last change |
u |
Undo |
Ctrl-R |
Redo |
Selection & search
| Key | Action |
|---|---|
v |
Visual selection |
V |
Visual line (full-row) selection |
Ctrl-V |
Visual block selection |
gv |
Re-enter previous visual selection |
/ / ? |
Search forward / backward (incremental) |
n / N |
Next / previous match |
* / # |
Search for current cell's value forward / backward |
f<char> / F<char> |
Jump to next / prev cell in row starting with <char> |
; / , |
Repeat last f/F (same / reversed direction) |
: |
Command mode |
Insert Mode
Type to edit the cell. ESC or Enter confirms. Arrow keys, Home,
End, Backspace, and Delete work as expected within the cell.
Visual Mode
Extend the selection with hjkl (or [count]j etc.), then:
| Key | Action |
|---|---|
y |
Yank selection |
d |
Delete selection |
c |
Change selection (clear and enter Insert mode) |
u / U / ~ |
Lowercase / uppercase / toggle case of selection (formula cells skipped) |
Esc |
Cancel selection |
Commands
| Command | Action |
|---|---|
:w |
Save |
:w file.csv |
Save as CSV |
:w file.cell |
Save as native format |
:w! |
Force save (flatten formulas, override warnings) |
:q |
Quit |
:q! |
Quit without saving |
:wq |
Save and quit |
:e file |
Open file |
:sort A asc |
Sort by column A ascending |
:sort B desc |
Sort by column B descending |
:set delimiter=| |
Change CSV/TSV delimiter for the next save |
:help / :help <topic> |
Open the in-app help screen / jump to a topic |
In the : prompt, ↑ / ↓ cycle through previously executed commands.
Mouse support
Mouse support is off by default so the terminal's native text
selection keeps working. Enable it at runtime with :set mouse on,
disable it with :set mouse off, or flip the current state with
:set mouse toggle.
When enabled:
- Left-click on a cell moves the cursor.
- Click + drag inside the grid selects a Visual range.
- Click + drag on a column header selects whole columns.
- Click + drag on a row header selects whole rows.
- Scroll wheel scrolls the viewport (cursor stays put). Horizontal
scroll works when the terminal emits
ScrollLeft/ScrollRight(commonly bound to Shift + wheel). - Double-click a cell to enter Insert mode on it.
- Drag past the visible edge auto-scrolls the viewport.
To copy a cell value out to your system clipboard while mouse mode is on, hold your terminal's bypass modifier when clicking and dragging:
| Terminal | Bypass |
|---|---|
| Linux terminals (gnome-terminal, alacritty, kitty, …) | Shift |
| Windows Terminal | Shift |
| macOS Terminal.app, iTerm2 | Option/Alt |
| tmux / screen | configure per their docs |
Formulas
Formulas start with = and support Excel-compatible syntax:
=A1+B1
=SUM(A1:A10)
=AVERAGE(B1:B5)
=IF(A1>100, "high", "low")
Supported Functions (v1)
SUM, AVERAGE, COUNT, MIN, MAX, IF
Formula compliance with the ODF (OpenDocument Formula) spec is tracked and will expand over time.
File Formats
- CSV/TSV -- Opens and saves standard comma/tab-separated files. Formulas are flattened to their computed values on CSV export.
**.cell** -- Native format that preserves formulas. Plain text, human-readable, inspired by sc-im.
When saving a CSV that contains formulas, cell warns you and suggests saving as .cell instead. Use :w! to force a CSV save.
Comparison with sc-im
sc-im is a battle-tested terminal spreadsheet built on the classic sc (Spreadsheet Calculator, 1981). It inspired cell's native .cell format. Here's how the two tools compare:
| cell | sc-im | |
|---|---|---|
| Language / TUI | Rust + ratatui | C + ncurses |
| Editing model | True Vim modal editing (i → Insert, ESC → Normal) |
Vim-inspired navigation; = to enter a value, e/E to edit |
| Formula syntax | Excel-compatible (=SUM(A1:A10), =IF(...)) |
@-prefix style (@sum(A1:A10), @avg(...)) |
| Built-in functions | SUM, AVERAGE, COUNT, MIN, MAX, IF | Extensive (@sum, @avg, @min, @max, @abs, @sqrt, ...) |
| File formats | CSV, TSV, .cell |
CSV, TSV, XLSX/XLS/ODS import, Markdown export, .sc |
| Cell formatting | not yet | Bold, italic, underline, RGB colors |
| Scripting | Headless CLI mode (--read / --write / --eval, stdin pipe) |
Lua scripting, external C modules, non-interactive mode |
| Charting | not yet | GNUPlot integration |
| Windows support | ✓ (pre-built binaries) | Limited |
| Clipboard | Built-in | Requires tmux / xclip / pbpaste |
| Config file | not yet | ~/.config/sc-im/scimrc |
Choose cell if…
- You want editing that works exactly like Vim (
ito insert,ESCto return,/to search) - You prefer Excel-compatible formula syntax (
=SUM,=IF,=AVERAGE) - You need a working binary on Windows without extra setup
- You value a modern, memory-safe codebase with minimal dependencies
Choose sc-im if…
- You need XLSX, ODS, or Markdown support right now
- You need Lua scripting or GNUPlot charting right now
- You need cell-level formatting (colors, bold, italic) right now
- You want a highly configurable, feature-rich tool with decades of history behind it
Architecture
cell/
crates/
cell-sheet-core/ # Data model, formula engine, file I/O (no TUI dependency)
cell-sheet-tui/ # Ratatui rendering, Vim modes, event loop
The core library is independent of the terminal UI and can be tested without a terminal.
Releasing
Releases are automated with release-plz from the release workflow:
- Pushes to
mainopen or update a release PR with the next version and changelog updates. - Merging the release PR publishes
cell-sheet-coreandcell-sheet-tuito crates.io via trusted publishing, creates thevX.Y.Ztag, and creates a draft GitHub Release. - The
vX.Y.Ztag then builds binaries for Linux (x86_64, aarch64), macOS (x86_64, aarch64), and Windows (x86_64), uploads archives and SHA256 checksums, and publishes the GitHub Release.
See RELEASE.md for maintainer instructions and failure handling.
Contributing
Contributions are welcome. See CONTRIBUTING.md for the development setup, project conventions, and pull request workflow.