JonnyWalker81/spread

★ 0Forks 0RustGitHub ↗Compare

README

Spread

A Calca-inspired TUI calculator/editor that combines vim-style text editing with live mathematical evaluation. Built in Rust using ratatui and powered by the Monkey programming language interpreter.

Features

  • Vim-style modal editing: Full vim modal editing support including normal, insert, visual, and command modes
  • Live mathematical evaluation: Write expressions and see results update in real-time using the => operator
  • Unit conversions: Convert between common units (km to miles, kg to lbs, celsius to fahrenheit, etc.)
  • Time functions: Built-in now() and utc() functions for current time calculations
  • Variable support: Define and use variables throughout your document
  • Function definitions: Create reusable functions using Monkey language syntax
  • Persistent evaluation: Variables maintain their values throughout the document
  • Split-pane interface: Editor on the left, calculation results on the right

Installation

Prerequisites

  • Rust (nightly toolchain recommended)
  • Nix with flakes enabled (optional, for development environment)
  • direnv (optional but recommended)

Building from source

git clone https://github.com/JonnyWalker81/spread.git
cd spread
cargo build --release

The binary will be available at target/release/spread.

With Nix

If you have Nix with flakes enabled:

git clone https://github.com/JonnyWalker81/spread.git
cd spread
direnv allow  # If using direnv
just build    # Or: cargo build --release

Usage

Interactive Mode (TUI)

spread [file.spread]

Evaluation Mode (CLI)

spread --eval file.spread

Key Bindings

Normal Mode

  • i - Enter insert mode
  • v - Enter visual mode
  • : - Enter command mode
  • h/j/k/l - Navigate (vim motions)
  • w/b - Word navigation
  • 0/$ - Line start/end
  • gg/G - Document start/end
  • dd - Delete line
  • yy - Yank line
  • p - Paste
  • u - Undo
  • Ctrl+r - Redo

Command Mode

  • :w - Save file
  • :q - Quit
  • :wq - Save and quit
  • :q! - Quit without saving

Examples

Basic Calculations

5 + 3 => 8
10 * 20 => 200
100 / 4 => 25
2^8 => 256

Variables

distance = 150
time = 2.5
speed = distance / time => 60

Unit Conversions

2km to miles => 1.242742
70kg to lbs => 154.3234
32f to c => 0
100c to f => 212
5 liters to gallons => 1.32086

Functions

# Define a function
calculate_tip = fn(bill, percent) { bill * percent / 100 }
bill_amount = 85.50
tip = calculate_tip(bill_amount, 20) => 17.1
total = bill_amount + tip => 102.6

# Using arrays
numbers = [1, 2, 3, 4, 5]
sum = fn(arr) { 
    if (len(arr) == 0) { 
        0 
    } else { 
        arr[0] + sum(rest(arr)) 
    }
}
total = sum(numbers) => 15

Time Functions

current_time = now() => 2025-07-20 17:21:12
utc_time = utc() => 2025-07-21 00:21:12 UTC

# Time-based calculations
start_hour = 9
current_hour = 17
hours_worked = current_hour - start_hour => 8
hourly_rate = 25
pay = hours_worked * hourly_rate => 200

Percentage Calculations

price = 150
discount = 20%
discount_amount = price * discount => 30
final_price = price - discount_amount => 120

Configuration

Configuration is stored in ~/.config/spread/config.toml:

[editor]
tab_size = 4
use_spaces = true  
line_numbers = true
wrap_lines = false

[ui]
theme = "default"
split_ratio = 0.6
show_line_numbers = true

[evaluator]
auto_evaluate = true
evaluation_delay_ms = 500
max_iterations = 1000
precision = 10

Development

This project uses a Nix flake for reproducible development environments.

Common Development Commands

# With just (task runner)
just build               # Development build
just build-release       # Release build  
just run                 # Run application
just test               # Run tests
just fmt                # Format code
just lint               # Run clippy
just watch              # Watch for changes

# With cargo directly
cargo build
cargo run -- file.spread
cargo test
RUST_LOG=spread=debug cargo run  # With debug logging

Debug Logging

  • In eval mode: RUST_LOG=spread=debug spread --eval file.spread
  • In TUI mode: RUST_LOG=spread=debug spread (logs written to spread.log)

Project Structure

spread/
├── src/
│   ├── main.rs         # Application entry point
│   ├── app.rs          # Main application state and event loop
│   ├── editor/         # Vim-style editor implementation
│   ├── evaluator/      # Mathematical expression evaluation
│   ├── interpreter/    # Monkey language interpreter
│   ├── document/       # Document model and persistence
│   ├── ui/             # Terminal UI components
│   └── config.rs       # Configuration management
├── flake.nix           # Nix development environment
├── Cargo.toml          # Rust dependencies
├── justfile            # Development task automation
└── CLAUDE.md           # AI assistant instructions

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License

Contributors

JonnyWalker81

Issues