Add render-select-minibuffer, fix CSI parser nil-code crash
- render-select-minibuffer: new function for bottom-anchored dialog panel (minibuffer style), accepts colors plist for theme integration - handle-text-input: guard code-char against nil key-event-code to prevent crash on CSI escape sequences (arrow keys)
This commit is contained in:
@@ -63,8 +63,9 @@ subsystems. All public symbols are exported for user convenience.
|
||||
#:dialog-on-dismiss
|
||||
#:dialog-size
|
||||
#:dialog-size-pixels
|
||||
#:render-dialog
|
||||
#:push-dialog
|
||||
#:render-dialog
|
||||
#:render-select-minibuffer
|
||||
#:push-dialog
|
||||
#:pop-dialog
|
||||
#:*dialog-stack*
|
||||
#:alert-dialog
|
||||
@@ -172,6 +173,58 @@ Content is rendered via ~draw-text~ inside the panel area.
|
||||
:white :default)))))
|
||||
#+END_SRC
|
||||
|
||||
** render-select-minibuffer
|
||||
|
||||
Renders a ~select~ widget as a bottom-anchored minibuffer panel at the
|
||||
given position. The panel fills a rectangular area, draws a separator
|
||||
line with the title at the top, the filtered options in the middle,
|
||||
and a filter input line (>= ~...~) at the bottom. ~colors~ is a plist
|
||||
with keys ~:bg-panel~, ~:separator~, ~:accent~, ~:text-muted~,
|
||||
~:agent-fg~, ~:input-fg~, ~:bg-input~, ~:input-prompt~.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ~/.local/share/cl-tty/src/components/dialog.lisp
|
||||
(defun render-select-minibuffer (be x y width height select title colors)
|
||||
(let* ((filtered (select-filtered-options select))
|
||||
(sel-idx (or (select-selected-index select) 0))
|
||||
(filter (select-filter select))
|
||||
(bg-p (getf colors :bg-panel))
|
||||
(sep-c (getf colors :separator)))
|
||||
(dotimes (r height)
|
||||
(draw-rect be x (+ y r) width 1 :bg bg-p))
|
||||
(draw-text be x y (make-string width :initial-element #\─) sep-c bg-p)
|
||||
(draw-text be (1+ x) y title (getf colors :accent) bg-p)
|
||||
(loop for item in filtered
|
||||
for i from 1
|
||||
for display-idx = (first item)
|
||||
for option = (third item)
|
||||
for opt-title = (getf option :title)
|
||||
for cat = (getf option :category)
|
||||
for sel-p = (eql display-idx sel-idx)
|
||||
for row = (+ y i)
|
||||
while (< row (+ y (min height (length filtered))))
|
||||
do (cond
|
||||
(sel-p
|
||||
(draw-rect be (1+ x) row (1- width) 1
|
||||
:bg (getf colors :input-fg))
|
||||
(draw-text be (1+ x) row
|
||||
(format nil " >> ~a" opt-title)
|
||||
(getf colors :bg-input)
|
||||
(getf colors :input-fg)))
|
||||
(cat
|
||||
(draw-text be (1+ x) row
|
||||
(format nil " ~a" opt-title)
|
||||
(getf colors :text-muted) bg-p))
|
||||
(t
|
||||
(draw-text be (1+ x) row
|
||||
(format nil " ~a" opt-title)
|
||||
(getf colors :agent-fg) bg-p))))
|
||||
(let ((filter-y (+ y (- height 3))))
|
||||
(draw-rect be x filter-y width 1 :bg bg-p)
|
||||
(draw-text be x filter-y
|
||||
(format nil "> ~a" (or filter ""))
|
||||
(getf colors :input-prompt) bg-p))))
|
||||
#+END_SRC
|
||||
|
||||
** push-dialog
|
||||
|
||||
Pushes a dialog onto =*dialog-stack*=. Returns the dialog for chaining.
|
||||
|
||||
Reference in New Issue
Block a user