A propertized string is not a string once it reaches the daemon's reader

comint hands the input sender its buffer text with font-lock's properties
still on it, and prin1 writes such a string as #(...) — which the daemon
reads as a bare symbol followed by a stray list, so the field stops being
a string without anything saying so.  The wire layer strips rather than
asking every caller to remember: it is the one place that knows the text
is about to become bytes.
This commit is contained in:
Joseph Ferano 2026-09-19 02:18:38 +07:00
parent 233bb780b0
commit 3165cb73a6
2 changed files with 20 additions and 2 deletions

View File

@ -177,9 +177,22 @@ reply that request was waiting for.")
;; a multibyte identifier would otherwise put the reply stream out of step by
;; exactly as many bytes as the payload has non-ASCII characters.
(defun flan-dev--bare (form)
"FORM with every string stripped of its text properties.
A propertized string prints as #(...) syntax, which the daemon's reader
takes as a bare symbol followed by a stray list the field silently stops
being a string. Buffer text arrives propertized (the REPL's comint input
does, for one), so the wire layer strips rather than trusting every caller
to."
(cond ((stringp form) (substring-no-properties form))
((consp form) (cons (flan-dev--bare (car form))
(flan-dev--bare (cdr form))))
(t form)))
(defun flan-dev--send (proc form)
"Send FORM to PROC as one framed message."
(let* ((payload (encode-coding-string (prin1-to-string form) 'utf-8 t)))
(let* ((payload (encode-coding-string (prin1-to-string (flan-dev--bare form))
'utf-8 t)))
(process-send-string proc (format "%d\n%s" (length payload) payload))))
(defun flan-dev--take-reply (proc)

View File

@ -570,7 +570,12 @@ is written instead — the real `message' call the real command makes."
(flan-repl)
(with-current-buffer flan-repl-buffer
(goto-char (point-max))
(insert "(+ 20 3)")
;; Propertized, as interactive input always is — font-lock marks what a
;; batch `insert' would leave bare. comint hands the sender the text
;; properties and all, and a propertized string prints as #(...), which
;; the daemon's reader takes as a symbol and a stray list rather than a
;; string. So this line is the regression test for `flan-dev--bare'.
(insert (propertize "(+ 20 3)" 'fontified t 'face 'default))
(flan-repl-return)
(let ((deadline (+ (float-time) 15)))
(while (and (not (string-match-p "23" (buffer-string)))