From 108abd054fd121ef888a3d6d60d7c65358da8620 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Mon, 18 May 2026 16:30:50 -0400 Subject: [PATCH] v1.0.0: add word-wrap support to text-input.render method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- org/text-input.org | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/org/text-input.org b/org/text-input.org index 944b0dd..a1a3f02 100644 --- a/org/text-input.org +++ b/org/text-input.org @@ -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