summaryrefslogtreecommitdiff
path: root/docs/repl-mode.md
blob: b89b5a482f356fafa9f1abf571aa85dffe66d828 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# REPL Mode

gt has an interactive Read-Eval-Print Loop (REPL) mode that provides a persistent calculation session with command history, tab completion, and persistent state. Use it for exploratory calculations, multi-step RPN work, and configuring settings like rational mode and metric prefix mode.

## Starting the REPL

### `gt` (no arguments)

Run gt without arguments when stdin is connected to a terminal:

```bash
gt
```

This starts the interactive prompt:

```
>
```

### `mage repl`

From the gt source directory, start a REPL session without building:

```bash
mage repl
```

This runs the Go source directly via `go run`.

### `--log <file>`

Append a session log of input and output to a file:

```bash
gt --log session.log
```

When stdin is not a terminal (e.g., piped input), gt falls back to single-command mode instead of starting the REPL. In that case it reads from stdin, tries RPN parsing first, and falls back to percentage calculation:

```bash
echo '3 4 +' | gt          # → 7
echo '20% of 150' | gt     # → 30
```

### No-input usage

Running gt with no input and no TTY displays usage information:

```bash
$ gt
Usage: gt <calculation>
       gt version
...
```

## Navigation and History

The REPL uses [chzyer/readline](https://github.com/chzyer/readline) for an Emacs-style interactive line editor.

### History

Commands are saved to `~/.gt_history` and persist across sessions. A maximum of 1000 entries are kept.

| Shortcut | Action |
|----------|--------|
| Up arrow | Previous command |
| Down arrow | Next command |
| Ctrl+R | Reverse history search (type to filter) |

### Line editing

| Shortcut | Action |
|----------|--------|
| Ctrl+A | Move to beginning of line |
| Ctrl+E | Move to end of line |
| Ctrl+F | Forward one character |
| Ctrl+B | Backward one character |
| Ctrl+H | Delete character before cursor (Backspace) |
| Ctrl+D | Delete character under cursor |
| Ctrl+W | Cut word before cursor |
| Ctrl+K | Cut from cursor to end of line |
| Ctrl+U | Cut from beginning to cursor |
| Ctrl+L | Clear the screen |

## Tab Completion

Pressing Tab completes built-in REPL commands based on what you've typed. Completion is case-insensitive.

The eight built-in commands are: `help`, `clear`, `quit`, `exit`, `rpn`, `calc`, `rat`, `stack`.

```
> h<TAB>
help
> q<TAB>
quit
> r<TAB>    # shows all 'r' commands
rat  rpn
```

When multiple commands match the prefix, cycling through Tab shows all options.

## State Persistence

### Variables

Variables defined in one session are saved to `~/.local/state/gt/vars` (XDG State directory) and automatically restored when you start a new session:

```
> x 42 =
x = 42
> quit
Goodbye!

# In a new session:
> x
42
```

### History

Command history is persisted to `~/.gt_history` and loaded on startup.

## Built-in REPL Commands

The REPL has eight built-in commands. They are recognized case-insensitively.

### `help`

Display general help or help for a specific command:

```
> help
PERC - Percentage Calculator REPL

Built-in Commands:
  help             Show this help message
  help <command>   Show help for a specific topic
  clear            Clear the screen
  quit / exit      Exit the REPL
  rpn / calc       Evaluate an RPN (postfix notation) expression
  rat on/off/toggle Switch between float64 and rational number modes
  stack            Show current stack state (same as 'rpn show')
...

> help clear
clear - Clear the screen
Usage: clear
```

### `clear`

Clear the terminal screen using ANSI escape sequences:

```
> clear
```

(Alternatively, press Ctrl+L.)

### `quit` / `exit`

Exit the REPL and print a farewell message:

```
> quit
Goodbye!
```

Both `quit` and `exit` are equivalent.

### `rpn` / `calc`

Prefix an RPN expression explicitly. These are optional — bare RPN expressions work without them:

```
> rpn 3 4 +
7
> calc 3 4 +
7
> 3 4 +
7
```

### `rat`

Switch between float64 and rational number modes. See [rational-mode.md](rational-mode.md) for full details.

```
> rat on
Rational mode enabled
> 1 3 /
0.3333333333
> rat off
Rational mode disabled (using float64)
> 1 3 /
0.3333333333
```

`rat` requires an argument: `on`, `off`, or `toggle`.

### `stack`

Show a hint for viewing the RPN stack. In the REPL, use `show` directly on the input line:

```
> stack
Use 'rpn show' to view the current stack state
```

## Calculation Modes

The REPL dispatches input through a chain of handlers:

1. **Built-in commands** — help, clear, quit, exit, rpn, calc, rat, stack
2. **RPN expressions** — bare RPN (`3 4 +`), single operators (`dup`), single numbers (`42`), and symbol syntax (`:x`)
3. **Percentage calculations** — `20% of 150`, `what is 20% of 150`, etc.
4. **Error** — unknown commands produce an error message

This means you can freely mix RPN and percentage calculations in a session:

```
> 20% of 150
20.00% of 150.00 = 30.00
  Steps: (20.00 / 100) * 150.00 = 0.20 * 150.00 = 30.00
> 3 4 +
7
> 30 20 +
50
```

## REPL-Only Features

Some features require the persistent state of REPL mode and are not available in single-command mode (`gt '<expression>'`).

### Rational mode (`rat`)

The `rat` command is REPL-only. See [rational-mode.md](rational-mode.md).

```
> rat on
Rational mode enabled
> 1 2 +
3.0000000000
```

### Metric prefix mode (`metric decimal set` / `metric binary set`)

Prefix mode changes persist across REPL lines. See [metric-commands.md](metric-commands.md).

```
> metric binary set
prefix mode: IEC
> 1GB @MB convert
1024
> metric decimal set
prefix mode: SI
> 1GB @MB convert
1000
```

In single-command mode, prefix mode is always SI and resets on every invocation.

### Custom metrics (`custom`)

Define your own units and use them in subsequent calculations. See [custom-metrics.md](custom-metrics.md).

```
> custom define foobar 42 Custom
defined custom metric "foobar" (factor: 42, category: Custom)
> 10foobar
420
> 10foobar 5foobar +
630
> custom undefine foobar
removed custom metric "foobar"
```

In single-command mode, `custom define` stops token evaluation after registering the metric, so subsequent tokens are not processed.

### Variables

Variables persist across REPL lines and are saved to disk between sessions:

```
> x 10 =
x = 10
> y 20 =
y = 20
> x y +
30
> quit
Goodbye!

# New session — variables are restored:
> x
10
```

### Metric commands (`metric show`, `metric list`, etc.)

All metric commands work in the REPL, inspecting the persistent stack:

```
> 100Mbps
100
> metric show
Mbps, DataRate, base: bps, factor: 1e+06
> metric list
DataRate, DataSize, Distance, Speed, Time, Universal, Weight
> 1km 5mi metric compatible
km (Distance) and mi (Distance): true
```

See [metric-commands.md](metric-commands.md) for full details.

## Exiting the REPL

Five methods exit the REPL:

| Method | Behavior |
|--------|----------|
| `quit` | Prints "Goodbye!" and exits |
| `exit` | Same as `quit` |
| Ctrl+D | EOF — exits cleanly |
| Ctrl+C | SIGINT — prints "Use 'quit' or 'exit' to exit, or Ctrl+D" and continues |
| | (pressing Ctrl+C again repeats the hint) |

Ctrl+C does not exit by default — it gives you a chance to cancel. Press Ctrl+D or type `quit` to leave.

## Practical Workflow Examples

### Multi-step RPN calculation

```
> 100Mbps
100
> 1hr *
360000000000
> metric show
bps, DataRate, base: bps, factor: 1
> @GB convert
360000000000
```

### Exploring metric categories

```
> metric list
DataRate, DataSize, Distance, Speed, Time, Universal, Weight
> metric DataRate
Gbps, Kbps, Mbps, Tbps, bps
> 1Gbps @Mbps convert
1000
> metric Distance
ft, in, km, m, mi, nm
> 100km @mi convert
62.13711922
```

### Defining and using custom units

```
> custom define reel 304.8 Distance
defined custom metric "reel" (factor: 304.8, category: Distance)
> 5reel @m convert
1524
> custom list
reel
> custom undefine reel
removed custom metric "reel"
```

### Switching between float and rational modes

```
> rat on
Rational mode enabled
> 10 3 -
7.0000000000
> 1 3 / 3 *
1.0000000000
> rat off
Rational mode disabled (using float64)
> 10 3 -
7
> 1 3 / 3 *
1
```

### Variable-driven calculations

```
> rate 100Mbps =
rate = 100
> time 2hr =
time = 2
> rate time *
200
> show
Stack (bottom to top):
  200 Mbps
```

## REPL vs Single-Command Mode

| Feature | REPL | Single-command |
|---------|------|----------------|
| Command history | Yes (persisted) | No |
| Tab completion | Yes | No |
| Arrow key navigation | Yes | No |
| Ctrl+R search | Yes | No |
| Variable persistence | Yes (saved to disk) | No (fresh per invocation) |
| `rat` (rational mode) | Yes | No |
| `metric binary set` persists | Yes | No (always SI) |
| Custom metrics across lines | Yes | No (define stops evaluation) |
| Line editing (Ctrl+A/E/W/K/U) | Yes | No |
| Session logging (`--log`) | Yes | No |

Use the REPL for interactive exploration, multi-step calculations, and any workflow involving state changes. Use single-command mode for scripts, one-off calculations, and piping.