Rename cl-tui -> cl-tty, v0.9.0: Dialog System + Toast

Rename: cl-tty avoids naming collision with Quicklisp's cl-tui (naryl/cl-tui,
a cl-charms-based ncurses library). Our project is pure escape-sequence CL.

v0.9.0 adds:
- Dialog base class: modal overlay with backdrop, centered panel, size
  variants (:small/:medium/:large), stack-based management
- Dialog subclasses: alert, confirm, select-dialog, prompt-dialog
- Toast notifications: transient, top-right corner, auto-dismiss,
  colored variants (info/success/warning/error)
- 78 tests total, 100% passing

ASDF: read-time package references (+fiveam:+) replaced with
find-symbol so .asd loads without FiveAM pre-loaded
This commit is contained in:
Hermes
2026-05-11 19:55:37 +00:00
parent 9648c72b85
commit 811d51a4f2
51 changed files with 930 additions and 229 deletions

View File

@@ -1,6 +1,6 @@
#+TITLE: cl-tui Modern Backend — v0.0.2
#+TITLE: cl-tty Modern Backend — v0.0.2
#+STARTUP: content
#+FILETAGS: :cl-tui:backend:v0.0.2:
#+FILETAGS: :cl-tty:backend:v0.0.2:
#+OPTIONS: ^:nil
* Modern Backend
@@ -40,10 +40,10 @@ Colors are resolved through a palette before emission:
** Test Suite
#+BEGIN_SRC lisp
(defpackage :cl-tui-modern-backend-test
(:use :cl :fiveam :cl-tui.backend)
(defpackage :cl-tty-modern-backend-test
(:use :cl :fiveam :cl-tty.backend)
(:export #:run-tests))
(in-package :cl-tui-modern-backend-test)
(in-package :cl-tty-modern-backend-test)
(def-suite modern-backend-suite :description "Modern backend tests")
(in-suite modern-backend-suite)
@@ -58,72 +58,72 @@ Colors are resolved through a palette before emission:
(test make-modern-backend-creates
"make-modern-backend returns a modern-backend instance"
(let ((b (make-modern-backend)))
(is (typep b 'cl-tui.backend::modern-backend))))
(is (typep b 'cl-tty.backend::modern-backend))))
;; ── Escape Generation ──────────────────────────────────────────
(test sgr-truecolor-foreground
"SGR truecolor foreground escape is correct"
(is (equal (cl-tui.backend::sgr-fg "#FFD700")
(is (equal (cl-tty.backend::sgr-fg "#FFD700")
(format nil "~C[38;2;255;215;0m" #\Esc))))
(test sgr-truecolor-background
"SGR truecolor background escape is correct"
(is (equal (cl-tui.backend::sgr-bg "#1a1b26")
(is (equal (cl-tty.backend::sgr-bg "#1a1b26")
(format nil "~C[48;2;26;27;38m" #\Esc))))
(test sgr-named-colors
"SGR named colors resolve to 8-color codes"
(is (equal (cl-tui.backend::sgr-fg :red)
(is (equal (cl-tty.backend::sgr-fg :red)
(format nil "~C[31m" #\Esc)))
(is (equal (cl-tui.backend::sgr-bg :blue)
(is (equal (cl-tty.backend::sgr-bg :blue)
(format nil "~C[44m" #\Esc))))
(test sgr-bold-italic
"SGR attribute escapes are correct"
(is (equal (cl-tui.backend::sgr-attr :bold) (format nil "~C[1m" #\Esc)))
(is (equal (cl-tui.backend::sgr-attr :italic) (format nil "~C[3m" #\Esc)))
(is (equal (cl-tui.backend::sgr-attr :underline) (format nil "~C[4m" #\Esc)))
(is (equal (cl-tui.backend::sgr-attr :reset) (format nil "~C[0m" #\Esc))))
(is (equal (cl-tty.backend::sgr-attr :bold) (format nil "~C[1m" #\Esc)))
(is (equal (cl-tty.backend::sgr-attr :italic) (format nil "~C[3m" #\Esc)))
(is (equal (cl-tty.backend::sgr-attr :underline) (format nil "~C[4m" #\Esc)))
(is (equal (cl-tty.backend::sgr-attr :reset) (format nil "~C[0m" #\Esc))))
;; ── Cursor ─────────────────────────────────────────────────────
(test cursor-move-escape
"cursor-move generates correct CSI escape"
(let ((b (make-modern-backend)))
(is (equal (cl-tui.backend::cursor-move-escape 5 10)
(is (equal (cl-tty.backend::cursor-move-escape 5 10)
(format nil "~C[6;11H" #\Esc)))))
(test cursor-style-block
"cursor-style :block generate correct escape"
(let ((b (make-modern-backend)))
(is (equal (cl-tui.backend::cursor-style-escape :block nil)
(is (equal (cl-tty.backend::cursor-style-escape :block nil)
(format nil "~C[2 q" #\Esc)))))
(test cursor-style-bar
"cursor-style :bar generate correct escape"
(let ((b (make-modern-backend)))
(is (equal (cl-tui.backend::cursor-style-escape :bar nil)
(is (equal (cl-tty.backend::cursor-style-escape :bar nil)
(format nil "~C[6 q" #\Esc)))))
(test cursor-style-underline-blink
"cursor-style :underline with blink"
(let ((b (make-modern-backend)))
(is (equal (cl-tui.backend::cursor-style-escape :underline t)
(is (equal (cl-tty.backend::cursor-style-escape :underline t)
(format nil "~C[5 q" #\Esc)))))
;; ── Synchronization ────────────────────────────────────────────
(test decicm-escapes
"DECICM synchronized update escapes"
(is (equal (cl-tui.backend::decicm-begin) (format nil "~C[?2026h" #\Esc)))
(is (equal (cl-tui.backend::decicm-end) (format nil "~C[?2026l" #\Esc))))
(is (equal (cl-tty.backend::decicm-begin) (format nil "~C[?2026h" #\Esc)))
(is (equal (cl-tty.backend::decicm-end) (format nil "~C[?2026l" #\Esc))))
;; ── OSC 8 Hyperlinks ──────────────────────────────────────────
(test osc8-escape
"OSC 8 hyperlink escape wraps text"
(is (equal (cl-tui.backend::osc8-link "http://example.com" "click here")
(is (equal (cl-tty.backend::osc8-link "http://example.com" "click here")
(format nil "~C]8;;http://example.com~C\\click here~C]8;;~C\\"
#\Esc #\Esc #\Esc #\Esc))))
@@ -131,21 +131,21 @@ Colors are resolved through a palette before emission:
(test hex-color-parsing
"hex-to-rgb parses valid hex colors"
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#FFD700")
(multiple-value-bind (r g b) (cl-tty.backend::hex-to-rgb "#FFD700")
(is (= r 255))
(is (= g 215))
(is (= b 0))))
(test hex-color-black
"hex-to-rgb parses black"
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#000000")
(multiple-value-bind (r g b) (cl-tty.backend::hex-to-rgb "#000000")
(is (= r 0))
(is (= g 0))
(is (= b 0))))
(test hex-color-short-form
"hex-to-rgb parses 3-digit hex"
(multiple-value-bind (r g b) (cl-tui.backend::hex-to-rgb "#F00")
(multiple-value-bind (r g b) (cl-tty.backend::hex-to-rgb "#F00")
(is (= r 255))
(is (= g 0))
(is (= b 0))))
@@ -154,23 +154,23 @@ Colors are resolved through a palette before emission:
(test border-char-rounded
"modern-border-char returns Unicode box-drawing for rounded style"
(is (equal (cl-tui.backend::border-char :rounded :top-left) "╭"))
(is (equal (cl-tui.backend::border-char :rounded :horizontal) "─"))
(is (equal (cl-tui.backend::border-char :rounded :vertical) "│"))
(is (equal (cl-tui.backend::border-char :rounded :bottom-right) "╯")))
(is (equal (cl-tty.backend::border-char :rounded :top-left) "╭"))
(is (equal (cl-tty.backend::border-char :rounded :horizontal) "─"))
(is (equal (cl-tty.backend::border-char :rounded :vertical) "│"))
(is (equal (cl-tty.backend::border-char :rounded :bottom-right) "╯")))
(test border-char-double
"modern-border-char returns double-line chars"
(is (equal (cl-tui.backend::border-char :double :top-left) "╔"))
(is (equal (cl-tui.backend::border-char :double :horizontal) "═"))
(is (equal (cl-tui.backend::border-char :double :vertical) "║")))
(is (equal (cl-tty.backend::border-char :double :top-left) "╔"))
(is (equal (cl-tty.backend::border-char :double :horizontal) "═"))
(is (equal (cl-tty.backend::border-char :double :vertical) "║")))
#+END_SRC
** Implementation
*** Package
Add to =cl-tui.backend= package:
Add to =cl-tty.backend= package:
#+BEGIN_SRC lisp
;; In package.lisp, add to :export:
@@ -179,7 +179,7 @@ Add to =cl-tui.backend= package:
;; sgr-fg sgr-bg sgr-attr cursor-move-escape cursor-style-escape
;; decicm-begin decicm-end osc8-link hex-to-rgb border-char
(in-package :cl-tui.backend)
(in-package :cl-tty.backend)
#+END_SRC
*** Color Resolution