diff options
author | Nicolas Goaziou <n.goaziou@gmail.com> | 2012-08-08 09:54:56 +0200 |
---|---|---|
committer | Nicolas Goaziou <n.goaziou@gmail.com> | 2012-08-08 09:56:28 +0200 |
commit | 0a04169769477dd183ad69d1358c37ae3a7897ff (patch) | |
tree | e4d210ad228bac3dc48d124965a6443300203bf8 | |
parent | 9dae6f04b12c8e38c8dcfc71e3a1a2ce6e63bf99 (diff) | |
download | org-mode-0a04169769477dd183ad69d1358c37ae3a7897ff.tar.gz |
org-element: Fix `org-element-at-point' in some corner cases
* lisp/org-element.el (org-element-item-parser,
org-element-plain-list-parser): Make sure that the element ends at
the beginning of a line if possible.
(org-element-at-point): Return expected element when point is at an
element's end or at its contents' end.
* testing/lisp/test-org-element.el: Add test.
* testing/lisp/test-org.el: Add test.
-rw-r--r-- | lisp/org-element.el | 63 | ||||
-rw-r--r-- | testing/lisp/test-org-element.el | 7 | ||||
-rw-r--r-- | testing/lisp/test-org.el | 9 |
3 files changed, 49 insertions, 30 deletions
diff --git a/lisp/org-element.el b/lisp/org-element.el index 711c791..121a615 100644 --- a/lisp/org-element.el +++ b/lisp/org-element.el @@ -981,10 +981,12 @@ Assume point is at the beginning of the item." 64)) ((string-match "[0-9]+" c) (string-to-number (match-string 0 c)))))) - (end (org-list-get-item-end begin struct)) + (end (save-excursion (goto-char (org-list-get-item-end begin struct)) + (unless (bolp) (forward-line)) + (point))) (contents-begin (progn (looking-at org-list-full-item-re) (goto-char (match-end 0)) - (org-skip-whitespace) + (skip-chars-forward " \r\t\n" limit) ;; If first line isn't empty, ;; contents really start at the text ;; after item's meta-data. @@ -1039,10 +1041,10 @@ CONTENTS is the contents of the element." (concat bullet (and counter (format "[@%d] " counter)) - (cond - ((eq checkbox 'on) "[X] ") - ((eq checkbox 'off) "[ ] ") - ((eq checkbox 'trans) "[-] ")) + (case checkbox + (on "[X] ") + (off "[ ] ") + (trans "[-] ")) (and tag (format "%s :: " tag)) (let ((contents (replace-regexp-in-string "\\(^\\)[ \t]*\\S-" ind contents nil nil 1))) @@ -1072,14 +1074,11 @@ Assume point is at the beginning of the list." (keywords (org-element--collect-affiliated-keywords)) (begin (car keywords)) (contents-end - (goto-char (org-list-get-list-end (point) struct prevs))) - (end (save-excursion (org-skip-whitespace) - (if (eobp) (point) (point-at-bol))))) - ;; Blank lines below list belong to the top-level list only. - (unless (= (org-list-get-top-point struct) contents-begin) - (setq end (min (org-list-get-bottom-point struct) - (progn (skip-chars-forward " \r\t\n" limit) - (if (eobp) (point) (point-at-bol)))))) + (progn (goto-char (org-list-get-list-end (point) struct prevs)) + (unless (bolp) (forward-line)) + (point))) + (end (progn (skip-chars-forward " \r\t\n" limit) + (if (eobp) (point) (point-at-bol))))) ;; Return value. (list 'plain-list (nconc @@ -4076,31 +4075,35 @@ first element of current section." (org-element-put-property element :parent parent) (when keep-trail (push element trail)) (cond - ;; 1. Skip any element ending before point or at point - ;; because the following element has started. On the - ;; other hand, if the element ends at point and that - ;; point is also the end of the buffer, do not skip it. - ((let ((end (org-element-property :end element))) - (when (or (< end origin) - (and (= end origin) (/= (point-max) end))) - (if (> (point-max) end) (goto-char end) - (throw 'exit (if keep-trail trail element)))))) + ;; 1. Skip any element ending before point. Also skip + ;; element ending at point when we're sure that another + ;; element has started. + ((let ((elem-end (org-element-property :end element))) + (when (or (< elem-end origin) + (and (= elem-end origin) (/= elem-end end))) + (goto-char elem-end)))) ;; 2. An element containing point is always the element at ;; point. ((not (memq type org-element-greater-elements)) (throw 'exit (if keep-trail trail element))) ;; 3. At any other greater element type, if point is - ;; within contents, move into it. Otherwise, return - ;; that element. As a special case, when ORIGIN is - ;; contents end and is also the end of the buffer, try - ;; to move inside the greater element to find the end - ;; of the innermost element. + ;; within contents, move into it. (t (let ((cbeg (org-element-property :contents-begin element)) (cend (org-element-property :contents-end element))) (if (or (not cbeg) (not cend) (> cbeg origin) (< cend origin) - (and (= cend origin) (/= (point-max) origin)) - (and (= cbeg origin) (memq type '(plain-list table)))) + ;; Create an anchor for tables and plain lists: + ;; when point is at the very beginning of these + ;; elements, ignoring affiliated keywords, + ;; target them instead of their contents. + (and (= cbeg origin) (memq type '(plain-list table))) + ;; When point is at contents end, do not move + ;; into elements with an explicit ending, but + ;; return that element instead. + (and (= cend origin) + (memq type + '(center-block drawer dynamic-block inlinetask + quote-block special-block)))) (throw 'exit (if keep-trail trail element)) (setq parent element) (case type diff --git a/testing/lisp/test-org-element.el b/testing/lisp/test-org-element.el index e25daa6..1af1d07 100644 --- a/testing/lisp/test-org-element.el +++ b/testing/lisp/test-org-element.el @@ -2263,6 +2263,13 @@ Paragraph \\alpha." (eq 'plain-list (org-test-with-temp-text "- item" (org-element-type (org-element-at-point))))) + ;; Special case: at the closing line of a greater element, be sure + ;; to return it instead of the last element in its contents. + (should + (eq 'center-block + (org-test-with-temp-text "#+BEGIN_CENTER\nParagraph\n#+END_CENTER" + (progn (forward-line 2) + (org-element-type (org-element-at-point)))))) ;; With an optional argument, return trail. (should (equal '(paragraph center-block) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index cb48524..38e4a70 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -151,6 +151,15 @@ http://article.gmane.org/gmane.emacs.orgmode/21459/" (goto-char (point-max)) (org-fill-paragraph) (buffer-string))))) + ;; Correctly fill the last paragraph of a greater element. + (should + (equal "#+BEGIN_CENTER\n- 012345\n 789\n#+END_CENTER" + (org-test-with-temp-text "#+BEGIN_CENTER\n- 012345 789\n#+END_CENTER" + (let ((fill-column 8)) + (forward-line) + (end-of-line) + (org-fill-paragraph) + (buffer-string))))) ;; Special case: Fill first paragraph when point is at an item or ;; a plain-list or a footnote reference. (should |