forked from mirrors/org-mode
Drawer visibility tooling mimics blocks'
* lisp/org.el (org-hide-drawer-toggle): New function. (org-flag-drawer): Assume either a parser drawer or buffer positions are provided. Remove unnecessary checks, since this is a low-level function. * testing/lisp/test-org.el (test-org/hide-drawer-toggle): New test. (test-org/flag-drawer): (test-org/show-set-visibility): Update tests.
This commit is contained in:
parent
e515a7cec8
commit
e6cd5a50d1
75
lisp/org.el
75
lisp/org.el
|
@ -6042,33 +6042,68 @@ a list of strings specifying which drawers should not be hidden."
|
||||||
;; `org-drawer-regexp'.
|
;; `org-drawer-regexp'.
|
||||||
(goto-char (org-element-property :end drawer))))))))))
|
(goto-char (org-element-property :end drawer))))))))))
|
||||||
|
|
||||||
(defun org-flag-drawer (flag &optional element beg end)
|
(defun org-flag-drawer (flag &optional drawer beg end)
|
||||||
"When FLAG is non-nil, hide the drawer we are at.
|
"When FLAG is non-nil, hide the drawer we are at.
|
||||||
Otherwise make it visible.
|
Otherwise make it visible.
|
||||||
|
|
||||||
When optional argument ELEMENT is a parsed drawer, as returned by
|
When optional argument DRAWER is a parsed drawer, as returned by
|
||||||
`org-element-at-point', hide or show that drawer instead.
|
`org-element-at-point', hide or show that drawer instead.
|
||||||
|
|
||||||
When buffer positions BEG and END are provided, hide or show that
|
When buffer positions BEG and END are provided, hide or show that
|
||||||
region as a drawer without further ado."
|
region as a drawer without further ado.
|
||||||
(if (and beg end) (org-flag-region beg end flag 'org-hide-drawer)
|
|
||||||
(let ((drawer (or element
|
The function assumes either DRAWER, or BEG and END are non-nil."
|
||||||
(and (save-excursion
|
(let ((beg (save-excursion
|
||||||
(beginning-of-line)
|
(goto-char (or beg
|
||||||
(looking-at-p org-drawer-regexp))
|
(org-element-property :post-affiliated drawer)))
|
||||||
(org-element-at-point)))))
|
(line-end-position)))
|
||||||
(when (memq (org-element-type drawer) '(drawer property-drawer))
|
(end (save-excursion
|
||||||
(let ((post (org-element-property :post-affiliated drawer)))
|
(goto-char (or end (org-element-property :end drawer)))
|
||||||
(org-flag-region
|
(skip-chars-backward " \t\n")
|
||||||
(save-excursion (goto-char post) (line-end-position))
|
(line-end-position))))
|
||||||
(save-excursion (goto-char (org-element-property :end drawer))
|
(org-flag-region beg end flag 'org-hide-drawer)))
|
||||||
(skip-chars-backward " \t\n")
|
|
||||||
(line-end-position))
|
(defun org-hide-drawer-toggle (&optional force no-error element)
|
||||||
flag 'org-hide-drawer)
|
"Toggle the visibility of the current drawer.
|
||||||
;; When the drawer is hidden away, make sure point lies in
|
|
||||||
;; a visible part of the buffer.
|
When optional argument FORCE is `off', make drawer visible. If
|
||||||
|
it is non-nil, hide it unconditionally. Throw an error when not
|
||||||
|
at a drawer, unless NO-ERROR is non-nil. When optional argument
|
||||||
|
ELEMENT is provided, consider it instead of the current drawer.
|
||||||
|
|
||||||
|
Return a non-nil value when toggling is successful."
|
||||||
|
(interactive)
|
||||||
|
(let ((element (or element (org-element-at-point))))
|
||||||
|
(cond
|
||||||
|
((memq (org-element-type element) '(drawer property-drawer))
|
||||||
|
(let* ((post (org-element-property :post-affiliated element))
|
||||||
|
(start (save-excursion
|
||||||
|
(goto-char post)
|
||||||
|
(line-end-position)))
|
||||||
|
(end (save-excursion
|
||||||
|
(goto-char (org-element-property :end element))
|
||||||
|
(skip-chars-backward " \t\n")
|
||||||
|
(line-end-position))))
|
||||||
|
;; Do nothing when not before or at the block opening line or at
|
||||||
|
;; the block closing line.
|
||||||
|
(unless (let ((eol (line-end-position)))
|
||||||
|
(and (> eol start) (/= eol end)))
|
||||||
|
(let ((flag
|
||||||
|
(cond ((eq force 'off) nil)
|
||||||
|
(force t)
|
||||||
|
((eq (get-char-property start 'invisible)
|
||||||
|
'org-hide-drawer)
|
||||||
|
nil)
|
||||||
|
(t t))))
|
||||||
|
(org-flag-drawer flag element))
|
||||||
|
;; When the drawer is hidden away, make sure point is left
|
||||||
|
;; in a visible part of the buffer.
|
||||||
(when (invisible-p (max (1- (point)) (point-min)))
|
(when (invisible-p (max (1- (point)) (point-min)))
|
||||||
(goto-char post)))))))
|
(goto-char post))
|
||||||
|
;; Signal success.
|
||||||
|
t)))
|
||||||
|
(no-error nil)
|
||||||
|
(t (user-error "Not at a drawer")))))
|
||||||
|
|
||||||
;;;; Visibility cycling
|
;;;; Visibility cycling
|
||||||
|
|
||||||
|
|
|
@ -7240,15 +7240,24 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
|
||||||
;; Hide drawer.
|
;; Hide drawer.
|
||||||
(should
|
(should
|
||||||
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
||||||
(org-flag-drawer t)
|
(org-flag-drawer t (org-element-at-point))
|
||||||
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
||||||
|
(org-flag-drawer t nil (point-min) (point-max))
|
||||||
(get-char-property (line-end-position) 'invisible)))
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
;; Show drawer.
|
;; Show drawer.
|
||||||
(should-not
|
(should-not
|
||||||
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
||||||
(org-flag-drawer t)
|
(org-flag-drawer t nil (point-min) (point-max))
|
||||||
(org-flag-drawer nil)
|
(org-flag-drawer nil nil (point-min) (point-max))
|
||||||
(get-char-property (line-end-position) 'invisible)))
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
;; Test optional argument.
|
(should-not
|
||||||
|
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
||||||
|
(org-flag-drawer t nil (point-min) (point-max))
|
||||||
|
(org-flag-drawer nil (org-element-at-point))
|
||||||
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
|
;; Hide drawer remotely.
|
||||||
(should
|
(should
|
||||||
(org-test-with-temp-text "Text\n:D1:\nc1\n:END:\n\n:D2:\nc2\n:END:"
|
(org-test-with-temp-text "Text\n:D1:\nc1\n:END:\n\n:D2:\nc2\n:END:"
|
||||||
(let ((drawer (save-excursion (search-forward ":D2")
|
(let ((drawer (save-excursion (search-forward ":D2")
|
||||||
|
@ -7261,32 +7270,46 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
|
||||||
(let ((drawer (save-excursion (search-forward ":D2")
|
(let ((drawer (save-excursion (search-forward ":D2")
|
||||||
(org-element-at-point))))
|
(org-element-at-point))))
|
||||||
(org-flag-drawer t drawer)
|
(org-flag-drawer t drawer)
|
||||||
(get-char-property (line-end-position) 'invisible))))
|
(get-char-property (line-end-position) 'invisible)))))
|
||||||
;; Do not hide fake drawers.
|
|
||||||
(should-not
|
(ert-deftest test-org/hide-drawer-toggle ()
|
||||||
(org-test-with-temp-text "#+begin_example\n:D:\nc\n:END:\n#+end_example"
|
"Test `org-hide-drawer-toggle' specifications."
|
||||||
(forward-line 1)
|
;; Error when not at a drawer.
|
||||||
(org-flag-drawer t)
|
(should-error
|
||||||
|
(org-test-with-temp-text ":fake-drawer:\ncontents"
|
||||||
|
(org-hide-drawer-toggle 'off)
|
||||||
(get-char-property (line-end-position) 'invisible)))
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
;; Do not hide incomplete drawers.
|
(should-error
|
||||||
(should-not
|
(org-test-with-temp-text
|
||||||
(org-test-with-temp-text ":D:\nparagraph"
|
"#+begin_example\n<point>:D:\nc\n:END:\n#+end_example"
|
||||||
(forward-line 1)
|
(org-hide-drawer-toggle t)))
|
||||||
(org-flag-drawer t)
|
;; Hide drawer.
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text ":drawer:\ncontents\n:end:"
|
||||||
|
(org-hide-drawer-toggle)
|
||||||
(get-char-property (line-end-position) 'invisible)))
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
;; Do not hide drawers when called from final blank lines.
|
;; Show drawer unconditionally when optional argument is `off'.
|
||||||
(should-not
|
(should-not
|
||||||
(org-test-with-temp-text ":DRAWER:\nA\n:END:\n\n"
|
(org-test-with-temp-text ":drawer:\ncontents\n:end:"
|
||||||
(goto-char (point-max))
|
(org-hide-drawer-toggle)
|
||||||
(org-flag-drawer t)
|
(org-hide-drawer-toggle 'off)
|
||||||
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
|
;; Hide drawer unconditionally when optional argument is non-nil.
|
||||||
|
(should
|
||||||
|
(org-test-with-temp-text ":drawer:\ncontents\n:end:"
|
||||||
|
(org-hide-drawer-toggle t)
|
||||||
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
|
;; Do not hide drawer when called from final blank lines.
|
||||||
|
(should-not
|
||||||
|
(org-test-with-temp-text ":drawer:\ncontents\n:end:\n\n<point>"
|
||||||
|
(org-hide-drawer-toggle)
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(get-char-property (line-end-position) 'invisible)))
|
(get-char-property (line-end-position) 'invisible)))
|
||||||
;; Don't leave point in an invisible part of the buffer when hiding
|
;; Don't leave point in an invisible part of the buffer when hiding
|
||||||
;; a drawer away.
|
;; a drawer away.
|
||||||
(should-not
|
(should-not
|
||||||
(org-test-with-temp-text ":DRAWER:\ncontents\n:END:"
|
(org-test-with-temp-text ":drawer:\ncontents\n<point>:end:"
|
||||||
(goto-char (point-max))
|
(org-hide-drawer-toggle)
|
||||||
(org-flag-drawer t)
|
|
||||||
(get-char-property (point) 'invisible))))
|
(get-char-property (point) 'invisible))))
|
||||||
|
|
||||||
(ert-deftest test-org/hide-block-toggle ()
|
(ert-deftest test-org/hide-block-toggle ()
|
||||||
|
@ -7406,14 +7429,14 @@ CLOCK: [2012-03-29 Thu 10:00]--[2012-03-29 Thu 16:40] => 6:40"
|
||||||
(org-invisible-p2)))
|
(org-invisible-p2)))
|
||||||
(should-not
|
(should-not
|
||||||
(org-test-with-temp-text ":DRAWER:\nText\n:END:"
|
(org-test-with-temp-text ":DRAWER:\nText\n:END:"
|
||||||
(org-flag-drawer t)
|
(org-hide-drawer-toggle)
|
||||||
(search-forward "Text")
|
(search-forward "Text")
|
||||||
(org-show-set-visibility 'minimal)
|
(org-show-set-visibility 'minimal)
|
||||||
(org-invisible-p2)))
|
(org-invisible-p2)))
|
||||||
(should-not
|
(should-not
|
||||||
(org-test-with-temp-text
|
(org-test-with-temp-text
|
||||||
"#+BEGIN_QUOTE\n<point>:DRAWER:\nText\n:END:\n#+END_QUOTE"
|
"#+BEGIN_QUOTE\n<point>:DRAWER:\nText\n:END:\n#+END_QUOTE"
|
||||||
(org-flag-drawer t)
|
(org-hide-drawer-toggle)
|
||||||
(forward-line -1)
|
(forward-line -1)
|
||||||
(org-hide-block-toggle)
|
(org-hide-block-toggle)
|
||||||
(search-forward "Text")
|
(search-forward "Text")
|
||||||
|
|
Loading…
Reference in New Issue