v1.0.0: merge container (scrollbox + tabbar) into cl-tty.box
Eliminates the cl-tty.container package by merging scrollbox and tabbar components directly into cl-tty.box, where the component system lives. Changes: - added scrollbox/tabbar exports to cl-tty.box defpackage in package.org - changed scrollbox.org in-package from cl-tty.container to cl-tty.box - changed tabbar.org in-package from cl-tty.container to cl-tty.box - tabbar's key-event-key references are qualified with cl-tty.input: (avoids circular :use dependency with cl-tty.input which :uses cl-tty.box) - deleted container-package.org - updated test packages, integration tests, scripts, ASDF - all 14 test suites pass at 100%
This commit is contained in:
@@ -33,11 +33,10 @@
|
||||
(:file "text-input" :depends-on ("input-package" "input" "box"))
|
||||
(:file "textarea" :depends-on ("input-package" "input" "box"))
|
||||
(:file "keybindings" :depends-on ("input-package" "input"))
|
||||
;; Container components (v0.6.0)
|
||||
(:file "container-package" :depends-on ("package" "input-package"))
|
||||
(:file "scrollbox" :depends-on ("container-package" "dirty" "box"))
|
||||
(:file "tabbar" :depends-on ("container-package" "dirty" "box"))
|
||||
;; Markdown + Code + Diff rendering (v0.8.0)
|
||||
;; Container components merged into box (v0.6.0)
|
||||
(:file "scrollbox" :depends-on ("package" "dirty" "box"))
|
||||
(:file "tabbar" :depends-on ("package" "dirty" "box"))
|
||||
;; Markdown + Code + Diff rendering (v0.8.0)
|
||||
(:file "markdown-package" :depends-on ("package"))
|
||||
(:file "markdown" :depends-on ("markdown-package"))
|
||||
;; Dialog + Toast (v0.9.0)
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
#+TITLE: Container Package
|
||||
#+STARTUP: content
|
||||
#+FILETAGS: :cl-tty:container:
|
||||
|
||||
* Overview
|
||||
|
||||
The ~cl-tty.container~ package defines the container component types:
|
||||
ScrollBox and TabBar. It uses ~cl-tty.backend~, ~cl-tty.box~,
|
||||
~cl-tty.layout~, and ~cl-tty.input~.
|
||||
|
||||
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 ~/.local/share/cl-tty/src/components/container-package.lisp
|
||||
(defpackage :cl-tty.container
|
||||
(:use :cl :cl-tty.backend :cl-tty.box :cl-tty.layout :cl-tty.input)
|
||||
(:export
|
||||
;; ScrollBox
|
||||
#:scroll-box #:make-scroll-box
|
||||
#:scroll-box-scroll-y #:scroll-box-scroll-x
|
||||
#:scroll-box-children
|
||||
#:scroll-by #:sticky-scroll-p
|
||||
#:clamp-scroll
|
||||
;; TabBar
|
||||
#:tab-bar #:make-tab-bar
|
||||
#:tab-bar-active #:tab-bar-tabs
|
||||
#:tab-bar-add #:tab-bar-next #:tab-bar-prev
|
||||
#:tab-bar-select #:tab-bar-handle-key
|
||||
;; Rendering
|
||||
#:render))
|
||||
#+END_SRC
|
||||
@@ -50,7 +50,7 @@ package, so the symbol must be interned and accessible.
|
||||
(defpackage :cl-tty-integration-test
|
||||
(:use :cl :fiveam
|
||||
:cl-tty.backend :cl-tty.box :cl-tty.layout
|
||||
:cl-tty.input :cl-tty.container
|
||||
:cl-tty.input
|
||||
:cl-tty.rendering :cl-tty.dialog))
|
||||
|
||||
(in-package :cl-tty-integration-test)
|
||||
|
||||
@@ -175,6 +175,15 @@ means themes can be swapped without touching component instances.
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/package.lisp
|
||||
;; Theme engine
|
||||
#:theme #:make-theme #:theme-mode
|
||||
#:theme-color #:load-preset #:define-preset))
|
||||
(in-package :cl-tty.box)
|
||||
#:theme-color #:load-preset #:define-preset
|
||||
;; Container components (merged from cl-tty.container)
|
||||
#:scroll-box #:make-scroll-box
|
||||
#:scroll-box-scroll-y #:scroll-box-scroll-x
|
||||
#:scroll-box-children
|
||||
#:scroll-by #:sticky-scroll-p
|
||||
#:clamp-scroll
|
||||
#:tab-bar #:make-tab-bar
|
||||
#:tab-bar-active #:tab-bar-tabs
|
||||
#:tab-bar-add #:tab-bar-next #:tab-bar-prev
|
||||
#:tab-bar-select #:tab-bar-handle-key))
|
||||
#+END_SRC
|
||||
|
||||
@@ -46,7 +46,7 @@ the CLOS-based component protocol — ~render~ dispatches on the class,
|
||||
and dirty-mixin provides the marking machinery used by the refresh loop.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/scrollbox.lisp
|
||||
(in-package #:cl-tty.container)
|
||||
(in-package :cl-tty.box)
|
||||
|
||||
(defclass scroll-box (dirty-mixin)
|
||||
((children :initform nil :initarg :children
|
||||
@@ -344,7 +344,7 @@ unconditionally; it runs the ~scrollbox-suite~ and prints results via
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/tests/scrollbox-tabbar-tests.lisp
|
||||
(defpackage :cl-tty-scrollbox-test
|
||||
(:use :cl :fiveam :cl-tty.backend :cl-tty.box :cl-tty.layout :cl-tty.input :cl-tty.container)
|
||||
(:use :cl :fiveam :cl-tty.backend :cl-tty.box :cl-tty.layout :cl-tty.input)
|
||||
(:export #:run-tests))
|
||||
(in-package #:cl-tty-scrollbox-test)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ the symbol namespace clean and avoids accidental collisions with
|
||||
user-level code.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/tabbar.lisp
|
||||
(in-package #:cl-tty.container)
|
||||
(in-package :cl-tty.box)
|
||||
#+END_SRC
|
||||
|
||||
** TabBar class
|
||||
@@ -168,7 +168,7 @@ bar lives alongside other focusable elements.
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/tabbar.lisp
|
||||
(defun tab-bar-handle-key (tb event)
|
||||
"Handle a key-event on a TabBar. Returns T if handled."
|
||||
(case (key-event-key event)
|
||||
(case (cl-tty.input:key-event-key event)
|
||||
(:left (tab-bar-prev tb) t)
|
||||
(:right (tab-bar-next tb) t)
|
||||
(t nil)))
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
'("src/backend/classes.lisp" "src/backend/package.lisp"
|
||||
"src/backend/detection.lisp" "src/backend/simple.lisp" "src/backend/modern.lisp"
|
||||
"src/layout/layout.lisp"
|
||||
"src/components/container-package.lisp"
|
||||
"src/components/dialog-package.lisp" "src/components/dialog.lisp"
|
||||
"src/components/dirty.lisp"
|
||||
"src/components/input-package.lisp" "src/components/input.lisp"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
'("src/backend/classes.lisp" "src/backend/package.lisp"
|
||||
"src/backend/detection.lisp" "src/backend/simple.lisp" "src/backend/modern.lisp"
|
||||
"src/layout/layout.lisp"
|
||||
"src/components/container-package.lisp"
|
||||
"src/components/dialog-package.lisp" "src/components/dialog.lisp"
|
||||
"src/components/dirty.lisp"
|
||||
"src/components/input-package.lisp" "src/components/input.lisp"
|
||||
|
||||
Reference in New Issue
Block a user