summaryrefslogtreecommitdiff
path: root/src/tutor.txt
blob: ae22ede9393da9d972687ebd5bd9e1b5ad44a22a (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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

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

 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;
 most are text you move a cursor over. Modal editing is layered on top.

 Three modes (the BOX at the pane's top-left corner shows which):
      NORMAL   block cursor, keys move and edit. The box is BLANK.
   ^  INSERT   keys type text at the cursor.
   $  TTY      keys go straight to the shell. (terminals only)

 A bare `pardes` opens one shell already in TTY. Give it a file or a
 directory and you start in NORMAL.

 SIX PARTS, ordered by what is most different from editors you know:
   1 — THE MOUSE.      Acme's three buttons; nothing like vim.
   2 — PANES.          Moving between them. Esc, Shift-Esc, Ctrl-w.
   3 — THE TTY.        Raw input, prompt-aware Esc, and the mode tag.
   4 — DETACHED.       The core outliving the terminal showing it.
   5 — THE KEYS.       Helix-style modal, and where it differs.
   6 — THE REST.       PDFs, images, the language backend, scripting.

 PRACTICE BLOCKS (part 5): the "# keys:" line lists keystrokes
 (space-separated; esc/enter/bs are special, the rest type each char).
 The lines under "# before" are what you practice on; "# after" is what
 you should end up with. They are here to be TYPED and nothing runs
 them. What pins the real behaviour is `zig build hxdiff`, which replays
 test/hxcases against goldens recorded from a real helix, and
 `zig build hxparity`, which runs each case twice — once in a file pane,
 once in a shell — and demands the two agree.

 Hold j to reach part 1.


=================================================================
=   PART 1 — THE MOUSE (acme chording)                          =
=================================================================

 Three buttons, three verbs:
   LEFT    select, and focus the pane. Also pins the cursor.
   MIDDLE  EXECUTE the word or selection (a builtin, or a shell line).
   RIGHT   LOOK: open the file, directory or URL under the pointer.

 CHORDS — hold one button and click another without letting go:
   1-2   (hold left, click middle)  CUT the left selection
   1-3   (hold left, click right)   PASTE over it
   both, in one hold                SNARF (copy)
   2-1   (hold middle, click left)  execute the middle word WITH the
                                    left selection as its argument

 Every tag with text leads with Save; a terminal also has Togglettymode
 and Filter. Tty opens a terminal; New belongs to each column tag.
 Images show "Tty Del Collapse"; PDFs also have PdfSections and PdfTint.
 Every pane has Collapse: hide its body, then execute again to expand it.
 The top bar is:

   Newcol Joincol Find Grep Help Changelog Tutor Dump NextColor
   Debug Kill

 Reach it from the keyboard with `k` off the topmost tagline; `j` comes
 back down.

 KEYBOARD EQUIVALENTS, because the buttons are not the only way in:
   Enter  = LOOK    (right button)
   Tab    = EXECUTE (middle button)
 Both act on the selection when there is one. Neither is a way into TTY.


=================================================================
=   PART 2 — PANES: MOVING BETWEEN THEM                         =
=================================================================

 Panes live in columns. Everything here works in any mode, because
 getting OUT of a pane must work from inside a pane that owns its keys.

 FOCUS A NEIGHBOUR
   Ctrl-w h/j/k/l   focus the pane left / down / up / right
   SPC w h/j/k/l    the same, in body normal mode only
 Use Ctrl-w in a terminal: there SPC belongs to the shell.

 GO BACK
   Esc          hop to the pane you were in BEFORE this one. Held down
                it alternates between two. This is the `Last` builtin,
                also SPC j j.
   Ctrl-o       walk the jump history BACK   (the `Back` builtin)
   Ctrl-i       walk it FORWARD              (`Forward`; SPC j l shows
                the stack as a buffer)
 Ctrl-i and Tab are the same byte on an old terminal. Where they are,
 Tab keeps meaning execute and Ctrl-i does nothing — the right way
 round, since Tab-executes is the older and more used of the two.

 WHEN Esc MEANS SOMETHING ELSE
 Three panes have their own claim on Escape, so there is a second
 spelling that always leaves:

   Shift-Esc    leave this pane, whatever Escape means inside it

   in INSERT      Esc returns to normal. Press it again to hop.
   in a PDF       Esc cancels the selection and the search highlights
                  and stays in the document. Shift-Esc hops out.
   in raw TTY     Esc goes to the program — vim gets its Escape.
                  Shift-Esc hops out. But see part 3: at a shell
                  PROMPT, plain Esc hops too.

 Shift-Esc needs a terminal that reports modifiers on Escape (the kitty
 keyboard protocol). Where the host does not, it arrives as a plain
 Escape and means whatever Escape means in that pane.

 MAKE AND MOVE PANES
   Alt-n        new terminal below the active one
   Alt-c        move the active pane into a fresh column — any pane, not
                just a terminal. A no-op if it is alone in its column,
                or if the sixth column already exists.
   New          in a column tag: a new scratch pane
   Newcol       in the top bar: a pane in a new column
   Tty          new terminal in the calling pane's directory
   Togglettymode in a terminal tag: switch editor/raw mode (Ctrl-B)
   Joincol      delete this column, move its panes to the one right
   Del          in a pane's own tag: close it

 A new file opens in a new COLUMN only if both panes would still get
 100 columns of width. Otherwise it stacks in the one you are in.


=================================================================
=   PART 3 — THE TTY (a terminal is just a pane)                =
=================================================================

 There is no "open a terminal in a split" 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.

 On a terminal pane:
   NORMAL  ( )  the PROMPTS are gone — a clean acme page — but the
                command you typed at each one stays, pulled to the left
                edge, because that is the part worth reading. Navigate
                with the same h/j/k/l/w/b/e as a file.
   INSERT  (^)  the same page; keys type an insertion overlay.
   TTY     ($)  the REAL shell. Prompts back, keys straight to the pty.

 ENTERING TTY
   Ctrl-b       toggle raw TTY/editor mode on a terminal pane
   Shift-Esc    also enters raw TTY from editor mode
   Togglettymode in the pane tag switches modes in either direction

 `pardes --tty-toggle=g` chooses Ctrl-g for toggling instead.
 Entering TTY moves the shell's real cursor to the place you selected
 on its prompt input line, using its OSC 133 prompt marks.

 RAW INPUT
 Ctrl-b switches to editor mode. Other keys go to the child,
 including Ctrl-o, Ctrl-w, Ctrl-V, Ctrl-Shift-V, Alt shortcuts, and
 modified Escape. Plain Esc at a detected shell prompt hops
 to the previous pane. While a program owns the terminal, Esc goes
 to that program too. Use the Togglettymode tag to leave raw input
 in place. Desktop paste events still feed the child.

 On Linux, Tty9p (SPC n 9 from editor mode) opens a terminal with
 this session mounted through kernel v9fs. It asks sudo in that pane,
 then starts your normal shell. $PARDES_MOUNT names its mounted tree.

 `Filter` in a terminal's tag toggles a pane-local, theme-keyed palette.


=================================================================
=   PART 4 — DETACHED SESSIONS (the core outlives the terminal) =
=================================================================

 A pardes session is a core — the text, the undo history, the layout,
 the pane shells — and a frontend that draws it. Normally they are one
 process. They do not have to be.

 STARTING ONE
   pardes --detach          a session named by this process's pid
   pardes --detach=work     ...named `work`
   pardes --attach          become a frontend of the one session there is
   pardes --attach=work     ...of the session called `work`
   pardes-gui --attach=work an SDL window is a frontend too

 And from inside a running editor, as ordinary acme words — type one in
 a tag and execute it, or press its chord:

   Attach          hand this window to the session there is   (SPC s a)
   Attach work     ...to `work`
   Detach          leave the session, and leave it running    (SPC s D)

 WHAT MAKES IT DIFFERENT FROM tmux
 The pane shells belong to the SESSION, not to the frontend. Attach,
 detach, kill the terminal, attach from another one, and the build that
 was running in pane 3 is still running and has been scrolling into the
 core the whole time. Nothing is replayed to you; it never stopped.

 `Attach` switches IN PLACE. The window, the terminal and the process
 stay; what changes is where the state lives. Only on a successful
 handshake does the frontend give up its own core — so a failed attach
 costs you nothing.

 `Detach` is the smaller half: only the frontend that ran it leaves.
 The session, its shells and every other attached frontend are
 untouched, so leaving is a SUCCESS — the terminal prints where to come
 back to and exits 0. In a session with nothing to detach from it says
 so on the message row and does nothing.

 MORE THAN ONE FRONTEND
 N frontends attached to one session all see the SAME screen, at the
 smallest common grid — `screen -x`, not N sessions. Two windows of
 different sizes converge on the smaller and the larger letterboxes.

 WHAT A DAEMON CAN ALSO DO
 A detached session serves acme's control filesystem like any other:

   pardes --detach=work          9P on the session's default unix socket

 Every native session is scriptable over 9P — see part 6.

 The socket lives in $XDG_RUNTIME_DIR (else ~/.local/state/pardes),
 created 0700, never /tmp: it carries keystrokes into a live editor.


=================================================================
=   PART 5 — THE KEYS (helix-style modal)                       =
=================================================================

 Same core as helix: a block cursor you move with h/j/k/l, motions that
 SELECT what they cross, and an edit that acts on the selection. There
 is no verb+noun — the motion already selected, so `wd` is what `dw`
 was in vim.

-----------------------------------------------------------------
= 5.1 MOTION AND COUNTS                                          =
-----------------------------------------------------------------

          k          h left, l right, j down, k up (also arrows)
      h     l        w/b/e word forward/back/end (W/B/E long)
          j          0 line start, $ end, ^ first non-blank
                     gg first line, ge START of the last line
                     f/F/t/T find a character forward/back

 Bare G does NOTHING. `ge` is the start of the last line.

# keys: l l l
# before
abcdef
# after
abcdef

 A number typed FIRST is a count, and only some keys take one: the
 motions, f/F/t/T and the `Alt-.` that repeats them, gg/gj/gk/g|, `x`,
 `o`/`O`, `>`/`<`, `p`/`P`, Ctrl-a/Ctrl-x, ]p/[p and ]space/[space, and
 the cursor-list keys C, Alt-C and )/(. Everywhere else it is swallowed:
 `3d` deletes once, `3i` types once. `0` is always line-start and never
 the start of a count. Ctrl-d/u/f/b ignore counts: a page is a page.

# keys: 3 l i Z esc
# before
abcdef
# after
abcZdef

-----------------------------------------------------------------
= 5.2 ENTERING INSERT                                            =
-----------------------------------------------------------------

 `i` at the cursor.  `a` after it.  `I` first non-blank.  `A` end of
 line.  `o` open below.  `O` open above.  Esc returns to normal.

# keys: i X esc
# before
abc
# after
Xabc

# keys: o line2 esc
# before
line1
# after
line1
line2

-----------------------------------------------------------------
= 5.3 MOTIONS SELECT                                             =
-----------------------------------------------------------------

 w/b/e and f/F/t/T leave a SELECTION behind them. So `i` after a motion
 types at the selection's START, not where the cursor stopped. `;`
 collapses a selection to a single cursor first.

# keys: w ; i Z esc
# before
one two
# after
one Ztwo

-----------------------------------------------------------------
= 5.4 SELECT AND EDIT                                            =
-----------------------------------------------------------------

   x      select the LINE (again: extend by one more)
   v      character-wise select, then move
   d      delete the selection   c  change it   y  yank it
   p / P  paste after / before
   u undo    U redo
   > <    indent / outdent      Ctrl-a / Ctrl-x  increment / decrement

 Selection is LINE-first here — `x` — with `v` for characters. That is
 the main divergence from helix.

# keys: x c typed esc
# before
replace me
# after
typed

-----------------------------------------------------------------
= 5.5 THE REST, IN ONE PLACE                                     =
-----------------------------------------------------------------

   s / S      regex, one cursor per match, previewing as you type.
              C , ( ) Alt-s Alt-- Alt-_ _ work the resulting LIST.
   m i / m a  textobjects: w W p, the bracket pairs, the three quotes
   m s/r/d    surround add / replace / delete;  mm  jump to the match
   ] [        step by paragraph, blank line, diagnostic
   |          filter every selection through /bin/sh -c (savable file
              panes only)
   :          the tag as a command line
   /          case-insensitive SUBSTRING search, one hit per line — not
              a regex. The regex lives on s and S.
   n / N      select the next/previous LOOK-able text, across panes, as
              a ring. Enter opens what you land on.

 VIEWPORT
   zt zz zb   scroll so the cursor is at top / center / bottom
   zj zk      scroll one line, cursor pushed along
   Ctrl-d/u   half page down / up
   Ctrl-f     full page down.  Ctrl-b pages up on a FILE pane; on a
              terminal it is the tty toggle (part 3).

-----------------------------------------------------------------
= 5.6 SPC — THE LEADER                                           =
-----------------------------------------------------------------

 Nearly every builtin has a NAME you can execute anywhere text lives and
 a KEY PATH you can press. SPC in body normal mode starts the path; what
 you have typed shows on the pane's message row until it fires. Esc
 abandons it, and so does any key that leads nowhere.

   SPC ?        list every path
   SPC d        Del         Kill remains available in the topbar.
   SPC f s      Save        SPC f f    Find      SPC f n  New
   SPC y Y p P R    the system clipboard
   SPC w h/j/k/l    focus a neighbouring pane
   SPC j j      the pane before this one     SPC j o/i  back / forward
   SPC s a      Attach      SPC s D    Detach
   SPC t *      the toggles                  SPC l *   the language
   SPC h t      this tutor


=================================================================
=   PART 6 — THE REST                                           =
=================================================================

 NOT TEXT
   .pdf     the real document through MuPDF. j/k scroll it, `/` searches
            it, Esc cancels selection and highlights, Shift-Esc leaves.
            PdfFit / PdfTint / PdfSections sit in its own tag.
   images   pixels where the shell has them, petscii glyphs where it
            does not (SPC t p / l / a).

 LANGUAGE — ZLS, compiled in, .zig only. Nothing runs in the background
 and nothing is cached: gd gD gy gi gr, the ten SPC l words, ]d/[d and
 ]D/[D, `=` for a format diff, and Tab after a dot in insert.

 THE CONTROL FILESYSTEM — the extension mechanism, and there is no
 plugin API, no interpreter and no rebuild. A program that opens files
 IS an extension.

   pardes          the 9P socket opens by default

 A directory per pane holding `body`, `tag`, `ctl`, `addr`, `data`,
 `event`, `pty/` and the rest, plus `index`, `cons` and `new/` at the
 top under /self. Every pane shell receives `$PARDES_9P` (the socket)
 and `$PARDES_PANE` (its serial). Use a 9P client to read and write:

     /self/pane/<serial>/body
     /self/index
     /self/new/ctl

 A terminal pane also has `pty/`:

     /self/pane/3/pty/ctl     winsize, sig
     /self/pane/3/pty/data    terminal input/output

 Over 9P the same tree answers plan9port, from anywhere:

     9p -a $XDG_RUNTIME_DIR/pardes-9p-work.sock ls /
     9p -a $XDG_RUNTIME_DIR/pardes-9p-work.sock read /self/index

 ...and pardes is a 9P CLIENT too, so one session can read another's:

     pardes --mount=peer=work
     /n/peer/self/pane/1/body    Look opens the other session's body

 TWO THINGS WORTH KNOWING. While a program holds a pane's `event` file
 open, MIDDLE AND RIGHT CLICKS IN THAT PANE BELONG TO IT: pardes reports
 them and performs nothing, so that pane's tag can carry the program's
 own words. The keyboard is never suppressed, and the clicks come back
 when it exits.

 And writing an event record back — `origin type q0 q1` — makes pardes
 perform the Look or Exec it names. That is arbitrary command execution
 by design. The socket sits in the user's private runtime directory.

 docs/fs.md describes the filesystem and mount paths.


=================================================================
=             SUMMARY                                            =
=================================================================

 MOUSE      L select/focus   M execute   R look(open)
            1-2 cut   1-3 paste   both in one hold = snarf
            2-1 = execute the middle word with the left selection
            keyboard: Enter = look, Tab = execute

 PANES      Ctrl-w h/j/k/l  focus a neighbour (SPC w h/j/k/l in a body)
            Esc             the pane you were in before this one
            Shift-Esc       leave, whatever Escape means in here
            Ctrl-o / Ctrl-i jump history back / forward
            Alt-n new terminal below   Alt-c pane into a new column

 TTY        a terminal IS a pane
            Ctrl-b toggles raw input; Shift-Esc enters from editor mode
            Togglettymode in the tag switches modes in either direction
            Esc goes to the program — except at a shell PROMPT, where
                it hops to the previous pane
            Ctrl-b switches to editor mode
            All other keys belong to the child, including Ctrl-V

 DETACHED   pardes --detach[=name]     the core, no terminal
            pardes --attach[=name]     a frontend for it
            Attach / Detach            the same, as words (SPC s a / s D)
            the pane shells belong to the SESSION and never stop
            N frontends share ONE screen at the smallest common grid
            the default 9P socket works in a daemon too

 KEYS       h j k l  w b e  0 $ ^  gg ge  f F t T  v x  d c y p
            i a I A o O   u undo  U redo
            motions SELECT, so `i` types at the selection's start and
                `;` collapses first
            a leading NUMBER is a count on motions, x, o/O, > <, p P,
                Ctrl-a/x and ]space — not on the other edits
            bare G does nothing; `ge` is the START of the last line
            s / S regex cursors;  m i/a textobjects;  m s/r/d surround
            ] [ paragraph, blank line, diagnostic;  | pipe a selection
            / is a case-insensitive SUBSTRING search, not a regex
            SPC is the leader (SPC ? lists every path)

 SCRIPTING  9P is served by default on $PARDES_9P
            /self/pane/<id>/{body,tag,ctl,addr,data,event,pty/}
            a script holding `event` owns that pane's middle and right
                clicks; writing a record back runs it

 vs HELIX   selection is LINE-first (x), v for characters; `/` is a
            substring search, not a regex.
 vs VIM     no verb+noun — the motion already selected, so `wd` is
            what `dw` was; Esc hops focus; bare G is a no-op.
 vs BOTH    a terminal is just a pane, and the core can outlive the
            terminal that is showing it.

 Spawn this tutor again: middle-click "Tutor" in the top bar, or SPC h t.

 Quit: this is a file pane — `:q` is not wired. Close it with Del in its
 tag, "Kill" in the top bar to quit everything, or Ctrl-c the app.