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:
111
org/package.org
111
org/package.org
@@ -38,6 +38,21 @@ etc., and ~cl-tty.layout~ for ~layout-node~, ~compute-layout~, and the
|
||||
The only direct dependencies are these two packages — no other
|
||||
application code is needed to define components.
|
||||
|
||||
** Box exports
|
||||
|
||||
The ~box~ class is the primary rectangular container: it renders a
|
||||
bordered region with optional title and background color. The accessor
|
||||
family (~box-border-style~, ~box-title~, ~box-title-align~,
|
||||
~box-fg~, ~box-bg~) follows a consistent naming convention so that
|
||||
users can infer slot names from the class name. ~render-box~ is the
|
||||
specialized method that draws the border and fills the interior.
|
||||
|
||||
The ~box-layout-node~ accessor connects the box to its layout tree
|
||||
node, which is essential for the render pipeline's coordinate
|
||||
computation. We export it separately from the rendering symbols
|
||||
because it is also needed by code that walks the component tree
|
||||
without triggering a full render.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
(defpackage :cl-tty.box
|
||||
(:use :cl :cl-tty.backend :cl-tty.layout)
|
||||
@@ -48,30 +63,118 @@ application code is needed to define components.
|
||||
#:box-border-style #:box-title #:box-title-align
|
||||
#:box-fg #:box-bg
|
||||
#:render-box
|
||||
#+END_SRC
|
||||
|
||||
** Span exports
|
||||
|
||||
Spans are lightweight inline-style records — not full classes with
|
||||
layout. Each span stores a substring of the parent text along with
|
||||
its visual attributes. The reader-named accessors (~span-text~,
|
||||
~span-bold~, ~span-italic~, etc.) let rendering code inspect span
|
||||
properties without pulling in the internal representation. We keep
|
||||
the accessor list flat (no grouping macro) to make the package
|
||||
surface easy to grep and to keep the API browser-friendly.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Span
|
||||
#:span
|
||||
#:span-text #:span-bold #:span-italic #:span-underline
|
||||
#:span-reverse #:span-dim #:span-fg #:span-bg
|
||||
#+END_SRC
|
||||
|
||||
** Text exports
|
||||
|
||||
~text~ and ~make-text~ are the construction interface for the text
|
||||
renderable. The ~text-layout-node~ accessor follows the same pattern
|
||||
as ~box-layout-node~, bridging the component and layout layers.
|
||||
~text-content~ and ~text-spans~ expose the raw data for rendering;
|
||||
~text-fg~, ~text-bg~, and ~text-wrap-mode~ control global text
|
||||
appearance. ~render-text~ is the CLOS method that walks the span list
|
||||
and calls ~draw-text~ from the backend.
|
||||
|
||||
These symbols live in the ~cl-tty.box~ package rather than a
|
||||
separate ~cl-tty.text~ package to keep inter-component references
|
||||
trivial — boxes can hold text children, and text can be nested inside
|
||||
other components, all without cross-package imports.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Text
|
||||
#:text #:make-text
|
||||
#:text-layout-node #:text-content #:text-spans
|
||||
#:text-fg #:text-bg #:text-wrap-mode
|
||||
#:render-text
|
||||
#+END_SRC
|
||||
|
||||
** Utility exports (for tests)
|
||||
|
||||
~word-wrap~ and ~split-string~ are internal text-processing utilities
|
||||
used by the text renderer to break lines and tokenize input. They are
|
||||
exported specifically so the test suite can unit-test them in
|
||||
isolation. They are not part of the public component API and should
|
||||
not be relied upon by application code outside of tests.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Utilities (for tests)
|
||||
#:word-wrap #:split-string
|
||||
#+END_SRC
|
||||
|
||||
** Dirty tracking
|
||||
|
||||
The dirty-mixin protocol lets any component class participate in the
|
||||
change-propagation system. ~dirty-mixin~ is the mixin class, and
|
||||
~dirty-p~, ~mark-clean~, ~mark-dirty~ are the three operations that
|
||||
the render pipeline calls to decide whether a subtree needs
|
||||
re-rendering.
|
||||
|
||||
Having these as generic functions (rather than a single ~(setf
|
||||
dirty-p)~) makes it easy for subclasses to add side effects on dirty
|
||||
transitions — for example, invalidating a cached bitmap or
|
||||
recomputing string metrics.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Dirty tracking
|
||||
#:dirty-mixin #:dirty-p #:mark-clean #:mark-dirty
|
||||
#+END_SRC
|
||||
|
||||
** Rendering pipeline
|
||||
|
||||
~render~, ~render-screen~, and ~render-node~ are the three entry
|
||||
points into the rendering dispatch. ~component-layout-node~,
|
||||
~component-children~, and ~component-parent~ form the tree-navigation
|
||||
interface that ~render-node~ uses to walk the component hierarchy.
|
||||
~available-width~ and ~available-height~ are passed down the tree to
|
||||
constrain layout. ~propagate-dirty~ walks upward from a changed
|
||||
component to mark ancestors as dirty, ensuring the screen is
|
||||
re-drawn from the correct root.
|
||||
|
||||
Collecting these under a single "Rendering pipeline" group signals to
|
||||
readers that they form a coherent subsystem — if you override one,
|
||||
you likely need to understand all of them.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Rendering pipeline
|
||||
#:render #:render-screen #:render-node
|
||||
#:component-layout-node #:component-children #:component-parent
|
||||
#:available-width #:available-height
|
||||
#:propagate-dirty
|
||||
#+END_SRC
|
||||
|
||||
** Theme engine
|
||||
|
||||
~theme~ and ~make-theme~ are the constructor and class for theme
|
||||
objects. ~theme-mode~ selects the active color mode (light/dark).
|
||||
~theme-color~ looks up a named color in the current theme.
|
||||
~load-preset~ loads a theme from a file, and ~define-preset~ registers
|
||||
a preset at compile time.
|
||||
|
||||
The theme engine is isolated from the rest of the component layer —
|
||||
boxes and text reference theme colors by name at render time, and the
|
||||
theme object is passed in from the application level. This separation
|
||||
means themes can be swapped without touching component instances.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/package.lisp
|
||||
;; Theme engine
|
||||
#:theme #:make-theme #:theme-mode
|
||||
#:theme-color #:load-preset #:define-preset))
|
||||
(in-package :cl-tty.box)
|
||||
#+END_SRC
|
||||
|
||||
The ~#:word-wrap~ and ~#:split-string~ exports are for tests only —
|
||||
they're utility functions used internally by ~text~ rendering but
|
||||
exposed so the test suite can unit-test them directly.
|
||||
|
||||
Reference in New Issue
Block a user