Skip to content

Commit e0e016c

Browse files
committed
org-element: Do not try to sync element cache in the middle of a change
* lisp/org-element.el (org-element--cache-sync): Do not sync between `before-change-functions' and `after-change-functions'. Fixes https://orgmode.org/list/87tu7tdljo.fsf@no.workgroup
1 parent a7cc95c commit e0e016c

File tree

1 file changed

+63
-59
lines changed

1 file changed

+63
-59
lines changed

lisp/org-element.el

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5946,67 +5946,71 @@ where cache is partially updated before current modification are
59465946
actually submitted."
59475947
(when (buffer-live-p buffer)
59485948
(with-current-buffer (or (buffer-base-buffer buffer) buffer)
5949-
;; Check if the buffer have been changed outside visibility of
5950-
;; `org-element--cache-before-change' and `org-element--cache-after-change'.
5951-
(if (/= org-element--cache-last-buffer-size (buffer-size))
5952-
(progn
5953-
(org-element--cache-warn
5954-
"Unregistered buffer modifications detected. Resetting.
5949+
;; Do not sync when, for example, in the middle of
5950+
;; `combine-change-calls'. See the commentary inside
5951+
;; `org-element--cache-active-p'.
5952+
(when (org-element--cache-active-p)
5953+
;; Check if the buffer have been changed outside visibility of
5954+
;; `org-element--cache-before-change' and `org-element--cache-after-change'.
5955+
(if (/= org-element--cache-last-buffer-size (buffer-size))
5956+
(progn
5957+
(org-element--cache-warn
5958+
"Unregistered buffer modifications detected. Resetting.
59555959
If this warning appears regularly, please report the warning text to Org mode mailing list (M-x org-submit-bug-report).
59565960
The buffer is: %s\n Current command: %S\n Backtrace:\n%S"
5957-
(buffer-name (current-buffer))
5958-
this-command
5959-
(when (and (fboundp 'backtrace-get-frames)
5960-
(fboundp 'backtrace-to-string))
5961-
(backtrace-to-string (backtrace-get-frames 'backtrace))))
5962-
(org-element-cache-reset))
5963-
(let ((inhibit-quit t) request next)
5964-
(setq org-element--cache-interrupt-C-g-count 0)
5965-
(when org-element--cache-sync-timer
5966-
(cancel-timer org-element--cache-sync-timer))
5967-
(let ((time-limit (time-add nil org-element-cache-sync-duration)))
5968-
(catch 'org-element--cache-interrupt
5969-
(when org-element--cache-sync-requests
5970-
(org-element--cache-log-message "Syncing down to %S-%S" (or future-change threshold) threshold))
5971-
(while org-element--cache-sync-requests
5972-
(setq request (car org-element--cache-sync-requests)
5973-
next (nth 1 org-element--cache-sync-requests))
5974-
(org-element--cache-process-request
5975-
request
5976-
(when next (org-element--request-key next))
5977-
threshold
5978-
(unless threshold time-limit)
5979-
future-change
5980-
offset)
5981-
;; Re-assign current and next requests. It could have
5982-
;; been altered during phase 1.
5983-
(setq request (car org-element--cache-sync-requests)
5984-
next (nth 1 org-element--cache-sync-requests))
5985-
;; Request processed. Merge current and next offsets and
5986-
;; transfer ending position.
5987-
(when next
5988-
;; The following requests can only be either phase 1
5989-
;; or phase 2 requests. We need to let them know
5990-
;; that additional shifting happened ahead of them.
5991-
(cl-incf (org-element--request-offset next) (org-element--request-offset request))
5992-
(org-element--cache-log-message
5993-
"Updating next request offset to %S: %s"
5994-
(org-element--request-offset next)
5995-
(let ((print-length 10) (print-level 3)) (prin1-to-string next)))
5996-
;; FIXME: END part of the request only matters for
5997-
;; phase 0 requests. However, the only possible
5998-
;; phase 0 request must be the first request in the
5999-
;; list all the time. END position should be
6000-
;; unused.
6001-
(setf (org-element--request-end next) (org-element--request-end request)))
6002-
(setq org-element--cache-sync-requests
6003-
(cdr org-element--cache-sync-requests)))))
6004-
;; If more requests are awaiting, set idle timer accordingly.
6005-
;; Otherwise, reset keys.
6006-
(if org-element--cache-sync-requests
6007-
(org-element--cache-set-timer buffer)
6008-
(setq org-element--cache-change-warning nil)
6009-
(setq org-element--cache-sync-keys-value (1+ org-element--cache-sync-keys-value))))))))
5961+
(buffer-name (current-buffer))
5962+
this-command
5963+
(when (and (fboundp 'backtrace-get-frames)
5964+
(fboundp 'backtrace-to-string))
5965+
(backtrace-to-string (backtrace-get-frames 'backtrace))))
5966+
(org-element-cache-reset))
5967+
(let ((inhibit-quit t) request next)
5968+
(setq org-element--cache-interrupt-C-g-count 0)
5969+
(when org-element--cache-sync-timer
5970+
(cancel-timer org-element--cache-sync-timer))
5971+
(let ((time-limit (time-add nil org-element-cache-sync-duration)))
5972+
(catch 'org-element--cache-interrupt
5973+
(when org-element--cache-sync-requests
5974+
(org-element--cache-log-message "Syncing down to %S-%S" (or future-change threshold) threshold))
5975+
(while org-element--cache-sync-requests
5976+
(setq request (car org-element--cache-sync-requests)
5977+
next (nth 1 org-element--cache-sync-requests))
5978+
(org-element--cache-process-request
5979+
request
5980+
(when next (org-element--request-key next))
5981+
threshold
5982+
(unless threshold time-limit)
5983+
future-change
5984+
offset)
5985+
;; Re-assign current and next requests. It could have
5986+
;; been altered during phase 1.
5987+
(setq request (car org-element--cache-sync-requests)
5988+
next (nth 1 org-element--cache-sync-requests))
5989+
;; Request processed. Merge current and next offsets and
5990+
;; transfer ending position.
5991+
(when next
5992+
;; The following requests can only be either phase 1
5993+
;; or phase 2 requests. We need to let them know
5994+
;; that additional shifting happened ahead of them.
5995+
(cl-incf (org-element--request-offset next) (org-element--request-offset request))
5996+
(org-element--cache-log-message
5997+
"Updating next request offset to %S: %s"
5998+
(org-element--request-offset next)
5999+
(let ((print-length 10) (print-level 3)) (prin1-to-string next)))
6000+
;; FIXME: END part of the request only matters for
6001+
;; phase 0 requests. However, the only possible
6002+
;; phase 0 request must be the first request in the
6003+
;; list all the time. END position should be
6004+
;; unused.
6005+
(setf (org-element--request-end next) (org-element--request-end request)))
6006+
(setq org-element--cache-sync-requests
6007+
(cdr org-element--cache-sync-requests)))))
6008+
;; If more requests are awaiting, set idle timer accordingly.
6009+
;; Otherwise, reset keys.
6010+
(if org-element--cache-sync-requests
6011+
(org-element--cache-set-timer buffer)
6012+
(setq org-element--cache-change-warning nil)
6013+
(setq org-element--cache-sync-keys-value (1+ org-element--cache-sync-keys-value)))))))))
60106014

60116015
(defun org-element--cache-process-request
60126016
(request next-request-key threshold time-limit future-change offset)

0 commit comments

Comments
 (0)