summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2010-07-14 21:31:50 +0200
committerNicolas Goaziou <n.goaziou@gmail.com>2010-09-01 19:05:46 +0200
commit2dd3b8a2a8e31c8c4a6e4b26708d436d1e79d8fa (patch)
treecf51d67b04b3f8c5848ff6a6cd8a5fc65bbb26ec
parent2e4e05b3d6b3a8ba441e079371d8959ec57e67f3 (diff)
downloadorg-mode-2dd3b8a2a8e31c8c4a6e4b26708d436d1e79d8fa.tar.gz
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.
-rw-r--r--lisp/org-list.el158
-rw-r--r--lisp/org-timer.el71
2 files changed, 145 insertions, 84 deletions
diff --git a/lisp/org-list.el b/lisp/org-list.el
index 4603f45..56da141 100644
--- a/lisp/org-list.el
+++ b/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
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))
- (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
diff --git a/lisp/org-timer.el b/lisp/org-timer.el
index 94319e7..3b3ced2 100644
--- a/lisp/org-timer.el
+++ b/lisp/org-timer.el
@@ -195,16 +195,69 @@ that was not started at the correct moment."
(defun org-timer-item (&optional arg)
"Insert a description-type item with the current timer value."
(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)))
- (insert ":: ")))
+ (insert ":: "))))
(defun org-timer-fix-incomplete (hms)
"If hms is a H:MM:SS string with missing hour or hour and minute, fix it."