Browse Source

Better support for timer lists. Trying to insert a new item with point
in a special block now move before block.

* org-list.el (org-insert-item): Move before any special block in a
list prior to add a new item.
* org-timer.el (org-timer-item): When in a timer list, insert a new
timer item like `org-insert-item'. If in another list, send an
error. Otherwise, start a new timer list.

Nicolas Goaziou 14 years ago
parent
commit
2dd3b8a2a8
2 changed files with 145 additions and 84 deletions
  1. 83 75
      lisp/org-list.el
  2. 62 9
      lisp/org-timer.el

+ 83 - 75
lisp/org-list.el

@@ -613,82 +613,90 @@ so this really moves item trees."
 
 
 If cursor is before first character after bullet of the item, the
 If cursor is before first character after bullet of the item, the
 new item will be created before the current one. Return t when
 new item will be created before the current one. Return t when
-things worked, nil when we are not in an item, or we are inside a
-block, or item is invisible."
+things worked, nil when we are not in an item, or item is
+invisible."
   (unless (or (not (org-in-item-p))
   (unless (or (not (org-in-item-p))
-	      (org-invisible-p)
-	      (org-in-regexps-block-p "^[ \t]*#\\+begin_\\([a-zA-Z]\\)"
-	      			      '(concat "^[ \t]*#\\+end_" (match-string 1))))
-    (let* ((pos (point))
-	   (before-p (and (org-at-item-p)
-			  (<= (point) (match-end 0))))
-	   (item-start (org-beginning-of-item))
-	   (bullet-init (and (looking-at (org-item-re))
-			     (match-string 0)))
-	   (description-p (and (looking-at "[ \t]*\\(.*?\\) ::")
-			       (match-string 1)))
-	   (timer-p (and description-p
-			 (string-match "^[-+*][ \t]+[0-9]+:[0-9]+:[0-9]+$" description-p)))
-	   ;; Guess number of blank lines used to separate items.
-	   (blank-lines-nb (let ((insert-blank-p
-				  (cdr (assq 'plain-list-item org-blank-before-new-entry))))
-			     (cond
-			      ((or
-				org-empty-line-terminates-plain-lists
-				(not insert-blank-p))
-			       0)
-			      ((eq insert-blank-p t) 1)
-			      ;; plain-list-item is 'auto. Count blank
-			      ;; lines separating items in list.
-			      (t
-			       (save-excursion
-				 (if (progn
-				       (org-end-of-item-list)
-				       (skip-chars-backward " \r\t\n")
-				       (org-search-backward-unenclosed
-					"^[ \t]*$" (save-excursion (org-beginning-of-item-list)) t))
-				     (1+ (org-back-over-empty-lines))
-				   0))))))
-	   (insert-fun (lambda (&optional string-after-bullet)
-			 ;; insert bullet above item in order to avoid
-			 ;; bothering with possible blank lines ending
-			 ;; last item
-			 (org-beginning-of-item)
-			 (insert (concat bullet-init
-					 (when checkbox "[ ] ")
-					 (when (and description-p (not timer-p))
-					   (concat (read-string "Term: ") " :: "))))
-			 (save-excursion
-			   (insert (concat string-after-bullet
-					   (make-string (1+ blank-lines-nb) ?\n))))
-			 (unless before-p (org-move-item-down)))))
-      (goto-char pos)
-      (cond
-       ;; if we're adding a timer, delegate to `org-timer-item' after
-       ;; inserting a coherent number of blank lines.
-       (timer-p
-	(newline (1+ blank-lines-nb))
-	(org-timer-item) t)
-       (before-p
-	(funcall insert-fun)
-	;; Renumber in this case, as we're not moving down.
-	(org-maybe-renumber-ordered-list) t)
-       ;; if we can't split item, just insert bullet at the end of
-       ;; item.
-       ((not (org-get-alist-option org-M-RET-may-split-line 'item))
-	(funcall insert-fun) t)
-       ;; else, insert a new bullet along with everything from point
-       ;; down to last non-blank line of item
-       (t
-	(delete-horizontal-space)
-	;; get pos again in case previous command changed line.
-	(let* ((pos (point))
-	       (end-before-blank (org-end-of-item-before-blank))
-	       (after-bullet (when (< pos end-before-blank)
-			       (prog1
-				   (buffer-substring pos end-before-blank)
-				 (delete-region pos end-before-blank)))))
-	  (funcall insert-fun after-bullet) t))))))
+	      (org-invisible-p))
+    ;; Timer list: delegate to `org-timer-item'.
+    (if (save-excursion
+	  (org-beginning-of-item)
+	  (looking-at "[ \t]*[-+*][ \t]+[0-9]+:[0-9]+:[0-9]+ ::"))
+	(progn
+	  (org-timer-item) t)
+      ;; else check if we're in a special block. If so, move before it
+      ;; prior to add a new item.
+      (when (org-in-regexps-block-p
+	     "^[ \t]*#\\+\\(begin\\|BEGIN\\)_\\([a-zA-Z0-9_]+\\)"
+	     '(concat "^[ \t]*#\\+\\(end\\|END\\)_" (match-string 2)))
+	;; in case we're on the #+begin line
+	(end-of-line)
+	(re-search-backward "^[ \t]*#\\+\\(begin\\|BEGIN\\)" nil t)
+	(end-of-line 0))
+      (let ((pos (point))
+	    (before-p (and (org-at-item-p)
+			   (<= (point) (match-end 0))))
+	    (item-start (org-beginning-of-item))
+	    (bullet-init (and (looking-at (org-item-re))
+			      (match-string 0)))
+	    (description-p (and (looking-at "[ \t]*\\(.*?\\) ::")
+				(match-string 1)))
+	    ;; Guess number of blank lines used to separate items.
+	    (blank-lines-nb
+	     (let ((insert-blank-p
+		    (cdr (assq 'plain-list-item org-blank-before-new-entry))))
+	       (cond
+		((or
+		  org-empty-line-terminates-plain-lists
+		  (not insert-blank-p))
+		 0)
+		((eq insert-blank-p t) 1)
+		;; plain-list-item is 'auto. Count blank
+		;; lines separating items in list.
+		(t
+		 (save-excursion
+		   (if (progn
+			 (org-end-of-item-list)
+			 (skip-chars-backward " \r\t\n")
+			 (org-search-backward-unenclosed
+			  "^[ \t]*$" (save-excursion (org-beginning-of-item-list)) t))
+		       (1+ (org-back-over-empty-lines))
+		     0))))))
+	    (insert-fun
+	     (lambda (&optional string-after-bullet)
+	       ;; insert bullet above item in order to avoid
+	       ;; bothering with possible blank lines ending
+	       ;; last item
+	       (org-beginning-of-item)
+	       (insert (concat bullet-init
+			       (when checkbox "[ ] ")
+			       (when description-p
+				 (concat (read-string "Term: ") " :: "))))
+	       (save-excursion
+		 (insert (concat string-after-bullet
+				 (make-string (1+ blank-lines-nb) ?\n))))
+	       (unless before-p (org-move-item-down)))))
+	(goto-char pos)
+	(cond
+	 (before-p
+	  (funcall insert-fun)
+	  ;; Renumber in this case, as we're not moving down.
+	  (org-maybe-renumber-ordered-list) t)
+	 ;; if we can't split item, just insert bullet at the end of
+	 ;; item.
+	 ((not (org-get-alist-option org-M-RET-may-split-line 'item))
+	  (funcall insert-fun) t)
+	 ;; else, insert a new bullet along with everything from point
+	 ;; down to last non-blank line of item
+	 (t
+	  (delete-horizontal-space)
+	  ;; get pos again in case previous command changed line.
+	  (let* ((pos (point))
+		 (end-before-blank (org-end-of-item-before-blank))
+		 (after-bullet (when (< pos end-before-blank)
+				 (prog1
+				     (buffer-substring pos end-before-blank)
+				   (delete-region pos end-before-blank)))))
+	    (funcall insert-fun after-bullet) t)))))))
 
 
 ;;; Indentation
 ;;; Indentation
 
 

+ 62 - 9
lisp/org-timer.el

@@ -195,16 +195,69 @@ that was not started at the correct moment."
 (defun org-timer-item (&optional arg)
 (defun org-timer-item (&optional arg)
   "Insert a description-type item with the current timer value."
   "Insert a description-type item with the current timer value."
   (interactive "P")
   (interactive "P")
-  (let ((ind (save-excursion
-	       (if (not (org-in-item-p))
-		   (org-indent-line-function)
-		 (org-beginning-of-item)
-		 (org-get-indentation)))))
-    (or (bolp) (newline))
-    (org-indent-line-to ind)
-    (insert "- ")
+  (cond
+   ;; If we are in a timer list, insert item like `org-insert-item'.
+   ((and (org-in-item-p)
+	 (save-excursion
+	   (org-beginning-of-item)
+	   (looking-at "[ \t]*[-+*][ \t]+[0-9]+:[0-9]+:[0-9]+ ::")))
+    (let ((pos (point))
+	  (before-p (and (org-at-item-p)
+			 (<= (point) (match-end 0))))
+	  (item-start (org-beginning-of-item))
+	  (bullet-init (and (looking-at (org-item-re))
+			    (match-string 0)))
+	  (blank-lines-nb
+	   (let ((insert-blank-p
+		  (cdr (assq 'plain-list-item org-blank-before-new-entry))))
+	     (cond
+	      ((or org-empty-line-terminates-plain-lists
+		   (not insert-blank-p))
+	       0)
+	      ((eq insert-blank-p t) 1)
+	      (t
+	       (save-excursion
+		 (if (progn
+		       (org-end-of-item-list)
+		       (skip-chars-backward " \r\t\n")
+		       (org-search-backward-unenclosed
+			"^[ \t]*$" (save-excursion (org-beginning-of-item-list)) t))
+		     (1+ (org-back-over-empty-lines))
+		   0))))))
+	  (insert-fun
+	   (lambda (&optional string-after-bullet)
+	     (org-beginning-of-item)
+	     (insert bullet-init)
+	     (org-timer (if arg '(4)))
+	     (insert ":: ")
+	     (save-excursion
+	       (insert (concat string-after-bullet
+			       (make-string (1+ blank-lines-nb) ?\n))))
+	     (unless before-p (org-move-item-down)))))
+      (goto-char pos)
+      (cond
+       (before-p (funcall insert-fun))
+       ((not (org-get-alist-option org-M-RET-may-split-line 'item))
+	(funcall insert-fun))
+       (t
+	(delete-horizontal-space)
+	(let* ((pos (point))
+	       (end-before-blank (org-end-of-item-before-blank))
+	       (after-bullet (when (< pos end-before-blank)
+			       (prog1
+				   (buffer-substring pos end-before-blank)
+				 (delete-region pos end-before-blank)))))
+	  (funcall insert-fun after-bullet) t)))))
+   ;; We are still are in a list, of a wrong type: throw an error.
+   ((org-in-item-p)
+    (error "This is not a timer list"))
+   ;; Else, go to beginning of line, and insert the timer
+   (t
+    (beginning-of-line)
+    (org-indent-line-function)
+    (insert  "- ")
     (org-timer (if arg '(4)))
     (org-timer (if arg '(4)))
-    (insert ":: ")))
+    (insert ":: "))))
 
 
 (defun org-timer-fix-incomplete (hms)
 (defun org-timer-fix-incomplete (hms)
   "If hms is a H:MM:SS string with missing hour or hour and minute, fix it."
   "If hms is a H:MM:SS string with missing hour or hour and minute, fix it."