Skip to content

nasedkinpv/numr

Repository files navigation

numr

CI

A text calculator for natural language expressions with a vim-style TUI.

Try it online →

numr TUI demo - calculations with variables, units, currencies, and continuation

Features

  • Natural language expressions: 20% of 150, $100 in euros, 2 hours + 30 min
  • Variables: tax = 15% then 100 + tax
  • Unit conversions: Length, weight, time, temperature, data sizes
  • Compound units: 5 m * 10 m = 50 m², 100 km / 2 h = 50 km/h
  • Currency conversions: USD, EUR, GBP, JPY, CHF, CNY, CAD, AUD, INR, KRW, RUB, ILS, PLN, UAH + crypto (BTC, ETH, SOL, and more)
  • Number base conversions: 22 to hex, 22 to bin
  • Math functions and constants: median(1, 3, 2), clamp(120, 0, 100), sin(90°), factorial(5)
  • Angle conversions: 90° to rad, 3.14159 rad to deg, rad(180), deg(pi)
  • Live exchange rates: Loaded and refreshed explicitly by each frontend, with a shared 1-hour cache
  • Dual keybinding modes: Vim (modal) or Standard (direct input) - toggle with Shift+Tab
  • Mouse support: Scroll with mouse wheel or trackpad
  • File persistence: Save with Ctrl+S, supports custom files
  • Syntax highlighting: Numbers, operators, variables, units, and currencies
  • Comments: Lines starting with # or // are treated as comments
  • Continuation: Start a line with an operator (+ 10, * 2) to continue from the previous result
  • Wrap mode: Toggle text wrapping; results follow the final expression row and ignore trailing comments
  • Grouped totals: Currencies and units summed separately in footer (respects exchange rates)

Installation

macOS (Homebrew)

brew tap nasedkinpv/tap
brew install numr

Installs both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).

Arch Linux (AUR)

# Using yay
yay -S numr

# Using paru
paru -S numr

Installs both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).

From source

# Install the TUI binary
cargo install --path crates/numr-tui

# Install the CLI binary
cargo install --path crates/numr-cli

# Or build both from source
cargo build --release

# Binaries will be available at target/release/numr and target/release/numr-cli

Release archives also contain both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).

Usage

TUI Mode

# Open default file (stored in OS config directory)
numr

# Open specific file
numr example.numr

CLI Mode

# Single expression
numr-cli "20% of 150"

# Evaluate file (aligned "input = result" output)
numr-cli -f example.numr

# Interactive REPL
numr-cli -i

# Pipe mode
echo "100 + 200" | numr-cli

# Show running total
numr-cli -t -f example.numr

# Aligned output for any mode
numr-cli --verbose "20% of 150"

By default, numr-cli prints just the result. File mode (-f) uses aligned input = result output. Use --verbose to get aligned output in other modes. Use -t to show a running total at the end.

On Linux, use rlwrap numr-cli -i for readline-style history and editing in the REPL.

JSON-RPC Server Mode

Run numr as a backend for other tools (editors, launchers, scripts):

numr-cli --server

Send JSON-RPC 2.0 requests via stdin, receive responses via stdout:

echo '{"jsonrpc":"2.0","method":"eval","params":{"expr":"20% of 150"},"id":1}' | numr-cli --server
# {"jsonrpc":"2.0","result":{"type":"number","value":"30","display":"30"},"id":1}

The transport is newline-delimited JSON. It supports calls, notifications, null IDs, and JSON-RPC batches; each input frame is limited to 1 MiB. Notifications update server state but produce no response.

Available methods:

Method Params Description
eval {"expr": "..."} Evaluate expression
eval_lines {"lines": [...]} Evaluate multiple lines
clear none Clear state
get_totals none Get grouped totals
get_variables none List variables
reload_rates none Refresh exchange rates

See docs/json-rpc.md for the complete protocol, result schema, limits, and error codes.

Keybindings (TUI)

The TUI supports two keybinding modes: Vim (default) and Standard. Press Shift+Tab to toggle between them.

Vim Mode

Normal Mode

Key Action
i / a Enter Insert mode at/after cursor
I / A Enter Insert mode at line start/end
o / O New line below/above and enter Insert mode
s Substitute character (delete and insert)
C Change to end of line
h / j / k / l Move left/down/up/right
w / b / e Word forward/backward/end
0 / $ Line start/end
gg / G First/last line
Space Move right
PageUp/Down Scroll page
x / X Delete char forward/backward
dd Delete line
D Delete to end of line
J Join lines
W / N / H Toggle wrap/line numbers/header
? / F1 Toggle help
Ctrl+s Save
Ctrl+r Refresh rates
F12 Toggle debug
Shift+Tab Switch to Standard mode
q Quit

Insert Mode

Key Action
Esc Return to Normal mode
Type Insert text
Backspace / Delete Delete char backward/forward
Option+Backspace / Ctrl+w Delete previous word
Cmd+Backspace / Ctrl+u Delete to line start
Enter New line
Arrows / PageUp/Down Navigate
Home / End Line start/end
Ctrl+s Save

Standard Mode

Direct input like traditional editors - no modal switching required.

Key Action
Type Insert text directly
Arrow keys Move cursor
Home / End Line start/end
PageUp/Down Scroll page
Ctrl+a / Ctrl+e Line start/end
Ctrl+g Go to first line
Backspace / Delete Delete char
Option+Backspace / Ctrl+w Delete previous word
Cmd+Backspace / Ctrl+u Delete to line start
Ctrl+k Delete to line end
Enter New line
Option+z Toggle wrap
Ctrl+l / Ctrl+h Toggle line numbers/header
? / F1 Toggle help
Ctrl+s Save
Ctrl+r Refresh rates
Shift+Tab Switch to Vim mode
Ctrl+q Quit

Supported Operations

Category Examples
Arithmetic 10 + 20, 6 * 7, 2 ^ 8
Percentages 20% of 150, $50 - 10%, 100 + 15%
Variables tax = 8% then price + tax
Continuation $100+ $50* 2 (chains from previous)
Functions sum(), avg(), min(), max(), median(), clamp(), sqrt(), abs(), round(), floor(), ceil(), sin(), cos(), tan(), rad(), deg(), ln(), log(), log_y(), factorial(), mod()
Base conversion 22 to hex0x16, 22 to bin0b10110
Unit conversion 5 km in miles, 22 C in F, 1 TB in GB
Compound units 5 m * 10 m50 m², 100 km / 2 h50 km/h
Currency $100 in eur, 1 BTC in USD
Comments # comment or // comment
Reference previous _ or ANS for last result

Compound unit aliases: kph (km/h), mph (mi/h), mps (m/s), m2 (m²), km2 (km²), ft2 (ft²)

See example.numr for a complete, executable tour of arithmetic, variables, continuations, functions, currencies, angles, and compound units. Constants are pi, e, and phi.

Supported Units

Category Units
Length km, m, cm, mm, mi/miles, ft/feet, in/inches
Area /m2, km²/km2, ft²/ft2, acre, hectare/ha
Speed m/s/mps, km/h/kph, mph, knot
Weight kg, g, mg, lb/lbs, oz, ton
Volume L, mL, gal, /m3
Time months/mo, weeks/wk, days/d, hours/hr/h, minutes/min, seconds/sec/s
Energy J, kJ, cal, kcal, kWh
Power W, kW
Temperature K/Kelvin, C/Celsius, F/Fahrenheit
Data TB, GB, MB, KB, bytes
Fiat $/USD, /EUR, £/GBP, ¥/JPY, CHF, CNY, CAD, AUD, /INR, /KRW, /RUB, /ILS, /PLN, /UAH
Crypto /BTC, Ξ/ETH, /SOL, /USDT, USDC, BNB, XRP, /ADA, Ð/DOGE, DOT, Ł/LTC, LINK, AVAX, MATIC, TON

Architecture

Calculation semantics live in the pure, WASM-compatible numr-core; numr-editor provides shared highlighting and UTF-8 primitives; CLI, TUI, web, and desktop remain thin I/O and presentation adapters. See docs/architecture.md for the complete component map, contracts, dependency direction, and rate data flow. The web frontend is maintained in the separate numr-web repository.

Config and cache are stored in the OS config directory (~/.config/numr/ on Linux, ~/Library/Application Support/numr/ on macOS). Settings persist automatically when toggled in the TUI.

Example config.toml:

[preferences]
keybinding_mode = "vim"   # "vim" or "standard"
wrap_mode = false
show_line_numbers = false
show_header = false

[files]
default_path = "~/Documents/calculations.numr"

[api]
fiat_rates_url = "https://open.er-api.com/v6/latest/USD"
crypto_rates_url = "https://api.coingecko.com/api/v3/simple/price"

[api.keys]
coingecko_api_key = "your-key-here"

CoinGecko API key header (demo vs pro) is selected automatically based on the URL host.

Exchange rates are cached to rates.json in the same config directory with 1-hour expiry. Cache I/O is explicit and writes use atomic replacement. The native adapters share this cache:

  • TUI: Starts a background refresh without blocking the event loop
  • CLI: Loads the cache, then fetches only if no usable cached rates exist
  • JSON-RPC server: Loads the cache at startup; network access occurs only through reload_rates

Rate sources:

Integrations

License

MIT

About

Natural-language text calculator with TUI/CLI: variables, units, currencies, and live exchange rates

Topics

Resources

License

Stars

256 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors

Languages