Skip to content

Commit eb796ae

Browse files
committed
org-element-cache: Use `buffer-size' to detect silent modifications
* lisp/org-element.el (org-element--cache-diagnostics-modifications): (org-element--cache-silent-modification-check): Remove variables that were introduced to deal with false positives. The new check is more reliable. (org-element--cache-last-buffer-size): New variable storing the last known buffer size registered before/after handled buffer edits. (org-element--cache-sync): Use `buffer-size' instead of `buffer-chars-modified-tick' heuristics. `buffer-size' may not catch all the modifications, but it does not cause numerous false-positives triggered by quail. See Emacs Bug#51766 for the detailed discussion. (org-element--cache-before-change): (org-element-cache-reset): Record buffer size before/after changes. * lisp/org-macs.el (org-unique-local-variables): Do not carry over buffer-local `org-element--cache-last-buffer-size' when cloning buffer.
1 parent d788fe9 commit eb796ae

File tree

2 files changed

+15
-61
lines changed

2 files changed

+15
-61
lines changed

lisp/org-element.el

Lines changed: 14 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5322,29 +5322,6 @@ to be correct. Setting this to a value less than 0.0001 is useless.")
53225322
(defvar org-element--cache-map-statistics-threshold 0.1
53235323
"Time threshold in seconds to log statistics for `org-element-cache-map'.")
53245324

5325-
(defvar org-element--cache-diagnostics-modifications t
5326-
"Non-nil enables cache warnings when for silent modifications.
5327-
5328-
Silent modifications are the modifications in Org buffers that are not
5329-
registered by `org-element--cache-before-change' and
5330-
`org-element--cache-after-change'.
5331-
5332-
This variable may cause false-positives because some Emacs versions
5333-
can change `buffer-chars-modified-tick' internally even though no
5334-
visible changes in buffer are being made. Some of such expected cases
5335-
are covered by heuristics, but not all.")
5336-
5337-
(defvar org-element--cache-silent-modification-check t
5338-
"Detect changes in buffer made inside `with-silent-modifications'.
5339-
5340-
Note that some internal Emacs functions may also trigger a warning and
5341-
cache reset. The warning can be suppressed by setting
5342-
`org-element--cache-diagnostics-modifications' to nil, but the cache
5343-
will still be refreshed to be safe.
5344-
5345-
WARNING: Setting this variable to nil may cause cache corruption is some
5346-
third-party packages make undetected changes in buffers.")
5347-
53485325
(defvar org-element--cache-diagnostics-level 2
53495326
"Detail level of the diagnostics.")
53505327

@@ -5454,6 +5431,9 @@ See `org-element--cache-key' for more information.")
54545431
(defvar-local org-element--cache-change-tic nil
54555432
"Last `buffer-chars-modified-tick' for registered changes.")
54565433

5434+
(defvar-local org-element--cache-last-buffer-size nil
5435+
"Last value of `buffer-size' for registered changes.")
5436+
54575437
(defvar org-element--cache-non-modifying-commands
54585438
'(org-agenda
54595439
org-agenda-redo
@@ -5968,46 +5948,17 @@ actually submitted."
59685948
(with-current-buffer (or (buffer-base-buffer buffer) buffer)
59695949
;; Check if the buffer have been changed outside visibility of
59705950
;; `org-element--cache-before-change' and `org-element--cache-after-change'.
5971-
(if (and (/= org-element--cache-change-tic
5972-
(buffer-chars-modified-tick))
5973-
org-element--cache-silent-modification-check
5974-
;; FIXME: Below is a heuristics noticed by observation.
5975-
;; quail.el with non-latin input does silent
5976-
;; modifications in buffer increasing the tick counter
5977-
;; but not actually changing the buffer text:
5978-
;; https://list.orgmode.org/87sfw2luhj.fsf@localhost/T/#you
5979-
;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-11/msg00894.html
5980-
;; However, the values of `buffer-chars-modified-tick'
5981-
;; and `buffer-modified-tick' appear to be same after
5982-
;; the quail.el's changes in buffer. We do not
5983-
;; consider these exact changes as a dangerous silent
5984-
;; edit.
5985-
(/= (buffer-chars-modified-tick)
5986-
(buffer-modified-tick)))
5951+
(if (/= org-element--cache-last-buffer-size (buffer-size))
59875952
(progn
5988-
(when (or (and org-element--cache-diagnostics-modifications
5989-
;; A number of Emacs internal operations in
5990-
;; Emacs 26 and 27 alter
5991-
;; `buffer-chars-modified-tick' (see
5992-
;; https://list.orgmode.org/87ee7jdv70.fsf@localhost/T/#t
5993-
;; https://list.orgmode.org/2022-01-06T12-13-17@devnull.Karl-Voit.at/T/#mb3771758f81b31721ba2f420878a4d16081dc483).
5994-
;; We have no way to distinguish them from
5995-
;; dangerious silent edits. So, we can
5996-
;; only reset the cache, but do not show
5997-
;; warning to not irritate the users.)
5998-
(not (version< emacs-version "28")))
5999-
(and (boundp 'org-batch-test) org-batch-test))
6000-
(org-element--cache-warn
6001-
"Unregistered buffer modifications detected. Resetting.
5953+
(org-element--cache-warn
5954+
"Unregistered buffer modifications detected. Resetting.
60025955
If this warning appears regularly, please report the warning text to Org mode mailing list (M-x org-submit-bug-report).
6003-
The buffer is: %s\n Current command: %S\n Chars modified: %S\n Buffer modified: %S\n Backtrace:\n%S"
6004-
(buffer-name (current-buffer))
6005-
(list this-command (buffer-chars-modified-tick) (buffer-modified-tick))
6006-
(buffer-chars-modified-tick)
6007-
(buffer-modified-tick)
6008-
(when (and (fboundp 'backtrace-get-frames)
6009-
(fboundp 'backtrace-to-string))
6010-
(backtrace-to-string (backtrace-get-frames 'backtrace)))))
5956+
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))))
60115962
(org-element-cache-reset))
60125963
(let ((inhibit-quit t) request next)
60135964
(setq org-element--cache-interrupt-C-g-count 0)
@@ -6688,6 +6639,7 @@ The function returns the new value of `org-element--cache-change-warning'."
66886639
(when (org-element--cache-active-p t)
66896640
(org-with-wide-buffer
66906641
(setq org-element--cache-change-tic (buffer-chars-modified-tick))
6642+
(setq org-element--cache-last-buffer-size (buffer-size))
66916643
(goto-char beg)
66926644
(beginning-of-line)
66936645
(let ((bottom (save-excursion
@@ -7282,6 +7234,7 @@ buffers."
72827234
(current-buffer)
72837235
:inherit 'org-element--cache))
72847236
(setq-local org-element--cache-change-tic (buffer-chars-modified-tick))
7237+
(setq-local org-element--cache-last-buffer-size (buffer-size))
72857238
(setq-local org-element--cache-gapless nil)
72867239
(setq-local org-element--cache
72877240
(avl-tree-create #'org-element--cache-compare))

lisp/org-macs.el

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ ones and overrule settings in the other lists."
594594
'(org-element--cache
595595
org-element--headline-cache
596596
org-element--cache-change-tic
597+
org-element--cache-last-buffer-size
597598
org-element--cache-change-warning
598599
org-element--cache-gapless
599600
org-element--cache-hash-left

0 commit comments

Comments
 (0)