Function: org-fold-core--buffer-substring-filter

org-fold-core--buffer-substring-filter is a byte-compiled function defined in org-fold-core.el.gz.

Signature

(org-fold-core--buffer-substring-filter BEG END &optional DELETE)

Documentation

Clear folding state in killed text.

This function is intended to be used as filter-buffer-substring-function. The arguments and return value are as specified for filter-buffer-substring.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org-fold-core.el.gz
;;; Handling killing/yanking of folded text

;; By default, all the text properties of the killed text are
;; preserved, including the folding text properties.  This can be
;; awkward when we copy a text from an indirect buffer to another
;; indirect buffer (or the base buffer).  The copied text might be
;; visible in the source buffer, but might disappear if we yank it in
;; another buffer.  This happens in the following situation:
;; ---- base buffer ----
;; * Headline<begin fold>
;; Some text hidden in the base buffer, but revealed in the indirect
;; buffer.<end fold>
;; * Another headline
;;
;; ---- end of base buffer ----
;; ---- indirect buffer ----
;; * Headline
;; Some text hidden in the base buffer, but revealed in the indirect
;; buffer.
;; * Another headline
;;
;; ---- end of indirect buffer ----
;; If we copy the text under "Headline" from the indirect buffer and
;; insert it under "Another headline" in the base buffer, the inserted
;; text will be hidden since it's folding text properties are copied.
;; Basically, the copied text would have two sets of folding text
;; properties: (1) Properties for base buffer telling that the text is
;; hidden; (2) Properties for the indirect buffer telling that the
;; text is visible.  The first set of the text properties in inactive
;; in the indirect buffer, but will become active once we yank the
;; text back into the base buffer.
;;
;; To avoid the above situation, we simply clear all the properties,
;; unrealated to current buffer when a text is copied.
;; FIXME: Ideally, we may want to carry the folding state of copied
;; text between buffer (probably via user customization).
(defun org-fold-core--buffer-substring-filter (beg end &optional delete)
  "Clear folding state in killed text.
This function is intended to be used as `filter-buffer-substring-function'.
The arguments and return value are as specified for `filter-buffer-substring'."
  (let ((return-string (buffer-substring--filter beg end delete))
	;; The list will be used as an argument to `remove-text-properties'.
	props-list)
    ;; There is no easy way to examine all the text properties of a
    ;; string, so we utilize the fact that printed string
    ;; representation lists all its properties.
    ;; Loop over the elements of string representation.
    (unless (or (string= "" return-string)
                (<= end beg)
                (eq org-fold-core-style 'overlays))
      ;; Collect all the text properties the string is completely
      ;; hidden with.
      (dolist (spec (org-fold-core-folding-spec-list))
        (when (and (org-fold-core-region-folded-p beg end spec)
                   (org-region-invisible-p beg end))
          (push (org-fold-core--property-symbol-get-create spec nil t) props-list)))
      (dolist (plist
               (if (fboundp 'object-intervals)
                   (object-intervals return-string)
                 ;; Backward compatibility with Emacs <28.
                 ;; FIXME: Is there any better way to do it?
                 ;; Yes, it is a hack.
                 ;; The below gives us string representation as a list.
                 ;; Note that we need to remove unreadable values, like markers (#<...>).
                 (seq-partition
                  (cdr (let ((data (read (replace-regexp-in-string
                                          "^#(" "("
                                          (replace-regexp-in-string
                                           " #(" " ("
                                           (replace-regexp-in-string
                                            "#<[^>]+>" "dummy"
                                            ;; Get text representation of the string object.
                                            ;; Make sure to print everything (see `prin1' docstring).
                                            ;; `prin1' is used to print "%S" format.
                                            (let (print-level print-length)
                                              (format "%S" return-string))))))))
                         (if (listp data) data (list data))))
                  3)))
        (let* ((start (car plist))
               (fin (cadr plist))
               (plist (car (cddr plist))))
          ;; Only lists contain text properties.
          (when (listp plist)
            ;; Collect all the relevant text properties.
            (while plist
              (let* ((prop (car plist))
                     (prop-name (symbol-name prop)))
                ;; Reveal hard-hidden text.  See
                ;; `org-fold-core--optimise-for-huge-buffers'.
                (when (and (eq prop 'invisible)
                           (member (cadr plist) (org-fold-core-folding-spec-list)))
                  (remove-text-properties start fin '(invisible t) return-string))
                ;; We do not care about values now.
                (setq plist (cddr plist))
                (when (string-match-p org-fold-core--spec-property-prefix prop-name)
                  ;; Leave folding specs from current buffer.  See
                  ;; comments in `org-fold-core--property-symbol-get-create' to
                  ;; understand why it works.
                  (unless (member prop (cdr (assq 'invisible char-property-alias-alist)))
                    (push prop props-list))))))))
      (remove-text-properties 0 (length return-string) props-list return-string))
    return-string))