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
|
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):
nm NORMAL block cursor, keys move/edit. DEFAULT on startup.
in INSERT keys type text at the cursor.
sy 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 chording; nothing like Vim/Helix.
PART 2 — the TTY. A terminal is just a pane; Enter positions you.
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 are a chording language
over text. Pardes inherits this directly. (Vim and Helix have almost
none of this — their mouse is for selection/scroll only.)
LEFT (button 1) select text; a no-drag click also FOCUSES the
pane and PINS the modal cursor where you click
(so you can then edit there with the keyboard).
MIDDLE (button 2) "execute" the selected text. Selecting a builtin
name runs it; anything else is SENT to the shell
the pane runs (if any). This is how you run a
command you typed in text mode.
RIGHT (button 3) "look" — resolve the word under the cursor as a
path and open it: a directory opens/focuses a
terminal there and ls's it; a file opens a file
pane scrolled to a ":line" suffix if present.
CHORDING (the acme magic): hold one button, press another. The
classic is select-then-execute:
- drag with LEFT to select a shell command you've typed
- while STILL holding LEFT, press MIDDLE -> it runs
- release both
You can also select with LEFT then press RIGHT to "look" the selected
word up as a file. Two-button chords = select-and-act in one gesture.
THE TAG: every pane has a top bar (the "tag") — the pane's directory
followed by the builtin command names (Newcol Delcol Del Tutor). It's just
text: middle-click "Del" to close the window, "Newcol" to make a new
column, "Delcol" to close the column, "Tutor" to spawn this tutor.
Right-click a directory in any body to open a terminal there.
LAYOUT: columns split horizontally, windows stack in each column.
- drag the VERTICAL gap between columns to resize
- drag the HORIZONTAL gap between stacked windows to resize
- drag the red box (top-left of a pane) to MOVE a window between
columns / reorder it
- 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 (nm) shows the REAL shell — prompts and typed input visible.
You navigate the screen with the same h/j/k/l/w/b/e
as a file pane.
INSERT (in) hides the prompt rows — a clean compose surface
(acme-style) where you type a command to run.
TTY (sy) keys go straight to the shell as terminal input.
ESC: insert -> normal. (Never reaches tty.)
ENTER: normal -> tty, AND moves the shell's REAL cursor to where
your modal cursor was on the input line:
- empty input -> shell cursor at the prompt START
- typed text -> shell cursor at/after the char you
navigated to (start-vs-end matters)
This is tty-native: it reuses the shell's OSC 133 semantic
prompt via ghostty's promptClickMove (our shell rc opts in
with cl=line). The shell moves its own cursor with arrow keys
it understands — Pardes doesn't fake a cursor on top.
So the flow is: navigate the shell screen in normal, hit Enter exactly
where you want to keep typing/editing, and you're IN the shell at that
spot. No separate "terminal mode cursor" to reconcile.
(Positioning needs a live shell + a pty; covered by the e2e suite,
tests.zig step 4b: type ABCDEF, navigate to the F, Enter, type X ->
ABCDEXF, proving the shell cursor moved mid-input.)
=================================================================
= 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:
- NO select mode / multi-cursor (Helix). Selection is LINE-first:
`x` grows a line selection downward; d/c/y act on it.
- NO verb+noun (Vim's dw, cw). Motions only MOVE. To delete a word
you select its lines with x then d.
- ESC never reaches tty. Enter does (on terminals).
- 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. No `v` select-mode: `x` grows a line selection
downward; d/c/y act on it.
`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 / Ctrl-b full page down / up
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)
chord L+M = select-and-run; tag builtins (Del, ...)
TTY: terminal IS a pane; Enter from normal -> tty AT the
cursor's spot (start if empty, mid-text otherwise)
KEYS (helix): h j k l w b e 0 $ ^ gg G x d c y p i a I A o O
zt zz zb Ctrl-d/u/f/b Ctrl-w hjkl Alt-n/c
vs Helix: no select-mode, no multi-cursor; selection is LINE-first.
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 Enter reuses the shell's
own prompt to position you precisely.
To spawn THIS tutor again from anywhere: middle-click "Tutor" in any
pane's tag (it's a builtin, next to Newcol/Delcol/Del).
Quit the tutor: this is a file pane — `:q` isn't wired; close the
window (middle-click "Del" in the tag) or Ctrl-c the app.
|