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.
This commit is contained in:
Nicolas Goaziou 2010-07-14 21:31:50 +02:00
parent 2e4e05b3d6
commit 2dd3b8a2a8
2 changed files with 145 additions and 84 deletions

View File

@ -613,13 +613,26 @@ 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 things worked, nil when we are not in an item, or item is
block, or item is invisible." invisible."
(unless (or (not (org-in-item-p)) (unless (or (not (org-in-item-p))
(org-invisible-p) (org-invisible-p))
(org-in-regexps-block-p "^[ \t]*#\\+begin_\\([a-zA-Z]\\)" ;; Timer list: delegate to `org-timer-item'.
'(concat "^[ \t]*#\\+end_" (match-string 1)))) (if (save-excursion
(let* ((pos (point)) (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) (before-p (and (org-at-item-p)
(<= (point) (match-end 0)))) (<= (point) (match-end 0))))
(item-start (org-beginning-of-item)) (item-start (org-beginning-of-item))
@ -627,10 +640,9 @@ block, or item is invisible."
(match-string 0))) (match-string 0)))
(description-p (and (looking-at "[ \t]*\\(.*?\\) ::") (description-p (and (looking-at "[ \t]*\\(.*?\\) ::")
(match-string 1))) (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. ;; Guess number of blank lines used to separate items.
(blank-lines-nb (let ((insert-blank-p (blank-lines-nb
(let ((insert-blank-p
(cdr (assq 'plain-list-item org-blank-before-new-entry)))) (cdr (assq 'plain-list-item org-blank-before-new-entry))))
(cond (cond
((or ((or
@ -649,14 +661,15 @@ block, or item is invisible."
"^[ \t]*$" (save-excursion (org-beginning-of-item-list)) t)) "^[ \t]*$" (save-excursion (org-beginning-of-item-list)) t))
(1+ (org-back-over-empty-lines)) (1+ (org-back-over-empty-lines))
0)))))) 0))))))
(insert-fun (lambda (&optional string-after-bullet) (insert-fun
(lambda (&optional string-after-bullet)
;; insert bullet above item in order to avoid ;; insert bullet above item in order to avoid
;; bothering with possible blank lines ending ;; bothering with possible blank lines ending
;; last item ;; last item
(org-beginning-of-item) (org-beginning-of-item)
(insert (concat bullet-init (insert (concat bullet-init
(when checkbox "[ ] ") (when checkbox "[ ] ")
(when (and description-p (not timer-p)) (when description-p
(concat (read-string "Term: ") " :: ")))) (concat (read-string "Term: ") " :: "))))
(save-excursion (save-excursion
(insert (concat string-after-bullet (insert (concat string-after-bullet
@ -664,11 +677,6 @@ block, or item is invisible."
(unless before-p (org-move-item-down))))) (unless before-p (org-move-item-down)))))
(goto-char pos) (goto-char pos)
(cond (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 (before-p
(funcall insert-fun) (funcall insert-fun)
;; Renumber in this case, as we're not moving down. ;; Renumber in this case, as we're not moving down.
@ -688,7 +696,7 @@ block, or item is invisible."
(prog1 (prog1
(buffer-substring pos end-before-blank) (buffer-substring pos end-before-blank)
(delete-region pos end-before-blank))))) (delete-region pos end-before-blank)))))
(funcall insert-fun after-bullet) t)))))) (funcall insert-fun after-bullet) t)))))))
;;; Indentation ;;; Indentation

View File

@ -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 (cond
(if (not (org-in-item-p)) ;; If we are in a timer list, insert item like `org-insert-item'.
(org-indent-line-function) ((and (org-in-item-p)
(save-excursion
(org-beginning-of-item) (org-beginning-of-item)
(org-get-indentation))))) (looking-at "[ \t]*[-+*][ \t]+[0-9]+:[0-9]+:[0-9]+ ::")))
(or (bolp) (newline)) (let ((pos (point))
(org-indent-line-to ind) (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 "- ") (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."