emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/org 7dee2c07f4 2/3: org-fold-core: Fix folding for `ise


From: ELPA Syncer
Subject: [elpa] externals/org 7dee2c07f4 2/3: org-fold-core: Fix folding for `isearch-filter-prediacate' outside isearch
Date: Thu, 1 Jun 2023 09:59:32 -0400 (EDT)

branch: externals/org
commit 7dee2c07f459680eacbc3afdccff2f1a0d930086
Author: Ihor Radchenko <yantar92@posteo.net>
Commit: Ihor Radchenko <yantar92@posteo.net>

    org-fold-core: Fix folding for `isearch-filter-prediacate' outside isearch
    
    * lisp/org-fold-core.el (org-fold-core--keep-overlays): New internal
    macro, signaling `org-fold-core-region' to keep overlays in place and
    store new overlays for later use in isearch.
    (org-fold-core-region): Never remove overlays and store newly created
    ones in `org-fold-core--isearch-overlays' when
    `org-fold-core--keep-overlays' is non-nil.  Remove resolved FIXME.
    (org-fold-core--isearch-setup): Advice `isearch-clean-overlays' as
    more reliable way to clear all the temporary overlays created for
    isearch.  `query-replace' and EVIL packages use
    `isearch-filter-predicate' separately as thus `isearch-mode-end-hook'
    is not sufficient to ensure that isearch overlays are converted back
    to text properties.
    (org-fold-core--isearch-show-temporary): Do not alter match data, as
    isearch expects the match data to stay unchanged.  Arrange the
    overlays to be kept for isearch consumption (otherwise, isearch will
    signal an error; see
    https://list.orgmode.org/orgmode/87pmc4smdg.fsf@fastmail.fm/).
    (org-fold-core--create-isearch-overlays): Call `org-fold-core-region'
    with let-bound `org-fold-core-style' instead of repeating the code
    from `org-fold-core-region'.
    
    Reported-by: Michael Dauer <mick.dauer@gmail.com>
    Link:
    
https://list.orgmode.org/orgmode/CAP7OBx+L11ck3Ni6rv94HGU3otdj6C4rG-rMDzkwR1LTj=BWiw@mail.gmail.com/
    Link+: https://list.orgmode.org/orgmode/87pmc4smdg.fsf@fastmail.fm/
    Link+: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=60399
    Link+: https://yhetil.org/emacs-devel/87fs7c10cq.fsf@web.de/
---
 lisp/org-fold-core.el | 109 +++++++++++++++++++++++++++++---------------------
 1 file changed, 63 insertions(+), 46 deletions(-)

diff --git a/lisp/org-fold-core.el b/lisp/org-fold-core.el
index 1d48bd3896..d58cbc6490 100644
--- a/lisp/org-fold-core.el
+++ b/lisp/org-fold-core.el
@@ -984,6 +984,16 @@ WITH-MARKERS must be nil when RELATIVE is non-nil."
 
 ;;;;; Region visibility
 
+(defvar org-fold-core--keep-overlays nil
+  "When non-nil, `org-fold-core-region' will not remove existing overlays.
+Also, new overlays will be added to `org-fold-core--isearch-overlays'.")
+(defvar org-fold-core--isearch-overlays) ; defined below
+(defmacro org-fold-core--keep-overlays (&rest body)
+  "Run BODY with `org-fold-core--keep-overlays' set to t."
+  (declare (debug (body)))
+  `(let ((org-fold-core--keep-overlays t))
+     ,@body))
+
 ;; This is the core function performing actual folding/unfolding.  The
 ;; folding state is stored in text property (folding property)
 ;; returned by `org-fold-core--property-symbol-get-create'.  The value of the
@@ -996,7 +1006,16 @@ If SPEC-OR-ALIAS is omitted and FLAG is nil, unfold 
everything in the region."
     (when spec (org-fold-core--check-spec spec))
     (with-silent-modifications
       (org-with-wide-buffer
-       (when (eq org-fold-core-style 'overlays) (remove-overlays from to 
'invisible spec))
+       (when (eq org-fold-core-style 'overlays)
+         (if org-fold-core--keep-overlays
+             (mapc
+              (lambda (ov)
+                (when (eq spec (overlay-get ov 'invisible))
+                  (overlay-put ov 'org-invisible spec)
+                  (overlay-put ov 'invisible nil)))
+              (overlays-in from to))
+           (remove-overlays from to 'org-invisible spec)
+           (remove-overlays from to 'invisible spec)))
        (if flag
           (if (not spec)
                (error "Calling `org-fold-core-region' with missing SPEC")
@@ -1006,17 +1025,12 @@ If SPEC-OR-ALIAS is omitted and FLAG is nil, unfold 
everything in the region."
                  (let ((o (make-overlay from to nil
                                         
(org-fold-core-get-folding-spec-property spec :front-sticky)
                                         
(org-fold-core-get-folding-spec-property spec :rear-sticky))))
+                   (when org-fold-core--keep-overlays (push o 
org-fold-core--isearch-overlays))
                    (overlay-put o 'evaporate t)
                    (overlay-put o (org-fold-core--property-symbol-get-create 
spec) spec)
                    (overlay-put o 'invisible spec)
                    (overlay-put o 'isearch-open-invisible 
#'org-fold-core--isearch-show)
-                   ;; FIXME: Disabling to work around Emacs bug#60399
-                   ;; and https://orgmode.org/list/87zgb6tk6h.fsf@localhost.
-                   ;; The proper fix will require making sure that
-                   ;; `org-fold-core-isearch-open-function' does not
-                   ;; delete the overlays used by isearch.
-                   ;; (overlay-put o 'isearch-open-invisible-temporary 
#'org-fold-core--isearch-show-temporary)
-                   )
+                   (overlay-put o 'isearch-open-invisible-temporary 
#'org-fold-core--isearch-show-temporary))
               (put-text-property from to 
(org-fold-core--property-symbol-get-create spec) spec)
               (put-text-property from to 'isearch-open-invisible 
#'org-fold-core--isearch-show)
               (put-text-property from to 'isearch-open-invisible-temporary 
#'org-fold-core--isearch-show-temporary)
@@ -1104,6 +1118,13 @@ TYPE can be either `text-properties' or `overlays'."
     (`overlays
      (when (eq org-fold-core-style 'text-properties)
        (setq-local isearch-filter-predicate 
#'org-fold-core--isearch-filter-predicate-overlays)
+       ;; When `isearch-filter-predicate' is called outside isearch,
+       ;; it is common that `isearch-mode-end-hook' does not get
+       ;; executed, but `isearch-clean-overlays' usually does.
+       (advice-add
+        'isearch-clean-overlays :after
+        #'org-fold-core--clear-isearch-overlays
+        '((name . isearch-clean-overlays@org-fold-core)))
        (add-hook 'isearch-mode-end-hook 
#'org-fold-core--clear-isearch-overlays nil 'local)))
     (_ (error "%s: Unknown type of setup for `org-fold-core--isearch-setup'" 
type))))
 
@@ -1152,26 +1173,34 @@ This function is intended to be used as 
`isearch-filter-predicate'."
   "Temporarily reveal text in REGION.
 Hide text instead if HIDE-P is non-nil.
 REGION can also be an overlay in current buffer."
-  (when (overlayp region)
-    (setq region (cons (overlay-start region)
-                       (overlay-end region))))
-  (if (not hide-p)
-      (let ((pos (car region)))
-       (while (< pos (cdr region))
-          (let ((spec-no-open
-                 (catch :found
-                   (dolist (spec (org-fold-core-get-folding-spec 'all pos))
-                     (unless (org-fold-core-get-folding-spec-property spec 
:isearch-open)
-                       (throw :found spec))))))
-            (if spec-no-open
-                ;; Skip regions folded with folding specs that cannot be 
opened.
-                (setq pos (org-fold-core-next-folding-state-change 
spec-no-open pos (cdr region)))
-             (dolist (spec (org-fold-core-get-folding-spec 'all pos))
-               (push (cons spec (org-fold-core-get-region-at-point spec pos)) 
(gethash region org-fold-core--isearch-local-regions)))
-              (org-fold-core--isearch-show region)
-             (setq pos (org-fold-core-next-folding-state-change nil pos (cdr 
region)))))))
-    (mapc (lambda (val) (org-fold-core-region (cadr val) (cddr val) t (car 
val))) (gethash region org-fold-core--isearch-local-regions))
-    (remhash region org-fold-core--isearch-local-regions)))
+  (save-match-data ; match data must not be modified.
+    (let ((org-fold-core-style (if (overlayp region) 'overlays 
'text-properties)))
+      (when (overlayp region)
+        (setq region (cons (overlay-start region)
+                           (overlay-end region))))
+      (if (not hide-p)
+          (let ((pos (car region)))
+           (while (< pos (cdr region))
+              (let ((spec-no-open
+                     (catch :found
+                       (dolist (spec (org-fold-core-get-folding-spec 'all pos))
+                         (unless (org-fold-core-get-folding-spec-property spec 
:isearch-open)
+                           (throw :found spec))))))
+                (if spec-no-open
+                    ;; Skip regions folded with folding specs that cannot be 
opened.
+                    (setq pos (org-fold-core-next-folding-state-change 
spec-no-open pos (cdr region)))
+                 (dolist (spec (org-fold-core-get-folding-spec 'all pos))
+                   (push (cons spec (org-fold-core-get-region-at-point spec 
pos)) (gethash region org-fold-core--isearch-local-regions)))
+                  ;; isearch expects all the temporarily opened overlays to 
exist.
+                  ;; See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=60399
+                  (org-fold-core--keep-overlays
+                   (org-fold-core--isearch-show region))
+                 (setq pos (org-fold-core-next-folding-state-change nil pos 
(cdr region)))))))
+        (mapc (lambda (val)
+                (org-fold-core--keep-overlays
+                 (org-fold-core-region (cadr val) (cddr val) t (car val))))
+              (gethash region org-fold-core--isearch-local-regions))
+        (remhash region org-fold-core--isearch-local-regions)))))
 
 (defvar-local org-fold-core--isearch-special-specs nil
   "List of specs that can break visibility state when converted to overlays.
@@ -1196,24 +1225,12 @@ instead of text properties.  The created overlays will 
be stored in
            ;; We do not want it here.
            (with-silent-modifications
               (org-fold-core-region (car region) (cdr region) nil spec)
-             ;; The overlay is modeled after `outline-flag-region'
-             ;; [2020-05-09 Sat] overlay for 'outline blocks.
-             (let ((o (make-overlay (car region) (cdr region) nil 
'front-advance)))
-               (overlay-put o 'evaporate t)
-               (overlay-put o 'invisible spec)
-                (overlay-put o 'org-invisible spec)
-                ;; Make sure that overlays are applied in the same order
-                ;; with the folding specs.
-                ;; Note: `memq` returns cdr with car equal to the first
-                ;; found matching element.
-                (overlay-put o 'priority (length (memq spec 
(org-fold-core-folding-spec-list))))
-               ;; `delete-overlay' here means that spec information will be 
lost
-               ;; for the region. The region will remain visible.
-                (if (org-fold-core-get-folding-spec-property spec 
:isearch-open)
-                   (overlay-put o 'isearch-open-invisible #'delete-overlay)
-                  (overlay-put o 'isearch-open-invisible #'ignore)
-                  (overlay-put o 'isearch-open-invisible-temporary #'ignore))
-               (push o org-fold-core--isearch-overlays))))))
+              (let ((org-fold-core-style 'overlays))
+                (org-fold-core-region (car region) (cdr region) t spec)
+                (let ((o (cdr (get-char-property-and-overlay
+                               (car region)
+                               (org-fold-core--property-symbol-get-create spec 
nil t)))))
+                  (push o org-fold-core--isearch-overlays)))))))
       (setq pos (org-fold-core-next-folding-state-change nil pos end)))))
 
 (defun org-fold-core--isearch-filter-predicate-overlays (beg end)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]