gridline 0.2.0

Terminal spreadsheet with Rhai-powered formulas.
gridline-0.2.0 is not a library.
Visit the last successful build: gridline-0.1.6

Gridline ✨

Gridline is a terminal spreadsheet with Rhai support. Cells can contain numbers, text, or formulas powered by the Rhai scripting language. Your sheet lives in a plain text file, and your reusable logic can live in a separate .rhai functions file.

Interfaces: TUI is the default and primary experience (cargo run, cargo install gridline) and is fairly mature. The GUI is behind a feature flag, still experimental, and subject to breaking changes as the vision evolves. webui is a planned future interface.

What you get (today):

  • TUI grid with a formula bar and command mode
  • A1-style references in formulas (=A1 + B2) and range functions (=SUM(A1:B5))
  • Dependency tracking and recalculation with undo/redo support
  • Load/reload user functions from a .rhai file (-f at startup, :source at runtime)
  • Vim keybindings by default, optional Emacs keymap
  • Custom keymaps via TOML (optional override)
  • Plain text storage format (one cell per line)
  • CSV import/export (:import, :export)
  • Markdown export with ASCII charts (-o flag or command mode)
  • Command-line evaluation mode (-c flag)
  • Row/column insertion and deletion
  • Simple plotting in a modal (bar/line/scatter)
  • Interactive help system (:help)

Why it's fun:

  • 🧾 Plain-text sheets you can diff and version
  • 🧠 Formulas are real Rhai scripts (with spreadsheet sugar)
  • πŸ“ˆ Quick plots right in the terminal

Screenshots

Quick Start πŸš€

Build and run:

cargo run

Open an example file:

cargo run -- examples/plot.grid


# GUI (experimental, breaking changes expected)

cargo run --features gui --bin gridline-gui -- examples/plot.grid


# WebUI (stub / future)

cargo run --features webui --bin gridline-webui

Command-line Evaluation

Evaluate formulas without opening the TUI:

# Evaluate and print to stdout

cargo run -- -c "SUM(0..100)"


# Evaluate and export to markdown

cargo run -- -c "VEC(1..20).map(|x| POW(x, 2))" -o squares.md


# Export existing file to markdown

cargo run -- examples/plot.grid -o plot.md

Loading Functions

Load custom Rhai functions at startup (can specify multiple files):

cargo run -- -f examples/functions.rhai examples/plot.grid

cargo run -- -f lib1.rhai -f lib2.rhai examples/plot.grid

Auto-load a default functions file if present:

  • Gridline will auto-load default.rhai from your OS config directory (resolved via directories::ProjectDirs) if it exists.
    • Linux: typically ~/.config/gridline/default.rhai
    • Disable with --no-default-functions

Load or reload functions at runtime:

:source examples/functions.rhai
:so                                 # reload all loaded files

Cell Input Rules 🧾

Gridline interprets cell input like this:

  • empty / whitespace => empty cell
  • leading = => formula (Rhai script; stored without the =)
  • quoted "text" => text (quotes stripped)
  • otherwise, parseable as f64 => number
  • else => text

Examples:

A1: 10
A2: "hello"
A3: =A1 * 2
A4: =SUM(A1:A3)

Formulas (Rhai + Spreadsheet Sugar) 🧠

Inside formulas:

  • A1 becomes cell(0, 0) (0-indexed internally)
  • @A1 becomes value(0, 0) (typed access: numbers/text/bools)
  • SUM(A1:B5) becomes sum_range(0, 0, 4, 1)

Arrays "spill" down the column. If you need to do an in-place operation that returns () (like Rhai's Array.sort()), use OUTPUT:

A1: 30
A2: 10
A3: 20
B1: =OUTPUT(VEC(A1:A3), |v| { v.sort(); v })

Typed refs are useful when a referenced cell contains text (or a formula that returns text):

B1: =if C1 > 100 { "expensive" } else { "cheap" }
A1: =len(@B1)

Built-in range functions (ALL CAPS):

  • SUM, AVG, COUNT, MIN, MAX
  • SUMIF(range, |x| condition) - sum values where predicate is true
  • COUNTIF(range, |x| condition) - count cells where predicate is true
  • VEC (convert a range to an array; respects direction: VEC(A3:A1) returns [A3, A2, A1])
  • SPILL(arr) or SPILL(range) - convert ranges/arrays to spillable arrays (also available as method: arr.SPILL())
  • Chart functions: BARCHART, LINECHART, SCATTER (support optional title and axis labels)

Other built-ins:

  • ROW() - current cell's row (1-indexed)
  • COL() - current cell's column (1-indexed)
  • RAND() - random float in [0.0, 1.0)
  • RANDINT(min, max) - random integer in [min, max] inclusive
  • POW(base, exp) - exponentiation (base^exp)
  • SQRT(x) - square root
  • OUTPUT(value, fn) - apply function to value and return result (useful for in-place operations like sort())

Custom Functions Example 🧩

Create a .rhai file:

fn fib(n) {
  if n < 2 { n } else { fib(n - 1) + fib(n - 2) }
}

Load it (either -f or :source), then use it in a cell:

A1: "Fibonacci"
B1: 10
C1: =fib(B1)

Plotting πŸ“ˆ

Plotting works by making a formula cell return a tagged plot spec. The grid shows a placeholder (e.g. <BAR>), and you can open the plot modal.

Example (examples/plot.grid):

C1: =SCATTER(A1:B5, "title", "xaxis", "yaxis")
D1: =BARCHART(B1:B5)

Open the plot modal:

  • Vim keymap: P
  • Emacs keymap: M-p

Commands ⌨️

Command mode:

  • Vim: :
  • Emacs: M-x

File Operations

  • :w or :w <path> (alias :save) - save
  • :q - quit (warns if modified)
  • :q! - force quit
  • :wq - save and quit
  • :e <path> (alias :open, :load) - open file
  • :import <file.csv> - import CSV data at current cursor position
  • :export <file.csv> - export grid to CSV format

Navigation

  • :goto A100 (alias :g A100) - jump to a cell

Grid Editing

  • :ir or :insertrow - insert row above current row
  • :dr or :deleterow - delete current row
  • :ic or :insertcol - insert column to the left of current column
  • :dc or :deletecol - delete current column
  • :colwidth 15 (alias :cw) - set current column width
  • :colwidth A 15 - set a specific column width

Functions and Help

  • :source <file.rhai> (alias :so) - load functions; :so with no args reloads all loaded files
  • :help or :h - open help modal

Keymaps πŸ—ΊοΈ

Select keybindings:

gridline --keymap vim

gridline --keymap emacs

gridline --keymap vim --keymap-file /path/to/keymaps.toml

Keymap files (optional):

  • Default location: config directory gridline/keymaps.toml (platform-specific)
  • Override with --keymap-file <path>
  • If a keymap name is not found in the file, Gridline falls back to the built-in map (vim or emacs)
    • Linux: ~/.config/gridline/keymaps.toml
    • macOS: ~/Library/Application Support/gridline/keymaps.toml
    • Windows: %APPDATA%\\gridline\\keymaps.toml

Sample keymap file:

  • examples/keymaps.toml

Status bar has an always-on cheat sheet, but the core controls are:

Vim Mode (default)

  • hjkl - move cursor
  • i or Enter - edit cell
  • Esc - cancel edit
  • v - visual select (start range selection)
  • y - yank (copy)
  • p - paste
  • u - undo
  • Ctrl+r - redo
  • > or + - increase column width
  • < or - - decrease column width
  • P - open plot modal
  • :w - save
  • :q - quit
  • :help - open help modal

Emacs Mode (experimental)

Note: Emacs mode is incomplete and must be enabled with --keymap emacs. Some documented keybindings may not work as expected.

  • C-n/p/f/b - move cursor (next/previous/forward/back)
  • Enter - edit cell
  • C-g - cancel edit
  • C-SPC - set mark (start visual selection)
  • M-w - copy
  • C-y - paste
  • M-p - open plot modal
  • M-x - command mode

Use :w and :q in command mode for save/quit operations.

File Formats πŸ“

Grid Files (.grd / .grid)

Plain text format with one cell per line:

CELLREF: VALUE

Comments start with #. Values follow the same input rules as interactive editing.

CSV Import/Export

Import CSV data into your grid:

# In command mode

:import data.csv

Export grid to CSV:

# In command mode

:export output.csv

CSV features:

  • Preserves leading zeros in numeric strings
  • Handles quoted fields and escaped quotes
  • Imports at current cursor position

Markdown Export

Export your grid as a markdown table with ASCII charts:

# Command-line export

cargo run -- examples/plot.grid -o output.md


# Or evaluate formula and export

cargo run -- -c "VEC(1..10).map(|x| x * x)" -o squares.md

The markdown export includes:

  • Grid data as a markdown table
  • ASCII renderings of any charts
  • Row and column labels

Development πŸ”§

cargo fmt

cargo clippy --all-targets -- -D warnings

cargo test

License πŸ“œ

Licensed under either of:

  • Apache License, Version 2.0 (LICENSE-APACHE)
  • MIT license (LICENSE-MIT)