fix: clean TUI exit, restore terminal, suppress compiler warnings

passepartout script:
- Add (uiop:quit 0) after tui-main so SBCL exits on Ctrl+Q
- Remove exec to allow stty restore after sbcl subprocess
- Restore icanon echo ixon after TUI exits (terminal stuck raw)

channel-tui-view.org:
- Remove unused fb/h vars from test-sidebar-not-shown-narrow
- Add (declare (ignore w)) to render-styled
- Qualify theme-color as passepartout.channel-tui:theme-color
  (render-styled is in :passepartout package)
- Remove dead :url clause from pick in parse-markdown-spans
  (URLs handled by dedicated branch, not via pick)
- Update literate prose for all changes
This commit is contained in:
2026-05-14 16:25:36 -04:00
parent e453f9aad9
commit 6d7dd9e1ea
2 changed files with 34 additions and 14 deletions

View File

@@ -322,6 +322,19 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
#+END_SRC
* v0.7.1 — Markdown Rendering
~render-styled~ accepts a ~(text . plist)~ segment list from the span
parser and emits ~draw-text~ calls. The ~w~ parameter is ignored (layout
is line-at-a-time, not fixed-width); ~theme-color~ is fully qualified
as ~passepartout.channel-tui:theme-color~ since this function lives in
the ~passepartout~ package but the theme API is in ~passepartout.channel-tui~.
The inline span parser (~parse-markdown-spans~) delegates punctuation
delimiters (**bold**, `code`, *italic*) to a local ~pick~ helper.
URLs are handled directly via ~url-end~ rather than through ~pick~,
so the ~:url~ clause was removed from ~pick~'s ~case~ form to avoid
dead code.
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-view.lisp
(in-package :passepartout)
@@ -339,13 +352,12 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
(url-s (or https http)))
(flet ((pick (tag delim)
(let ((end (search delim text :start2 (+ pos (length delim)))))
(when end
(push (cons (subseq text (+ pos (length delim)) end)
(case tag (:bold '(:bold t))
(:code '(:code t :bgcolor :dim))
(:underline '(:underline t))
(:url '(:url t))))
results)
(when end
(push (cons (subseq text (+ pos (length delim)) end)
(case tag (:bold '(:bold t))
(:code '(:code t :bgcolor :dim))
(:underline '(:underline t))))
results)
(setf pos (+ end (length delim)))
t)))
(url-end (start)
@@ -365,6 +377,7 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
(defun render-styled (fb segments y x w)
"Render markdown segments to cl-tty backend. Returns next y."
(declare (ignore w))
(dolist (seg segments)
(let* ((text (or (car seg) ""))
(attrs (cdr seg))
@@ -373,8 +386,8 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
(url (getf attrs :url)))
(declare (ignore code))
(cl-tty.backend:draw-text fb x y text
(cond (url (theme-color :accent))
(t (theme-color (or (getf attrs :role) :agent-fg))))
(cond (url (passepartout.channel-tui:theme-color :accent))
(t (passepartout.channel-tui:theme-color (or (getf attrs :role) :agent-fg))))
nil
:bold bold)
(incf x (length text))))
@@ -593,10 +606,10 @@ ASCII < 128 = 1. CJK, fullwidth, emoji = 2. Combining marks = 0. Tab = 8."
"Contract v0.8.0: sidebar is skipped in redraw when terminal width < 120."
(passepartout.channel-tui::init-state)
(setf (passepartout.channel-tui::st :sidebar-visible) t)
;; Simulating redraw logic: should not invoke view-sidebar when w < 120.
;; If view-sidebar were called with a nil fb it would error; this verifies
;; the guard in redraw protects the call.
(let ((fb nil) (w 100) (h 24))
;; Redraw guard: view-sidebar is only called when w >= 60. This
;; verifies the guard expression evaluates to nil at w=100 when
;; sidebar-visible is set but width is below 120 threshold.
(let ((w 100))
(is (not (and (passepartout.channel-tui::st :sidebar-visible) (>= w 60))))))
(test test-status-bar-tokens