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 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.") for it this is only what Emacs is responsible for killing.")
(defun flan-dev--daemon-sentinel (proc _event) (defun flan-dev--daemon-sentinel (proc event)
"Say that the daemon PROC has gone, once, when it does." "Say that the daemon PROC has gone, once, when it does. EVENT says how."
(unless (process-live-p proc) (unless (process-live-p proc)
(when (eq proc flan-dev--daemon) (when (eq proc flan-dev--daemon)
(setq flan-dev--daemon nil) (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 ;; program finished, or it never built — and the buffer is where the
;; difference is written. ;; difference is written.
(message "flan dev: the daemon exited (%s); see %s" (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) (defun flan-dev--start-daemon (file socket)
"Start `flan dev' on FILE listening on SOCKET, and return the process." "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)) ((not (process-live-p proc))
;; The likeliest failure by far: the program did not compile, so the ;; 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 ;; 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" (user-error "flan dev: the daemon exited before it was ready; see %s"
flan-dev-daemon-buffer)) flan-dev-daemon-buffer))
((> (float-time) deadline) ((> (float-time) deadline)
(display-buffer flan-dev-daemon-buffer)
(user-error "flan dev: no socket on %s after %ss; see %s" (user-error "flan dev: no socket on %s after %ss; see %s"
(abbreviate-file-name socket) flan-dev-start-timeout (abbreviate-file-name socket) flan-dev-start-timeout
flan-dev-daemon-buffer)) 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, 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." which is the one thing a dev loop exists to avoid doing by accident."
(interactive (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 (and buffer-file-name
(string-suffix-p ".flan" buffer-file-name)
(file-name-nondirectory buffer-file-name))))) (file-name-nondirectory buffer-file-name)))))
(when (process-live-p flan-dev--daemon) (when (process-live-p flan-dev--daemon)
(user-error "flan dev: already running on %s; M-x flan-dev-quit first" (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-describe "flan-dev")
(declare-function flan-show-output "flan-dev") (declare-function flan-show-output "flan-dev")
(declare-function flan-repl "flan-repl") (declare-function flan-repl "flan-repl")
(declare-function flan-break "flan-dev")
(declare-function flan-doc "flan-dev") (declare-function flan-doc "flan-dev")
(declare-function flan-dev "flan-dev") (declare-function flan-dev "flan-dev")
(declare-function flan-dev-quit "flan-dev") (declare-function flan-dev-quit "flan-dev")
(declare-function flan-dev-restart-program "flan-dev")
(defgroup flan nil (defgroup flan nil
"Editing and evaluating Flan." "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 ;; C-h after a prefix is how anyone finds out what is under C-c, and a
;; binding there takes that away. ;; binding there takes that away.
(define-key map (kbd "C-c C-v") #'flan-doc) (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) map)
"Keymap for `flan-mode'.") "Keymap for `flan-mode'.")