forked from mirrors/org-mode
Use the full org-fold-core API when `org-fold-core-style' is `overlays'
The old fallback folding mechanism was re-using old function versions to work with overlay folds directly. Switch to using org-fold-core API instead. This avoids code duplication. * lisp/ol.el (org-toggle-link-display--overlays): Merge overlay and text-property versions. (org-toggle-link-display--text-properties): (org-toggle-link-display): * lisp/org-cycle.el (org-cycle-overview--overlays): (org-cycle-overview--text-properties): (org-cycle-overview): (org-cycle-content--text-properties): (org-cycle-content): (org-cycle-content--overlays): * lisp/org-element.el (org-element-swap-A-B--overlays): (org-element-swap-A-B): (org-element-swap-A-B--text-properties): * lisp/org-fold.el (org-fold-save-outline-visibility--overlays): (org-fold-save-outline-visibility--text-properties): (org-fold-save-outline-visibility): (org-fold-region--overlays): (org-fold-region): (org-fold-show-all--text-properties): (org-fold-show-all--overlays): (org-fold-show-all): (org-fold-show-branches-buffer--text-properties): (org-fold-show-branches-buffer): (org-fold-show-branches-buffer--overlays): (org-fold--hide-drawers--overlays): (org-fold--hide-drawers--text-properties): (org-fold--hide-drawers): (org-fold-show-set-visibility--overlays): (org-fold-show-set-visibility--text-properties): (org-fold-show-set-visibility): (org-fold-check-before-invisible-edit--overlays): (org-fold-check-before-invisible-edit--text-properties): (org-fold-check-before-invisible-edit): (org-fold--hide-wrapper-toggle): * lisp/org-inlinetask.el (org-inlinetask-toggle-visibility--text-properties): (org-inlinetask-toggle-visibility): (org-inlinetask-toggle-visibility--overlays): * lisp/org-list.el (org-list-swap-items--text-properties): (org-list-swap-items): (org-list-swap-items--overlays): * lisp/org-macs.el (org-invisible-p--text-properties): (org-invisible-p): (org-invisible-p--overlays): (org-find-visible--overlays): (org-find-visible--text-properties): (org-find-visible): (org-find-invisible--overlays): (org-find-invisible--text-properties): (org-find-invisible): * lisp/org.el (org-next-visible-heading--overlays): (org-next-visible-heading--text-properties): (org-next-visible-heading): (org--forward-paragraph-once--overlays): (org--forward-paragraph-once--text-properties): (org--forward-paragraph-once): (org--backward-paragraph-once--overlays): (org--backward-paragraph-once--text-properties): (org--backward-paragraph-once): * testing/lisp/test-org.el (test-org/drag-element-backward): (test-org/drag-element-forward): Update tests.
This commit is contained in:
parent
01d84f2e50
commit
b8a0ddf52f
15
lisp/ol.el
15
lisp/ol.el
|
@ -1491,24 +1491,11 @@ If the link is in hidden text, expose it."
|
|||
(org-fold-core-set-folding-spec-property (car org-link--link-folding-spec) :visible t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-toggle-link-display--overlays ()
|
||||
"Toggle the literal or descriptive display of links."
|
||||
(interactive)
|
||||
(if org-link-descriptive (remove-from-invisibility-spec '(org-link))
|
||||
(add-to-invisibility-spec '(org-link)))
|
||||
(org-restart-font-lock)
|
||||
(setq org-link-descriptive (not org-link-descriptive)))
|
||||
(defun org-toggle-link-display--text-properties ()
|
||||
(defun org-toggle-link-display ()
|
||||
"Toggle the literal or descriptive display of links in current buffer."
|
||||
(interactive)
|
||||
(setq org-link-descriptive (not org-link-descriptive))
|
||||
(org-link-descriptive-ensure))
|
||||
(defsubst org-toggle-link-display ()
|
||||
"Toggle the literal or descriptive display of links."
|
||||
(interactive)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-toggle-link-display--text-properties)
|
||||
(org-toggle-link-display--overlays)))
|
||||
|
||||
;;;###autoload
|
||||
(defun org-store-link (arg &optional interactive?)
|
||||
|
|
|
@ -644,23 +644,7 @@ With a numeric prefix, show all headlines up to that level."
|
|||
(_ nil)))
|
||||
(org-end-of-subtree)))))))
|
||||
|
||||
(defun org-cycle-overview--overlays ()
|
||||
"Switch to overview mode, showing only top-level headlines."
|
||||
(interactive)
|
||||
(org-fold-show-all '(headings drawers))
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(when (re-search-forward org-outline-regexp-bol nil t)
|
||||
(let* ((last (line-end-position))
|
||||
(level (- (match-end 0) (match-beginning 0) 1))
|
||||
(regexp (format "^\\*\\{1,%d\\} " level)))
|
||||
(while (re-search-forward regexp nil :move)
|
||||
(org-fold-region last (line-end-position 0) t 'outline)
|
||||
(setq last (line-end-position))
|
||||
(setq level (- (match-end 0) (match-beginning 0) 1))
|
||||
(setq regexp (format "^\\*\\{1,%d\\} " level)))
|
||||
(org-fold-region last (point) t 'outline)))))
|
||||
(defun org-cycle-overview--text-properties ()
|
||||
(defun org-cycle-overview ()
|
||||
"Switch to overview mode, showing only top-level headlines."
|
||||
(interactive)
|
||||
(save-excursion
|
||||
|
@ -680,14 +664,8 @@ With a numeric prefix, show all headlines up to that level."
|
|||
(setq level (- (match-end 0) (match-beginning 0) 1))
|
||||
(setq regexp (format "^\\*\\{1,%d\\} " level)))
|
||||
(org-fold-region last (point) t 'outline)))))
|
||||
(defun org-cycle-overview ()
|
||||
"Switch to overview mode, showing only top-level headlines."
|
||||
(interactive)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-cycle-overview--text-properties)
|
||||
(org-cycle-overview--overlays)))
|
||||
|
||||
(defun org-cycle-content--text-properties (&optional arg)
|
||||
(defun org-cycle-content (&optional arg)
|
||||
"Show all headlines in the buffer, like a table of contents.
|
||||
With numerical argument N, show content up to level N."
|
||||
(interactive "p")
|
||||
|
@ -706,27 +684,6 @@ With numerical argument N, show content up to level N."
|
|||
(while (re-search-backward regexp nil t)
|
||||
(org-fold-region (line-end-position) last t 'outline)
|
||||
(setq last (line-end-position 0))))))
|
||||
(defun org-cycle-content--overlays (&optional arg)
|
||||
"Show all headlines in the buffer, like a table of contents.
|
||||
With numerical argument N, show content up to level N."
|
||||
(interactive "p")
|
||||
(org-fold-show-all '(headings drawers))
|
||||
(save-excursion
|
||||
(goto-char (point-max))
|
||||
(let ((regexp (if (and (wholenump arg) (> arg 0))
|
||||
(format "^\\*\\{1,%d\\} " arg)
|
||||
"^\\*+ "))
|
||||
(last (point)))
|
||||
(while (re-search-backward regexp nil t)
|
||||
(org-fold-region (line-end-position) last t 'outline)
|
||||
(setq last (line-end-position 0))))))
|
||||
(defun org-cycle-content (&optional arg)
|
||||
"Show all headlines in the buffer, like a table of contents.
|
||||
With numerical argument N, show content up to level N."
|
||||
(interactive "p")
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-cycle-content--text-properties arg)
|
||||
(org-cycle-content--overlays arg)))
|
||||
|
||||
(defvar org-cycle-scroll-position-to-restore nil
|
||||
"Temporarily store scroll position to restore.")
|
||||
|
|
|
@ -8024,7 +8024,7 @@ parse tree."
|
|||
(or (and (>= beg-A beg-B) (<= end-A end-B))
|
||||
(and (>= beg-B beg-A) (<= end-B end-A)))))
|
||||
|
||||
(defun org-element-swap-A-B--overlays (elem-A elem-B)
|
||||
(defun org-element-swap-A-B (elem-A elem-B)
|
||||
"Swap elements ELEM-A and ELEM-B.
|
||||
Assume ELEM-B is after ELEM-A in the buffer. Leave point at the
|
||||
end of ELEM-A."
|
||||
|
@ -8039,79 +8039,13 @@ end of ELEM-A."
|
|||
(when (and specialp
|
||||
(or (not (eq (org-element-type elem-B) 'paragraph))
|
||||
(/= (org-element-property :begin elem-B)
|
||||
(org-element-property :contents-begin elem-B))))
|
||||
(org-element-property :contents-begin elem-B))))
|
||||
(error "Cannot swap elements"))
|
||||
;; In a special situation, ELEM-A will have no indentation. We'll
|
||||
;; give it ELEM-B's (which will in, in turn, have no indentation).
|
||||
(let* ((ind-B (when specialp
|
||||
(goto-char (org-element-property :begin elem-B))
|
||||
(current-indentation)))
|
||||
(beg-A (org-element-property :begin elem-A))
|
||||
(end-A (save-excursion
|
||||
(goto-char (org-element-property :end elem-A))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point-at-eol)))
|
||||
(beg-B (org-element-property :begin elem-B))
|
||||
(end-B (save-excursion
|
||||
(goto-char (org-element-property :end elem-B))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point-at-eol)))
|
||||
;; Store inner overlays responsible for visibility status.
|
||||
;; We also need to store their boundaries as they will be
|
||||
;; removed from buffer.
|
||||
(overlays
|
||||
(cons
|
||||
(delq nil
|
||||
(mapcar (lambda (o)
|
||||
(and (>= (overlay-start o) beg-A)
|
||||
(<= (overlay-end o) end-A)
|
||||
(list o (overlay-start o) (overlay-end o))))
|
||||
(overlays-in beg-A end-A)))
|
||||
(delq nil
|
||||
(mapcar (lambda (o)
|
||||
(and (>= (overlay-start o) beg-B)
|
||||
(<= (overlay-end o) end-B)
|
||||
(list o (overlay-start o) (overlay-end o))))
|
||||
(overlays-in beg-B end-B)))))
|
||||
;; Get contents.
|
||||
(body-A (buffer-substring beg-A end-A))
|
||||
(body-B (delete-and-extract-region beg-B end-B)))
|
||||
(goto-char beg-B)
|
||||
(when specialp
|
||||
(setq body-B (replace-regexp-in-string "\\`[ \t]*" "" body-B))
|
||||
(indent-to-column ind-B))
|
||||
(insert body-A)
|
||||
;; Restore ex ELEM-A overlays.
|
||||
(let ((offset (- beg-B beg-A)))
|
||||
(dolist (o (car overlays))
|
||||
(move-overlay (car o) (+ (nth 1 o) offset) (+ (nth 2 o) offset)))
|
||||
(goto-char beg-A)
|
||||
(delete-region beg-A end-A)
|
||||
(insert body-B)
|
||||
;; Restore ex ELEM-B overlays.
|
||||
(dolist (o (cdr overlays))
|
||||
(move-overlay (car o) (- (nth 1 o) offset) (- (nth 2 o) offset))))
|
||||
(goto-char (org-element-property :end elem-B)))))
|
||||
(defun org-element-swap-A-B--text-properties (elem-A elem-B)
|
||||
"Swap elements ELEM-A and ELEM-B.
|
||||
Assume ELEM-B is after ELEM-A in the buffer. Leave point at the
|
||||
end of ELEM-A."
|
||||
(goto-char (org-element-property :begin elem-A))
|
||||
;; There are two special cases when an element doesn't start at bol:
|
||||
;; the first paragraph in an item or in a footnote definition.
|
||||
(let ((specialp (not (bolp))))
|
||||
;; Only a paragraph without any affiliated keyword can be moved at
|
||||
;; ELEM-A position in such a situation. Note that the case of
|
||||
;; a footnote definition is impossible: it cannot contain two
|
||||
;; paragraphs in a row because it cannot contain a blank line.
|
||||
(when (and specialp
|
||||
(or (not (eq (org-element-type elem-B) 'paragraph))
|
||||
(/= (org-element-property :begin elem-B)
|
||||
(org-element-property :contents-begin elem-B))))
|
||||
(error "Cannot swap elements"))
|
||||
;; In a special situation, ELEM-A will have no indentation. We'll
|
||||
;; give it ELEM-B's (which will in, in turn, have no indentation).
|
||||
(org-fold-core-ignore-modifications ;; Preserve folding state
|
||||
;; Preserve folding state when `org-fold-core-style' is set to
|
||||
;; `text-properties'.
|
||||
(org-fold-core-ignore-modifications
|
||||
;; In a special situation, ELEM-A will have no indentation. We'll
|
||||
;; give it ELEM-B's (which will in, in turn, have no indentation).
|
||||
(let* ((ind-B (when specialp
|
||||
(goto-char (org-element-property :begin elem-B))
|
||||
(current-indentation)))
|
||||
|
@ -8125,26 +8059,31 @@ end of ELEM-A."
|
|||
(goto-char (org-element-property :end elem-B))
|
||||
(skip-chars-backward " \r\t\n")
|
||||
(point-at-eol)))
|
||||
;; Store inner folds responsible for visibility status.
|
||||
(folds
|
||||
(cons
|
||||
(org-fold-core-get-regions :from beg-A :to end-A :relative t)
|
||||
(org-fold-core-get-regions :from beg-B :to end-B :relative t)))
|
||||
;; Get contents.
|
||||
(body-A (buffer-substring beg-A end-A))
|
||||
(body-B (delete-and-extract-region beg-B end-B)))
|
||||
(body-B (buffer-substring beg-B end-B)))
|
||||
;; Clear up the folds.
|
||||
(org-fold-region beg-A end-A nil)
|
||||
(org-fold-region beg-B end-B nil)
|
||||
(delete-region beg-B end-B)
|
||||
(goto-char beg-B)
|
||||
(when specialp
|
||||
(setq body-B (replace-regexp-in-string "\\`[ \t]*" "" body-B))
|
||||
(indent-to-column ind-B))
|
||||
(insert body-A)
|
||||
;; Restore ex ELEM-A folds.
|
||||
(org-fold-core-regions (car folds) :relative beg-B)
|
||||
(goto-char beg-A)
|
||||
(delete-region beg-A end-A)
|
||||
(insert body-B)
|
||||
;; Restore ex ELEM-A folds.
|
||||
(org-fold-core-regions (cdr folds) :relative beg-A)
|
||||
(goto-char (org-element-property :end elem-B))))))
|
||||
(defsubst org-element-swap-A-B (elem-A elem-B)
|
||||
"Swap elements ELEM-A and ELEM-B.
|
||||
Assume ELEM-B is after ELEM-A in the buffer. Leave point at the
|
||||
end of ELEM-A."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-element-swap-A-B--text-properties elem-A elem-B)
|
||||
(org-element-swap-A-B--overlays elem-A elem-B)))
|
||||
|
||||
|
||||
(provide 'org-element)
|
||||
|
||||
|
|
332
lisp/org-fold.el
332
lisp/org-fold.el
|
@ -254,6 +254,7 @@ smart Make point visible, and do insertion/deletion if it is
|
|||
(defalias 'org-fold-get-folding-spec #'org-fold-core-get-folding-spec)
|
||||
(defalias 'org-fold-get-folding-specs-in-region #'org-fold-core-get-folding-specs-in-region)
|
||||
(defalias 'org-fold-get-region-at-point #'org-fold-core-get-region-at-point)
|
||||
(defalias 'org-fold-get-regions #'org-fold-core-get-regions)
|
||||
(defalias 'org-fold-next-visibility-change #'org-fold-core-next-visibility-change)
|
||||
(defalias 'org-fold-previous-visibility-change #'org-fold-core-previous-visibility-change)
|
||||
(defalias 'org-fold-next-folding-state-change #'org-fold-core-next-folding-state-change)
|
||||
|
@ -262,110 +263,16 @@ smart Make point visible, and do insertion/deletion if it is
|
|||
|
||||
;;;;; Macros
|
||||
|
||||
(defmacro org-fold-save-outline-visibility--overlays (use-markers &rest body)
|
||||
"Save and restore outline visibility around BODY.
|
||||
If USE-MARKERS is non-nil, use markers for the positions. This
|
||||
means that the buffer may change while running BODY, but it also
|
||||
means that the buffer should stay alive during the operation,
|
||||
because otherwise all these markers will point to nowhere."
|
||||
(declare (debug (form body)) (indent 1))
|
||||
(org-with-gensyms (data invisible-types markers?)
|
||||
`(let* ((,invisible-types '(org-hide-block outline))
|
||||
(,markers? ,use-markers)
|
||||
(,data
|
||||
(mapcar (lambda (o)
|
||||
(let ((beg (overlay-start o))
|
||||
(end (overlay-end o))
|
||||
(type (overlay-get o 'invisible)))
|
||||
(and beg end
|
||||
(> end beg)
|
||||
(memq type ,invisible-types)
|
||||
(list (if ,markers? (copy-marker beg) beg)
|
||||
(if ,markers? (copy-marker end t) end)
|
||||
type))))
|
||||
(org-with-wide-buffer
|
||||
(overlays-in (point-min) (point-max))))))
|
||||
(unwind-protect (progn ,@body)
|
||||
(org-with-wide-buffer
|
||||
(dolist (type ,invisible-types)
|
||||
(remove-overlays (point-min) (point-max) 'invisible type))
|
||||
(pcase-dolist (`(,beg ,end ,type) (delq nil ,data))
|
||||
(org-fold-region beg end t type)
|
||||
(when ,markers?
|
||||
(set-marker beg nil)
|
||||
(set-marker end nil))))))))
|
||||
(defmacro org-fold-save-outline-visibility--text-properties (use-markers &rest body)
|
||||
"Save and restore outline visibility around BODY.
|
||||
If USE-MARKERS is non-nil, use markers for the positions. This
|
||||
means that the buffer may change while running BODY, but it also
|
||||
means that the buffer should stay alive during the operation,
|
||||
because otherwise all these markers will point to nowhere."
|
||||
(declare (debug (form body)) (indent 1))
|
||||
(org-with-gensyms (data specs markers?)
|
||||
`(let* ((,specs (org-fold-core-folding-spec-list))
|
||||
(,markers? ,use-markers)
|
||||
(,data
|
||||
(org-with-wide-buffer
|
||||
(let (data-val)
|
||||
(dolist (spec ,specs)
|
||||
(let ((pos (point-min)))
|
||||
(while (< pos (point-max))
|
||||
(when (org-fold-get-folding-spec spec pos)
|
||||
(let ((region (org-fold-get-region-at-point spec pos)))
|
||||
(if ,markers?
|
||||
(push (list (copy-marker (car region))
|
||||
(copy-marker (cdr region) t)
|
||||
spec)
|
||||
data-val)
|
||||
(push (list (car region) (cdr region) spec)
|
||||
data-val))))
|
||||
(setq pos (org-fold-next-folding-state-change spec pos)))))
|
||||
data-val))))
|
||||
(unwind-protect (progn ,@body)
|
||||
(org-with-wide-buffer
|
||||
(org-fold-region (point-min) (point-max) nil)
|
||||
(pcase-dolist (`(,beg ,end ,spec) (delq nil ,data))
|
||||
(org-fold-region beg end t spec)
|
||||
(when ,markers?
|
||||
(set-marker beg nil)
|
||||
(set-marker end nil))))))))
|
||||
(defmacro org-fold-save-outline-visibility (use-markers &rest body)
|
||||
"Save and restore outline visibility around BODY.
|
||||
If USE-MARKERS is non-nil, use markers for the positions. This
|
||||
means that the buffer may change while running BODY, but it also
|
||||
means that the buffer should stay alive during the operation,
|
||||
because otherwise all these markers will point to nowhere."
|
||||
(declare (debug (form body)) (indent 1))
|
||||
`(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-save-outline-visibility--text-properties ,use-markers ,@body)
|
||||
(org-fold-save-outline-visibility--overlays ,use-markers ,@body)))
|
||||
(defalias 'org-fold-save-outline-visibility #'org-fold-core-save-visibility)
|
||||
|
||||
;;;; Changing visibility (regions, blocks, drawers, headlines)
|
||||
|
||||
;;;;; Region visibility
|
||||
|
||||
;; (defalias 'org-fold-region #'org-fold-core-region)
|
||||
(defun org-fold-region--overlays (from to flag spec)
|
||||
"Hide or show lines from FROM to TO, according to FLAG.
|
||||
SPEC is the invisibility spec, as a symbol."
|
||||
(remove-overlays from to 'invisible spec)
|
||||
;; Use `front-advance' since text right before to the beginning of
|
||||
;; the overlay belongs to the visible line than to the contents.
|
||||
(when flag
|
||||
(let ((o (make-overlay from to nil 'front-advance)))
|
||||
(overlay-put o 'evaporate t)
|
||||
(overlay-put o 'invisible spec)
|
||||
(overlay-put o
|
||||
'isearch-open-invisible
|
||||
(lambda (&rest _) (org-fold-show-context 'isearch))))))
|
||||
(defsubst org-fold-region (from to flag &optional spec)
|
||||
"Hide or show lines from FROM to TO, according to FLAG.
|
||||
SPEC is the invisibility spec, as a symbol."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-core-region from to flag spec)
|
||||
(org-fold-region--overlays from to flag spec)))
|
||||
(defalias 'org-fold-region #'org-fold-core-region)
|
||||
(defalias 'org-fold-regions #'org-fold-core-regions)
|
||||
|
||||
(defun org-fold-show-all--text-properties (&optional types)
|
||||
(defun org-fold-show-all (&optional types)
|
||||
"Show all contents in the visible part of the buffer.
|
||||
By default, the function expands headings, blocks and drawers.
|
||||
When optional argument TYPES is a list of symbols among `blocks',
|
||||
|
@ -373,51 +280,11 @@ When optional argument TYPES is a list of symbols among `blocks',
|
|||
(interactive)
|
||||
(dolist (type (or types '(blocks drawers headings)))
|
||||
(org-fold-region (point-min) (point-max) nil
|
||||
(pcase type
|
||||
(`blocks 'block)
|
||||
(`drawers 'drawer)
|
||||
(`headings 'headline)
|
||||
(_ (error "Invalid type: %S" type))))))
|
||||
(defun org-fold-show-all--overlays (&optional types)
|
||||
"Show all contents in the visible part of the buffer.
|
||||
By default, the function expands headings, blocks and drawers.
|
||||
When optional argument TYPE is a list of symbols among `blocks',
|
||||
`drawers' and `headings', to only expand one specific type."
|
||||
(interactive)
|
||||
(let ((types (or types '(blocks drawers headings))))
|
||||
(when (memq 'blocks types)
|
||||
(org-fold-region (point-min) (point-max) nil 'org-hide-block))
|
||||
(cond
|
||||
;; Fast path. Since headings and drawers share the same
|
||||
;; invisible spec, clear everything in one go.
|
||||
((and (memq 'headings types)
|
||||
(memq 'drawers types))
|
||||
(org-fold-region (point-min) (point-max) nil 'outline))
|
||||
((memq 'headings types)
|
||||
(org-fold-region (point-min) (point-max) nil 'outline)
|
||||
(org-cycle-hide-drawers 'all))
|
||||
((memq 'drawers types)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(while (re-search-forward org-drawer-regexp nil t)
|
||||
(let* ((pair (get-char-property-and-overlay (line-beginning-position)
|
||||
'invisible))
|
||||
(o (cdr-safe pair)))
|
||||
(if (overlayp o) (goto-char (overlay-end o))
|
||||
(pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(outline . ,o)
|
||||
(goto-char (overlay-end o))
|
||||
(delete-overlay o))
|
||||
(_ nil))))))))))
|
||||
(defsubst org-fold-show-all (&optional types)
|
||||
"Show all contents in the visible part of the buffer.
|
||||
By default, the function expands headings, blocks and drawers.
|
||||
When optional argument TYPES is a list of symbols among `blocks',
|
||||
`drawers' and `headings', to only expand one specific type."
|
||||
(interactive)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-show-all--text-properties types)
|
||||
(org-fold-show-all--overlays types)))
|
||||
(pcase type
|
||||
(`blocks 'block)
|
||||
(`drawers 'drawer)
|
||||
(`headings 'headline)
|
||||
(_ (error "Invalid type: %S" type))))))
|
||||
|
||||
(defun org-fold-flag-above-first-heading (&optional arg)
|
||||
"Hide from bob up to the first heading.
|
||||
|
@ -596,7 +463,7 @@ heading to appear."
|
|||
(interactive)
|
||||
(org-fold-show-children 1000))
|
||||
|
||||
(defun org-fold-show-branches-buffer--text-properties ()
|
||||
(defun org-fold-show-branches-buffer ()
|
||||
"Show all branches in the buffer."
|
||||
(org-fold-flag-above-first-heading)
|
||||
(org-fold-hide-sublevels 1)
|
||||
|
@ -605,20 +472,6 @@ heading to appear."
|
|||
(while (outline-get-next-sibling)
|
||||
(org-fold-show-branches)))
|
||||
(goto-char (point-min)))
|
||||
(defun org-fold-show-branches-buffer--overlays ()
|
||||
"Show all branches in the buffer."
|
||||
(org-fold-flag-above-first-heading)
|
||||
(outline-hide-sublevels 1)
|
||||
(unless (eobp)
|
||||
(outline-show-branches)
|
||||
(while (outline-get-next-sibling)
|
||||
(outline-show-branches)))
|
||||
(goto-char (point-min)))
|
||||
(defsubst org-fold-show-branches-buffer ()
|
||||
"Show all branches in the buffer."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-show-branches-buffer--text-properties)
|
||||
(org-fold-show-branches-buffer--overlays)))
|
||||
|
||||
;;;;; Blocks and drawers visibility
|
||||
|
||||
|
@ -652,18 +505,12 @@ Return a non-nil value when toggling is successful."
|
|||
;; at the block closing line.
|
||||
(unless (let ((eol (line-end-position)))
|
||||
(and (> eol start) (/= eol end)))
|
||||
(let* ((spec (if (eq org-fold-core-style 'text-properties)
|
||||
category
|
||||
(if (eq category 'block) 'org-hide-block 'outline)))
|
||||
(flag
|
||||
(cond ((eq force 'off) nil)
|
||||
(force t)
|
||||
((if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-folded-p start spec)
|
||||
(eq spec (get-char-property start 'invisible)))
|
||||
nil)
|
||||
(t t))))
|
||||
(org-fold-region start end flag spec))
|
||||
(org-fold-region start end
|
||||
(cond ((eq force 'off) nil)
|
||||
(force t)
|
||||
((org-fold-folded-p start category) nil)
|
||||
(t t))
|
||||
category)
|
||||
;; When the block is hidden away, make sure point is left in
|
||||
;; a visible part of the buffer.
|
||||
(when (invisible-p (max (1- (point)) (point-min)))
|
||||
|
@ -716,27 +563,7 @@ Return a non-nil value when toggling is successful."
|
|||
(end (point-max)))
|
||||
(org-fold--hide-drawers begin end)))
|
||||
|
||||
(defun org-fold--hide-drawers--overlays (begin end)
|
||||
"Hide all drawers between BEGIN and END."
|
||||
(save-excursion
|
||||
(goto-char begin)
|
||||
(while (and (< (point) end) (re-search-forward org-drawer-regexp end t))
|
||||
(let* ((pair (get-char-property-and-overlay (line-beginning-position)
|
||||
'invisible))
|
||||
(o (cdr-safe pair)))
|
||||
(if (overlayp o) (goto-char (overlay-end o)) ;invisible drawer
|
||||
(pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(outline . ,o) (goto-char (overlay-end o))) ;already folded
|
||||
(_
|
||||
(let* ((drawer (org-element-at-point))
|
||||
(type (org-element-type drawer)))
|
||||
(when (memq type '(drawer property-drawer))
|
||||
(org-fold-hide-drawer-toggle t nil drawer)
|
||||
;; Make sure to skip drawer entirely or we might flag it
|
||||
;; another time when matching its ending line with
|
||||
;; `org-drawer-regexp'.
|
||||
(goto-char (org-element-property :end drawer)))))))))))
|
||||
(defun org-fold--hide-drawers--text-properties (begin end)
|
||||
(defun org-fold--hide-drawers (begin end)
|
||||
"Hide all drawers between BEGIN and END."
|
||||
(save-excursion
|
||||
(goto-char begin)
|
||||
|
@ -753,11 +580,6 @@ Return a non-nil value when toggling is successful."
|
|||
;; another time when matching its ending line with
|
||||
;; `org-drawer-regexp'.
|
||||
(goto-char (org-element-property :end drawer))))))))
|
||||
(defun org-fold--hide-drawers (begin end)
|
||||
"Hide all drawers between BEGIN and END."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold--hide-drawers--text-properties begin end)
|
||||
(org-fold--hide-drawers--overlays begin end)))
|
||||
|
||||
(defun org-fold-hide-archived-subtrees (beg end)
|
||||
"Re-hide all archived subtrees after a visibility state change."
|
||||
|
@ -784,43 +606,10 @@ be shown."
|
|||
((cdr (assq key org-fold-show-context-detail)))
|
||||
(t (cdr (assq 'default org-fold-show-context-detail))))))
|
||||
|
||||
(defun org-fold-show-set-visibility--overlays (detail)
|
||||
"Set visibility around point according to DETAIL.
|
||||
DETAIL is either nil, `minimal', `local', `ancestors',
|
||||
`ancestors-full', `lineage', `tree', `canonical' or t. See
|
||||
`org-show-context-detail' for more information."
|
||||
;; Show current heading and possibly its entry, following headline
|
||||
;; or all children.
|
||||
(if (and (org-at-heading-p) (not (eq detail 'local)))
|
||||
(org-fold-heading nil)
|
||||
(org-fold-show-entry)
|
||||
;; If point is hidden within a drawer or a block, make sure to
|
||||
;; expose it.
|
||||
(dolist (o (overlays-at (point)))
|
||||
(when (memq (overlay-get o 'invisible) '(org-hide-block outline))
|
||||
(delete-overlay o)))
|
||||
(unless (org-before-first-heading-p)
|
||||
(org-with-limited-levels
|
||||
(cl-case detail
|
||||
((tree canonical t) (org-fold-show-children))
|
||||
((nil minimal ancestors ancestors-full))
|
||||
(t (save-excursion
|
||||
(outline-next-heading)
|
||||
(org-fold-heading nil)))))))
|
||||
;; Show whole subtree.
|
||||
(when (eq detail 'ancestors-full) (org-fold-show-subtree))
|
||||
;; Show all siblings.
|
||||
(when (eq detail 'lineage) (org-fold-show-siblings))
|
||||
;; Show ancestors, possibly with their children.
|
||||
(when (memq detail '(ancestors ancestors-full lineage tree canonical t))
|
||||
(save-excursion
|
||||
(while (org-up-heading-safe)
|
||||
(org-fold-heading nil)
|
||||
(when (memq detail '(canonical t)) (org-fold-show-entry))
|
||||
(when (memq detail '(tree canonical t)) (org-fold-show-children))))))
|
||||
|
||||
(defvar org-hide-emphasis-markers); Defined in org.el
|
||||
(defvar org-pretty-entities); Defined in org.el
|
||||
(defun org-fold-show-set-visibility--text-properties (detail)
|
||||
(defun org-fold-show-set-visibility (detail)
|
||||
"Set visibility around point according to DETAIL.
|
||||
DETAIL is either nil, `minimal', `local', `ancestors',
|
||||
`ancestors-full', `lineage', `tree', `canonical' or t. See
|
||||
|
@ -880,14 +669,6 @@ DETAIL is either nil, `minimal', `local', `ancestors',
|
|||
(org-fold-heading nil)
|
||||
(when (memq detail '(canonical t)) (org-fold-show-entry))
|
||||
(when (memq detail '(tree canonical t)) (org-fold-show-children))))))
|
||||
(defun org-fold-show-set-visibility (detail)
|
||||
"Set visibility around point according to DETAIL.
|
||||
DETAIL is either nil, `minimal', `local', `ancestors', `lineage',
|
||||
`tree', `canonical' or t. See `org-fold-show-context-detail' for more
|
||||
information."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-show-set-visibility--text-properties detail)
|
||||
(org-fold-show-set-visibility--overlays detail)))
|
||||
|
||||
(defun org-fold-reveal (&optional siblings)
|
||||
"Show current entry, hierarchy above it, and the following headline.
|
||||
|
@ -1065,70 +846,7 @@ This function is intended to be used as :fragile property of
|
|||
unfold?)))))
|
||||
|
||||
;; Catching user edits inside invisible text
|
||||
(defun org-fold-check-before-invisible-edit--overlays (kind)
|
||||
"Check if editing KIND is dangerous with invisible text around.
|
||||
The detailed reaction depends on the user option
|
||||
`org-fold-catch-invisible-edits'."
|
||||
;; First, try to get out of here as quickly as possible, to reduce overhead
|
||||
(when (and org-fold-catch-invisible-edits
|
||||
(or (not (boundp 'visible-mode)) (not visible-mode))
|
||||
(or (get-char-property (point) 'invisible)
|
||||
(get-char-property (max (point-min) (1- (point))) 'invisible)))
|
||||
;; OK, we need to take a closer look. Do not consider
|
||||
;; invisibility obtained through text properties (e.g., link
|
||||
;; fontification), as it cannot be toggled.
|
||||
(let* ((invisible-at-point
|
||||
(pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(,_ . ,(and (pred overlayp) o)) o)))
|
||||
(invisible-before-point
|
||||
(and (not (bobp))
|
||||
(pcase (get-char-property-and-overlay (1- (point)) 'invisible)
|
||||
(`(,_ . ,(and (pred overlayp) o)) o))))
|
||||
(border-and-ok-direction
|
||||
(or
|
||||
;; Check if we are acting predictably before invisible
|
||||
;; text.
|
||||
(and invisible-at-point (not invisible-before-point)
|
||||
(memq kind '(insert delete-backward)))
|
||||
;; Check if we are acting predictably after invisible text
|
||||
;; This works not well, and I have turned it off. It seems
|
||||
;; better to always show and stop after invisible text.
|
||||
;; (and (not invisible-at-point) invisible-before-point
|
||||
;; (memq kind '(insert delete)))
|
||||
)))
|
||||
(when (or invisible-at-point invisible-before-point)
|
||||
(when (eq org-fold-catch-invisible-edits 'error)
|
||||
(user-error "Editing in invisible areas is prohibited, make them visible first"))
|
||||
(if (and org-custom-properties-overlays
|
||||
(y-or-n-p "Display invisible properties in this buffer? "))
|
||||
(org-toggle-custom-properties-visibility)
|
||||
;; Make the area visible
|
||||
(save-excursion
|
||||
(when (and (not invisible-at-point) invisible-before-point)
|
||||
(goto-char
|
||||
(previous-single-char-property-change (point) 'invisible)))
|
||||
;; Remove whatever overlay is currently making yet-to-be
|
||||
;; edited text invisible. Also remove nested invisibility
|
||||
;; related overlays.
|
||||
(delete-overlay (or invisible-at-point invisible-before-point))
|
||||
(let ((origin (if invisible-at-point (point) (1- (point)))))
|
||||
(while (pcase (get-char-property-and-overlay origin 'invisible)
|
||||
(`(,_ . ,(and (pred overlayp) o))
|
||||
(delete-overlay o)
|
||||
t)))))
|
||||
(cond
|
||||
((eq org-fold-catch-invisible-edits 'show)
|
||||
;; That's it, we do the edit after showing
|
||||
(message
|
||||
"Unfolding invisible region around point before editing")
|
||||
(sit-for 1))
|
||||
((and (eq org-fold-catch-invisible-edits 'smart)
|
||||
border-and-ok-direction)
|
||||
(message "Unfolding invisible region around point before editing"))
|
||||
(t
|
||||
;; Don't do the edit, make the user repeat it in full visibility
|
||||
(user-error "Edit in invisible region aborted, repeat to confirm with text visible"))))))))
|
||||
(defun org-fold-check-before-invisible-edit--text-properties (kind)
|
||||
(defun org-fold-check-before-invisible-edit (kind)
|
||||
"Check if editing KIND is dangerous with invisible text around.
|
||||
The detailed reaction depends on the user option
|
||||
`org-fold-catch-invisible-edits'."
|
||||
|
@ -1179,14 +897,6 @@ The detailed reaction depends on the user option
|
|||
(t
|
||||
;; Don't do the edit, make the user repeat it in full visibility
|
||||
(user-error "Edit in invisible region aborted, repeat to confirm with text visible"))))))))
|
||||
(defsubst org-fold-check-before-invisible-edit (kind)
|
||||
"Check if editing KIND is dangerous with invisible text around.
|
||||
The detailed reaction depends on the user option
|
||||
`org-fold-catch-invisible-edits'."
|
||||
;; First, try to get out of here as quickly as possible, to reduce overhead
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-fold-check-before-invisible-edit--text-properties kind)
|
||||
(org-fold-check-before-invisible-edit--overlays kind)))
|
||||
|
||||
(provide 'org-fold)
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@ If the task has an end part, also demote it."
|
|||
(add-text-properties (match-beginning 3) (match-end 3)
|
||||
'(face org-inlinetask font-lock-fontified t)))))
|
||||
|
||||
(defun org-inlinetask-toggle-visibility--text-properties ()
|
||||
(defun org-inlinetask-toggle-visibility ()
|
||||
"Toggle visibility of inline task at point."
|
||||
(let ((end (save-excursion
|
||||
(org-inlinetask-goto-end)
|
||||
|
@ -320,26 +320,6 @@ If the task has an end part, also demote it."
|
|||
((org-fold-get-folding-spec 'headline (1+ start))
|
||||
(org-fold-region start end nil 'headline))
|
||||
(t (org-fold-region start end t 'headline)))))
|
||||
(defun org-inlinetask-toggle-visibility--overlays ()
|
||||
"Toggle visibility of inline task at point."
|
||||
(let ((end (save-excursion
|
||||
(org-inlinetask-goto-end)
|
||||
(if (bolp) (1- (point)) (point))))
|
||||
(start (save-excursion
|
||||
(org-inlinetask-goto-beginning)
|
||||
(point-at-eol))))
|
||||
(cond
|
||||
;; Nothing to show/hide.
|
||||
((= end start))
|
||||
;; Inlinetask was folded: expand it.
|
||||
((eq (get-char-property (1+ start) 'invisible) 'outline)
|
||||
(org-fold-region start end nil 'outline))
|
||||
(t (org-fold-region start end t 'outline)))))
|
||||
(defsubst org-inlinetask-toggle-visibility ()
|
||||
"Toggle visibility of inline task at point."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-inlinetask-toggle-visibility--text-properties)
|
||||
(org-inlinetask-toggle-visibility--overlays)))
|
||||
|
||||
(defun org-inlinetask-hide-tasks (state)
|
||||
"Hide inline tasks in buffer when STATE is `contents' or `children'.
|
||||
|
|
115
lisp/org-list.el
115
lisp/org-list.el
|
@ -1079,7 +1079,7 @@ It determines the number of whitespaces to append by looking at
|
|||
(replace-match spaces nil nil bullet 1)
|
||||
bullet))))
|
||||
|
||||
(defun org-list-swap-items--text-properties (beg-A beg-B struct)
|
||||
(defun org-list-swap-items (beg-A beg-B struct)
|
||||
"Swap item starting at BEG-A with item starting at BEG-B in STRUCT.
|
||||
|
||||
Blank lines at the end of items are left in place. Item
|
||||
|
@ -1102,11 +1102,23 @@ This function modifies STRUCT."
|
|||
(body-B (buffer-substring beg-B end-B-no-blank))
|
||||
(between-A-no-blank-and-B (buffer-substring end-A-no-blank beg-B))
|
||||
(sub-A (cons beg-A (org-list-get-subtree beg-A struct)))
|
||||
(sub-B (cons beg-B (org-list-get-subtree beg-B struct))))
|
||||
(sub-B (cons beg-B (org-list-get-subtree beg-B struct)))
|
||||
;; Store inner folds responsible for visibility status.
|
||||
(folds
|
||||
(cons
|
||||
(org-fold-core-get-regions :from beg-A :to end-A :relative t)
|
||||
(org-fold-core-get-regions :from beg-B :to end-B :relative t))))
|
||||
;; Clear up the folds.
|
||||
(org-fold-region beg-A end-B-no-blank nil)
|
||||
;; 1. Move effectively items in buffer.
|
||||
(goto-char beg-A)
|
||||
(delete-region beg-A end-B-no-blank)
|
||||
(insert (concat body-B between-A-no-blank-and-B body-A))
|
||||
;; Restore visibility status.
|
||||
(org-fold-core-regions (cdr folds) :relative beg-A)
|
||||
(org-fold-core-regions
|
||||
(car folds)
|
||||
:relative (+ beg-B (- size-B size-A (length between-A-no-blank-and-B))))
|
||||
;; 2. Now modify struct. No need to re-read the list, the
|
||||
;; transformation is just a shift of positions. Some special
|
||||
;; attention is required for items ending at END-A and END-B
|
||||
|
@ -1137,105 +1149,6 @@ This function modifies STRUCT."
|
|||
(setq struct (sort struct #'car-less-than-car))
|
||||
;; Return structure.
|
||||
struct))))
|
||||
(defun org-list-swap-items--overlays (beg-A beg-B struct)
|
||||
"Swap item starting at BEG-A with item starting at BEG-B in STRUCT.
|
||||
|
||||
Blank lines at the end of items are left in place. Item
|
||||
visibility is preserved. Return the new structure after the
|
||||
changes.
|
||||
|
||||
Assume BEG-A is lesser than BEG-B and that BEG-A and BEG-B belong
|
||||
to the same sub-list.
|
||||
|
||||
This function modifies STRUCT."
|
||||
(save-excursion
|
||||
(let* ((end-A-no-blank (org-list-get-item-end-before-blank beg-A struct))
|
||||
(end-B-no-blank (org-list-get-item-end-before-blank beg-B struct))
|
||||
(end-A (org-list-get-item-end beg-A struct))
|
||||
(end-B (org-list-get-item-end beg-B struct))
|
||||
(size-A (- end-A-no-blank beg-A))
|
||||
(size-B (- end-B-no-blank beg-B))
|
||||
(body-A (buffer-substring beg-A end-A-no-blank))
|
||||
(body-B (buffer-substring beg-B end-B-no-blank))
|
||||
(between-A-no-blank-and-B (buffer-substring end-A-no-blank beg-B))
|
||||
(sub-A (cons beg-A (org-list-get-subtree beg-A struct)))
|
||||
(sub-B (cons beg-B (org-list-get-subtree beg-B struct)))
|
||||
;; Store overlays responsible for visibility status. We
|
||||
;; also need to store their boundaries as they will be
|
||||
;; removed from buffer.
|
||||
(overlays
|
||||
(cons
|
||||
(delq nil
|
||||
(mapcar (lambda (o)
|
||||
(and (>= (overlay-start o) beg-A)
|
||||
(<= (overlay-end o) end-A)
|
||||
(list o (overlay-start o) (overlay-end o))))
|
||||
(overlays-in beg-A end-A)))
|
||||
(delq nil
|
||||
(mapcar (lambda (o)
|
||||
(and (>= (overlay-start o) beg-B)
|
||||
(<= (overlay-end o) end-B)
|
||||
(list o (overlay-start o) (overlay-end o))))
|
||||
(overlays-in beg-B end-B))))))
|
||||
;; 1. Move effectively items in buffer.
|
||||
(goto-char beg-A)
|
||||
(delete-region beg-A end-B-no-blank)
|
||||
(insert (concat body-B between-A-no-blank-and-B body-A))
|
||||
;; 2. Now modify struct. No need to re-read the list, the
|
||||
;; transformation is just a shift of positions. Some special
|
||||
;; attention is required for items ending at END-A and END-B
|
||||
;; as empty spaces are not moved there. In others words,
|
||||
;; item BEG-A will end with whitespaces that were at the end
|
||||
;; of BEG-B and the same applies to BEG-B.
|
||||
(dolist (e struct)
|
||||
(let ((pos (car e)))
|
||||
(cond
|
||||
((< pos beg-A))
|
||||
((memq pos sub-A)
|
||||
(let ((end-e (nth 6 e)))
|
||||
(setcar e (+ pos (- end-B-no-blank end-A-no-blank)))
|
||||
(setcar (nthcdr 6 e)
|
||||
(+ end-e (- end-B-no-blank end-A-no-blank)))
|
||||
(when (= end-e end-A) (setcar (nthcdr 6 e) end-B))))
|
||||
((memq pos sub-B)
|
||||
(let ((end-e (nth 6 e)))
|
||||
(setcar e (- (+ pos beg-A) beg-B))
|
||||
(setcar (nthcdr 6 e) (+ end-e (- beg-A beg-B)))
|
||||
(when (= end-e end-B)
|
||||
(setcar (nthcdr 6 e)
|
||||
(+ beg-A size-B (- end-A end-A-no-blank))))))
|
||||
((< pos beg-B)
|
||||
(let ((end-e (nth 6 e)))
|
||||
(setcar e (+ pos (- size-B size-A)))
|
||||
(setcar (nthcdr 6 e) (+ end-e (- size-B size-A))))))))
|
||||
(setq struct (sort struct #'car-less-than-car))
|
||||
;; Restore visibility status, by moving overlays to their new
|
||||
;; position.
|
||||
(dolist (ov (car overlays))
|
||||
(move-overlay
|
||||
(car ov)
|
||||
(+ (nth 1 ov) (- (+ beg-B (- size-B size-A)) beg-A))
|
||||
(+ (nth 2 ov) (- (+ beg-B (- size-B size-A)) beg-A))))
|
||||
(dolist (ov (cdr overlays))
|
||||
(move-overlay (car ov)
|
||||
(+ (nth 1 ov) (- beg-A beg-B))
|
||||
(+ (nth 2 ov) (- beg-A beg-B))))
|
||||
;; Return structure.
|
||||
struct)))
|
||||
(defsubst org-list-swap-items (beg-A beg-B struct)
|
||||
"Swap item starting at BEG-A with item starting at BEG-B in STRUCT.
|
||||
|
||||
Blank lines at the end of items are left in place. Item
|
||||
visibility is preserved. Return the new structure after the
|
||||
changes.
|
||||
|
||||
Assume BEG-A is lesser than BEG-B and that BEG-A and BEG-B belong
|
||||
to the same sub-list.
|
||||
|
||||
This function modifies STRUCT."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-list-swap-items--text-properties beg-A beg-B struct)
|
||||
(org-list-swap-items--overlays beg-A beg-B struct)))
|
||||
|
||||
(defun org-list-separating-blank-lines-number (pos struct prevs)
|
||||
"Return number of blank lines that should separate items in list.
|
||||
|
|
|
@ -1272,7 +1272,7 @@ the value in cadr."
|
|||
prop s)))
|
||||
|
||||
;; FIXME: move to org-fold?
|
||||
(defun org-invisible-p--text-properties (&optional pos folding-only)
|
||||
(defun org-invisible-p (&optional pos folding-only)
|
||||
"Non-nil if the character after POS is invisible.
|
||||
If POS is nil, use `point' instead. When optional argument
|
||||
FOLDING-ONLY is non-nil, only consider invisible parts due to
|
||||
|
@ -1282,25 +1282,6 @@ fontification."
|
|||
(cond ((not value) nil)
|
||||
(folding-only (org-fold-folded-p (or pos (point))))
|
||||
(t value))))
|
||||
(defun org-invisible-p--overlays (&optional pos folding-only)
|
||||
"Non-nil if the character after POS is invisible.
|
||||
If POS is nil, use `point' instead. When optional argument
|
||||
FOLDING-ONLY is non-nil, only consider invisible parts due to
|
||||
folding of a headline, a block or a drawer, i.e., not because of
|
||||
fontification."
|
||||
(let ((value (get-char-property (or pos (point)) 'invisible)))
|
||||
(cond ((not value) nil)
|
||||
(folding-only (memq value '(org-hide-block outline)))
|
||||
(t (and (invisible-p (or pos (point))) value)))))
|
||||
(defsubst org-invisible-p (&optional pos folding-only)
|
||||
"Non-nil if the character after POS is invisible.
|
||||
If POS is nil, use `point' instead. When optional argument
|
||||
FOLDING-ONLY is non-nil, only consider invisible parts due to
|
||||
folding of a headline, a block or a drawer, i.e., not because of
|
||||
fontification."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-invisible-p--text-properties pos folding-only)
|
||||
(org-invisible-p--overlays pos folding-only)))
|
||||
|
||||
(defun org-truly-invisible-p ()
|
||||
"Check if point is at a character currently not visible.
|
||||
|
@ -1324,37 +1305,17 @@ move it back by one char before doing this check."
|
|||
(and (org-invisible-p beg)
|
||||
(org-invisible-p (org-fold-next-visibility-change beg end)))))
|
||||
|
||||
(defun org-find-visible--overlays ()
|
||||
"Return closest visible buffer position, or `point-max'."
|
||||
(if (org-invisible-p)
|
||||
(next-single-char-property-change (point) 'invisible)
|
||||
(point)))
|
||||
(defun org-find-visible--text-properties ()
|
||||
(defun org-find-visible ()
|
||||
"Return closest visible buffer position, or `point-max'."
|
||||
(if (org-invisible-p)
|
||||
(org-fold-next-visibility-change (point))
|
||||
(point)))
|
||||
(defsubst org-find-visible ()
|
||||
"Return closest visible buffer position, or `point-max'."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-find-visible--text-properties)
|
||||
(org-find-visible--overlays)))
|
||||
|
||||
(defun org-find-invisible--overlays ()
|
||||
"Return closest invisible buffer position, or `point-max'."
|
||||
(if (org-invisible-p)
|
||||
(point)
|
||||
(next-single-char-property-change (point) 'invisible)))
|
||||
(defun org-find-invisible--text-properties ()
|
||||
(defun org-find-invisible ()
|
||||
"Return closest invisible buffer position, or `point-max'."
|
||||
(if (org-invisible-p)
|
||||
(point)
|
||||
(org-fold-next-visibility-change (point))))
|
||||
(defsubst org-find-invisible ()
|
||||
"Return closest invisible buffer position, or `point-max'."
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-find-invisible--text-properties)
|
||||
(org-find-invisible--overlays)))
|
||||
|
||||
|
||||
;;; Time
|
||||
|
|
227
lisp/org.el
227
lisp/org.el
|
@ -20357,33 +20357,7 @@ Stop at the first and last subheadings of a superior heading."
|
|||
(interactive "p")
|
||||
(org-forward-heading-same-level (if arg (- arg) -1) invisible-ok))
|
||||
|
||||
(defun org-next-visible-heading--overlays (arg)
|
||||
"Move to the next visible heading line.
|
||||
With ARG, repeats or can move backward if negative."
|
||||
(interactive "p")
|
||||
(let ((regexp (concat "^" (org-get-limited-outline-regexp))))
|
||||
(if (< arg 0)
|
||||
(beginning-of-line)
|
||||
(end-of-line))
|
||||
(while (and (< arg 0) (re-search-backward regexp nil :move))
|
||||
(unless (bobp)
|
||||
(while (pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(outline . ,o)
|
||||
(goto-char (overlay-start o))
|
||||
(re-search-backward regexp nil :move))
|
||||
(_ nil))))
|
||||
(cl-incf arg))
|
||||
(while (and (> arg 0) (re-search-forward regexp nil t))
|
||||
(while (pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(outline . ,o)
|
||||
(goto-char (overlay-end o))
|
||||
(re-search-forward regexp nil :move))
|
||||
(_
|
||||
(end-of-line)
|
||||
nil))) ;leave the loop
|
||||
(cl-decf arg))
|
||||
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
|
||||
(defun org-next-visible-heading--text-properties (arg)
|
||||
(defun org-next-visible-heading (arg)
|
||||
"Move to the next visible heading line.
|
||||
With ARG, repeats or can move backward if negative."
|
||||
(interactive "p")
|
||||
|
@ -20405,13 +20379,6 @@ With ARG, repeats or can move backward if negative."
|
|||
(end-of-line))
|
||||
(cl-decf arg))
|
||||
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
|
||||
(defun org-next-visible-heading (arg)
|
||||
"Move to the next visible heading line.
|
||||
With ARG, repeats or can move backward if negative."
|
||||
(interactive "p")
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org-next-visible-heading--text-properties arg)
|
||||
(org-next-visible-heading--overlays arg)))
|
||||
|
||||
(defun org-previous-visible-heading (arg)
|
||||
"Move to the previous visible heading.
|
||||
|
@ -20547,79 +20514,7 @@ Function may return a real element, or a pseudo-element with type
|
|||
(list :begin b :end e :parent p :post-blank 0 :post-affiliated b)))
|
||||
(_ e))))
|
||||
|
||||
(defun org--forward-paragraph-once--overlays ()
|
||||
"Move forward to end of paragraph or equivalent, once.
|
||||
See `org-forward-paragraph'."
|
||||
(interactive)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(skip-chars-forward " \t\n")
|
||||
(cond
|
||||
((eobp) nil)
|
||||
;; When inside a folded part, move out of it.
|
||||
((pcase (get-char-property-and-overlay (point) 'invisible)
|
||||
(`(,(or `outline `org-hide-block) . ,o)
|
||||
(goto-char (overlay-end o))
|
||||
(forward-line)
|
||||
t)
|
||||
(_ nil)))
|
||||
(t
|
||||
(let* ((element (org--paragraph-at-point))
|
||||
(type (org-element-type element))
|
||||
(contents-begin (org-element-property :contents-begin element))
|
||||
(end (org-element-property :end element))
|
||||
(post-affiliated (org-element-property :post-affiliated element)))
|
||||
(cond
|
||||
((eq type 'plain-list)
|
||||
(forward-char)
|
||||
(org--forward-paragraph-once))
|
||||
;; If the element is folded, skip it altogether.
|
||||
((pcase (org-with-point-at post-affiliated
|
||||
(get-char-property-and-overlay (line-end-position)
|
||||
'invisible))
|
||||
(`(,(or `outline `org-hide-block) . ,o)
|
||||
(goto-char (overlay-end o))
|
||||
(forward-line)
|
||||
t)
|
||||
(_ nil)))
|
||||
;; At a greater element, move inside.
|
||||
((and contents-begin
|
||||
(> contents-begin (point))
|
||||
(not (eq type 'paragraph)))
|
||||
(goto-char contents-begin)
|
||||
;; Items and footnote definitions contents may not start at
|
||||
;; the beginning of the line. In this case, skip until the
|
||||
;; next paragraph.
|
||||
(cond
|
||||
((not (bolp)) (org--forward-paragraph-once))
|
||||
((org-previous-line-empty-p) (forward-line -1))
|
||||
(t nil)))
|
||||
;; Move between empty lines in some blocks.
|
||||
((memq type '(comment-block example-block export-block src-block
|
||||
verse-block))
|
||||
(let ((contents-start
|
||||
(org-with-point-at post-affiliated
|
||||
(line-beginning-position 2))))
|
||||
(if (< (point) contents-start)
|
||||
(goto-char contents-start)
|
||||
(let ((contents-end
|
||||
(org-with-point-at end
|
||||
(skip-chars-backward " \t\n")
|
||||
(line-beginning-position))))
|
||||
(cond
|
||||
((>= (point) contents-end)
|
||||
(goto-char end)
|
||||
(skip-chars-backward " \t\n")
|
||||
(forward-line))
|
||||
((re-search-forward "^[ \t]*\n" contents-end :move)
|
||||
(forward-line -1))
|
||||
(t nil))))))
|
||||
(t
|
||||
;; Move to element's end.
|
||||
(goto-char end)
|
||||
(skip-chars-backward " \t\n")
|
||||
(forward-line))))))))
|
||||
(defun org--forward-paragraph-once--text-properties ()
|
||||
(defun org--forward-paragraph-once ()
|
||||
"Move forward to end of paragraph or equivalent, once.
|
||||
See `org-forward-paragraph'."
|
||||
(interactive)
|
||||
|
@ -20688,117 +20583,8 @@ See `org-forward-paragraph'."
|
|||
(goto-char end)
|
||||
(skip-chars-backward " \t\n")
|
||||
(forward-line))))))))
|
||||
(defun org--forward-paragraph-once ()
|
||||
"Move forward to end of paragraph or equivalent, once.
|
||||
See `org-forward-paragraph'."
|
||||
(interactive)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org--forward-paragraph-once--text-properties)
|
||||
(org--forward-paragraph-once--overlays)))
|
||||
|
||||
(defun org--backward-paragraph-once--overlays ()
|
||||
"Move backward to start of paragraph or equivalent, once.
|
||||
See `org-backward-paragraph'."
|
||||
(interactive)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(cond
|
||||
((bobp) nil)
|
||||
;; Blank lines at the beginning of the buffer.
|
||||
((and (org-match-line "^[ \t]*$")
|
||||
(save-excursion (skip-chars-backward " \t\n") (bobp)))
|
||||
(goto-char (point-min)))
|
||||
;; When inside a folded part, move out of it.
|
||||
((pcase (get-char-property-and-overlay (1- (point)) 'invisible)
|
||||
(`(,(or `outline `org-hide-block) . ,o)
|
||||
(goto-char (1- (overlay-start o)))
|
||||
(org--backward-paragraph-once)
|
||||
t)
|
||||
(_ nil)))
|
||||
(t
|
||||
(let* ((element (org--paragraph-at-point))
|
||||
(type (org-element-type element))
|
||||
(begin (org-element-property :begin element))
|
||||
(post-affiliated (org-element-property :post-affiliated element))
|
||||
(contents-end (org-element-property :contents-end element))
|
||||
(end (org-element-property :end element))
|
||||
(parent (org-element-property :parent element))
|
||||
(reach
|
||||
;; Move to the visible empty line above position P, or
|
||||
;; to position P. Return t.
|
||||
(lambda (p)
|
||||
(goto-char p)
|
||||
(when (and (org-previous-line-empty-p)
|
||||
(let ((end (line-end-position 0)))
|
||||
(or (= end (point-min))
|
||||
(not (org-invisible-p (1- end))))))
|
||||
(forward-line -1))
|
||||
t)))
|
||||
(cond
|
||||
;; Already at the beginning of an element.
|
||||
((= begin (point))
|
||||
(cond
|
||||
;; There is a blank line above. Move there.
|
||||
((and (org-previous-line-empty-p)
|
||||
(let ((lep (line-end-position 0)))
|
||||
;; When the first headline start at point 2, don't choke while
|
||||
;; checking with `org-invisible-p'.
|
||||
(or (= lep 1)
|
||||
(not (org-invisible-p (1- (line-end-position 0)))))))
|
||||
(forward-line -1))
|
||||
;; At the beginning of the first element within a greater
|
||||
;; element. Move to the beginning of the greater element.
|
||||
((and parent
|
||||
(not (eq 'section (org-element-type parent)))
|
||||
(= begin (org-element-property :contents-begin parent)))
|
||||
(funcall reach (org-element-property :begin parent)))
|
||||
;; Since we have to move anyway, find the beginning
|
||||
;; position of the element above.
|
||||
(t
|
||||
(forward-char -1)
|
||||
(org--backward-paragraph-once))))
|
||||
;; Skip paragraphs at the very beginning of footnote
|
||||
;; definitions or items.
|
||||
((and (eq type 'paragraph)
|
||||
(org-with-point-at begin (not (bolp))))
|
||||
(funcall reach (progn (goto-char begin) (line-beginning-position))))
|
||||
;; If the element is folded, skip it altogether.
|
||||
((org-with-point-at post-affiliated
|
||||
(org-invisible-p (line-end-position) t))
|
||||
(funcall reach begin))
|
||||
;; At the end of a greater element, move inside.
|
||||
((and contents-end
|
||||
(<= contents-end (point))
|
||||
(not (eq type 'paragraph)))
|
||||
(cond
|
||||
((memq type '(footnote-definition plain-list))
|
||||
(skip-chars-backward " \t\n")
|
||||
(org--backward-paragraph-once))
|
||||
((= contents-end (point))
|
||||
(forward-char -1)
|
||||
(org--backward-paragraph-once))
|
||||
(t
|
||||
(goto-char contents-end))))
|
||||
;; Move between empty lines in some blocks.
|
||||
((and (memq type '(comment-block example-block export-block src-block
|
||||
verse-block))
|
||||
(let ((contents-start
|
||||
(org-with-point-at post-affiliated
|
||||
(line-beginning-position 2))))
|
||||
(when (> (point) contents-start)
|
||||
(let ((contents-end
|
||||
(org-with-point-at end
|
||||
(skip-chars-backward " \t\n")
|
||||
(line-beginning-position))))
|
||||
(if (> (point) contents-end)
|
||||
(progn (goto-char contents-end) t)
|
||||
(skip-chars-backward " \t\n" begin)
|
||||
(re-search-backward "^[ \t]*\n" contents-start :move)
|
||||
t))))))
|
||||
;; Move to element's start.
|
||||
(t
|
||||
(funcall reach begin))))))))
|
||||
(defun org--backward-paragraph-once--text-properties ()
|
||||
(defun org--backward-paragraph-once ()
|
||||
"Move backward to start of paragraph or equivalent, once.
|
||||
See `org-backward-paragraph'."
|
||||
(interactive)
|
||||
|
@ -20893,13 +20679,6 @@ See `org-backward-paragraph'."
|
|||
;; Move to element's start.
|
||||
(t
|
||||
(funcall reach begin))))))))
|
||||
(defun org--backward-paragraph-once ()
|
||||
"Move backward to start of paragraph or equivalent, once.
|
||||
See `org-backward-paragraph'."
|
||||
(interactive)
|
||||
(if (eq org-fold-core-style 'text-properties)
|
||||
(org--backward-paragraph-once--text-properties)
|
||||
(org--backward-paragraph-once--overlays)))
|
||||
|
||||
(defun org-forward-element ()
|
||||
"Move forward by one element.
|
||||
|
|
|
@ -682,10 +682,10 @@ b. Item 2<point>"
|
|||
(search-backward "- item 1")
|
||||
(org-move-item-down)
|
||||
(forward-line)
|
||||
(list (org-invisible-p2)
|
||||
(list (org-fold-get-folding-spec)
|
||||
(progn
|
||||
(search-backward " body 2")
|
||||
(org-invisible-p2)))))))
|
||||
(org-fold-get-folding-spec)))))))
|
||||
;; Preserve children visibility.
|
||||
(org-test-with-temp-text "* Headline
|
||||
- item 1
|
||||
|
|
|
@ -4655,7 +4655,7 @@ Text.
|
|||
(push region regions))))
|
||||
regions)))))
|
||||
(should
|
||||
(equal '((63 . 82) (26 . 48))
|
||||
(equal '((26 . 48) (63 . 82))
|
||||
(let ((org-fold-core-style 'overlays))
|
||||
(org-test-with-temp-text
|
||||
"
|
||||
|
@ -4747,7 +4747,7 @@ Text.
|
|||
(org-drag-element-forward)
|
||||
(should
|
||||
(equal
|
||||
'((63 . 82) (26 . 48))
|
||||
'((26 . 48) (63 . 82))
|
||||
(mapcar (lambda (ov) (cons (overlay-start ov) (overlay-end ov)))
|
||||
(overlays-in (point-min) (point-max))))))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue