diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-01-14 23:25:13 +0100 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2017-01-14 23:25:13 +0100 |
commit | 4d9857f97b1bb4f7237ef1ce5d2602bca6b4fe33 (patch) | |
tree | ba72c48b76620589052e6d81a00c19a2b31c6806 | |
parent | 4a878bce4aabd00bf179ae368a6162bf40db3260 (diff) | |
parent | f0c08e3cbb9a2235a458d7826f4626e501338e0e (diff) | |
download | org-mode-4d9857f97b1bb4f7237ef1ce5d2602bca6b4fe33.tar.gz |
Merge branch 'maint'
-rw-r--r-- | lisp/org.el | 51 | ||||
-rw-r--r-- | testing/lisp/test-org.el | 20 |
2 files changed, 40 insertions, 31 deletions
diff --git a/lisp/org.el b/lisp/org.el index 6c3642d..2d7f5e1 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -24590,29 +24590,34 @@ Move to the previous element at the same level, when possible." (defun org-drag-element-backward () "Move backward element at point." (interactive) - (if (org-with-limited-levels (org-at-heading-p)) (org-move-subtree-up) - (let* ((elem (or (org-element-at-point) - (user-error "No element at point"))) - (prev-elem - (save-excursion - (goto-char (org-element-property :begin elem)) - (skip-chars-backward " \r\t\n") - (unless (bobp) - (let* ((beg (org-element-property :begin elem)) - (prev (org-element-at-point)) - (up prev)) - (while (and (setq up (org-element-property :parent up)) - (<= (org-element-property :end up) beg)) - (setq prev up)) - prev))))) - ;; Error out if no previous element or previous element is - ;; a parent of the current one. - (if (or (not prev-elem) (org-element-nested-p elem prev-elem)) - (user-error "Cannot drag element backward") - (let ((pos (point))) - (org-element-swap-A-B prev-elem elem) - (goto-char (+ (org-element-property :begin prev-elem) - (- pos (org-element-property :begin elem))))))))) + (let ((elem (or (org-element-at-point) + (user-error "No element at point")))) + (if (eq (org-element-type elem) 'headline) + ;; Preserve point when moving a whole tree, even if point was + ;; on blank lines below the headline. + (let ((offset (skip-chars-backward " \t\n"))) + (unwind-protect (org-move-subtree-up) + (forward-char (- offset)))) + (let ((prev-elem + (save-excursion + (goto-char (org-element-property :begin elem)) + (skip-chars-backward " \r\t\n") + (unless (bobp) + (let* ((beg (org-element-property :begin elem)) + (prev (org-element-at-point)) + (up prev)) + (while (and (setq up (org-element-property :parent up)) + (<= (org-element-property :end up) beg)) + (setq prev up)) + prev))))) + ;; Error out if no previous element or previous element is + ;; a parent of the current one. + (if (or (not prev-elem) (org-element-nested-p elem prev-elem)) + (user-error "Cannot drag element backward") + (let ((pos (point))) + (org-element-swap-A-B prev-elem elem) + (goto-char (+ (org-element-property :begin prev-elem) + (- pos (org-element-property :begin elem)))))))))) (defun org-drag-element-forward () "Move forward element at point." diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 52f37a4..352ee07 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -3267,21 +3267,18 @@ Outside." :type 'user-error) ;; Error when trying to swap nested elements. (should-error - (org-test-with-temp-text "#+BEGIN_CENTER\nTest.\n#+END_CENTER" - (forward-line) + (org-test-with-temp-text "#+BEGIN_CENTER\n<point>Test.\n#+END_CENTER" (org-drag-element-backward)) :type 'user-error) ;; Error when trying to swap an headline element and a non-headline ;; element. (should-error - (org-test-with-temp-text "Test.\n* Head 1" - (forward-line) + (org-test-with-temp-text "Test.\n<point>* Head 1" (org-drag-element-backward)) - :type 'user-error) + :type 'error) ;; Error when called before first element. (should-error - (org-test-with-temp-text "\n" - (forward-line) + (org-test-with-temp-text "\n<point>" (org-drag-element-backward)) :type 'user-error) ;; Preserve visibility of elements and their contents. @@ -3299,7 +3296,14 @@ Text. (search-backward "- item 1") (org-drag-element-backward) (mapcar (lambda (ov) (cons (overlay-start ov) (overlay-end ov))) - (overlays-in (point-min) (point-max))))))) + (overlays-in (point-min) (point-max)))))) + ;; Pathological case: handle call with point in blank lines right + ;; after a headline. + (should + (equal "* H2\n* H1\nText\n\n" + (org-test-with-temp-text "* H1\nText\n* H2\n\n<point>" + (org-drag-element-backward) + (buffer-string))))) (ert-deftest test-org/drag-element-forward () "Test `org-drag-element-forward' specifications." |