New user option vc-display-failed-async-commands

* lisp/vc/vc-dispatcher.el (vc-display-failed-async-commands):
New user option.
(vc-do-async-command): Use it.
* doc/emacs/vc1-xtra.texi (General VC Options):
* etc/NEWS: Document it.
* lisp/vc/vc-dispatcher.el (vc-do-command): Adjust message to
begin "Failed" not "Done" when command exits non-zero.
* lisp/vc/vc.el (vc-checkin): Adjust message to end in
"...failed" not "...done" when async command exits non-zero.
This commit is contained in:
Sean Whitton 2026-03-05 13:24:27 +00:00
parent f398a4d299
commit 8d16a0557d
4 changed files with 39 additions and 5 deletions

View file

@ -896,6 +896,18 @@ to indicate which shell commands it runs, and logs additional messages
when the commands finish. If the variable has any other non-@code{nil}
value, Emacs both logs and displays these messages.
@vindex vc-display-failed-async-commands
VC mode runs certain shall commands asynchronously, allow you to
continue to use Emacs for other purposes while the command completes.
This is mostly used for commands which access the network, such as
pulling and pushing for distributed VCS (@pxref{Pulling / Pushing}).
When the command starts, VC displays a buffer into which the commands
output will be written. If @code{vc-display-failed-async-commands} is
non-@code{nil}, VC will additionally ensure that this buffer is
displayed when the command finishes running but failed. This means you
can freely close the window displaying the command's buffer and know
that it'll pop up again in the case that running the command failed.
@vindex vc-async-checkin
Normally checkin operations are done synchronously; that is, Emacs
waits until the checkin has completed before doing anything else. This

View file

@ -2932,6 +2932,11 @@ You can disable this by customizing 'vc-dir-show-outgoing-count' to nil.
*** New user option 'vc-async-checkin' to enable async checkin operations.
Currently only supported by the Git and Mercurial backends.
+++
*** New user option 'vc-display-failed-async-commands'.
If non-nil, displays the buffer with the output of the failed command
when an asynchronous VC command (e.g. pulls and pushes) fails.
---
*** New 'log-edit-hook' option to display diff of changes to commit.
You can customize 'log-edit-hook' to include its new

View file

@ -150,6 +150,13 @@ logged in the *Messages* buffer, but not displayed."
:type 'boolean
:group 'vc)
(defcustom vc-display-failed-async-commands nil
"If non-nil, display VC async command buffers when the command fails.
Considers VC async commands to have failed whenever they die to a signal
or exit non-zero."
:type 'boolean
:group 'vc)
;; Variables the user doesn't need to know about.
(defvar vc-log-operation nil)
@ -527,7 +534,9 @@ that is inserted into the command line before the filename."
(vc-run-delayed
(let ((message-truncate-lines t)
(inhibit-message vc--inhibit-message))
(message "Done in background: %s"
(message "%s in background: %s"
(if (zerop (process-exit-status proc))
"Done" "Failed")
full-command)))))
;; Run synchronously
(vc--command-message "Running in foreground: %s"
@ -596,7 +605,10 @@ Display the buffer in some window, but don't select it."
(time-to-seconds
(time-since start-time))))
(set-marker (process-mark proc)
(point))))))))))
(point)))))
(when (and vc-display-failed-async-commands
(not (zerop (process-exit-status proc))))
(vc--display-async-command-buffer buffer)))))))
(setq buffer (get-buffer-create buffer))
(if (get-buffer-process buffer)
(error "Another VC action on %s is running" root))

View file

@ -2192,7 +2192,7 @@ have changed; continue with old fileset?" (current-buffer))))
;; NOQUERY parameter non-nil.
(vc-buffer-sync-fileset (list backend files)))
(when register (vc-register (list backend register)))
(let (to-remove-props)
(let (to-remove-props proc)
(cl-flet ((do-it ()
;; We used to change buffers to get local value of
;; `vc-checkin-switches', but the (singular) local
@ -2206,18 +2206,23 @@ have changed; continue with old fileset?" (current-buffer))))
(remove-props-done-msg ()
(dolist (file to-remove-props)
(vc-file-setprop file 'display-state nil))
(message "Checking in %s...done" (vc-delistify files))))
(message "Checking in %s...%s"
(vc-delistify files)
(if (or (not proc)
(zerop (process-exit-status proc)))
"done" "failed"))))
(if do-async
;; Rely on `vc-set-async-update' to update properties
;; other than the display-only `display-state' property.
(let ((ret (do-it)))
(when (eq (car-safe ret) 'async)
(setq proc (cadr ret))
(dolist (file files)
(let ((file (expand-file-name file)))
(vc-file-setprop file 'display-state "committing")
(vc-dir-resynch-file file)
(push file to-remove-props)))
(vc-exec-after #'remove-props-done-msg nil (cadr ret)))
(vc-exec-after #'remove-props-done-msg nil proc))
ret)
(prog2 (message "Checking in %s..." (vc-delistify files))
(with-vc-properties files (do-it)