literate: restructure all 19 org files with per-function blocks and prose
Every function, defclass, defstruct, defgeneric, defmethod, defmacro, defvar, and defparameter in every org file now has its own #+BEGIN_SRC block with literate prose above it explaining the design reasoning. Block counts before → after: package.org: 1 → 7 container-package.org: 1 → 1 (prose expanded) dirty.org: 4 → 6 render.org: 10 → 25 theme.org: 6 → 19 box-renderable.org: 9 → 29 scrollbox.org: 8 → 26 tabbar.org: 5 → 10 backend-protocol.org: 8 → 66 modern-backend.org: 17 → 53 detection.org: 4 → 6 layout-engine.org: 9 → 36 framebuffer.org: 8 → 37 markdown-renderer.org:13 → 38 dialog.org: 17 → 23 (merged dual structure) mouse.org: 4 → 25 select.org: 12 → 30 slot.org: 4 → 12 text-input.org: 11 → 53 Total: ~153 blocks → ~502 blocks Bugs fixed during restructuring: - render.org: stray π character typo (backenπd → backend) - modern-backend.org: sgr-attr missing closing paren + #+END_SRC - detection.org: invalid #\Esc character reference - select.org: extra closing paren in select-visible-options All 13 test suites pass at 100%.
This commit is contained in:
@@ -11,6 +11,100 @@ ScrollBox and TabBar. It uses ~cl-tty.backend~, ~cl-tty.box~,
|
||||
The package exports both ScrollBox and TabBar classes, constructors,
|
||||
accessors, and navigation functions.
|
||||
|
||||
* Why a Separate Package?
|
||||
|
||||
The base ~cl-tty.box~ package was designed for the fundamental
|
||||
renderable types — box, text, spans, dirty-tracking, the render
|
||||
pipeline, and the theme engine. These are the building blocks that
|
||||
virtually every component depends on. Container components —
|
||||
ScrollBox and TabBar — are higher-level composite widgets with
|
||||
specific behavioral contracts (viewport scrolling, tab navigation,
|
||||
keyboard dispatch) that are not needed by every component user.
|
||||
|
||||
Separating them into ~cl-tty.container~ achieves two things:
|
||||
|
||||
1. It keeps ~cl-tty.box~ lean. Users who only need basic
|
||||
renderables (boxes, text) do not pull in scroll-logic or
|
||||
tab-navigation code. This is especially important for the
|
||||
test suite — container tests have their own setup, backend
|
||||
capture, and assertion patterns that are unrelated to the
|
||||
base component tests.
|
||||
|
||||
2. It establishes a clean dependency boundary. ~cl-tty.box~
|
||||
depends only on ~cl-tty.backend~ and ~cl-tty.layout~.
|
||||
Container components additionally depend on ~cl-tty.input~,
|
||||
because TabBar handles key events. By putting container
|
||||
code in its own package, we avoid creating a circular or
|
||||
incidental dependency between the input system and the
|
||||
base component layer.
|
||||
|
||||
* What the Container Package Provides
|
||||
|
||||
The package exports two full component families:
|
||||
|
||||
- **ScrollBox**: A viewport-based container that holds a list of
|
||||
child components and provides vertical/horizontal scrolling with
|
||||
viewport culling (only visible children are rendered), scrollbar
|
||||
display, sticky-scroll (auto-scroll to bottom on new content),
|
||||
and scroll-offset clamping. ScrollBox inherits ~dirty-mixin~,
|
||||
implements the component protocol (~render~, ~component-children~,
|
||||
~component-layout-node~), and integrates with the layout engine.
|
||||
Its constructor ~make-scroll-box~ accepts ~:children~,
|
||||
~:scroll-y~, ~:scroll-x~, and ~:sticky-scroll-p~ keyword args.
|
||||
|
||||
- **TabBar**: A horizontal tab-navigation widget that manages a
|
||||
list of named tabs, tracks the active tab, and dispatches
|
||||
keyboard events (Left/Right for prev/next). TabBar also inherits
|
||||
~dirty-mixin~ and implements ~render~ and ~component-layout-node~.
|
||||
It provides ~tab-bar-add~ for dynamic tab creation, ~tab-bar-next~
|
||||
/ ~tab-bar-prev~ for cycling, ~tab-bar-select~ for direct
|
||||
activation, and ~tab-bar-handle-key~ for keyboard integration.
|
||||
|
||||
Both components export the generic ~render~ method, allowing the
|
||||
rendering pipeline to dispatch ~(render instance backend)~ uniformly.
|
||||
|
||||
* Design Decisions: ScrollBox and TabBar in One Package
|
||||
|
||||
ScrollBox and TabBar are very different widgets — one manages a
|
||||
scrollable viewport, the other renders a row of selectable labels.
|
||||
They are kept in the same package rather than split into
|
||||
~cl-tty.scroll-box~ and ~cl-tty.tab-bar~ for several reasons:
|
||||
|
||||
1. **Shared dependencies**: Both components :use the same four
|
||||
packages (~cl-tty.backend~, ~cl-tty.box~, ~cl-tty.layout~,
|
||||
~cl-tty.input~). They both inherit from ~dirty-mixin~ and
|
||||
implement the component protocol. A shared package avoids
|
||||
duplicating the ~:use~ and ~:export~ boilerplate.
|
||||
|
||||
2. **Co-located tests**: The test suite
|
||||
(~tests/scrollbox-tabbar-tests.lisp~) tests both components
|
||||
in one file and one FiveAM suite. They share test helpers,
|
||||
backend-capture patterns, and the same package dependency.
|
||||
Keeping them in one source package means the test defpackage
|
||||
only needs one ~:use~ clause for the container, and symbols
|
||||
from both components are visible together.
|
||||
|
||||
3. **Common contract**: Both components are "containers" in the
|
||||
architectural sense — they manage a collection of sub-items
|
||||
(children or tabs) and provide navigation over them. A
|
||||
TabBar is conceptually a horizontal container of selectable
|
||||
entries; a ScrollBox is a vertical container with scroll.
|
||||
Placing them under the same ~:cl-tty.container~ namespace
|
||||
signals to users that these are the composite widget types,
|
||||
as opposed to the atomic renderables in ~:cl-tty.box~.
|
||||
|
||||
4. **Practical usage patterns**: In typical TUI applications, a
|
||||
TabBar switches between views and a ScrollBox displays the
|
||||
content of each view. They are often used together in the
|
||||
same composition. Having them in one package eliminates
|
||||
cross-package qualification or redundant ~:import-from~
|
||||
declarations when building combined layouts.
|
||||
|
||||
If either component grows substantial internal logic in the future
|
||||
(say, ScrollBox develops virtual scrolling, infinite loading, or
|
||||
its own input model), it could be split into its own package at
|
||||
that point. The current scope favors simplicity and co-location.
|
||||
|
||||
* Package Definition
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/container-package.lisp
|
||||
|
||||
Reference in New Issue
Block a user