v1.0.0: add word-wrap support to text-input.render method

The text-input widget now renders multi-line word-wrapped text using
cl-tty.box:word-wrap instead of single-line truncation. The cursor
position is computed from the wrapped lines using the same algorithm
as position-cursor but now lives in the library where it belongs.

This is the critical step that enables passepartout to replace its
ad-hoc view-input + position-cursor with a simple (render input be) call.

Placeholder text is shown when value is empty, drawn with :dim style.
Block cursor (█) at the correct word-wrapped position. All tests pass
at 100% including integration tests.
This commit is contained in:
2026-05-18 16:30:50 -04:00
parent d0382f9290
commit 108abd054f

View File

@@ -1590,12 +1590,26 @@ width, it's clamped to the last visible position.
(x (if ln (layout-node-x ln) 0)) (y (if ln (layout-node-y ln) 0))
(w (if ln (layout-node-width ln) 80))
(value (text-input-value in)) (cursor (text-input-cursor in))
(display (if (plusp (length value)) value (or (text-input-placeholder in) "")))
(truncated (subseq display 0 (min (length display) w))))
(draw-text backend x y truncated nil nil)
(when (plusp (length value))
(let ((cursor-col (min cursor (length truncated))))
(draw-text backend (+ x cursor-col) y "█" :bright-white nil)))))
(display (if (plusp (length value)) value (or (text-input-placeholder in) ""))))
(when (zerop (length display)) (return-from render (values)))
(let* ((lines (cl-tty.box:word-wrap display w))
(n-lines (length lines)))
;; Draw each wrapped line
(loop for line in lines
for row from 0
do (let ((fg (if (plusp (length value)) nil :dim)))
(draw-text backend x (+ y row) line fg nil)))
;; Draw block cursor at the right position when value is non-empty
(when (plusp (length value))
(let ((cl 0) (cc 0) (accum 0))
(dotimes (i n-lines)
(let ((len (length (nth i lines))))
(when (and (>= cursor accum) (or (< cursor (+ accum len)) (= i (1- n-lines))))
(setf cl i cc (- cursor accum)))
(incf accum (1+ len))))
(let ((cx (+ x cc))
(cy (+ y cl)))
(draw-text backend cx cy "█" :bright-white nil)))))))
#+END_SRC
* Keybinding System