aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2013-02-16 22:45:53 +0100
committerStephen Berman2013-02-16 22:45:53 +0100
commit21d0ff7bc8ec16e2808924b317d189dad90391c3 (patch)
tree9019819aa24cd23353dd298d4ef33d4edfa9e5c4
parentb117d0fbfca07ae8e3881a4d15e366d54a10095e (diff)
downloademacs-21d0ff7bc8ec16e2808924b317d189dad90391c3.tar.gz
emacs-21d0ff7bc8ec16e2808924b317d189dad90391c3.zip
* calendar/todos.el: Improve handling of overlays.
(todos-get-overlay): New function. (todos-prefix-overlay): Remove, since subsumed by todos-get-overlay, and replace by the latter in callers. (todos-reset-prefix): Apply only to buffer visiting Todos files. Simplify implementation and use `todos' overlay property. (todos-reset-done-separator): Use todos-get-overlay and `todos' overlay property. Fix logic. (todos-category-select): Use todos-get-overlay and `todos' overlay property. (todos-remove-item): Use todos-get-overlay. Correct obsolete code. (todos-prefix-overlays): Use todos-top-priority face also for non-numerical prefix of top priority items. Add `todos' overlay property. (todos-hide-show-date-time): Simplify, using todos-get-overlay and `todos' overlay property.
-rw-r--r--lisp/ChangeLog19
-rw-r--r--lisp/calendar/todos.el166
2 files changed, 98 insertions, 87 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 869a2f3deb7..2e4aac74190 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,22 @@
12013-02-16 Stephen Berman <stephen.berman@gmx.net>
2
3 * calendar/todos.el: Improve handling of overlays.
4 (todos-get-overlay): New function.
5 (todos-prefix-overlay): Remove, since subsumed by
6 todos-get-overlay, and replace by the latter in callers.
7 (todos-reset-prefix): Apply only to buffer visiting Todos files.
8 Simplify implementation and use `todos' overlay property.
9 (todos-reset-done-separator): Use todos-get-overlay and `todos'
10 overlay property. Fix logic.
11 (todos-category-select): Use todos-get-overlay and `todos' overlay
12 property.
13 (todos-remove-item): Use todos-get-overlay. Correct obsolete code.
14 (todos-prefix-overlays): Use todos-top-priority face also for
15 non-numerical prefix of top priority items. Add `todos' overlay
16 property.
17 (todos-hide-show-date-time): Simplify, using todos-get-overlay and
18 `todos' overlay property.
19
12013-02-14 Stephen Berman <stephen.berman@gmx.net> 202013-02-14 Stephen Berman <stephen.berman@gmx.net>
2 21
3 * calendar/todos.el (todos-edit-multiline, todos-edit-quit): 22 * calendar/todos.el (todos-edit-multiline, todos-edit-quit):
diff --git a/lisp/calendar/todos.el b/lisp/calendar/todos.el
index e3bac9fb60a..13249f95c10 100644
--- a/lisp/calendar/todos.el
+++ b/lisp/calendar/todos.el
@@ -212,21 +212,14 @@ These reflect the priorities of the items in each category."
212(defun todos-reset-prefix (symbol value) 212(defun todos-reset-prefix (symbol value)
213 "The :set function for `todos-prefix' and `todos-number-priorities'." 213 "The :set function for `todos-prefix' and `todos-number-priorities'."
214 (let ((oldvalue (symbol-value symbol)) 214 (let ((oldvalue (symbol-value symbol))
215 (files (append todos-files todos-archives))) 215 (files todos-file-buffers))
216 (custom-set-default symbol value) 216 (custom-set-default symbol value)
217 (when (not (equal value oldvalue)) 217 (when (not (equal value oldvalue))
218 (dolist (f files) 218 (dolist (f files)
219 (with-current-buffer (find-file-noselect f) 219 (with-current-buffer (find-file-noselect f)
220 (save-window-excursion 220 (remove-overlays 1 (1+ (buffer-size)) 'todos 'prefix)
221 (todos-show) 221 ;; Activate the new setting in the current category.
222 (save-excursion 222 (save-excursion (todos-category-select)))))))
223 (widen)
224 (goto-char (point-min))
225 (while (not (eobp))
226 (remove-overlays (point) (point)); 'before-string prefix)
227 (forward-line)))
228 ;; Activate the new setting (save-restriction does not help).
229 (save-excursion (todos-category-select))))))))
230 223
231(defcustom todos-item-mark "*" 224(defcustom todos-item-mark "*"
232 "String used to mark items. 225 "String used to mark items.
@@ -1181,14 +1174,16 @@ done items are shown. Its value is determined by user option
1181 (concat "\n\\(" (regexp-quote todos-category-done) "\\)") nil t) 1174 (concat "\n\\(" (regexp-quote todos-category-done) "\\)") nil t)
1182 (let* ((beg (match-beginning 1)) 1175 (let* ((beg (match-beginning 1))
1183 (end (match-end 0)) 1176 (end (match-end 0))
1184 (ovs (overlays-at beg)) 1177 (ov (progn (goto-char beg)
1185 (ov (when ovs (car ovs))) 1178 (todos-get-overlay 'separator)))
1186 (old-sep (when ov (overlay-get ov 'display))) 1179 (old-sep (when ov (overlay-get ov 'display)))
1187 new-ov) 1180 new-ov)
1188 (when (string= old-sep sep) 1181 (when old-sep
1189 (setq new-ov (make-overlay beg end)) 1182 (unless (string= old-sep sep)
1190 (overlay-put new-ov 'display todos-done-separator) 1183 (setq new-ov (make-overlay beg end))
1191 (delete-overlay ov))))))) 1184 (overlay-put new-ov 'todos 'separator)
1185 (overlay-put new-ov 'display todos-done-separator)
1186 (delete-overlay ov))))))))
1192 1187
1193(defun todos-category-completions () 1188(defun todos-category-completions ()
1194 "Return a list of completions for `todos-read-category'. 1189 "Return a list of completions for `todos-read-category'.
@@ -1259,17 +1254,12 @@ Todos files named in `todos-category-completions-files'."
1259 ;; Make display overlay for done items separator string, unless there 1254 ;; Make display overlay for done items separator string, unless there
1260 ;; already is one. 1255 ;; already is one.
1261 (let* ((done-sep todos-done-separator) 1256 (let* ((done-sep todos-done-separator)
1262 (ovs (overlays-at done-sep-start)) 1257 (ov (progn (goto-char done-sep-start)
1263 ;; ov-sep0 ov-sep1) 1258 (todos-get-overlay 'separator))))
1264 ov-sep) 1259 (unless ov
1265 ;; There should never be more than one overlay here, so car suffices. 1260 (setq ov (make-overlay done-sep-start done-end))
1266 (unless (and ovs (string= (overlay-get (car ovs) 'display) done-sep)) 1261 (overlay-put ov 'todos 'separator)
1267 (setq ov-sep (make-overlay done-sep-start done-end)) 1262 (overlay-put ov 'display done-sep))))
1268 (overlay-put ov-sep 'display done-sep))))
1269 ;; (setq ov-sep0 (make-overlay done-sep-start done-end))
1270 ;; (setq ov-sep1 (make-overlay done-end done-end))
1271 ;; (overlay-put ov-sep0 'invisible t)
1272 ;; (overlay-put ov-sep1 'after-string done-sep)))
1273 (narrow-to-region (point-min) done-start) 1263 (narrow-to-region (point-min) done-start)
1274 ;; Loading this from todos-mode, or adding it to the mode hook, causes 1264 ;; Loading this from todos-mode, or adding it to the mode hook, causes
1275 ;; Emacs to hang in todos-item-start, at (looking-at todos-item-start). 1265 ;; Emacs to hang in todos-item-start, at (looking-at todos-item-start).
@@ -1517,11 +1507,10 @@ The final element is \"*\", indicating an unspecified month.")
1517 1507
1518(defun todos-remove-item () 1508(defun todos-remove-item ()
1519 "Internal function called in editing, deleting or moving items." 1509 "Internal function called in editing, deleting or moving items."
1520 (let* ((beg (todos-item-start)) 1510 (let* ((end (progn (todos-item-end) (1+ (point))))
1521 (end (progn (todos-item-end) (1+ (point)))) 1511 (beg (todos-item-start))
1522 (ovs (overlays-in beg beg))) 1512 (ov (todos-get-overlay 'prefix)))
1523 ;; There can be both prefix/number and mark overlays. 1513 (when ov (delete-overlay ov))
1524 (while ovs (delete-overlay (car ovs)) (pop ovs))
1525 (delete-region beg end))) 1514 (delete-region beg end)))
1526 1515
1527(defun todos-diary-item-p () 1516(defun todos-diary-item-p ()
@@ -1545,20 +1534,24 @@ The final element is \"*\", indicating an unspecified month.")
1545 (progn (goto-char (point-min)) 1534 (progn (goto-char (point-min))
1546 (looking-at todos-done-string-start))))) 1535 (looking-at todos-done-string-start)))))
1547 1536
1548(defun todos-prefix-overlay () 1537(defun todos-get-overlay (val)
1549 "Return this item's prefix overlay." 1538 "Return the overlay at point whose `todos' property has value VAL."
1550 ;; Why doesn't this work? 1539 ;; Use overlays-in to find prefix overlays and check over two
1551 ;; (get-char-property-and-overlay lbp 'before-string) 1540 ;; positions to find done separator overlay.
1552 (let* ((lbp (line-beginning-position)) 1541 (let ((ovs (overlays-in (point) (1+ (point))))
1553 (ovs (overlays-in lbp lbp))) 1542 ov)
1554 (car ovs))) 1543 (catch 'done
1544 (while ovs
1545 (setq ov (pop ovs))
1546 (when (eq (overlay-get ov 'todos) val)
1547 (throw 'done ov))))))
1555 1548
1556(defun todos-marked-item-p () 1549(defun todos-marked-item-p ()
1557 "Non-nil if this item begins with `todos-item-mark'. 1550 "Non-nil if this item begins with `todos-item-mark'.
1558 In that case, return the item's prefix overlay." 1551 In that case, return the item's prefix overlay."
1559 ;; If a todos-item-insert command is called on a Todos file before 1552 ;; If a todos-item-insert command is called on a Todos file before
1560 ;; it is visited, it has no prefix overlays, so conditionalize: 1553 ;; it is visited, it has no prefix overlays, so conditionalize:
1561 (let* ((ov (todos-prefix-overlay)) 1554 (let* ((ov (todos-get-overlay 'prefix))
1562 (pref (when ov (overlay-get ov 'before-string))) 1555 (pref (when ov (overlay-get ov 'before-string)))
1563 (marked (when pref 1556 (marked (when pref
1564 (string-match (concat "^" (regexp-quote todos-item-mark)) 1557 (string-match (concat "^" (regexp-quote todos-item-mark))
@@ -1571,7 +1564,7 @@ The final element is \"*\", indicating an unspecified month.")
1571 ;; Insertion pushes item down but not its prefix overlay. When the 1564 ;; Insertion pushes item down but not its prefix overlay. When the
1572 ;; overlay includes a mark, this would now mark the inserted ITEM, 1565 ;; overlay includes a mark, this would now mark the inserted ITEM,
1573 ;; so move it to the pushed down item. 1566 ;; so move it to the pushed down item.
1574 (let ((ov (todos-prefix-overlay)) 1567 (let ((ov (todos-get-overlay 'prefix))
1575 (marked (todos-marked-item-p))) 1568 (marked (todos-marked-item-p)))
1576 (insert item "\n") 1569 (insert item "\n")
1577 (when marked (move-overlay ov (point) (point)))) 1570 (when marked (move-overlay ov (point) (point))))
@@ -1585,41 +1578,45 @@ The overlay's value is the string `todos-prefix' or with non-nil
1585the number of todo or done items in the category indicating the 1578the number of todo or done items in the category indicating the
1586item's priority. Todo and done items are numbered independently 1579item's priority. Todo and done items are numbered independently
1587of each other." 1580of each other."
1588 (let ((prefix (propertize (concat todos-prefix " ") 1581 (let ((num 0)
1589 'face 'todos-prefix-string))
1590 (num 0)
1591 (cat-tp (or (cdr (assoc-string 1582 (cat-tp (or (cdr (assoc-string
1592 (todos-current-category) 1583 (todos-current-category)
1593 (nth 2 (assoc-string todos-current-todos-file 1584 (nth 2 (assoc-string todos-current-todos-file
1594 todos-priorities-rules)))) 1585 todos-priorities-rules))))
1595 todos-show-priorities)) 1586 todos-show-priorities))
1596 done) 1587 done prefix)
1597 (save-excursion 1588 (save-excursion
1598 (goto-char (point-min)) 1589 (goto-char (point-min))
1599 (while (not (eobp)) 1590 (while (not (eobp))
1600 (when (or (todos-date-string-matcher (line-end-position)) 1591 (when (or (todos-date-string-matcher (line-end-position))
1601 (todos-done-string-matcher (line-end-position))) 1592 (todos-done-string-matcher (line-end-position)))
1602 (goto-char (match-beginning 0)) 1593 (goto-char (match-beginning 0))
1603 (when todos-number-priorities 1594 (setq num (1+ num))
1604 (setq num (1+ num)) 1595 ;; Reset number to 1 for first done item.
1605 ;; Reset number to 1 for first done item. 1596 (when (and (looking-at todos-done-string-start)
1606 (when (and (looking-at todos-done-string-start) 1597 (looking-back (concat "^"
1607 (looking-back (concat "^" 1598 (regexp-quote todos-category-done)
1608 (regexp-quote todos-category-done) 1599 "\n")))
1609 "\n"))) 1600 (setq num 1
1610 (setq num 1 1601 done t))
1611 done t)) 1602 (setq prefix (concat (propertize
1612 (setq prefix (propertize (concat (number-to-string num) " ") 1603 (if todos-number-priorities
1613 'face 1604 (number-to-string num)
1614 ;; Numbers of top priorities have 1605 todos-prefix)
1615 ;; a distinct face in Todos mode. 1606 'face
1616 (if (and (not done) (<= num cat-tp) 1607 ;; Prefix of top priority items has a
1617 (eq major-mode 'todos-mode)) 1608 ;; distinct face in Todos mode.
1618 'todos-top-priority 1609 (if (and (not done) (<= num cat-tp)
1619 'todos-prefix-string)))) 1610 (eq major-mode 'todos-mode))
1620 (let ((ov (todos-prefix-overlay)) 1611 'todos-top-priority
1612 'todos-prefix-string))
1613 " "))
1614 (let ((ov (todos-get-overlay 'prefix))
1621 (marked (todos-marked-item-p))) 1615 (marked (todos-marked-item-p)))
1616 ;; Prefix overlay must be at a single position so its
1617 ;; bounds aren't changed when (re)moving an item.
1622 (unless ov (setq ov (make-overlay (point) (point)))) 1618 (unless ov (setq ov (make-overlay (point) (point))))
1619 (overlay-put ov 'todos 'prefix)
1623 (overlay-put ov 'before-string (if marked 1620 (overlay-put ov 'before-string (if marked
1624 (concat todos-item-mark prefix) 1621 (concat todos-item-mark prefix)
1625 prefix)))) 1622 prefix))))
@@ -3764,26 +3761,21 @@ face."
3764 (save-excursion 3761 (save-excursion
3765 (save-restriction 3762 (save-restriction
3766 (goto-char (point-min)) 3763 (goto-char (point-min))
3767 (let ((ovs (overlays-in (point) (1+ (point)))) 3764 (if (todos-get-overlay 'header)
3768 ov hidden) 3765 (remove-overlays 1 (1+ (buffer-size)) 'todos 'header)
3769 (while ovs
3770 (setq ov (pop ovs))
3771 (if (equal (overlay-get ov 'display) "")
3772 (setq ovs nil hidden t)))
3773 (widen) 3766 (widen)
3774 (goto-char (point-min)) 3767 (goto-char (point-min))
3775 (if hidden 3768 (while (not (eobp))
3776 (remove-overlays (point-min) (point-max) 'display "") 3769 (when (re-search-forward
3777 (while (not (eobp)) 3770 (concat todos-date-string-start todos-date-pattern
3778 (when (re-search-forward 3771 "\\( " diary-time-regexp "\\)?"
3779 (concat todos-date-string-start todos-date-pattern 3772 (regexp-quote todos-nondiary-end) "? ")
3780 "\\( " diary-time-regexp "\\)?" 3773 nil t)
3781 (regexp-quote todos-nondiary-end) "? ") 3774 (unless (save-match-data (todos-done-item-p))
3782 nil t) 3775 (setq ov (make-overlay (match-beginning 0) (match-end 0) nil t))
3783 (unless (save-match-data (todos-done-item-p)) 3776 (overlay-put ov 'todos 'header)
3784 (setq ov (make-overlay (match-beginning 0) (match-end 0) nil t)) 3777 (overlay-put ov 'display "")))
3785 (overlay-put ov 'display ""))) 3778 (todos-forward-item))))))
3786 (todos-forward-item)))))))
3787 3779
3788(defun todos-mark-unmark-item (&optional n) 3780(defun todos-mark-unmark-item (&optional n)
3789 "Mark item with `todos-item-mark' if unmarked, otherwise unmark it. 3781 "Mark item with `todos-item-mark' if unmarked, otherwise unmark it.
@@ -3794,7 +3786,7 @@ marking of the next N items."
3794 (dotimes (i n) 3786 (dotimes (i n)
3795 (let* ((cat (todos-current-category)) 3787 (let* ((cat (todos-current-category))
3796 (marks (assoc cat todos-categories-with-marks)) 3788 (marks (assoc cat todos-categories-with-marks))
3797 (ov (todos-prefix-overlay)) 3789 (ov (todos-get-overlay 'prefix))
3798 (pref (overlay-get ov 'before-string))) 3790 (pref (overlay-get ov 'before-string)))
3799 (if (todos-marked-item-p) 3791 (if (todos-marked-item-p)
3800 (progn 3792 (progn
@@ -3817,7 +3809,7 @@ marking of the next N items."
3817 (while (not (eobp)) 3809 (while (not (eobp))
3818 (let* ((cat (todos-current-category)) 3810 (let* ((cat (todos-current-category))
3819 (marks (assoc cat todos-categories-with-marks)) 3811 (marks (assoc cat todos-categories-with-marks))
3820 (ov (todos-prefix-overlay)) 3812 (ov (todos-get-overlay 'prefix))
3821 (pref (overlay-get ov 'before-string))) 3813 (pref (overlay-get ov 'before-string)))
3822 (unless (todos-marked-item-p) 3814 (unless (todos-marked-item-p)
3823 (overlay-put ov 'before-string (concat todos-item-mark pref)) 3815 (overlay-put ov 'before-string (concat todos-item-mark pref))
@@ -3834,7 +3826,7 @@ marking of the next N items."
3834 (while (not (eobp)) 3826 (while (not (eobp))
3835 (let* ((cat (todos-current-category)) 3827 (let* ((cat (todos-current-category))
3836 (marks (assoc cat todos-categories-with-marks)) 3828 (marks (assoc cat todos-categories-with-marks))
3837 (ov (todos-prefix-overlay)) 3829 (ov (todos-get-overlay 'prefix))
3838 (pref (overlay-get ov 'before-string))) 3830 (pref (overlay-get ov 'before-string)))
3839 (when (todos-marked-item-p) 3831 (when (todos-marked-item-p)
3840 (overlay-put ov 'before-string (substring pref 1)) 3832 (overlay-put ov 'before-string (substring pref 1))
@@ -4883,7 +4875,7 @@ the format of Diary entries."
4883 (interactive) 4875 (interactive)
4884 (widen) 4876 (widen)
4885 (todos-edit-mode) 4877 (todos-edit-mode)
4886 (remove-overlays) ; nil nil 'before-string) 4878 (remove-overlays)
4887 (message "%s" (substitute-command-keys 4879 (message "%s" (substitute-command-keys
4888 (concat "Type \\[todos-edit-quit] to check file format " 4880 (concat "Type \\[todos-edit-quit] to check file format "
4889 "validity and return to Todos mode.\n")))) 4881 "validity and return to Todos mode.\n"))))
@@ -5412,7 +5404,7 @@ meaning to raise or lower the item's priority by one."
5412 (todos-insert-with-overlays item) 5404 (todos-insert-with-overlays item)
5413 ;; If item was marked, restore the mark. 5405 ;; If item was marked, restore the mark.
5414 (and marked 5406 (and marked
5415 (let* ((ov (todos-prefix-overlay)) 5407 (let* ((ov (todos-get-overlay 'prefix))
5416 (pref (overlay-get ov 'before-string))) 5408 (pref (overlay-get ov 'before-string)))
5417 (overlay-put ov 'before-string (concat todos-item-mark pref))))))) 5409 (overlay-put ov 'before-string (concat todos-item-mark pref)))))))
5418 5410