bin/bro.js — the syntax-highlighting pager as JS (+ a tty leaf)
Mirror bro (the dog toolchain's TUI pager/renderer) as bin/bro.js on jabc, the JS-027/JS-038 way. A SELF-CONTAINED viewer: URI args → io.mmap+tok.parse in JS → hunks → paint. NO stdin TLV pipe and NO forking C producers — bro.js RUNS JS commands for its content (view / search / open) in-process; that is the point. The native gap is tiny — a terminal-control leaf (raw-mode + winsize); the bulk is a pure-JS port of bro/BRO.c (renderer + colour-diff + TUI). Method: Issues.
bro (bro/INDEX.md, README.md): indexes hunk TLV records into rows, paints
cells from tok32 tags + a THEME, and classifies diff lines (bro_classify: EQ/PURE_IN/PURE_RM/MOD_INLINE/MOD_SPLIT, the 25% inline-vs-split rule). TUI in BRO.c: raw-mode loop, 32-deep view stack, search, :/# GURI prompt, status bar.
tcgetattr/tcsetattr raw mode
(BRO.c:320/341), ioctl(TIOCGWINSZ) size (:353), sigaction(SIGWINCH) (:3050), open(/dev/tty). abc/TTY.h is escape-FORMATTING only, not control.
uri,
io.mmap/readdir/spawn/read/write, the pol loop, ansi. THEME (tag→SGR) and the SGR-1006 mouse decode become pure-JS tables/decoders.
abc/TTY (or abc/FILE) raw-mode + winsize wrapper (libabc, the
JS-047 leaf pattern) → bind tty.raw/tty.cook/tty.size (+ /dev/tty open). Optional: bind abc/ANSI ANSIu8sDrainCSI for key/mouse-escape decode.
bin/bro.js + bin/lib/*: the pager — event loop + keymap, row index + cell
painter, the colour-diff classifier, codepoint soft-wrap, the 32-deep view stack (scroll preserved), the live status bar, the :/# prompt, in-view search.
io.mmap+tok.parse → one HUNK; a dir →
io.readdir → one 'F' hunk per entry. Hunks live in JS; no external feed.
(spot/graf): bro.js obtains content by running JS commands in-process — the whole point. Cross-file : spot search needs a JS spot (absent) → deferred.
try/finally
around the loop AND an uncaught-throw hook in main.cpp (JABCRun routes the throw) — or a crash wedges the user's shell in raw mode.
tty.size on each ~100ms input tick (VTIME-style) andre-render on change — no signal binding needed (the lone optional native bit).
per-keystroke re-render is cheap over big hunk sets.
SGR is emitted via ansi.cpp or a bound abc/ANSI delta.
ANSIRaw/ANSICook/ANSITtySize in abc/ANSI.c/.h (DRY'd
onto ANSIBgColor's shared ansi_tty_raw helper) + js/tty.cpp tty.raw/ cook/size (stateless, rule #4) + pty JABCtty test. libabc 40cf6df6, beagle dc96aaaf. Terminal control belongs in ANSI, not FILE.
bin/bro.js + bin/lib/bro.js plain file/dir viewer DONE (~/todo/JS-053,
not landed): URI→io.mmap+tok.parse→hunk, dir→io.readdir 'F' rows, a tag→SGR painter + soft-wrap + status-bar scaffold (for TODO#3); the BROPlain sink byte-matches bro --plain (.c/.js, #line/#symbol, dir, multi). be-js-bro-view + 47/47 green; js-only. Delta: a miss exits 1 not 206 (JS-026).
the :/# GURI prompt (open / goto-line / in-view search), mouse (optional).
:#TODO.c spot grep/regex/snippet) needs a JS spot —absent; v1 stubs/defers it (do NOT fork the C spot — against the premise).
main.cppis mandatory BEFORE any interactive TODO lands.
40cf6df6
(ANSIRaw/Cook/TtySize in abc/ANSI, DRY'd with ANSIBgColor), beagle dc96aaaf (tty.* leaf + abc pin); JABCtty green, graf-indexed both shards.
~/todo/JS-053, ready to land (js-only,single-shard); the interactive raw-mode TUI (TODO#3) still open.