Optional Integrations (contrib/)¶
contrib/ holds optional, opt-in integrations that layer external libraries
on top of the core toolkit. Nothing here is part of the core cl-tty-kit
build or CI — :cl-tty-kit's own dependency is the conditional sb-posix
(see Compatibility). These modules pull additional
libraries from Quicklisp, or from nerima-lisp/cl-prolog,
nerima-lisp/cl-weave, and nerima-lisp/cl-parser-kit via this repository's
flake.nix (nix develop puts all three on CL_SOURCE_REGISTRY, the same
as :cl-tty-kit/test), and must be loaded explicitly.
Why isolate these from core CI
.github/workflows/ci.yml runs contrib/verify-contrib.lisp in its own
contrib job with continue-on-error: true. Quicklisp installs
introduce a network dependency that a core language toolkit's build
should never require — a flaky network never blocks a core merge, and a
contrib regression never blocks a core release.
cl-tty-kit-cl-prolog-csi-grammar — DCG grammar via nerima-lisp/cl-prolog¶
A declarative recognizer for the ECMA-48 CSI (Control Sequence Introducer)
byte-class grammar, built on
nerima-lisp/cl-prolog
(pulled from this repository's flake.nix inputs — it is not distributed by
Quicklisp). Input Decoding already decodes CSI sequences
imperatively on the render loop's hot path; this module instead expresses
that same sequence shape — zero or more parameter bytes, then zero or more
intermediate bytes, then exactly one final byte — as a def-dcg-rule
grammar run through phrase, demonstrating cl-prolog's DCG support
independently of the hand-written decoder.
;; nix develop -- puts cl-prolog on CL_SOURCE_REGISTRY, once per shell
(asdf:load-system :cl-tty-kit-cl-prolog-csi-grammar)
(tty-csi-grammar:csi-sequence-valid-p "1;1H") ; => T (cursor position)
(tty-csi-grammar:csi-sequence-valid-p "38;5;196m") ; => T (SGR, 256-color fg)
(tty-csi-grammar:csi-sequence-valid-p "1;1") ; => NIL (no final byte)
cl-tty-kit-cl-parser-kit-csi-grammar — combinator grammar via nerima-lisp/cl-parser-kit¶
A second, independent declarative recognizer for the same ECMA-48 CSI grammar
as the DCG version above, built on
nerima-lisp/cl-parser-kit's
seq/many/type-token parser combinators instead of cl-prolog's DCG rules
(pulled from this repository's flake.nix inputs — it is not distributed by
Quicklisp). contrib/verify-contrib.lisp cross-checks the two grammars agree
on every case, the same differential-testing shape
the SGR oracle uses against
the hand-written decoder.
;; nix develop -- puts cl-parser-kit on CL_SOURCE_REGISTRY, once per shell
(asdf:load-system :cl-tty-kit-cl-parser-kit-csi-grammar)
(tty-csi-parser-kit-grammar:csi-sequence-valid-p "1;1H") ; => T (cursor position)
(tty-csi-parser-kit-grammar:csi-sequence-valid-p "38;5;196m") ; => T (SGR, 256-color fg)
(tty-csi-parser-kit-grammar:csi-sequence-valid-p "1;1") ; => NIL (no final byte)
cl-tty-kit-weave-tests — property-based fuzz tests via nerima-lisp/cl-weave¶
Property-based tests built on
nerima-lisp/cl-weave (pulled
from this repository's flake.nix inputs — it is not distributed by
Quicklisp). cl-weave's it-property generators
(gen-vector, gen-string, gen-character, ...) fuzz the UTF-8 octet
decoder and the public cl-tty-kit:decode-input entry point
(see Input Decoding) with thousands of arbitrary byte
sequences, asserting the documented contract: malformed input always signals
a cl-tty-kit:tty-kit-error condition (see Conditions) and
never an undocumented Lisp error — the realistic threat model for decoders
that read attacker-controlled PTY bytes. It also regression-tests the DCG CSI
grammar above.
;; nix develop -- puts cl-prolog and cl-weave on CL_SOURCE_REGISTRY, once per shell
(asdf:load-system :cl-tty-kit-weave-tests)
(cl-tty-kit/weave-property-tests:run-tests) ; => T on success
;; Run more generated cases per property (default is cl-weave's own):
;; CL_WEAVE_PROPERTY_TESTS=2000 sbcl --script contrib/verify-contrib.lisp
contrib/literate/tty-relations.clw — literate source via clweb¶
A literate program written for clweb,
the Common Lisp descendant of Knuth's WEB (the CL "weave" tool), at its
latest Quicklisp release. It documents the rewrite from a Lisp-shaped
(head . body) clause (the same clause shape the logic engine
uses) to a cl-prolog2
ISO rule sexp — useful for running such clauses, however sourced, against a
full external ISO Prolog (swipl/gprolog/yap) — and tangles to loadable Lisp.
(ql:quickload :clweb)
(clweb:tangle-file "contrib/literate/tty-relations.clw") ; -> tty-relations.lisp
(clweb:weave "contrib/literate/tty-relations.clw") ; -> tty-relations.tex
Verifying the contrib¶
contrib/verify-contrib.lisp exercises the Quicklisp-backed clweb tangle
integration, and additionally exercises the cl-prolog/cl-parser-kit/cl-weave
integrations above when ASDF can find the relevant system (skipped, not
failed, otherwise):