Browse Source

Insert planning in visible part of narrowed buffer

* lisp/org.el (org-add-planning-info): Make sure planning info appears
in the visible part of a narrowed buffer.
* testing/lisp/test-org.el (test-org/deadline):
(test-org/schedule): Update tests.

Reported-by: Michaël Cadilhac <michael@cadilhac.name>
<http://lists.gnu.org/r/emacs-orgmode/2019-09/msg00091.html>
Nicolas Goaziou 2 months ago
parent
commit
271f5a6829
2 changed files with 104 additions and 101 deletions
  1. 94 91
      lisp/org.el
  2. 10 10
      testing/lisp/test-org.el

+ 94 - 91
lisp/org.el

@@ -10541,97 +10541,100 @@ the time to use.  If none is given, the user is prompted for
 a date.  REMOVE indicates what kind of entries to remove.  An old
 WHAT entry will also be removed."
   (let (org-time-was-given org-end-time-was-given default-time default-input)
-    (catch 'exit
-      (when (and (memq what '(scheduled deadline))
-		 (or (not time)
-		     (and (stringp time)
-			  (string-match "^[-+]+[0-9]" time))))
-	;; Try to get a default date/time from existing timestamp
-	(save-excursion
-	  (org-back-to-heading t)
-	  (let ((end (save-excursion (outline-next-heading) (point))) ts)
-	    (when (re-search-forward (if (eq what 'scheduled)
-					 org-scheduled-time-regexp
-				       org-deadline-time-regexp)
-				     end t)
-	      (setq ts (match-string 1)
-		    default-time (org-time-string-to-time ts)
-		    default-input (and ts (org-get-compact-tod ts)))))))
-      (when what
-	(setq time
-	      (if (stringp time)
-		  ;; This is a string (relative or absolute), set
-		  ;; proper date.
-		  (apply #'encode-time
-			 (org-read-date-analyze
-			  time default-time (decode-time default-time)))
-		;; If necessary, get the time from the user
-		(or time (org-read-date nil 'to-time nil
-					(cl-case what
-					  (deadline "DEADLINE")
-					  (scheduled "SCHEDULED")
-					  (otherwise nil))
-					default-time default-input)))))
-      (org-with-wide-buffer
-       (org-back-to-heading t)
-       (forward-line)
-       (unless (bolp) (insert "\n"))
-       (cond ((looking-at-p org-planning-line-re)
-	      ;; Move to current indentation.
-	      (skip-chars-forward " \t")
-	      ;; Check if we have to remove something.
-	      (dolist (type (if what (cons what remove) remove))
-		(save-excursion
-		  (when (re-search-forward
-			 (cl-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)
-		    ;; Delete until next keyword or end of line.
-		    (delete-region
-		     (match-beginning 0)
-		     (if (re-search-forward org-keyword-time-not-clock-regexp
-					    (line-end-position)
-					    t)
-			 (match-beginning 0)
-		       (line-end-position))))))
-	      ;; If there is nothing more to add and no more keyword
-	      ;; is left, remove the line completely.
-	      (if (and (looking-at-p "[ \t]*$") (not what))
-		  (delete-region (line-beginning-position)
-				 (line-beginning-position 2))
-		;; If we removed last keyword, do not leave trailing
-		;; white space at the end of line.
-		(let ((p (point)))
-		  (save-excursion
-		    (end-of-line)
-		    (unless (= (skip-chars-backward " \t" p) 0)
-		      (delete-region (point) (line-end-position)))))))
-	     ((not what) (throw 'exit nil)) ; Nothing to do.
-	     (t (insert-before-markers "\n")
-		(backward-char 1)
-		(when org-adapt-indentation
-		  (indent-to-column (1+ (org-outline-level))))))
-       (when what
-	 ;; Insert planning keyword.
-	 (insert (cl-case what
-		   (closed org-closed-string)
-		   (deadline org-deadline-string)
-		   (scheduled org-scheduled-string)
-		   (otherwise (error "Invalid planning type: %s" what)))
-		 " ")
-	 ;; Insert associated timestamp.
-	 (let ((ts (org-insert-time-stamp
-		    time
-		    (or org-time-was-given
-			(and (eq what 'closed) org-log-done-with-time))
-		    (eq what 'closed)
-		    nil nil (list org-end-time-was-given))))
-	   (unless (eolp) (insert " "))
-	   ts))))))
+    (when (and (memq what '(scheduled deadline))
+	       (or (not time)
+		   (and (stringp time)
+			(string-match "^[-+]+[0-9]" time))))
+      ;; Try to get a default date/time from existing timestamp
+      (save-excursion
+	(org-back-to-heading t)
+	(let ((end (save-excursion (outline-next-heading) (point))) ts)
+	  (when (re-search-forward (if (eq what 'scheduled)
+				       org-scheduled-time-regexp
+				     org-deadline-time-regexp)
+				   end t)
+	    (setq ts (match-string 1)
+		  default-time (org-time-string-to-time ts)
+		  default-input (and ts (org-get-compact-tod ts)))))))
+    (when what
+      (setq time
+	    (if (stringp time)
+		;; This is a string (relative or absolute), set
+		;; proper date.
+		(apply #'encode-time
+		       (org-read-date-analyze
+			time default-time (decode-time default-time)))
+	      ;; If necessary, get the time from the user
+	      (or time (org-read-date nil 'to-time nil
+				      (cl-case what
+					(deadline "DEADLINE")
+					(scheduled "SCHEDULED")
+					(otherwise nil))
+				      default-time default-input)))))
+    (org-with-wide-buffer
+     (org-back-to-heading t)
+     (let ((planning? (save-excursion
+			(forward-line)
+			(looking-at-p org-planning-line-re))))
+       (cond
+	(planning?
+	 (forward-line)
+	 ;; Move to current indentation.
+	 (skip-chars-forward " \t")
+	 ;; Check if we have to remove something.
+	 (dolist (type (if what (cons what remove) remove))
+	   (save-excursion
+	     (when (re-search-forward
+		    (cl-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)
+	       ;; Delete until next keyword or end of line.
+	       (delete-region
+		(match-beginning 0)
+		(if (re-search-forward org-keyword-time-not-clock-regexp
+				       (line-end-position)
+				       t)
+		    (match-beginning 0)
+		  (line-end-position))))))
+	 ;; If there is nothing more to add and no more keyword is
+	 ;; left, remove the line completely.
+	 (if (and (looking-at-p "[ \t]*$") (not what))
+	     (delete-region (line-beginning-position)
+			    (line-beginning-position 2))
+	   ;; If we removed last keyword, do not leave trailing white
+	   ;; space at the end of line.
+	   (let ((p (point)))
+	     (save-excursion
+	       (end-of-line)
+	       (unless (= (skip-chars-backward " \t" p) 0)
+		 (delete-region (point) (line-end-position)))))))
+	(what
+	 (end-of-line)
+	 (insert "\n")
+	 (when org-adapt-indentation
+	   (indent-to-column (1+ (org-outline-level)))))
+	(t nil)))
+     (when what
+       ;; Insert planning keyword.
+       (insert (cl-case what
+		 (closed org-closed-string)
+		 (deadline org-deadline-string)
+		 (scheduled org-scheduled-string)
+		 (otherwise (error "Invalid planning type: %s" what)))
+	       " ")
+       ;; Insert associated timestamp.
+       (let ((ts (org-insert-time-stamp
+		  time
+		  (or org-time-was-given
+		      (and (eq what 'closed) org-log-done-with-time))
+		  (eq what 'closed)
+		  nil nil (list org-end-time-was-given))))
+	 (unless (eolp) (insert " "))
+	 ts)))))
 
 (defvar org-log-note-marker (make-marker)
   "Marker pointing at the entry where the note is to be inserted.")

+ 10 - 10
testing/lisp/test-org.el

@@ -4732,7 +4732,7 @@ Paragraph<point>"
   "Test `org-deadline' specifications."
   ;; Insert a new value or replace existing one.
   (should
-   (equal "* H\nDEADLINE: <2012-03-29>\n"
+   (equal "* H\nDEADLINE: <2012-03-29>"
 	  (org-test-with-temp-text "* H"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil))
@@ -4751,7 +4751,7 @@ Paragraph<point>"
 	     nil nil 1))))
   ;; Accept delta time, e.g., "+2d".
   (should
-   (equal "* H\nDEADLINE: <2015-03-04>\n"
+   (equal "* H\nDEADLINE: <2015-03-04>"
 	  (org-test-at-time "2014-03-04"
 	    (org-test-with-temp-text "* H"
 	      (let ((org-adapt-indentation nil)
@@ -4761,7 +4761,7 @@ Paragraph<point>"
 	       "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1)))))
   ;; Preserve repeater.
   (should
-   (equal "* H\nDEADLINE: <2012-03-29 +2y>\n"
+   (equal "* H\nDEADLINE: <2012-03-29 +2y>"
 	  (org-test-with-temp-text "* H"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil))
@@ -4818,7 +4818,7 @@ Paragraph<point>"
   ;; `org-loop-over-headlines-in-active-region' is non-nil, insert the
   ;; same value in all headlines in region.
   (should
-   (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>\n"
+   (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>"
 	  (org-test-with-temp-text "* H1\n* H2"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil)
@@ -4830,7 +4830,7 @@ Paragraph<point>"
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
   (should-not
-   (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>\n"
+   (equal "* H1\nDEADLINE: <2012-03-29>\n* H2\nDEADLINE: <2012-03-29>"
 	  (org-test-with-temp-text "* H1\n* H2"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil)
@@ -4846,7 +4846,7 @@ Paragraph<point>"
   "Test `org-schedule' specifications."
   ;; Insert a new value or replace existing one.
   (should
-   (equal "* H\nSCHEDULED: <2012-03-29>\n"
+   (equal "* H\nSCHEDULED: <2012-03-29>"
 	  (org-test-with-temp-text "* H"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil))
@@ -4865,7 +4865,7 @@ Paragraph<point>"
 	     nil nil 1))))
   ;; Accept delta time, e.g., "+2d".
   (should
-   (equal "* H\nSCHEDULED: <2015-03-04>\n"
+   (equal "* H\nSCHEDULED: <2015-03-04>"
 	  (org-test-at-time "2014-03-04"
 	    (org-test-with-temp-text "* H"
 	      (let ((org-adapt-indentation nil)
@@ -4875,7 +4875,7 @@ Paragraph<point>"
 	       "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1)))))
   ;; Preserve repeater.
   (should
-   (equal "* H\nSCHEDULED: <2012-03-29 +2y>\n"
+   (equal "* H\nSCHEDULED: <2012-03-29 +2y>"
 	  (org-test-with-temp-text "* H"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil))
@@ -4932,7 +4932,7 @@ Paragraph<point>"
   ;; `org-loop-over-headlines-in-active-region' is non-nil, insert the
   ;; same value in all headlines in region.
   (should
-   (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>\n"
+   (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>"
 	  (org-test-with-temp-text "* H1\n* H2"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil)
@@ -4944,7 +4944,7 @@ Paragraph<point>"
 	    (replace-regexp-in-string
 	     "\\( [.A-Za-z]+\\)>" "" (buffer-string) nil nil 1))))
   (should-not
-   (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>\n"
+   (equal "* H1\nSCHEDULED: <2012-03-29>\n* H2\nSCHEDULED: <2012-03-29>"
 	  (org-test-with-temp-text "* H1\n* H2"
 	    (let ((org-adapt-indentation nil)
 		  (org-last-inserted-timestamp nil)