forked from mirrors/org-mode
org-element: Change return value for element at point in some corner cases
* lisp/org-element.el (org-element-at-point): When point is before any element, in the first blank lines of the buffer, return nil. When point is within blank lines just after a headline, return that headline. (org-element-context): Return nil when point is within the blank at the beginning of the buffer. * testing/lisp/test-org-element.el: Add tests.
This commit is contained in:
parent
c300a50402
commit
13e49a6385
|
@ -4529,7 +4529,8 @@ As a special case, if point is at the very beginning of a list or
|
||||||
sub-list, returned element will be that list instead of the first
|
sub-list, returned element will be that list instead of the first
|
||||||
item. In the same way, if point is at the beginning of the first
|
item. In the same way, if point is at the beginning of the first
|
||||||
row of a table, returned element will be the table instead of the
|
row of a table, returned element will be the table instead of the
|
||||||
first row.
|
first row. Also, if point is within the first blank lines of
|
||||||
|
a buffer, return nil.
|
||||||
|
|
||||||
If optional argument KEEP-TRAIL is non-nil, the function returns
|
If optional argument KEEP-TRAIL is non-nil, the function returns
|
||||||
a list of of elements leading to element at point. The list's
|
a list of of elements leading to element at point. The list's
|
||||||
|
@ -4545,25 +4546,36 @@ first element of current section."
|
||||||
(beginning-of-line)
|
(beginning-of-line)
|
||||||
(if (not keep-trail) (org-element-headline-parser (point-max) t)
|
(if (not keep-trail) (org-element-headline-parser (point-max) t)
|
||||||
(list (org-element-headline-parser (point-max) t))))
|
(list (org-element-headline-parser (point-max) t))))
|
||||||
;; Otherwise move at the beginning of the section containing
|
;; Otherwise try to move at the beginning of the section
|
||||||
;; point.
|
;; containing point.
|
||||||
(let ((origin (point))
|
(let ((origin (point))
|
||||||
(end (save-excursion
|
(end (save-excursion
|
||||||
(org-with-limited-levels (outline-next-heading)) (point)))
|
(org-with-limited-levels (outline-next-heading)) (point)))
|
||||||
element type special-flag trail struct prevs parent)
|
element type special-flag trail struct prevs parent)
|
||||||
(org-with-limited-levels
|
(org-with-limited-levels
|
||||||
(if (org-with-limited-levels (org-before-first-heading-p))
|
(if (org-before-first-heading-p) (goto-char (point-min))
|
||||||
(goto-char (point-min))
|
|
||||||
(org-back-to-heading)
|
(org-back-to-heading)
|
||||||
(forward-line)))
|
(forward-line)))
|
||||||
(org-skip-whitespace)
|
(skip-chars-forward " \r\t\n" origin)
|
||||||
(beginning-of-line)
|
(beginning-of-line)
|
||||||
|
(if (looking-at "[ \t]*$")
|
||||||
|
;; If point is still at a blank line, we didn't reach
|
||||||
|
;; section beginning. it means we started either at the
|
||||||
|
;; beginning of the buffer, before any element, or in the
|
||||||
|
;; blank area after an headline. In the first case, return
|
||||||
|
;; a dummy `org-data' element. In the second case, return
|
||||||
|
;; the headline.
|
||||||
|
(progn (skip-chars-backward " \r\t\n")
|
||||||
|
(cond ((bobp) nil)
|
||||||
|
(keep-trail
|
||||||
|
(list (org-element-headline-parser (point-max) t)))
|
||||||
|
(t (org-element-headline-parser (point-max) t))))
|
||||||
;; Parse successively each element, skipping those ending
|
;; Parse successively each element, skipping those ending
|
||||||
;; before original position.
|
;; before original position.
|
||||||
(catch 'exit
|
(catch 'exit
|
||||||
(while t
|
(while t
|
||||||
(setq element
|
(setq element (org-element--current-element
|
||||||
(org-element--current-element end 'element special-flag struct)
|
end 'element special-flag struct)
|
||||||
type (car element))
|
type (car element))
|
||||||
(org-element-put-property element :parent parent)
|
(org-element-put-property element :parent parent)
|
||||||
(when keep-trail (push element trail))
|
(when keep-trail (push element trail))
|
||||||
|
@ -4611,7 +4623,7 @@ first element of current section."
|
||||||
(table (setq special-flag 'table-row struct nil))
|
(table (setq special-flag 'table-row struct nil))
|
||||||
(otherwise (setq special-flag nil struct nil)))
|
(otherwise (setq special-flag nil struct nil)))
|
||||||
(setq end cend)
|
(setq end cend)
|
||||||
(goto-char cbeg)))))))))))
|
(goto-char cbeg))))))))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun org-element-context (&optional element)
|
(defun org-element-context (&optional element)
|
||||||
|
@ -4619,12 +4631,13 @@ first element of current section."
|
||||||
|
|
||||||
Return value is a list like (TYPE PROPS) where TYPE is the type
|
Return value is a list like (TYPE PROPS) where TYPE is the type
|
||||||
of the element or object and PROPS a plist of properties
|
of the element or object and PROPS a plist of properties
|
||||||
associated to it.
|
associated to it, or nil if point is within the first blank lines
|
||||||
|
of the buffer.
|
||||||
|
|
||||||
Possible types are defined in `org-element-all-elements' and
|
Possible types are defined in `org-element-all-elements' and
|
||||||
`org-element-all-objects'. Properties depend on element or
|
`org-element-all-objects'. Properties depend on element or
|
||||||
object type, but always include :begin, :end, :parent
|
object type, but always include `:begin', `:end', `:parent' and
|
||||||
and :post-blank properties.
|
`:post-blank' properties.
|
||||||
|
|
||||||
Optional argument ELEMENT, when non-nil, is the closest element
|
Optional argument ELEMENT, when non-nil, is the closest element
|
||||||
containing point, as returned by `org-element-at-point'.
|
containing point, as returned by `org-element-at-point'.
|
||||||
|
@ -4632,12 +4645,16 @@ Providing it allows for quicker computation."
|
||||||
(org-with-wide-buffer
|
(org-with-wide-buffer
|
||||||
(let* ((origin (point))
|
(let* ((origin (point))
|
||||||
(element (or element (org-element-at-point)))
|
(element (or element (org-element-at-point)))
|
||||||
(type (car element))
|
(type (org-element-type element))
|
||||||
end)
|
end)
|
||||||
|
(cond
|
||||||
|
;; If point is within blank lines at the beginning of the
|
||||||
|
;; buffer, return nil.
|
||||||
|
((not element) nil)
|
||||||
;; Check if point is inside an element containing objects or at
|
;; Check if point is inside an element containing objects or at
|
||||||
;; a secondary string. In that case, move to beginning of the
|
;; a secondary string. In that case, move to beginning of the
|
||||||
;; element or secondary string and set END to the other side.
|
;; element or secondary string and set END to the other side.
|
||||||
(if (not (or (let ((post (org-element-property :post-affiliated element)))
|
((not (or (let ((post (org-element-property :post-affiliated element)))
|
||||||
(and post (> post origin)
|
(and post (> post origin)
|
||||||
(< (org-element-property :begin element) origin)
|
(< (org-element-property :begin element) origin)
|
||||||
(progn (beginning-of-line)
|
(progn (beginning-of-line)
|
||||||
|
@ -4685,7 +4702,8 @@ Providing it allows for quicker computation."
|
||||||
(search-forward key (line-end-position) t)
|
(search-forward key (line-end-position) t)
|
||||||
(forward-char)
|
(forward-char)
|
||||||
(setq end (line-end-position))))))))
|
(setq end (line-end-position))))))))
|
||||||
element
|
element)
|
||||||
|
(t
|
||||||
(let ((restriction (org-element-restriction type))
|
(let ((restriction (org-element-restriction type))
|
||||||
(parent element)
|
(parent element)
|
||||||
candidates)
|
candidates)
|
||||||
|
@ -4723,7 +4741,7 @@ Providing it allows for quicker computation."
|
||||||
(setq parent object
|
(setq parent object
|
||||||
restriction (org-element-restriction object)
|
restriction (org-element-restriction object)
|
||||||
end cend)))))))
|
end cend)))))))
|
||||||
parent))))))
|
parent)))))))
|
||||||
|
|
||||||
(defsubst org-element-nested-p (elem-A elem-B)
|
(defsubst org-element-nested-p (elem-A elem-B)
|
||||||
"Non-nil when elements ELEM-A and ELEM-B are nested."
|
"Non-nil when elements ELEM-A and ELEM-B are nested."
|
||||||
|
|
|
@ -2661,6 +2661,15 @@ Paragraph \\alpha."
|
||||||
(org-test-with-temp-text "- Para1\n- Para2\n\nPara3"
|
(org-test-with-temp-text "- Para1\n- Para2\n\nPara3"
|
||||||
(progn (forward-line 2)
|
(progn (forward-line 2)
|
||||||
(org-element-type (org-element-at-point))))))
|
(org-element-type (org-element-at-point))))))
|
||||||
|
;; Special case: within the first blank lines in buffer, return nil.
|
||||||
|
(should-not (org-test-with-temp-text "\nParagraph" (org-element-at-point)))
|
||||||
|
;; Special case: within the blank lines after a headline, return
|
||||||
|
;; that headline.
|
||||||
|
(should
|
||||||
|
(eq 'headline
|
||||||
|
(org-test-with-temp-text "* Headline\n\nParagraph"
|
||||||
|
(progn (forward-line)
|
||||||
|
(org-element-type (org-element-at-point))))))
|
||||||
;; With an optional argument, return trail.
|
;; With an optional argument, return trail.
|
||||||
(should
|
(should
|
||||||
(equal '(paragraph center-block)
|
(equal '(paragraph center-block)
|
||||||
|
@ -2733,7 +2742,9 @@ Paragraph \\alpha."
|
||||||
(org-test-with-temp-text "Some *text with _underline_ text*"
|
(org-test-with-temp-text "Some *text with _underline_ text*"
|
||||||
(progn
|
(progn
|
||||||
(search-forward "under")
|
(search-forward "under")
|
||||||
(org-element-type (org-element-context (org-element-at-point))))))))
|
(org-element-type (org-element-context (org-element-at-point)))))))
|
||||||
|
;; Return nil when point is within the first blank lines.
|
||||||
|
(should-not (org-test-with-temp-text "\n* Headline" (org-element-context))))
|
||||||
|
|
||||||
|
|
||||||
(provide 'test-org-element)
|
(provide 'test-org-element)
|
||||||
|
|
Loading…
Reference in New Issue