branch: elpa/magit
commit 11e13640c44b8c12396aa316bcf95845c4d4aae7
Author: Jonas Bernoulli <[email protected]>
Commit: Jonas Bernoulli <[email protected]>
Better support inserting section into multiple buffers
Normally buffers are refreshed one by one. However, the sections
may be inserted into the process buffer while another buffer is
being refreshed, in particular if `magit-git-debug' is enabled.
This lead to errors because `magit-insert-headers' which is used to
create the header sections in the status buffer adds a function to
the global value `magit-insert-section-hook'. If we switch to the
inserting a section into the process buffer while this is happening,
that hook function adds that section to the list of sections that
are later in `magit-insert-heading' processed again.
This can be prevented by only adding that function to the local value
of the hook.
That is enough to address this particular issues, but also add some
additional safety measures.
In `magit-process-insert-section' bind `magit-insert-section--current'
to nil. Currently this is not necessary, but future changes could make
it necessary, and since it also conceptually makes sense to bind these
when the other `magit-insert-section--*' functions are let-bound, there
is no harm in doing this proactively.
Make `magit-insert-section--current', `magit-insert-section--parent'
and `magit-insert-section--oldroot' automatically buffer local. These
variables are always about the sections in just one particular buffer.
As long as sections are only ever inserted into one buffer at a time,
it does not make a difference if these are local or global, but since
this is already not the case (due to additions to process buffer) and
we might in the future refresh buffers asynchronously, we need buffer-
local values.
---
lisp/magit-process.el | 1 +
lisp/magit-section.el | 46 +++++++++++++++++++++++-----------------------
2 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/lisp/magit-process.el b/lisp/magit-process.el
index f24f439394f..9a3df2669a2 100644
--- a/lisp/magit-process.el
+++ b/lisp/magit-process.el
@@ -693,6 +693,7 @@ Magit status buffer."
(defun magit-process-insert-section (pwd program args &optional errcode errlog)
(let ((inhibit-read-only t)
+ (magit-insert-section--current nil)
(magit-insert-section--parent magit-root-section)
(magit-insert-section--oldroot nil))
(goto-char (1- (point-max)))
diff --git a/lisp/magit-section.el b/lisp/magit-section.el
index e187e87daa2..7b885f52c64 100644
--- a/lisp/magit-section.el
+++ b/lisp/magit-section.el
@@ -602,9 +602,9 @@ with SECTION, otherwise return a list of section types."
(and-let* ((parent (oref section parent)))
(magit-section-lineage parent raw))))
-(defvar magit-insert-section--current nil "For internal use only.")
-(defvar magit-insert-section--parent nil "For internal use only.")
-(defvar magit-insert-section--oldroot nil "For internal use only.")
+(defvar-local magit-insert-section--current nil "For internal use only.")
+(defvar-local magit-insert-section--parent nil "For internal use only.")
+(defvar-local magit-insert-section--oldroot nil "For internal use only.")
;;; Menu
@@ -1593,26 +1593,26 @@ is explicitly expanded."
(defun magit-insert-headers (hook)
(let* ((header-sections nil)
- (magit-insert-section-hook
- (cons (lambda ()
- (push magit-insert-section--current
- header-sections))
- (ensure-list magit-insert-section-hook))))
- (magit-run-section-hook hook)
- (when header-sections
- (insert "\n")
- ;; Make the first header into the parent of the rest.
- (when (cdr header-sections)
- (setq header-sections (nreverse header-sections))
- (let* ((1st-header (pop header-sections))
- (header-parent (oref 1st-header parent)))
- (oset header-parent children (list 1st-header))
- (oset 1st-header children header-sections)
- (oset 1st-header content (oref (car header-sections) start))
- (oset 1st-header end (oref (car (last header-sections)) end))
- (dolist (sub-header header-sections)
- (oset sub-header parent 1st-header))
- (magit-section-maybe-add-heading-map 1st-header))))))
+ (fn (lambda () (push magit-insert-section--current header-sections))))
+ (unwind-protect
+ (progn
+ (add-hook 'magit-insert-section-hook fn -90 t)
+ (magit-run-section-hook hook)
+ (when header-sections
+ (insert "\n")
+ ;; Make the first header into the parent of the rest.
+ (when (cdr header-sections)
+ (setq header-sections (nreverse header-sections))
+ (let* ((1st-header (pop header-sections))
+ (header-parent (oref 1st-header parent)))
+ (oset header-parent children (list 1st-header))
+ (oset 1st-header children header-sections)
+ (oset 1st-header content (oref (car header-sections) start))
+ (oset 1st-header end (oref (car (last header-sections)) end))
+ (dolist (sub-header header-sections)
+ (oset sub-header parent 1st-header))
+ (magit-section-maybe-add-heading-map 1st-header)))))
+ (remove-hook 'magit-insert-section-hook fn t))))
(defun magit-section-maybe-add-heading-map (section)
(when (magit-section-content-p section)