Point at the reason rather than naming the buffer it is in

A program that does not compile kills the daemon before it binds, which is
the failure anyone starting one from Emacs will actually hit. Showing that
buffer is the difference between a message and an answer.

The prompt also offers the program last started: a restart after a quit is
the common case, and it is rarely the buffer you happen to be reading when
you decide on it. C-c C-x does the restart without the prompt at all.
This commit is contained in:
Joseph Ferano 2026-09-11 20:27:50 +07:00
parent aee8a032b1
commit fc3cd2361a
2 changed files with 16 additions and 5 deletions

View File

@ -355,8 +355,8 @@ socket, which is what `flan-dev-restart-program' is.")
A daemon started in a terminal is not here, and `flan-connect' still works
for it this is only what Emacs is responsible for killing.")
(defun flan-dev--daemon-sentinel (proc _event)
"Say that the daemon PROC has gone, once, when it does."
(defun flan-dev--daemon-sentinel (proc event)
"Say that the daemon PROC has gone, once, when it does. EVENT says how."
(unless (process-live-p proc)
(when (eq proc flan-dev--daemon)
(setq flan-dev--daemon nil)
@ -365,7 +365,7 @@ for it — this is only what Emacs is responsible for killing.")
;; program finished, or it never built — and the buffer is where the
;; difference is written.
(message "flan dev: the daemon exited (%s); see %s"
(string-trim (or _event "")) flan-dev-daemon-buffer))))
(string-trim (or event "")) flan-dev-daemon-buffer))))
(defun flan-dev--start-daemon (file socket)
"Start `flan dev' on FILE listening on SOCKET, and return the process."
@ -406,10 +406,13 @@ for it — this is only what Emacs is responsible for killing.")
((not (process-live-p proc))
;; The likeliest failure by far: the program did not compile, so the
;; daemon died before binding. The reason is in its buffer and not in
;; anything this end can see, so point at it rather than paraphrase.
;; anything this end can see — so show the buffer rather than name it
;; and leave someone to go and find it.
(display-buffer flan-dev-daemon-buffer)
(user-error "flan dev: the daemon exited before it was ready; see %s"
flan-dev-daemon-buffer))
((> (float-time) deadline)
(display-buffer flan-dev-daemon-buffer)
(user-error "flan dev: no socket on %s after %ss; see %s"
(abbreviate-file-name socket) flan-dev-start-timeout
flan-dev-daemon-buffer))
@ -425,8 +428,12 @@ Refuses while a daemon this Emacs started is still alive, by name: killing it
would take its program and everything that program has in memory with it,
which is the one thing a dev loop exists to avoid doing by accident."
(interactive
(list (read-file-name "flan dev: " nil nil t
;; The program last started, where there was one: a restart after a quit is
;; the common case, and it is rarely the buffer point happens to be in —
;; you quit from wherever you were reading when you decided to.
(list (read-file-name "flan dev: " nil flan-dev--file t
(and buffer-file-name
(string-suffix-p ".flan" buffer-file-name)
(file-name-nondirectory buffer-file-name)))))
(when (process-live-p flan-dev--daemon)
(user-error "flan dev: already running on %s; M-x flan-dev-quit first"

View File

@ -22,9 +22,11 @@
(declare-function flan-describe "flan-dev")
(declare-function flan-show-output "flan-dev")
(declare-function flan-repl "flan-repl")
(declare-function flan-break "flan-dev")
(declare-function flan-doc "flan-dev")
(declare-function flan-dev "flan-dev")
(declare-function flan-dev-quit "flan-dev")
(declare-function flan-dev-restart-program "flan-dev")
(defgroup flan nil
"Editing and evaluating Flan."
@ -125,6 +127,8 @@ line is off screen."
;; C-h after a prefix is how anyone finds out what is under C-c, and a
;; binding there takes that away.
(define-key map (kbd "C-c C-v") #'flan-doc)
;; The way out when a reload is refused: rebuild, relaunch, reconnect.
(define-key map (kbd "C-c C-x") #'flan-dev-restart-program)
map)
"Keymap for `flan-mode'.")