diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2014-11-16 13:57:21 +0100 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2014-11-16 14:02:13 +0100 |
commit | a7e62499f2fe5c313567212ee90ff743c5e734a8 (patch) | |
tree | 04bd16ce2d84c9d056decb7e85ce2f80ceb8e464 | |
parent | 61ba40c37152c41866e5d918ad6527bf0994599d (diff) | |
download | org-mode-a7e62499f2fe5c313567212ee90ff743c5e734a8.tar.gz |
Fix `org-return'
* lisp/org.el (org-return): Avoid false positives in function.
* testing/lisp/test-org.el (test-org/return): New test.
Thanks to Sébastien Vauban for reporting it.
<http://permalink.gmane.org/gmane.emacs.orgmode/92657>
-rwxr-xr-x | lisp/org.el | 85 | ||||
-rw-r--r-- | testing/lisp/test-org.el | 50 |
2 files changed, 97 insertions, 38 deletions
diff --git a/lisp/org.el b/lisp/org.el index 8146eb5..c0b9c19 100755 --- a/lisp/org.el +++ b/lisp/org.el @@ -20953,44 +20953,57 @@ If `org-special-ctrl-o' is nil, just call `open-line' everywhere." (defun org-return (&optional indent) "Goto next table row or insert a newline. + Calls `org-table-next-row' or `newline', depending on context. -See the individual commands for more information." + +When optional INDENT argument is non-nil, call +`newline-and-indent' instead of `newline'. + +When `org-return-follows-link' is non-nil and point is on +a timestamp or a link, call `org-open-at-point'. However, it +will not happen if point is in a table or on a \"dead\" +object (e.g., within a comment). In these case, you need to use +`org-open-at-point' directly." (interactive) - (let (org-ts-what) - (cond - ((or (bobp) (org-in-src-block-p)) - (if indent (newline-and-indent) (newline))) - ((org-at-table-p) - (org-table-justify-field-maybe) - (call-interactively 'org-table-next-row)) - ;; when `newline-and-indent' is called within a list, make sure - ;; text moved stays inside the item. - ((and (org-in-item-p) indent) - (if (and (org-at-item-p) (>= (point) (match-end 0))) - (progn - (save-match-data (newline)) - (org-indent-line-to (length (match-string 0)))) - (let ((ind (org-get-indentation))) - (newline) - (if (org-looking-back org-list-end-re) - (org-indent-line) - (org-indent-line-to ind))))) - ((and org-return-follows-link - (org-at-timestamp-p t) - (not (eq org-ts-what 'after))) - (org-follow-timestamp-link)) - ((and org-return-follows-link - (let ((tprop (get-text-property (point) 'face))) - (or (eq tprop 'org-link) - (and (listp tprop) (memq 'org-link tprop))))) - (call-interactively 'org-open-at-point)) - ((and (org-at-heading-p) - (looking-at - (org-re "\\([ \t]+\\(:[[:alnum:]_@#%:]+:\\)\\)[ \t]*$"))) - (org-show-entry) - (end-of-line 1) - (newline)) - (t (if indent (newline-and-indent) (newline)))))) + (if (and (save-excursion + (beginning-of-line) + (looking-at org-todo-line-regexp)) + (match-beginning 3) + (>= (point) (match-beginning 3))) + ;; Point is on headline tags. Do not break them: add a newline + ;; after the headline instead. + (progn (org-show-entry) + (end-of-line) + (if indent (newline-and-indent) (newline))) + (let* ((context (if org-return-follows-link (org-element-context) + (org-element-at-point))) + (type (org-element-type context))) + (cond + ;; In a table, call `org-table-next-row'. + ((or (and (eq type 'table) + (>= (point) (org-element-property :contents-begin context)) + (< (point) (org-element-property :contents-end context))) + (org-element-lineage context '(table-row table-cell) t)) + (org-table-justify-field-maybe) + (call-interactively #'org-table-next-row)) + ;; On a link or a timestamp but not on white spaces after it, + ;; call `org-open-line' if `org-return-follows-link' allows it. + ((and org-return-follows-link + (memq type '(link timestamp)) + (< (point) + (save-excursion (goto-char (org-element-property :end context)) + (skip-chars-backward " \t") + (point)))) + (call-interactively #'org-open-at-point)) + ;; In a list, make sure indenting keeps trailing text within. + ((and indent + (not (eolp)) + (org-element-lineage context '(item plain-list) t)) + (let ((trailing-data + (delete-and-extract-region (point) (line-end-position)))) + (newline-and-indent) + (save-excursion (insert trailing-data)))) + (t (if indent (newline-and-indent) (newline))))))) (defun org-return-indent () "Goto next table row or insert a newline and indent. diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 3b3dff8..3203dd9 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -734,10 +734,56 @@ ;;; Editing -;;;; Insert elements +(ert-deftest test-org/return () + "Test RET (`org-return') specifications." + ;; Regular test. + (should + (equal "Para\ngraph" + (org-test-with-temp-text "Para<point>graph" + (org-return) + (buffer-string)))) + ;; With optional argument, indent line. + (should + (equal " Para\n graph" + (org-test-with-temp-text " Para<point>graph" + (org-return t) + (buffer-string)))) + ;; On a table, call `org-table-next-row'. + (should + (org-test-with-temp-text "| <point>a |\n| b |" + (org-return) + (org-looking-at-p "b"))) + ;; Open link or timestamp under point when `org-return-follows-link' + ;; is non-nil. + (should + (org-test-with-temp-text "Link [[target<point>]] <<target>>" + (let ((org-return-follows-link t)) (org-return)) + (org-looking-at-p "<<target>>"))) + (should-not + (org-test-with-temp-text "Link [[target<point>]] <<target>>" + (let ((org-return-follows-link nil)) (org-return)) + (org-looking-at-p "<<target>>"))) + ;; However, do not open link when point is in a table. + (should + (org-test-with-temp-text "| [[target<point>]] |\n| between |\n| <<target>> |" + (let ((org-return-follows-link t)) (org-return)) + (org-looking-at-p "between"))) + ;; Special case: in a list, when indenting, do not break structure. + (should + (equal "- A\n B" + (org-test-with-temp-text "- A <point>B" + (org-return t) + (buffer-string)))) + ;; Special case: on tags part of a headline, add a newline below it + ;; instead of breaking it. + (should + (equal "* H :tag:\n" + (org-test-with-temp-text "* H :<point>tag:" + (org-return) + (buffer-string))))) (ert-deftest test-org/meta-return () - "Test M-RET (`org-meta-return')." + "Test M-RET (`org-meta-return') specifications." ;; In a table field insert a row above. (should (org-test-with-temp-text "| a |" |