diff options
| author | Stephen Berman | 2013-02-16 22:45:53 +0100 |
|---|---|---|
| committer | Stephen Berman | 2013-02-16 22:45:53 +0100 |
| commit | 21d0ff7bc8ec16e2808924b317d189dad90391c3 (patch) | |
| tree | 9019819aa24cd23353dd298d4ef33d4edfa9e5c4 | |
| parent | b117d0fbfca07ae8e3881a4d15e366d54a10095e (diff) | |
| download | emacs-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/ChangeLog | 19 | ||||
| -rw-r--r-- | lisp/calendar/todos.el | 166 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-02-14 Stephen Berman <stephen.berman@gmx.net> | 20 | 2013-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 | |||
| 1585 | the number of todo or done items in the category indicating the | 1578 | the number of todo or done items in the category indicating the |
| 1586 | item's priority. Todo and done items are numbered independently | 1579 | item's priority. Todo and done items are numbered independently |
| 1587 | of each other." | 1580 | of 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 | ||