███ ██ ██ ██ ███ ███ ██████ ████ ██ ██ ██ ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██████ ██ ██ ██ ██
A text calculator for natural language expressions with a vim-style TUI.
- Natural language expressions:
20% of 150,$100 in euros,2 hours + 30 min - Variables:
tax = 15%then100 + 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:
sin(pi / 2),log_y(2, 8),factorial(5),mod(10, 3) - Live exchange rates: Fetched automatically on startup
- 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 with bottom-aligned results
- Grouped totals: Currencies and units summed separately in footer (respects exchange rates)
brew tap nasedkinpv/tap
brew install numrInstalls both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).
# Using yay
yay -S numr
# Using paru
paru -S numrInstalls both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).
# 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-cliRelease archives also contain both binaries: numr (opens the calculator file in the TUI) and numr-cli (CLI/REPL/server).
# Open default file (stored in OS config directory)
numr
# Open specific file
numr example.numr# 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.
Run numr as a backend for other tools (editors, launchers, scripts):
numr-cli --serverSend 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}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 |
The TUI supports two keybinding modes: Vim (default) and Standard. Press Shift+Tab to toggle between them.
| 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 |
| Key | Action |
|---|---|
Esc |
Return to Normal mode |
| Type | Insert text |
Backspace / Delete |
Delete char backward/forward |
Enter |
New line |
Arrows / PageUp/Down |
Navigate |
Home / End |
Line start/end |
Ctrl+s |
Save |
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 |
Ctrl+k |
Delete line |
Enter |
New line |
Ctrl+w/l/h |
Toggle wrap/line numbers/header |
? / F1 |
Toggle help |
Ctrl+s |
Save |
Ctrl+r |
Refresh rates |
Shift+Tab |
Switch to Vim mode |
Ctrl+q |
Quit |
| 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(), sqrt(), abs(), round(), floor(), ceil(), sin(), cos(), tan(), ln(), log(), log_y(), factorial(), mod() |
| Base conversion | 22 to hex → 0x16, 22 to bin → 0b10110 |
| Unit conversion | 5 km in miles, 22 C in F, 1 TB in GB |
| Compound units | 5 m * 10 m → 50 m², 100 km / 2 h → 50 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²)
Full examples
10 + 20 → 30
100 - 25 → 75
6 * 7 → 42
100 / 4 → 25
2 ^ 8 → 256
22 to hex → 0x16
22 to bin → 0b10110
-42 to hex → -0x2a
20% of 150 → 30
100 + 15% → 115
$50 - 10% → $45
price = $100
tax = 8%
price + tax → $108
# This is a comment
// This is also a comment
Groceries $45.00
$100 → $100
+ $50 → $150 (continues from previous)
* 2 → $300
- 10% → $270
total = _ → $270 (_ or ANS references previous result)
sum(10, 20, 30) → 60
avg(10, 20, 30) → 20
min(5, 3, 8) → 3
max(5, 3, 8) → 8
sqrt(16) → 4
abs(-5) → 5
round(3.7) → 4
floor(3.7) → 3
ceil(3.2) → 4
sin(pi / 2) → 1
cos(0) → 1
ln(e) → 1
log(100) → 2
log_y(2, 8) → 3
factorial(5) → 120
mod(10, 3) → 1
Constants: pi, e, phi.
5 m * 10 m → 50 m²
100 km / 2 h → 50 km/h
50 kph * 2 h → 100 km
50 kph in mps → 13.89 m/s
25 km / 100 km → 0.25 (dimensionless)
| Category | Units |
|---|---|
| Length | km, m, cm, mm, mi/miles, ft/feet, in/inches |
| Area | m²/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, m³/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, zł/PLN, ₴/UAH |
| Crypto | ₿/BTC, Ξ/ETH, ◎/SOL, ₮/USDT, USDC, BNB, XRP, ₳/ADA, Ð/DOGE, DOT, Ł/LTC, LINK, AVAX, MATIC, TON |
graph TB
subgraph Frontends
CLI[numr-cli<br/>CLI · REPL · JSON-RPC]
TUI[numr-tui<br/>Terminal UI · Vim/Standard]
Web[numr-web<br/>WASM web app]
end
Editor[numr-editor<br/>Syntax highlighting]
subgraph Core[numr-core]
Engine[Engine]
Engine --> Parser[PEG Parser]
Parser --> Eval[Evaluator]
Eval --> Types[Currency · Units · Values]
Eval --> Cache[(Rate Cache)]
end
Fiat[open.er-api.com]
Crypto[CoinGecko]
CLI --> Engine
TUI --> Engine
TUI --> Editor
Web --> Engine
Web --> Editor
Cache -.-> Fiat
Cache -.-> Crypto
numr/
├── crates/
│ ├── numr-core/ # Core evaluation engine (WASM-compatible)
│ │ ├── parser/ # Pest PEG grammar and AST builder
│ │ ├── eval/ # Expression evaluation with unit/currency handling
│ │ ├── types/ # Value, Currency, Unit registries
│ │ ├── cache/ # Exchange rate caching with BFS path finding
│ │ ├── fetch.rs # HTTP rate fetching (optional "fetch" feature)
│ │ └── wasm.rs # WASM bindings (optional "wasm" feature)
│ ├── numr-editor/ # Syntax highlighting and text buffer (WASM-compatible)
│ ├── numr-tui/ # Terminal UI (Ratatui) with vim/standard modes
│ └── numr-cli/ # CLI, interactive REPL, and JSON-RPC server
The core library (numr-core) is UI-agnostic and can be embedded in CLI, TUI, GUI, or WASM contexts. The fetch feature flag enables HTTP fetching (adds reqwest dependency, not WASM-compatible).
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. Both TUI and CLI share this cache:
- TUI: Fetches fresh rates on startup
- CLI: Fetches only if cache is expired
Rate sources:
- Fiat currencies: open.er-api.com (152 currencies, free)
- Cryptocurrency: CoinGecko (15 tokens, free)
- elephant-numr — Provider for Walker/Elephant launcher
MIT
