diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-06-06 16:51:44 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2020-06-06 17:01:21 +0200 |
commit | 1aa095ccf18f5349874d736aee05130c9ffeec16 (patch) | |
tree | fbc700708af52719408c460c0531b24e1754570d | |
parent | 8fd24c0a539531023be2e5d1df6b2438be8f78ba (diff) | |
download | org-mode-1aa095ccf18f5349874d736aee05130c9ffeec16.tar.gz |
Fix drawer invisibility
* lisp/org.el (org-cycle-hide-drawers): Move back from "org-compat.el"
(org-cycle-hook):
(org-show-entry):
(org-set-startup-visibility):
(org-clean-visibility-after-subtree-move):
(org-sort-entries): Use `org-cycle-hide-drawers'.
(org-log-beginning):
(org--hide-wrapper-toggle):
(org-hide-drawer-all): Use `outline' invisibility spec for drawers.
(org-show-all): Rewrite taking into account drawers now have the same
invisibility spec as headlines.
(org-overview):
(org-content):
(org-tree-to-indirect-buffer): Use fast arguments for `org-show-all'.
(org-mode): Remove `org-hide-drawer' invisibility spec.
* lisp/org-compat.el (org-flag-drawer): Use `outline' for drawer
invisibility.
(org-cycle-hide-drawers): move back to "org.el".
* lisp/org-clock.el (org-clock-find-position): Use `outline' for
invisibility spec.
* lisp/org-agenda.el (org-agenda-show-and-scroll-up): Use
`org-cycle-hide-drawers'.
-rw-r--r-- | lisp/org-agenda.el | 2 | ||||
-rw-r--r-- | lisp/org-clock.el | 4 | ||||
-rw-r--r-- | lisp/org-compat.el | 23 | ||||
-rw-r--r-- | lisp/org.el | 113 |
4 files changed, 68 insertions, 74 deletions
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index f07c3b8..9fbeb2a 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -9093,7 +9093,7 @@ fold drawers." (ignore-errors (scroll-up))) (org-agenda-goto t) (org-show-entry) - (if arg (org-cycle-hide-property-drawers 'children) + (if arg (org-cycle-hide-drawers 'children) (org-with-wide-buffer (narrow-to-region (org-entry-beginning-position) (org-entry-end-position)) diff --git a/lisp/org-clock.el b/lisp/org-clock.el index fa53f02..b184fc3 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -1578,7 +1578,7 @@ line and position cursor in that line." (insert ":" drawer ":\n:END:\n") (org-indent-region beg (point)) (org-flag-region - (line-end-position -1) (1- (point)) t 'org-hide-drawer) + (line-end-position -1) (1- (point)) t 'outline) (forward-line -1)))) ;; When a clock drawer needs to be created because of the ;; number of clock items or simply if it is missing, collect @@ -1603,7 +1603,7 @@ line and position cursor in that line." (let ((end (point-marker))) (goto-char beg) (save-excursion (insert ":" drawer ":\n")) - (org-flag-region (line-end-position) (1- end) t 'org-hide-drawer) + (org-flag-region (line-end-position) (1- end) t 'outline) (org-indent-region (point) end) (forward-line) (unless org-log-states-order-reversed diff --git a/lisp/org-compat.el b/lisp/org-compat.el index 635a38d..5953f89 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -47,7 +47,6 @@ (declare-function org-get-heading "org" (&optional no-tags no-todo no-priority no-comment)) (declare-function org-get-tags "org" (&optional pos local)) (declare-function org-hide-block-toggle "org" (&optional force no-error element)) -(declare-function org-hide-drawer-all "org" ()) (declare-function org-link-display-format "ol" (s)) (declare-function org-link-set-parameters "ol" (type &rest rest)) (declare-function org-log-into-drawer "org" ()) @@ -645,7 +644,7 @@ When optional argument ELEMENT is a parsed drawer, as returned by When buffer positions BEG and END are provided, hide or show that region as a drawer without further ado." (declare (obsolete "use `org-hide-drawer-toggle' instead." "Org 9.4")) - (if (and beg end) (org-flag-region beg end flag 'org-hide-drawer) + (if (and beg end) (org-flag-region beg end flag 'outline) (let ((drawer (or element (and (save-excursion @@ -659,30 +658,12 @@ region as a drawer without further ado." (save-excursion (goto-char (org-element-property :end drawer)) (skip-chars-backward " \t\n") (line-end-position)) - flag 'org-hide-drawer) + flag 'outline) ;; When the drawer is hidden away, make sure point lies in ;; a visible part of the buffer. (when (invisible-p (max (1- (point)) (point-min))) (goto-char post))))))) -(defun org-cycle-hide-drawers (state &optional _) - "Re-hide all drawers after a visibility state change. -STATE should be one of the symbols listed in the docstring of -`org-cycle-hook'." - (declare (obsolete "use `org-hide-drawer-all' instead." "Org 9.4")) - (when (and (derived-mode-p 'org-mode) - (not (memq state '(overview folded contents)))) - (save-excursion - (let* ((globalp (eq state 'all)) - (beg (if globalp (point-min) (point))) - (end (if globalp (point-max) - (if (eq state 'children) - (save-excursion (outline-next-heading) (point)) - (org-end-of-subtree t))))) - (save-restriction - (narrow-to-region beg end) - (org-hide-drawer-all)))))) - (defun org-hide-block-toggle-maybe () "Toggle visibility of block at point. Unlike to `org-hide-block-toggle', this function does not throw diff --git a/lisp/org.el b/lisp/org.el index c04bbd6..e5cea04 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -1538,7 +1538,7 @@ the values `folded', `children', or `subtree'." :type 'hook) (defcustom org-cycle-hook '(org-cycle-hide-archived-subtrees - org-cycle-hide-property-drawers + org-cycle-hide-drawers org-cycle-show-empty-lines org-optimize-window-after-visibility-change) "Hook that is run after `org-cycle' has changed the buffer visibility. @@ -4789,7 +4789,6 @@ The following commands are available: (org-install-agenda-files-menu) (when org-link-descriptive (add-to-invisibility-spec '(org-link))) (add-to-invisibility-spec '(org-hide-block . t)) - (add-to-invisibility-spec '(org-hide-drawer . t)) (setq-local outline-regexp org-outline-regexp) (setq-local outline-level 'org-outline-level) (setq bidi-paragraph-direction 'left-to-right) @@ -5986,7 +5985,7 @@ Show the heading too, if it is currently invisible." (point-max))) nil 'outline) - (org-cycle-hide-property-drawers 'children)))) + (org-cycle-hide-drawers 'children)))) (defun org-show-children (&optional level) "Show all direct subheadings of this heading. @@ -6063,13 +6062,11 @@ 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 (cond ((eq category 'block) 'org-hide-block) - ((eq type 'property-drawer) 'outline) - (t 'org-hide-drawer))) + (let* ((spec (if (eq category 'block) 'org-hide-block 'outline)) (flag (cond ((eq force 'off) nil) (force t) - ((eq (get-char-property start 'invisible) spec) nil) + ((eq spec (get-char-property start 'invisible)) nil) (t t)))) (org-flag-region start end flag spec)) ;; When the block is hidden away, make sure point is left in @@ -6118,26 +6115,26 @@ Return a non-nil value when toggling is successful." (defun org-hide-drawer-all () "Fold all drawers in the current buffer." - (org-show-all '(drawers)) (save-excursion (goto-char (point-min)) (while (re-search-forward org-drawer-regexp nil t) - (let* ((drawer (org-element-at-point)) - (type (org-element-type drawer))) - (when (memq type '(drawer property-drawer)) - ;; We are sure regular drawers are unfolded because of - ;; `org-show-all' call above. However, property drawers may - ;; be folded, or in a folded headline. In that case, do not - ;; re-hide it. - (unless (and (eq type 'property-drawer) - (eq 'outline (get-char-property (point) 'invisible))) - (org-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-cycle-hide-property-drawers (state) + (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-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-cycle-hide-drawers (state) "Re-hide all drawers after a visibility state change. STATE should be one of the symbols listed in the docstring of `org-cycle-hook'." @@ -6147,21 +6144,20 @@ STATE should be one of the symbols listed in the docstring of (beg (if global? (point-min) (line-beginning-position))) (end (cond (global? (point-max)) ((eq state 'children) (org-entry-end-position)) - (t (save-excursion (org-end-of-subtree t)))))) + (t (save-excursion (org-end-of-subtree t t)))))) (org-with-point-at beg - (while (re-search-forward org-property-start-re end t) + (while (re-search-forward org-drawer-regexp end t) (pcase (get-char-property-and-overlay (point) 'invisible) ;; Do not fold already folded drawers. (`(outline . ,o) (goto-char (overlay-end o))) (_ - (let ((start (match-end 0))) - (when (org-at-property-drawer-p) - (let* ((case-fold-search t) - (end (re-search-forward org-property-end-re))) - ;; Property drawers use `outline' invisibility spec - ;; so they can be swallowed once we hide the - ;; outline. - (org-flag-region start end t 'outline))))))))))) + (let ((drawer (org-element-at-point))) + (when (memq (org-element-type drawer) '(drawer property-drawer)) + (org-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))))))))))) ;;;; Visibility cycling @@ -6176,13 +6172,31 @@ 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) - (dolist (type (or types '(blocks drawers headings))) - (org-flag-region (point-min) (point-max) nil - (pcase type - (`blocks 'org-hide-block) - (`drawers 'org-hide-drawer) - (`headings 'outline) - (_ (error "Invalid type: %S" type)))))) + (let ((types (or types '(blocks drawers headings)))) + (when (memq 'blocks types) + (org-flag-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-flag-region (point-min) (point-max) nil 'outline)) + ((memq 'headings types) + (org-flag-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)))))))))) ;;;###autoload (defun org-cycle (&optional arg) @@ -6511,7 +6525,7 @@ With a numeric prefix, show all headlines up to that level." (when org-hide-block-startup (org-hide-block-all)) (org-set-visibility-according-to-property) (org-cycle-hide-archived-subtrees 'all) - (org-cycle-hide-property-drawers 'all) + (org-cycle-hide-drawers 'all) (org-cycle-show-empty-lines t))) (defun org-set-visibility-according-to-property () @@ -6545,7 +6559,7 @@ With a numeric prefix, show all headlines up to that level." (defun org-overview () "Switch to overview mode, showing only top-level headlines." (interactive) - (org-show-all '(headings)) + (org-show-all '(headings drawers)) (save-excursion (goto-char (point-min)) (when (re-search-forward org-outline-regexp-bol nil t) @@ -6563,7 +6577,7 @@ With a numeric prefix, show all headlines up to that level." "Show all headlines in the buffer, like a table of contents. With numerical argument N, show content up to level N." (interactive "p") - (org-show-all '(headings)) + (org-show-all '(headings drawers)) (save-excursion (goto-char (point-max)) (let ((regexp (if (and (wholenump arg) (> arg 0)) @@ -6612,7 +6626,7 @@ This function is the default value of the hook `org-cycle-hook'." (when (and (not (org-invisible-p)) (org-invisible-p (line-end-position))) (outline-hide-entry)))) - (org-cycle-hide-property-drawers 'all) + (org-cycle-hide-drawers 'all) (org-cycle-show-empty-lines 'overview))))) (defun org-cycle-show-empty-lines (state) @@ -6798,7 +6812,7 @@ frame is not changed." (pop-to-buffer ibuf)) (t (error "Invalid value"))) (narrow-to-region beg end) - (org-show-all '(headings blocks)) + (org-show-all '(headings drawers blocks)) (goto-char pos) (run-hook-with-args 'org-cycle-hook 'all) (and (window-live-p cwin) (select-window cwin)))) @@ -8121,7 +8135,7 @@ function is being called interactively." (setq end (point-max)) (setq what "top-level") (goto-char start) - (org-show-all '(headings blocks)))) + (org-show-all '(headings drawers blocks)))) (setq beg (point)) (when (>= beg end) (goto-char start) (user-error "Nothing to sort")) @@ -8258,7 +8272,7 @@ function is being called interactively." "(empty for default `sort-subr' predicate): ") 'allow-empty)))) ((member dcst '(?p ?t ?s ?d ?c ?k)) '<)))) - (org-cycle-hide-property-drawers 'all) + (org-cycle-hide-drawers 'all) (when restore-clock? (move-marker org-clock-marker (1+ (next-single-property-change @@ -10722,8 +10736,7 @@ narrowing." (let ((beg (point))) (insert ":" drawer ":\n:END:\n") (org-indent-region beg (point)) - (org-flag-region - (line-end-position -1) (1- (point)) t 'org-hide-drawer)) + (org-flag-region (line-end-position -1) (1- (point)) t 'outline)) (end-of-line -1))))) (t (org-end-of-meta-data org-log-state-notes-insert-after-drawers) |