summaryrefslogtreecommitdiff
path: root/src/tutor.txt
blob: 94a2a20ec345990ed2ab70569afe54b5dd918c1b (plain) (blame)
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

                               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.
   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. 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.