Skip to content

Commit

Permalink
Use the full org-fold-core API when org-fold-core-style' is overlays'
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yantar92 committed Aug 13, 2022
1 parent 01d84f2 commit b8a0ddf
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 845 deletions.
15 changes: 1 addition & 14 deletions lisp/ol.el
Original file line number Diff line number Diff line change
Expand Up @@ -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?)
Expand Down
47 changes: 2 additions & 45 deletions lisp/org-cycle.el
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
Expand All @@ -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.")
Expand Down
103 changes: 21 additions & 82 deletions lisp/org-element.el
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand All @@ -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)))
Expand All @@ -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)

Expand Down
Loading

0 comments on commit b8a0ddf

Please sign in to comment.