reorg: tangle to XDG, remove stale lisp files, fix tui input
- Changed all 50 org file :tangle targets from ../lisp/ to ~/.local/share/passepartout/lisp/ (XDG data dir) - Removed 49 generated .lisp files from project lisp/ directory - Removed tests/system-integration-tests.lisp (generated) - Removed lisp/*.fasl (compiled, stale) - Updated core-manifest.org to tangle .asd to XDG root - Remapped quicklisp symlink: local-projects/passepartout → XDG TUI fixes in channel-tui-main.org: - Removed with-raw-terminal (stty raw breaks fd 0 reads in this SBCL) - Use cat subprocess + pipe for keyboard input (via :input :interactive) - Blocking read-char on pipe with with-timeout 0.1s for daemon processing - Key events queued via drain-queue alongside daemon messages - Full dialog key routing (Escape, Up/Down, Enter, filters, Backspace) - SIGWINCH resize handling - Post-handshake backend-size re-query - Daemon version in status bar (was v0.5.0 hardcoded) - Handshake version stored in state, no add-msg - :daemon-version and :size-queried in state plist - view-status uses draw-rect for background - Test section gated with #+passepartout-tests
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#+TITLE: Passepartout TUI — Controller
|
||||
#+PROPERTY: header-args:lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+PROPERTY: header-args:lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
|
||||
* Controller
|
||||
|
||||
@@ -31,7 +31,7 @@ Event handlers + daemon I/O + main loop.
|
||||
render/input event loop at ~30fps.
|
||||
|
||||
** Event Handlers
|
||||
#+BEGIN_SRC lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
(in-package :passepartout.channel-tui)
|
||||
|
||||
(defun on-key (ch)
|
||||
@@ -712,7 +712,7 @@ Event handlers + daemon I/O + main loop.
|
||||
#+END_SRC
|
||||
|
||||
** Daemon Communication
|
||||
#+BEGIN_SRC lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
(defun send-daemon (msg)
|
||||
(let ((s (st :stream)))
|
||||
(when (and s (open-stream-p s))
|
||||
@@ -766,7 +766,7 @@ Event handlers + daemon I/O + main loop.
|
||||
#+END_SRC
|
||||
|
||||
** Connection
|
||||
#+BEGIN_SRC lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
(defun connect-daemon (&optional (host "127.0.0.1") (port 9105))
|
||||
(add-msg :system "* Connecting to daemon... *")
|
||||
(loop for attempt from 1 to 3
|
||||
@@ -798,7 +798,7 @@ Event handlers + daemon I/O + main loop.
|
||||
#+END_SRC
|
||||
|
||||
** Main Loop
|
||||
#+BEGIN_SRC lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
|
||||
;; v0.8.0 — Global keymap
|
||||
(eval-when (:load-toplevel :execute)
|
||||
@@ -906,10 +906,18 @@ Event handlers + daemon I/O + main loop.
|
||||
(format nil "* Swank ~d M-x slime-connect *" swank-port)))
|
||||
(error ()
|
||||
(add-msg :system "* Swank unavailable *"))))
|
||||
(cl-tty.input:with-raw-terminal
|
||||
(cl-tty.backend:with-terminal (be w h)
|
||||
(let ((tty (sb-sys:make-fd-stream 0 :input t :buffering :none)))
|
||||
;; Initial render
|
||||
(cl-tty.backend:with-terminal (be w h)
|
||||
;; Disable echo only — keep canonical mode (line input). stty raw
|
||||
;; breaks read on fd 0 in this SBCL environment, but -echo alone
|
||||
;; works. A cat subprocess inherits the terminal and provides
|
||||
;; bytes through a pipe that SBCL reads reliably.
|
||||
(uiop:run-program '("stty" "-echo") :output nil :ignore-error-status t)
|
||||
(let* ((cat-proc (uiop:launch-program '("cat")
|
||||
:output :stream
|
||||
:input :interactive
|
||||
:stderr nil))
|
||||
(tty-in (uiop:process-info-output cat-proc)))
|
||||
;; Log backend info and terminal dimensions
|
||||
(cl-tty.backend:backend-clear be)
|
||||
(view-status be w h)
|
||||
(view-chat be w h)
|
||||
@@ -926,34 +934,36 @@ Event handlers + daemon I/O + main loop.
|
||||
(st :busy) nil)
|
||||
(add-msg :system "* Connection lost — type /reconnect to retry *"))))
|
||||
;; Check for terminal resize (SIGWINCH sets this flag)
|
||||
;; Keyboard reader: block on cat pipe with 0.1s timeout.
|
||||
(handler-case
|
||||
(sb-ext:with-timeout 0.1
|
||||
(let ((raw-ch (read-char tty-in nil nil)))
|
||||
(when raw-ch
|
||||
(let ((code (char-code raw-ch)))
|
||||
(queue-event
|
||||
(list :type :key
|
||||
:payload (list :code code
|
||||
:ch (cond
|
||||
((= code 13) :enter)
|
||||
((= code 10) :enter)
|
||||
((= code 27) :escape)
|
||||
((= code 9) :tab)
|
||||
((or (= code 127) (= code 8)) :backspace)
|
||||
((and (>= code 1) (<= code 26))
|
||||
(intern
|
||||
(string-upcase
|
||||
(format nil "CTRL-~a"
|
||||
(code-char (+ #x60 code))))
|
||||
:keyword))
|
||||
(t code)))))))))
|
||||
(sb-ext:timeout ()))
|
||||
;; Check for terminal resize (SIGWINCH sets this flag)
|
||||
(when (boundp 'cl-tty.input::*terminal-resized-p*)
|
||||
(when cl-tty.input::*terminal-resized-p*
|
||||
(setf cl-tty.input::*terminal-resized-p* nil)
|
||||
(multiple-value-setq (w h) (cl-tty.backend:backend-size be))
|
||||
(setf (st :dirty) (list t t t))))
|
||||
;; Read key input from fd 0 (blocking via listen + read-char)
|
||||
(let ((raw-ch (when (listen tty) (read-char tty nil nil))))
|
||||
(when raw-ch
|
||||
(let ((code (char-code raw-ch)))
|
||||
(let ((ch (cond
|
||||
((= code 13) :enter)
|
||||
((= code 10) :enter)
|
||||
((= code 27) :escape)
|
||||
((= code 9) :tab)
|
||||
((or (= code 127) (= code 8)) :backspace)
|
||||
((and (>= code 1) (<= code 26))
|
||||
(intern (string-upcase (format nil "CTRL-~a"
|
||||
(code-char (+ #x60 code))))
|
||||
:keyword))
|
||||
(t raw-ch))))
|
||||
(case ch
|
||||
(:CTRL-Q (setf (st :running) nil))
|
||||
(:CTRL-P (command-palette-show-commands))
|
||||
(:CTRL-B (setf (st :sidebar-visible) (not (st :sidebar-visible)))
|
||||
(setf (st :dirty) (list t t nil)))
|
||||
(:CTRL-L (setf (st :dirty) (list t t t)))
|
||||
(t (on-key ch)))))))
|
||||
(when (or (first (st :dirty)) (second (st :dirty)) (third (st :dirty)))
|
||||
(when (or (first (st :dirty)) (second (st :dirty)) (third (st :dirty)))
|
||||
(cl-tty.backend:backend-clear be)
|
||||
(view-status be w h)
|
||||
(view-chat be w h)
|
||||
@@ -995,13 +1005,13 @@ Event handlers + daemon I/O + main loop.
|
||||
(t (theme-color :agent-fg)))
|
||||
nil :bold sel-p)
|
||||
(incf y-off)))))))
|
||||
(sleep 0.1))))
|
||||
(close tty))
|
||||
(disconnect-daemon)))
|
||||
(sleep 0.1)))
|
||||
(uiop:terminate-process cat-proc))
|
||||
(progn (disconnect-daemon))))
|
||||
#+END_SRC
|
||||
|
||||
* Test Suite
|
||||
#+BEGIN_SRC lisp :tangle ../lisp/channel-tui-main.lisp
|
||||
#+BEGIN_SRC lisp :tangle /home/user/.local/share/passepartout/lisp/channel-tui-main.lisp
|
||||
(eval-when (:compile-toplevel :load-toplevel :execute)
|
||||
(ql:quickload :fiveam :silent t))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user