org-fold: Fix edge case when revealing fragile folds breaks some Emacs commands
* lisp/org-fold-core.el (org-fold-core--fix-folded-region): Delay revealing fragile regions to until the current command is executed. (org-fold-core--region-delayed): New function to postpone folding to the time when `post-command-hook' is executed. (org-fold-core--region-delayed-list): New internal variable holding delayed fold requests. (org-fold-core--process-delayed): New function to be used to process the delayed folds and cleanup `post-command-hook'. * testing/lisp/test-org-fold.el (test-org-fold/org-fold-reveal-broken-structure): Update tests to account for the delayed unfolding. Reported-by: Sebastian Miele <iota@whxvd.name> Link: https://orgmode.org/list/875y04yq9s.fsf@localhost
This commit is contained in:
parent
c9e5270bf1
commit
f9702a09e7
|
@ -1311,6 +1311,33 @@ instead of text properties. The created overlays will be stored in
|
|||
`(let ((org-fold-core--ignore-fragility-checks t))
|
||||
(progn ,@body)))
|
||||
|
||||
(defvar org-fold-core--region-delayed-list nil
|
||||
"List holding (MKFROM MKTO FLAG SPEC-OR-ALIAS) arguments to process.
|
||||
The list is used by `org-fold-core--region-delayed'.")
|
||||
(defun org-fold-core--region-delayed (from to flag &optional spec-or-alias)
|
||||
"Call `org-fold-core-region' after current command.
|
||||
Pass the same FROM, TO, FLAG, and SPEC-OR-ALIAS."
|
||||
;; Setup delayed folding.
|
||||
(add-hook 'post-command-hook #'org-fold-core--process-delayed)
|
||||
(let ((frommk (make-marker))
|
||||
(tomk (make-marker)))
|
||||
(set-marker frommk from (current-buffer))
|
||||
(set-marker tomk to (current-buffer))
|
||||
(push (list frommk tomk flag spec-or-alias) org-fold-core--region-delayed-list)))
|
||||
|
||||
(defun org-fold-core--process-delayed ()
|
||||
"Perform folding for `org-fold-core--region-delayed-list'."
|
||||
(when org-fold-core--region-delayed-list
|
||||
(mapc (lambda (args)
|
||||
(when (< (nth 0 args) (nth 1 args))
|
||||
(org-with-point-at (car args)
|
||||
(apply #'org-fold-core-region args))))
|
||||
;; Restore the initial folding order.
|
||||
(nreverse org-fold-core--region-delayed-list))
|
||||
;; Cleanup `post-command-hook'.
|
||||
(remove-hook 'post-command-hook #'org-fold-core--process-delayed)
|
||||
(setq org-fold-core--region-delayed-list nil)))
|
||||
|
||||
(defvar-local org-fold-core--last-buffer-chars-modified-tick nil
|
||||
"Variable storing the last return value of `buffer-chars-modified-tick'.")
|
||||
|
||||
|
@ -1428,7 +1455,10 @@ property, unfold the region if the :fragile function returns non-nil."
|
|||
(cons fold-begin fold-end)
|
||||
spec))
|
||||
;; Reveal completely, not just from the SPEC.
|
||||
(org-fold-core-region fold-begin fold-end nil)))))
|
||||
;; Do it only after command is finished -
|
||||
;; some Emacs commands assume that
|
||||
;; visibility is not altered by `after-change-functions'.
|
||||
(org-fold-core--region-delayed fold-begin fold-end nil)))))
|
||||
;; Move to next fold.
|
||||
(setq pos (org-fold-core-next-folding-state-change spec pos local-to)))))))))))))
|
||||
|
||||
|
|
|
@ -469,6 +469,7 @@ Text here"
|
|||
(should (org-invisible-p))
|
||||
(goto-char 1)
|
||||
(org-delete-char 1)
|
||||
(run-hooks 'post-command-hook)
|
||||
(re-search-forward "Text")
|
||||
(should-not (org-invisible-p)))
|
||||
(org-test-with-temp-text
|
||||
|
@ -480,6 +481,7 @@ Text here"
|
|||
(goto-char 1)
|
||||
(let ((last-command-event ?a))
|
||||
(org-self-insert-command 1))
|
||||
(run-hooks 'post-command-hook)
|
||||
(re-search-forward "Text")
|
||||
(should-not (org-invisible-p)))
|
||||
(org-test-with-temp-text
|
||||
|
@ -494,6 +496,7 @@ Text here"
|
|||
(should (org-invisible-p))
|
||||
(re-search-backward ":PROPERTIES:")
|
||||
(delete-char 1)
|
||||
(run-hooks 'post-command-hook)
|
||||
(re-search-forward "ID")
|
||||
(should-not (org-invisible-p)))
|
||||
(org-test-with-temp-text
|
||||
|
@ -508,6 +511,7 @@ Text here"
|
|||
(should (org-invisible-p))
|
||||
(re-search-forward ":END:")
|
||||
(delete-char -1)
|
||||
(run-hooks 'post-command-hook)
|
||||
(re-search-backward "ID")
|
||||
(should-not (org-invisible-p)))
|
||||
(org-test-with-temp-text
|
||||
|
@ -521,6 +525,7 @@ Text here"
|
|||
(re-search-forward "end")
|
||||
(should (org-invisible-p))
|
||||
(delete-char -1)
|
||||
(run-hooks 'post-command-hook)
|
||||
(re-search-backward "2")
|
||||
(should-not (org-invisible-p)))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue