|
|
@@ -0,0 +1,81 @@
|
|
|
+# How the original TP3 editor works (from TPSRC5/TPSRC6)
|
|
|
+
|
|
|
+## Entry (TPSRC5:917)
|
|
|
+`E` calls `kgetfn` for the file name, then `editor2`. It appends `CR LF` to the
|
|
|
+text end, clears the status flag, sets `dislin=1` (full redraw), points
|
|
|
+`sepptr` at the word-separator table `eseptab` (`<>,[].*+-/$:=(){}^#'`), clears
|
|
|
+the screen, and positions into the text. The entry stack arg is a text
|
|
|
+position — `#$FFFF` means "current cursor keep", but compiler error jumps pass
|
|
|
+a line offset so it reopens at the error line.
|
|
|
+
|
|
|
+## Text model
|
|
|
+One big buffer `[txbeg..txend]`, lines separated by `CR` (LF only kept at the
|
|
|
+end as a terminator). The **current line is edited in a separate small buffer**
|
|
|
+`line`: `eflush` (TPSRC6:1089) copies `line` back into the text — computes
|
|
|
+old-vs-new length, calls `echgsize` to expand/shrink the buffer, copies chars,
|
|
|
+and while copying remaps the block markers `bkbegl/bkendl` (line-buffer
|
|
|
+positions) onto `bkbeg/bkend` (text positions). Every movement command
|
|
|
+(`edn`, `eup`, `edellin`, `epagup`, search…) flushes first.
|
|
|
+
|
|
|
+## Main loop `edmain` (TPSRC5:932)
|
|
|
+1. `eredispl` — redraw window,
|
|
|
+2. erase stale status junk if `statera` set,
|
|
|
+3. `estat` — paint the status line,
|
|
|
+4. `edproc` — read a key, dispatch or return "insert this char",
|
|
|
+5. `edput` inserts/overwrites into `line` at `lnpos` (bails with "line full"
|
|
|
+ at `lineend0`, i.e. the "Line too long - CR inserted" case; `einsch`
|
|
|
+ makes room in insert mode), then `erepos` maps buffer offset→screen and
|
|
|
+ loops.
|
|
|
+
|
|
|
+## Command dispatch `edproc` (TPSRC5:981) is table-driven
|
|
|
+- `keyget` reads a key; if `AL >= #$20` (and not `7F` DEL) it's not a command
|
|
|
+ → return carry clear (→ insert char).
|
|
|
+- Control keys go into `cmdbuf` `[len, chars…]` and are matched against **two
|
|
|
+ compressed tables**. `ecmd1` is multi-key sequences (arrow keys / ESC `[`
|
|
|
+ K/M/…); `ecmd2` is single-key prefixes (^S, ^D, …; the table's `CH=#$1F`
|
|
|
+ mask makes the second key case-insensitive, so `^D` and `D` both work after
|
|
|
+ ^Q).
|
|
|
+- A `$01`/`$02` prefix byte = 1- or 2-char command; the table value is a
|
|
|
+ **command number**. Unrecognized → `JZ edmain` (TP3 just ignores it).
|
|
|
+- Command number indexes `ejmptab` (TPSRC6:1575) — 45 `WORD` targets in manual
|
|
|
+ order: CR, e-left, e-left, e-right, ^A word-left, ^F word-right, ^E up,
|
|
|
+ ^X down, ^W up-scroll, ^Z, ^R, ^C page, ^Q-S/D/E/X/R/C/B/K, ^Q-P, ^V, ^N,
|
|
|
+ ^Y, ^QY, ^T, ^G, DEL…, ^K-B/K, ^K-T, ^K-H, ^K-C/V/Y/R/W, ^K-D, ^I tab,
|
|
|
+ ^Q-I, ^QL, ^Q-F, ^Q-A, ^L, ^P.
|
|
|
+- **`MSB` bit on the address marks a "text changed" command** (`linins2`,
|
|
|
+ `edellin2`, `edeleol2`, `etab2`, block ops, search/replace): `ednochg` sets
|
|
|
+ `txchg=#$FF` and `txcomp=#$00` (invalidates compiled code) and masks it off
|
|
|
+ before the jump.
|
|
|
+- It pushes `edmain` as return address, copies an 8-byte "position FIFO"
|
|
|
+ (`pfifosrc→pfifodst`, the ^Q-P last-position stack), then jumps through the
|
|
|
+ selected address — each command `RET`s straight back into the loop.
|
|
|
+- Multi-key commands echo onto the status line via `eddiscmd` ("^K" display,
|
|
|
+ with control chars drawn as `^X`).
|
|
|
+
|
|
|
+## Status line `estat` (TPSRC5:1104)
|
|
|
+Repaints every loop: `Line n`, `Col n`, `Insert ` vs `Overwrite `, `Indent`
|
|
|
+when set, and the work file name at the right if the screen is ≥56 cols
|
|
|
+(`txwinx2 >= #$38`). Only the Col number is redrawn each pass
|
|
|
+(`horscr+phcol`); the Line number only when the text position moved.
|
|
|
+
|
|
|
+## Text operations
|
|
|
+All built on the same primitives: `echgsize` (expand/shrink by moving the
|
|
|
+tail, TPSRC6:1163) + block moves. `^Q-F` search (`efind`) builds a pattern in
|
|
|
+`srrepl`, applies options in `sropt` (bit flags: backward `$10`, case U,
|
|
|
+whole-word W via `etstsep`/`eseptab`, Nth), and uses `ejnbeg`-style line
|
|
|
+walking. Block `^K-C/V/Y` = `etstblk` (check hidden), `echgsize`, then
|
|
|
+copy/delete. `^K-W`/`^K-R` do DOS open/write/close with `fnbuf`. `^K-D`
|
|
|
+(`ekd`) closes the editor.
|
|
|
+
|
|
|
+## Display
|
|
|
+Draws via the `edmalin`/`edllp` scan of `edpos` forward, using
|
|
|
+`esetatt`/`esetblk` to invert block chars (or not, when `bkhide`), high-bit
|
|
|
+"bold" chars for menu letters, `escrolup` for ^W/^R scrolling, and skips
|
|
|
+writing while keys are pending in `eredispl` (`edisp1` polls `ekbdstat`) —
|
|
|
+same "don't paint if a key is waiting" trick at `estat:1105`.
|
|
|
+
|
|
|
+## Net effect
|
|
|
+A tight wait-loop operating on one big CR-separated buffer with a per-line
|
|
|
+edit cache, key-driven by two compact command tables, whose 45 handlers are
|
|
|
+plain jumps returning to the single main loop. Our `shell/Editor.mod` mirrors
|
|
|
+exactly this structure.
|