From: Dmitry Gutov Date: Fri, 13 Jun 2025 03:00:17 +0000 (+0300) Subject: New user option: vc-allow-async-diff X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d49d062cefe62b3ee99408131c9fbb3c554c0182;p=emacs.git New user option: vc-allow-async-diff Centralize the control for whether 'vc-diff' is asynchronous across the backends, while also allowing 'vc-BACKEND-diff' to be called asynchronously when needed. Previously in bug#21969. * lisp/vc/vc.el (vc-allow-async-diff): New user option. * lisp/vc/vc.el (vc-version-diff, vc-diff, vc-diff-mergebase) (vc-root-diff): Obey it. * lisp/vc/log-view.el (log-view-diff-common): Same. * lisp/vc/vc-annotate.el (vc-annotate-show-diff-revision-at-line-internal): Same. * lisp/vc/vc-git.el (vc-git-diff): Follow the ASYNC argument. * lisp/vc/vc-hg.el (vc-hg-diff): Same. * lisp/vc/vc-rcs.el (vc-rcs-diff): Same. (cherry picked from commit bec823b107ef7d3b51b8e430ccab82c81bd63d24) --- diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el index ffe51bee10a..6394fdde6c8 100644 --- a/lisp/vc/log-view.el +++ b/lisp/vc/log-view.el @@ -637,6 +637,7 @@ considered file(s)." (log-view-diff-common beg end t))) (defun log-view-diff-common (beg end &optional whole-changeset) + (defvar vc-allow-async-diff) (let* ((to (log-view-current-tag beg)) (fr-entry (log-view-current-entry end)) (fr (cadr fr-entry))) @@ -650,15 +651,16 @@ considered file(s)." (point)))) (setq fr (vc-call-backend log-view-vc-backend 'previous-revision nil fr))) (vc-diff-internal - t (list log-view-vc-backend - ;; The value passed here should follow what - ;; `vc-deduce-fileset' returns. If we want to see the - ;; diff for all the files in the changeset, pass NIL for - ;; the file list. - (unless whole-changeset - (if log-view-per-file-logs - (list (log-view-current-file)) - log-view-vc-fileset))) + vc-allow-async-diff + (list log-view-vc-backend + ;; The value passed here should follow what + ;; `vc-deduce-fileset' returns. If we want to see the + ;; diff for all the files in the changeset, pass NIL for + ;; the file list. + (unless whole-changeset + (if log-view-per-file-logs + (list (log-view-current-file)) + log-view-vc-fileset))) fr to))) (provide 'log-view) diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el index 9e9d4df8cc0..de432e4e1c3 100644 --- a/lisp/vc/vc-annotate.el +++ b/lisp/vc/vc-annotate.el @@ -594,6 +594,7 @@ the file in question, search for the log entry required and move point." (car rev-at-line) t 1))))))) (defun vc-annotate-show-diff-revision-at-line-internal (filediff) + (defvar vc-allow-async-diff) (if (not (derived-mode-p 'vc-annotate-mode)) (message "Cannot be invoked outside of a vc annotate buffer") (let* ((rev-at-line (vc-annotate-extract-revision-at-line)) @@ -606,7 +607,7 @@ the file in question, search for the log entry required and move point." (vc-call-backend vc-annotate-backend 'previous-revision (if filediff fname nil) rev)) (vc-diff-internal - t + vc-allow-async-diff ;; The value passed here should follow what ;; `vc-deduce-fileset' returns. (list vc-annotate-backend diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index cb461efa763..9ab82f7f5ac 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -1805,7 +1805,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"." samp coding-system-for-read t))) (setq coding-system-for-read 'undecided))) -(defun vc-git-diff (files &optional rev1 rev2 buffer _async) +(defun vc-git-diff (files &optional rev1 rev2 buffer async) "Get a difference report using Git between two revisions of FILES." (let (process-file-side-effects (command "diff-tree")) @@ -1817,7 +1817,7 @@ This requires git 1.8.4 or later, for the \"-L\" option of \"git log\"." (unless rev1 (setq rev1 "HEAD"))) (if vc-git-diff-switches (apply #'vc-git-command (or buffer "*vc-diff*") - 1 ; bug#21969 + (if async 'async 1) files command "--exit-code" diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index ff761f82535..76d5529ff45 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -525,7 +525,7 @@ This requires hg 4.4 or later, for the \"-L\" option of \"hg log\"." (cons 'vc-hg-region-history-font-lock-keywords (cdr font-lock-defaults)))) -(defun vc-hg-diff (files &optional oldvers newvers buffer _async) +(defun vc-hg-diff (files &optional oldvers newvers buffer async) "Get a difference report using hg between two revisions of FILES." (let* ((firstfile (car files)) (working (and firstfile (vc-working-revision firstfile)))) @@ -535,7 +535,7 @@ This requires hg 4.4 or later, for the \"-L\" option of \"hg log\"." (setq oldvers working)) (apply #'vc-hg-command (or buffer "*vc-diff*") - nil ; bug#21969 + (if async 'async 1) files "diff" (append (vc-switches 'hg 'diff) diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el index 2a6c8d925b1..081f6917ddc 100644 --- a/lisp/vc/vc-rcs.el +++ b/lisp/vc/vc-rcs.el @@ -554,11 +554,10 @@ files beneath it." (vc-rcs-print-log-cleanup)) (when limit 'limit-unsupported)) -(defun vc-rcs-diff (files &optional oldvers newvers buffer _async) +(defun vc-rcs-diff (files &optional oldvers newvers buffer async) "Get a difference report using RCS between two sets of files." (apply #'vc-do-command (or buffer "*vc-diff*") - ;; The repo is local, so this is fast anyway. - 1 ; bug#21969 + (if async 'async 1) "rcsdiff" (vc-expand-dirs files 'RCS) (append (list "-q" (and oldvers (concat "-r" oldvers)) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 504bc8b39f5..70f08aa36d8 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -873,6 +873,14 @@ if the local changes in the file have not been found and displayed yet." (const :tag "Yes" t)) :version "22.1") +(defcustom vc-allow-async-diff nil + "Non-nil to allow asynchronous diff process. +Enabling this means the buffer will be displayed before the diff is +generated, and so might only say \"No changes ...\"." + :type '(choice (const :tag "No" nil) + (const :tag "Yes" t)) + :version "31.1") + ;;;###autoload (defcustom vc-checkout-hook nil "Normal hook (list of functions) run after checking out a file. @@ -2347,7 +2355,7 @@ state of each file in the fileset." (error "Not a valid revision range")) ;; Yes, it's painful to call (vc-deduce-fileset) again. Alas, the ;; placement rules for (interactive) don't actually leave us a choice. - (vc-diff-internal t (vc-deduce-fileset t) rev1 rev2 + (vc-diff-internal vc-allow-async-diff (vc-deduce-fileset t) rev1 rev2 (called-interactively-p 'interactive))) ;;;###autoload @@ -2362,7 +2370,7 @@ state of each file in the fileset." (error "Not a valid revision range")) (vc--with-backend-in-rootdir "VC root-diff" (let ((default-directory rootdir)) - (vc-diff-internal t (list backend (list rootdir)) rev1 rev2 + (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) rev1 rev2 (called-interactively-p 'interactive))))) ;;;###autoload @@ -2380,7 +2388,7 @@ Optional argument FILESET, if non-nil, overrides the fileset." (call-interactively 'vc-version-diff) (let ((fileset (or fileset (vc-deduce-fileset t)))) (vc-buffer-sync-fileset fileset not-essential) - (vc-diff-internal t fileset nil nil + (vc-diff-internal vc-allow-async-diff fileset nil nil (called-interactively-p 'interactive))))) (defun vc-buffer-sync-fileset (fileset &optional not-essential missing-in-dirs) @@ -2432,8 +2440,9 @@ The merge base is a common ancestor between REV1 and REV2 revisions." (vc--with-backend-in-rootdir "VC root-diff" (let ((default-directory rootdir) (rev1 (vc-call-backend backend 'mergebase rev1 rev2))) - (vc-diff-internal t (list backend (list rootdir)) rev1 rev2 - (called-interactively-p 'interactive))))) + (vc-diff-internal + vc-allow-async-diff (list backend (list rootdir)) rev1 rev2 + (called-interactively-p 'interactive))))) (declare-function ediff-load-version-control "ediff" (&optional silent)) (declare-function ediff-vc-internal "ediff-vers" @@ -2509,7 +2518,7 @@ saving the buffer." (let ((default-directory rootdir) (fileset `(,backend (,rootdir)))) (vc-buffer-sync-fileset fileset not-essential) - (vc-diff-internal t fileset nil nil + (vc-diff-internal vc-allow-async-diff fileset nil nil (called-interactively-p 'interactive)))))) ;;;###autoload