From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kyle Meyer Subject: [PATCH] org-add-planning-info: Improve deletion handling Date: Sat, 27 Jun 2015 00:46:32 -0400 Message-ID: <87381dn4gn.fsf@kmlap.domain.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:34189) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z8i0l-00032T-QD for emacs-orgmode@gnu.org; Sat, 27 Jun 2015 00:46:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Z8i0h-0005uW-Rh for emacs-orgmode@gnu.org; Sat, 27 Jun 2015 00:46:39 -0400 Received: from mail-qk0-f182.google.com ([209.85.220.182]:32968) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Z8i0h-0005uL-Mb for emacs-orgmode@gnu.org; Sat, 27 Jun 2015 00:46:35 -0400 Received: by qkhu186 with SMTP id u186so65643605qkh.0 for ; Fri, 26 Jun 2015 21:46:34 -0700 (PDT) Received: from localhost ([2601:18a:c201:560f:9e4e:36ff:fe3d:ae9c]) by mx.google.com with ESMTPSA id v13sm8031040qhd.31.2015.06.26.21.46.33 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jun 2015 21:46:34 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Org-mode --=-=-= Content-Type: text/plain Hello, I've attached a patch that fixes up a few issues I've noticed with org-add-planning-info. The main one (in terms what I actually see when editing Org files) is that, when org-adapt-indentation is nil, closing a repeating TODO heading adds an extra space before the planning info entry when it cycles back to TODO. For example, marking * TODO h SCHEDULED: <2015-06-26 Fri +1w> as DONE inserts an extra space before SCHEDULED: * TODO h SCHEDULED: <2015-07-03 Fri +1w> :PROPERTIES: :LAST_REPEAT: [2015-06-26 Fri 23:38] :END: :LOGBOOK: - State "DONE" from "TODO" [2015-06-26 Fri 23:38] :END: --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-org-add-planning-info-Improve-deletion-handling.patch >From 6315be9e7a83cd9837807c2eb87ed7b3c6b70997 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Fri, 26 Jun 2015 21:33:34 -0400 Subject: [PATCH] org-add-planning-info: Improve deletion handling * lisp/org.el (org-add-planning-info): Reset point before each planning entry search. Clean up extra spaces. * testing/lisp/test-org.el (test-org/add-planning-info): Add tests. - Reposition save-excursion call to reset point every dolist iteration. Otherwise, the order of the entries to be removed matters, and a call like (org-add-planning-info nil nil 'scheduled 'deadline) on DEADLINE: <2015-06-26 Fri> SCHEDULED: <2015-06-26 Fri> will fail to remove the deadline entry. - Delete leading white space even when at the beginning of the line so that, when org-adapt-indentation is nil, a space is not inserted when removing the leading planning info entry. This prevents headings with repeating entries like SCHEDULED: <2015-06-26 Fri +1w> from being closed and recycled with an extra space in front of SCHEDULED. - Add leading white space to the planning info entry regexp to prevent leftover white space when removing entries other than the first entry. --- lisp/org.el | 35 ++++++----- testing/lisp/test-org.el | 159 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 16 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 02f5c22..5a7d6d3 100755 --- a/lisp/org.el +++ b/lisp/org.el @@ -13478,23 +13478,26 @@ (defun org-add-planning-info (what &optional time &rest remove) (skip-chars-forward " \t") ;; Check if we have to remove something. (dolist (type (if what (cons what remove) remove)) - (when (save-excursion - (re-search-forward - (case type - (closed org-closed-time-regexp) - (deadline org-deadline-time-regexp) - (scheduled org-scheduled-time-regexp) - (otherwise (error "Invalid planning type: %s" type))) - (line-end-position) t)) - (replace-match "") - (when (looking-at "--+<[^>]+>") (replace-match "")) - (when (and (not what) (eq type 'closed)) - (save-excursion - (beginning-of-line) - (if (looking-at "[ \t]*$") - (delete-region (point) (1+ (point-at-eol))))))) + (save-excursion + (when (re-search-forward + (concat + " *" + (case type + (closed org-closed-time-regexp) + (deadline org-deadline-time-regexp) + (scheduled org-scheduled-time-regexp) + (otherwise + (error "Invalid planning type: %s" type)))) + (line-end-position) t) + (replace-match "") + (when (looking-at "--+<[^>]+>") (replace-match "")) + (when (and (not what) (eq type 'closed)) + (save-excursion + (beginning-of-line) + (if (looking-at "[ \t]*$") + (delete-region (point) (1+ (point-at-eol)))))))) ;; Remove leading white spaces. - (when (and (not (bolp)) (looking-at "[ \t]+")) (replace-match "")))) + (when (looking-at "[ \t]+") (replace-match "")))) ((not what) (throw 'exit nil)) ; Nothing to do. (t (insert-before-markers "\n") (backward-char 1) diff --git a/testing/lisp/test-org.el b/testing/lisp/test-org.el index 35905d3..437b594 100644 --- a/testing/lisp/test-org.el +++ b/testing/lisp/test-org.el @@ -2858,6 +2858,165 @@ (ert-deftest test-org/at-planning-p () "* Headline\n*** Inlinetask\n*** END\nDEADLINE: <2014-03-04 tue.>" (let ((org-inlinetask-min-level 3)) (org-at-planning-p)))))) +(ert-deftest test-org/add-planning-info () + "Test `org-add-planning-info'." + ;; Create deadline when `org-adapt-indentation' is non-nil. + (should + (equal "* H\n DEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "* H\nParagraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Create deadline when `org-adapt-indentation' is nil. + (should + (equal "* H\nDEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "* H\nParagraph" + (let ((org-adapt-indentation nil)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Update deadline when `org-adapt-indentation' is non-nil. + (should + (equal "* H\n DEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "\ +* H + DEADLINE: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Update deadline when `org-adapt-indentation' is nil. + (should + (equal "* H\nDEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "\ +* H +DEADLINE: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation nil)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Schedule when `org-adapt-indentation' is non-nil. + (should + (equal "* H\n SCHEDULED: <2015-06-25>\nParagraph" + (org-test-with-temp-text "* H\nParagraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info 'scheduled "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Schedule when `org-adapt-indentation' is nil. + (should + (equal "* H\nSCHEDULED: <2015-06-25>\nParagraph" + (org-test-with-temp-text "* H\nParagraph" + (let ((org-adapt-indentation nil)) + (org-add-planning-info 'scheduled "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Add deadline when scheduled. + (should + (equal "\ +* H + DEADLINE: <2015-06-25> SCHEDULED: <2015-06-24> +Paragraph" + (org-test-with-temp-text "\ +* H + SCHEDULED: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>")) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Remove middle entry. + (should + (equal "\ +* H + CLOSED: [2015-06-24] SCHEDULED: <2015-06-24> +Paragraph" + (org-test-with-temp-text "\ +* H + CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info nil nil 'deadline)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string) + nil nil 1)))) + ;; Remove last entry and then middle entry (order should not + ;; matter). + (should + (equal "\ +* H + CLOSED: [2015-06-24] +Paragraph" + (org-test-with-temp-text "\ +* H + CLOSED: [2015-06-24 Wed] DEADLINE: <2015-06-25 Thu> SCHEDULED: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info nil nil 'scheduled 'deadline)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)[]>]" "" (buffer-string) + nil nil 1)))) + ;; Remove closed when `org-adapt-indentation' is non-nil. + (should + (equal "* H\n DEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "\ +* H + CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info nil nil 'closed)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Remove closed when `org-adapt-indentation' is nil. + (should + (equal "* H\nDEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "\ +* H +CLOSED: [2015-06-25 Thu] DEADLINE: <2015-06-25 Thu> +Paragraph" + (let ((org-adapt-indentation nil)) + (org-add-planning-info nil nil 'closed)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Remove closed entry and delete empty line. + (should + (equal "\ +* H +Paragraph" + (org-test-with-temp-text "\ +* H + CLOSED: [2015-06-24 Wed] +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info nil nil 'closed)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1)))) + ;; Remove one entry and update another. + (should + (equal "* H\n DEADLINE: <2015-06-25>\nParagraph" + (org-test-with-temp-text "\ +* H + SCHEDULED: <2015-06-23 Tue> DEADLINE: <2015-06-24 Wed> +Paragraph" + (let ((org-adapt-indentation t)) + (org-add-planning-info 'deadline "<2015-06-25 Thu>" 'scheduled)) + (replace-regexp-in-string + "\\( [.A-Za-z]+\\)>" "" (buffer-string) + nil nil 1))))) + ;;; Property API -- 2.4.4 --=-=-= Content-Type: text/plain -- Kyle --=-=-=--