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
|
PARDES TUTOR
tmux + vi + acme, from scratch.
The model is acme's: EVERYTHING is text, editable and executable
the same way. Modal editing (helix-style) lives on top of that.
Press j until you reach the introduction.
=================================================================
= INTRODUCTION =
=================================================================
Pardes is tmux + vi + acme, made from scratch. The foundation is
the acme model: a pane is just text on screen. There is no separate
"buffer" type — what you see is what you edit. Some panes happen to
be live terminals (tty mode); most are text you can move a cursor
over. Modal editing (helix-style) is layered on top of that.
Three modes (the tag shows which):
NOR NORMAL block cursor, keys move/edit. DEFAULT on startup.
INS INSERT keys type text at the cursor.
TTY TTY keys go straight to the shell. (terminals only)
This tutor is in THREE parts, ordered by what's most different from
editors you may know:
PART 1 — the MOUSE. Acme's three buttons; nothing like Vim/Helix.
PART 2 — the TTY. A terminal is just a pane; Ctrl-b drops into it
by default.
PART 3 — the KEYS. Helix-style modal (with the Pardes differences).
PRACTICE BLOCKS (part 3): the "# keys:" line lists keystrokes
(space-separated; esc/enter/bs are special, the rest type each char).
The clean lines under "# before" are what you practice on; the lines
under "# after" are what you should end up with. "# at: row,col"
(right after # keys:) sets where the cursor starts. These blocks are also run as unit
tests (generated from this file by tutor_gen).
Hold j to reach part 1.
=================================================================
= PART 1 — THE MOUSE (acme chording; the most different part) =
=================================================================
Acme's central idea: the THREE mouse buttons each ACT on text, and the
keyboard mirrors them. Pardes inherits this. (Vim and Helix have almost
none of it — their mouse is selection/scroll only.)
┌─────────┬─────────┬─────────┐
│ L │ M │ R │
│ (1) │ (2) │ (3) │
├─────────┴─────────┴─────────┤
│ │
│ ( o ) │ the wheel scrolls the pane
│ │
└─────────────────────────────┘
L select a plain click also FOCUSES the pane and PINS the modal
cursor where you click, so you can edit there next.
A click never changes a pane's MODE (tty stays tty).
M execute run the selected text: a builtin name runs it, anything
else is SENT to the shell the pane runs. This is how you
run a command you typed in a text mode.
R look open the word under the cursor as a path: a directory
opens/focuses a terminal there and ls's it; a file opens
a file pane (scrolled to a ":line" suffix if present).
SELECT-THEN-ACT: there is no held-button chord. Instead:
- MIDDLE-drag over text selects AND runs it on release (one gesture);
a no-drag middle click auto-expands to the word under the cursor.
- or select with the keyboard (`v` chars / `x` lines), then press
Tab to execute or Enter to look — the acme chords on the keyboard.
THE TAG: each pane has a one-line tag: its MODE (NOR/INS/TTY) + directory
or file path + builtins. File panes show "Save Del" by default; Save
writes the current file to disk, Del closes the window. Clicking a tag
edits it, ALWAYS in insert mode (a one-line tag has no use for normal
mode): type straight in, Enter looks / Tab executes the word at the
cursor, Esc hands focus back to the body. Terminal and
image panes show "Del". "Delcol" still exists as a command: type it in
a tag or body and execute it to close the whole column. A SEPARATE bar
across the top of the screen holds the window-agnostic builtins:
Kill Newcol Tutor Debug Colors NextColor
Middle-click "Newcol" for a new column, "Tutor" to spawn this tutor,
"Kill" to quit; Debug/Colors/NextColor toggle the stats overlay, the
syntax/ansi recolor, and the theme.
Right-click a directory in any body to open a terminal there.
LAYOUT: columns split the screen; windows stack within a column. Panes
abut with no wasted gap — a pane's own trailing edge (its last column, or
last row above the next tag) IS the resize handle: hover it and a dashed
line overlays that edge (keeping the underlying colors) to mark the drag.
- drag a column's right edge to resize it against its neighbour
- drag a window's bottom edge to resize it against the one below
- drag the accent box (top-left of a pane; indigo-purple, brighter
when the pane is focused) to MOVE a window between columns / reorder
- the scrollbar is the gutter below the box: left-click scrolls UP
to that point, right-click scrolls DOWN
(Mouse actions are hard to unit-test from text; they're covered by
the e2e suite: middle-click execute, right-click dir/file open, tag
builtins, drag-rearrange. See tests.zig steps 6-8.)
=================================================================
= PART 2 — THE TTY (a terminal is just a pane) =
=================================================================
This is the headline difference from Vim/Helix: there is no "open a
terminal in a split" that's separate from "edit a file in a split".
A TERMINAL IS A PANE. The same modal keys that edit a file navigate
the terminal's screen, and dropping into tty REUSES the shell's own
prompt model rather than layering an editor cursor on top.
On a terminal pane:
NORMAL (NOR) prompt rows are HIDDEN — a clean acme-style page. You
navigate it with the same h/j/k/l/w/b/e as a file.
INSERT (INS) same clean page; keys type an insertion overlay (the
command you're composing). Prompts still hidden.
TTY (TTY) the REAL shell — prompts + typed input shown, and keys
go straight to the pty as terminal input.
ESC: insert -> normal. (Esc never reaches tty.)
Ctrl-b: toggles TTY on a terminal by default — the ONLY way in or out.
Use `pardes --tty-toggle=g` (or another letter) to make Ctrl-g
the toggle instead. Entering is tty-native: if the shell is at
a prompt and your modal cursor sits on the input line, it first
moves the shell's REAL cursor to that spot —
- empty input -> shell cursor at the prompt START
- typed text -> shell cursor at/after the char you were on
via the shell's OSC 133 semantic prompt (ghostty promptClickMove;
our rc opts in with cl=line). The shell moves its own cursor with
arrow keys it understands — Pardes doesn't fake one on top.
ENTER / TAB (in normal) are NOT a way into tty — they're the acme mouse
chords on the keyboard: Enter = "look" (open the path under the cursor),
Tab = "execute". Both act on the selection if one is active.
So the flow is: navigate the hidden-prompt page in normal, hit the tty
toggle where you want to keep typing, and you're IN the live shell at
that spot. No separate "terminal mode cursor" to reconcile.
(The cursor positioning is enterTty's promptClickMove; it needs a live
shell at a prompt. Mouse/tty behavior is exercised by the e2e suite.)
=================================================================
= PART 3 — THE KEYS (helix-style modal, Pardes differences) =
=================================================================
Same core as Helix and Vim: a block cursor you move with h/j/k/l,
motions w/b/e, and you enter insert with i/a/o. The differences:
- Selection is LINE-first: `x` grows a line selection downward.
There's also `v` for a CHARACTER range. No multi-cursor. d/c/y act
on whichever selection is active (else the current line).
- NO verb+noun (Vim's dw, cw). Motions only MOVE. To delete a word,
select it (`v` then motions, or `x` for whole lines) then `d`.
- ESC never reaches tty; it only does insert -> normal. Dropping a
terminal into the live shell is the tty toggle (Ctrl-b by default;
see Part 2).
- Enter / Tab in normal mirror the mouse: Enter = look (open the path
under the cursor), Tab = execute. `u` undo, `U` redo.
- Editing a file pane MUTATES real content; a terminal pane yanks
rendered text and pastes it as an insertion run (shell output
can't be deleted, only pasted text can).
PRACTICE: run the keys on the "# before" lines; you should get the
"# after" lines. (These blocks are unit tests too.)
-----------------------------------------------------------------
= 3.1 MOVING THE CURSOR (h j k l) =
-----------------------------------------------------------------
k * h = left, l = right
h l * j = down, k = up (also: arrow keys)
j
The cursor sits ON a character (block). Motions only move.
# keys: l l l
# before
abcdef
# after
abcdef
-----------------------------------------------------------------
= 3.2 ENTERING INSERT: i a A I o O =
-----------------------------------------------------------------
`i` insert at cursor. `a` insert AFTER the cursor.
`A` insert at end of line. `I` insert at first non-blank.
`o` open line BELOW + insert. `O` open line ABOVE + insert.
(All match Vim and Helix.)
# keys: i X esc
# before
bcdef
# after
Xbcdef
Cursor on 'b' (col 0). `i` inserts before 'b'.
# keys: a Z esc
# before
abc
# after
aZbc
Cursor on 'a' (col 0). `a` inserts after 'a'.
# keys: A Z esc
# before
abc
# after
abcZ
`A` jumps to end then inserts — appends 'Z'.
# keys: I Z esc
# before
abc
# after
Zabc
`I` goes to the first non-blank ('a'), inserts before it.
# keys: o line2 esc
# before
line1
# after
line1
line2
`o` makes a blank line below, enters insert, "line2" typed, Esc.
# keys: O top esc
# before
bot
# after
top
bot
-----------------------------------------------------------------
= 3.3 WORD MOTIONS: w b e (W B E long) =
-----------------------------------------------------------------
`w` next word start, `b` prev word start, `e` next word END.
W/B/E treat punctuation as part of the word. Same as Vim & Helix.
# keys: w i Z esc
# before
foo bar
# after
foo Zbar
`w` from 'f'(col0) lands on 'b'(col4). Insert before 'b'.
# keys: e i Z esc
# before
foo bar
# after
foZo bar
`e` from 'f' lands on 'o'(col2, end of "foo"). Insert before it.
# keys: b i Z esc
# at: 0,4
# before
foo bar
# after
Zfoo bar
Cursor on 'b'(col4, "bar"). `b` -> start of previous word = 'f'(col0).
-----------------------------------------------------------------
= 3.4 LINE BOUNDS: 0 $ ^ g g G =
-----------------------------------------------------------------
`0` start of line, `$` end, `^` first non-blank.
`gg` first line, `G` last line. Same as Vim/Helix.
# keys: $ i Z esc
# before
abcde
# after
abcdZe
`$` to last char 'e', insert before it. (Cursor ON a char, so "end" =
last char, not past it.)
# keys: 0 i Z esc
# before
abcde
# after
Zabcde
# keys: ^ i Z esc
# before
abcde
# after
Zabcde
-----------------------------------------------------------------
= 3.5 LINE SELECTION + EDIT: x d c y p =
-----------------------------------------------------------------
The Pardes difference is LINE-first selection: `x` grows a line
selection downward; d/c/y act on it. `v` is still available for a
character range when you need one.
`x` start/extend a line selection
`d` delete the selected lines (yanked)
`c` clear the line + insert (change)
`y` yank the selection (or current line)
`p` paste the yank as a new line below
# keys: x d
# at: 1,0
# before
keep
gone
# after
keep
Cursor on "gone" (row 1). `x` selects it, `d` deletes it.
# keys: x x d
# at: 1,0
# before
a
b
c
# after
a
`x` selects "b", `x` extends to "c", `d` removes both.
# keys: x y j p
# before
orig
dupe
# after
orig
dupe
orig
`x` selects "orig", `y` yanks it, `j` to "dupe", `p` pastes below.
# keys: x c typed esc
# before
old
# after
typed
`x` selects "old", `c` clears it to an empty line + insert, type.
# keys: c Q esc
# at: 0,1
# before
ab
# after
aQ
No selection: cursor on 'b'(col1). `c` deletes 'b' + insert; type 'Q'.
-----------------------------------------------------------------
= 3.6 VIEWPORT + PANES =
-----------------------------------------------------------------
zt / zz / zb scroll so the cursor is at top/center/bottom
Ctrl-d / Ctrl-u half-page down / up
Ctrl-f full page down. (Ctrl-b pages up on a file pane;
on a terminal it is the default tty toggle. If you
start with --tty-toggle=g, Ctrl-g takes that role.)
Ctrl-w h/j/k/l focus the pane left/down/up/right
Alt-n new terminal below the active one
Alt-c move the active terminal into a fresh column
(No practice blocks: these are viewport/layout, not text edits.)
=================================================================
= SUMMARY =
=================================================================
MOUSE (acme): L select/focus+pin M execute R look(open)
select-then-act: middle-drag, or v/x then Tab
file tag = mode + path + "Save Del"; other tags show Del
top bar = Kill Newcol Tutor Debug Colors NextColor
TTY: a terminal IS a pane; Ctrl-b toggles the live shell by default,
landing its cursor where you navigated (prompt start if
the input is empty, mid-text otherwise)
KEYS (helix): h j k l w b e 0 $ ^ gg G v x d c y p i a I A o O
u undo U redo Enter=look Tab=execute
zt zz zb Ctrl-d/u Ctrl-f Ctrl-w hjkl Alt-n/c
vs Helix: no multi-cursor; selection is LINE-first (x), plus v chars.
vs Vim: no verb+noun (dw); motions only move; Esc never reaches tty.
vs both: a terminal is just a pane; the same keys edit text and
navigate the shell screen, and the tty toggle reuses the
shell's own prompt to position you precisely.
To spawn THIS tutor again from anywhere: middle-click "Tutor" in the
top bar (next to Kill / Newcol).
Quit the tutor: this is a file pane — `:q` isn't wired; close the
window (middle-click "Del" in its tag), "Kill" (top bar) to quit
everything, or Ctrl-c the app.
|