diff options
| author | Oliver Seidel | 1997-10-17 15:41:57 +0000 |
|---|---|---|
| committer | Oliver Seidel | 1997-10-17 15:41:57 +0000 |
| commit | e4541b670de21babbaaad1ca849c3a7e57ac2b2d (patch) | |
| tree | 63292bc00e2bf2e5df1b6333da9ef6e5e09e2097 | |
| parent | 0b140219122afb652c3e8943b019c06119c3f6ac (diff) | |
| download | emacs-e4541b670de21babbaaad1ca849c3a7e57ac2b2d.tar.gz emacs-e4541b670de21babbaaad1ca849c3a7e57ac2b2d.zip | |
Thanks to Harald Backer <harald.backer@fou.telenor.no>, we now have
the following facilities available:
Added todo-print, todo-top-priorities and todo-jump with matching
variables; Parameterized todo-header, todo-category-beg,
todo-category-end and todo-category-sep; Added autoload comments;
todo-category-select: Modified regexp to make category names unique;
todo-forward-item: Added optional COUNT vaiable; todo-insert-item:
Rewrote completing read entry.
Also, check out the extended list of things left to be done to this
package at the end of the documentation!
| -rw-r--r-- | lisp/calendar/todo-mode.el | 487 |
1 files changed, 355 insertions, 132 deletions
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index 078bbd1dfd1..cb7e020fc26 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: Oliver.Seidel@cl.cam.ac.uk (was valid on Aug 2, 1997) | 5 | ;; Author: Oliver.Seidel@cl.cam.ac.uk (was valid on Aug 2, 1997) |
| 6 | ;; Created: 2 Aug 1997 | 6 | ;; Created: 2 Aug 1997 |
| 7 | ;; Version: $Id: todo-mode.el,v 1.18 1997/10/15 17:18:11 os10000 Exp os10000 $ | 7 | ;; Version: $Id: todo-mode.el,v 1.19 1997/10/16 21:21:16 os10000 Exp os10000 $ |
| 8 | ;; Keywords: Categorised TODO list editor, todo-mode | 8 | ;; Keywords: Categorised TODO list editor, todo-mode |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -30,64 +30,83 @@ | |||
| 30 | 30 | ||
| 31 | ;; Preface, Quickstart Installation | 31 | ;; Preface, Quickstart Installation |
| 32 | ;; | 32 | ;; |
| 33 | ;; To get this to work, make emacs execute the line | 33 | ;; To get this to work, make emacs execute the line |
| 34 | ;; | 34 | ;; |
| 35 | ;; (require 'todo-mode) ;; load the TODO package | 35 | ;; (require 'todo-mode) ;; load the TODO package |
| 36 | ;; | 36 | ;; |
| 37 | ;; You may now enter new items by typing "M-x todo-insert-item", or enter | 37 | ;; If you don't like "require", do as Harald Backer prescribes: |
| 38 | ;; your the TODO list file by typing "M-x todo-show". | ||
| 39 | ;; | 38 | ;; |
| 40 | ;; The TODO list file has a special format and some auxiliary | 39 | ;; "I don't like require statements as they slow down startup |
| 41 | ;; information, which will be added by the todo-show function if it | 40 | ;; emacs. As I include .todo-do in diary and start calendar |
| 42 | ;; attempts to visit an un-initialised file. Hence it is | 41 | ;; at startup of emacs, the mode indicator of .todo-do will |
| 43 | ;; recommended to use the todo-show function for the first time, in | 42 | ;; make emacs fail, unless the following is defined:" |
| 44 | ;; order to initialise the file, but it is not necessary | ||
| 45 | ;; afterwards. | ||
| 46 | ;; | 43 | ;; |
| 47 | ;; As these commands are quite long to type, I would recommend the | 44 | ;; (autoload 'todo-mode "todo-mode" |
| 48 | ;; addition of two bindings to your to your global keymap. I | 45 | ;; "Major mode for editing TODO lists." t) |
| 49 | ;; personally have the following in my initialisation file: | ||
| 50 | ;; | 46 | ;; |
| 51 | ;; (global-set-key "\C-ct" 'todo-show) ;; switch to TODO buffer | 47 | ;; You may now enter new items by typing "M-x todo-insert-item", |
| 48 | ;; or enter your TODO list file by typing "M-x todo-show". | ||
| 49 | ;; | ||
| 50 | ;; The TODO list file has a special format and some auxiliary | ||
| 51 | ;; information, which will be added by the todo-show function if | ||
| 52 | ;; it attempts to visit an un-initialised file. Hence it is | ||
| 53 | ;; recommended to use the todo-show function for the first time, | ||
| 54 | ;; in order to initialise the file, but it is not necessary | ||
| 55 | ;; afterwards. | ||
| 56 | ;; | ||
| 57 | ;; As these commands are quite long to type, I would recommend | ||
| 58 | ;; the addition of two bindings to your to your global keymap. I | ||
| 59 | ;; personally have the following in my initialisation file: | ||
| 60 | ;; | ||
| 61 | ;; (global-set-key "\C-ct" 'todo-show) ;; switch to TODO buffer | ||
| 52 | ;; (global-set-key "\C-ci" 'todo-insert-item) ;; insert new item | 62 | ;; (global-set-key "\C-ci" 'todo-insert-item) ;; insert new item |
| 53 | ;; | 63 | ;; |
| 54 | ;; Note, however, that this recommendation has prompted some | 64 | ;; Note, however, that this recommendation has prompted some |
| 55 | ;; criticism, since the keys C-c LETTER are reserved for user | 65 | ;; criticism, since the keys C-c LETTER are reserved for user |
| 56 | ;; functions. I believe my recommendation is acceptable, since the | 66 | ;; functions. I believe my recommendation is acceptable, since |
| 57 | ;; Emacs Lisp Manual *Tips* section also details that the mode itself | 67 | ;; the Emacs Lisp Manual *Tips* section also details that the |
| 58 | ;; should not bind any functions to those keys. The express aim of | 68 | ;; mode itself should not bind any functions to those keys. The |
| 59 | ;; the above two bindings is to work outside the mode, which doesn't | 69 | ;; express aim of the above two bindings is to work outside the |
| 60 | ;; need the show function and offers a different binding for the | 70 | ;; mode, which doesn't need the show function and offers a |
| 61 | ;; insert function. They serve as shortcuts and are not even needed | 71 | ;; different binding for the insert function. They serve as |
| 62 | ;; (since the TODO mode will be entered by visiting the TODO file, and | 72 | ;; shortcuts and are not even needed (since the TODO mode will be |
| 63 | ;; later by switching to its buffer). | 73 | ;; entered by visiting the TODO file, and later by switching to |
| 74 | ;; its buffer). | ||
| 75 | ;; | ||
| 76 | ;; Version | ||
| 64 | ;; | 77 | ;; |
| 65 | ;; Pre-Requisites | 78 | ;; Which version of todo-mode.el does this documentation refer to? |
| 66 | ;; | 79 | ;; |
| 67 | ;; This package will require the following packages to be available on | 80 | ;; $Id:$ |
| 68 | ;; the load-path: | ||
| 69 | ;; | 81 | ;; |
| 70 | ;; time-stamp | 82 | ;; Pre-Requisites |
| 83 | ;; | ||
| 84 | ;; This package will require the following packages to be | ||
| 85 | ;; available on the load-path: | ||
| 86 | ;; | ||
| 87 | ;; time-stamp | ||
| 71 | ;; easymenu | 88 | ;; easymenu |
| 72 | ;; | 89 | ;; |
| 73 | ;; Mode Description | 90 | ;; Mode Description |
| 74 | ;; | 91 | ;; |
| 75 | ;; TODO is a major mode for EMACS which offers functionality to treat | 92 | ;; TODO is a major mode for EMACS which offers functionality to |
| 76 | ;; most lines in one buffer as a list of items one has to do. There | 93 | ;; treat most lines in one buffer as a list of items one has to |
| 77 | ;; are facilities to add new items, which are categorised, to edit or | 94 | ;; do. There are facilities to add new items, which are |
| 78 | ;; even delete items from the buffer. The buffer contents are | 95 | ;; categorised, to edit or even delete items from the buffer. |
| 79 | ;; currently compatible with the diary, so that the list of todo-items | 96 | ;; The buffer contents are currently compatible with the diary, |
| 80 | ;; will show up in the FANCY diary mode. | 97 | ;; so that the list of todo-items will show up in the FANCY diary |
| 98 | ;; mode. | ||
| 81 | ;; | 99 | ;; |
| 82 | ;; Notice: Besides the major mode, this file also exports the function | 100 | ;; Notice: Besides the major mode, this file also exports the |
| 83 | ;; "todo-show" which will change to the one specific TODO file that | 101 | ;; function "todo-show" which will change to the one specific |
| 84 | ;; has been specified in the todo-file-do variable. If this file does | 102 | ;; TODO file that has been specified in the todo-file-do |
| 85 | ;; not conform to the TODO mode conventions, the todo-show function | 103 | ;; variable. If this file does not conform to the TODO mode |
| 86 | ;; will add the appropriate header and footer. I don't anticipate | 104 | ;; conventions, the todo-show function will add the appropriate |
| 87 | ;; this to cause much grief, but be warned, in case you attempt to | 105 | ;; header and footer. I don't anticipate this to cause much |
| 88 | ;; read a plain text file. | 106 | ;; grief, but be warned, in case you attempt to read a plain text |
| 107 | ;; file. | ||
| 89 | ;; | 108 | ;; |
| 90 | ;; Operation | 109 | ;; Operation |
| 91 | ;; | 110 | ;; |
| 92 | ;; You will have the following facilities available: | 111 | ;; You will have the following facilities available: |
| 93 | ;; | 112 | ;; |
| @@ -95,119 +114,158 @@ | |||
| 95 | ;; | 114 | ;; |
| 96 | ;; + to go to next category | 115 | ;; + to go to next category |
| 97 | ;; - to go to previous category | 116 | ;; - to go to previous category |
| 117 | ;; d to file the current entry, including a | ||
| 118 | ;; comment and timestamp | ||
| 98 | ;; e to edit the current entry | 119 | ;; e to edit the current entry |
| 99 | ;; f to file the current entry, including a | 120 | ;; f to file the current entry, including a |
| 100 | ;; comment and timestamp | 121 | ;; comment and timestamp |
| 101 | ;; i to insert a new entry | 122 | ;; i to insert a new entry |
| 123 | ;; j jump to category | ||
| 102 | ;; k to kill the current entry | 124 | ;; k to kill the current entry |
| 103 | ;; l to lower the current entry's priority | 125 | ;; l to lower the current entry's priority |
| 104 | ;; n for the next entry | 126 | ;; n for the next entry |
| 105 | ;; p for the previous entry | 127 | ;; p for the previous entry |
| 128 | ;; P print | ||
| 106 | ;; q to save the list and exit the buffer | 129 | ;; q to save the list and exit the buffer |
| 107 | ;; r to raise the current entry's priority | 130 | ;; r to raise the current entry's priority |
| 108 | ;; s to save the list | 131 | ;; s to save the list |
| 132 | ;; t show top priority items for each category | ||
| 109 | ;; | 133 | ;; |
| 110 | ;; When you add a new entry, you are asked for the text and then for | 134 | ;; When you add a new entry, you are asked for the text and then |
| 111 | ;; the category. I for example have categories for things that I want | 135 | ;; for the category. I for example have categories for things |
| 112 | ;; to do in the office (like mail my mum), that I want to do in town | 136 | ;; that I want to do in the office (like mail my mum), that I |
| 113 | ;; (like buy cornflakes) and things I want to do at home (move my | 137 | ;; want to do in town (like buy cornflakes) and things I want to |
| 114 | ;; suitcases). The categories can be selected with the cursor keys | 138 | ;; do at home (move my suitcases). The categories can be |
| 115 | ;; and if you type in the name of a category which didn't exist | 139 | ;; selected with the cursor keys and if you type in the name of a |
| 116 | ;; before, an empty category of the desired name will be added and | 140 | ;; category which didn't exist before, an empty category of the |
| 117 | ;; filled with the new entry. | 141 | ;; desired name will be added and filled with the new entry. |
| 118 | ;; | 142 | ;; |
| 119 | ;; Configuration | 143 | ;; Configuration |
| 120 | ;; | 144 | ;; |
| 121 | ;; Variable todo-prefix | 145 | ;; Variable todo-prefix |
| 122 | ;; | 146 | ;; |
| 123 | ;; I would like to recommend that you use the prefix "*/*" (by | 147 | ;; I would like to recommend that you use the prefix "*/*" (by |
| 124 | ;; leaving the variable 'todo-prefix' untouched) so that the diary | 148 | ;; leaving the variable 'todo-prefix' untouched) so that the |
| 125 | ;; displays each entry every day. | 149 | ;; diary displays each entry every day. |
| 126 | ;; | 150 | ;; |
| 127 | ;; To understand what I mean, please read the documentation that goes | 151 | ;; To understand what I mean, please read the documentation that |
| 128 | ;; with the calendar since that will tell you how you can set up the | 152 | ;; goes with the calendar since that will tell you how you can |
| 129 | ;; fancy diary display and use the #include command to include your | 153 | ;; set up the fancy diary display and use the #include command to |
| 130 | ;; todo list file as part of your diary. | 154 | ;; include your todo list file as part of your diary. |
| 131 | ;; | 155 | ;; |
| 132 | ;; If you have the diary package set up to usually display more than | 156 | ;; If you have the diary package set up to usually display more |
| 133 | ;; one day's entries at once, consider using | 157 | ;; than one day's entries at once, consider using |
| 134 | ;; | 158 | ;; |
| 135 | ;; "&%%(equal (calendar-current-date) date)" | 159 | ;; "&%%(equal (calendar-current-date) date)" |
| 136 | ;; | 160 | ;; |
| 137 | ;; as the value of `todo-prefix'. Please note that this may slow down | 161 | ;; as the value of `todo-prefix'. Please note that this may slow |
| 138 | ;; the processing of your diary file some. | 162 | ;; down the processing of your diary file some. |
| 139 | ;; | 163 | ;; |
| 140 | ;; Variable todo-file-do | 164 | ;; Variable todo-file-do |
| 141 | ;; | 165 | ;; |
| 142 | ;; This variable is fairly self-explanatory. You have to store your TODO | 166 | ;; This variable is fairly self-explanatory. You have to store |
| 143 | ;; list somewhere. This variable tells the package where to go and find | 167 | ;; your TODO list somewhere. This variable tells the package |
| 144 | ;; this file. | 168 | ;; where to go and find this file. |
| 145 | ;; | 169 | ;; |
| 146 | ;; Variable todo-file-done | 170 | ;; Variable todo-file-done |
| 147 | ;; | 171 | ;; |
| 148 | ;; Even when you're done, you may wish to retain the entries. Given | 172 | ;; Even when you're done, you may wish to retain the entries. |
| 149 | ;; that they're timestamped and you are offered to add a comment, this | 173 | ;; Given that they're timestamped and you are offered to add a |
| 150 | ;; can make a useful diary of past events. It will even blend in with | 174 | ;; comment, this can make a useful diary of past events. It will |
| 151 | ;; the EMACS diary package. So anyway, this variable holds the name | 175 | ;; even blend in with the EMACS diary package. So anyway, this |
| 152 | ;; of the file for the filed todo-items. | 176 | ;; variable holds the name of the file for the filed todo-items. |
| 153 | ;; | 177 | ;; |
| 154 | ;; Variable todo-mode-hook | 178 | ;; Variable todo-mode-hook |
| 155 | ;; | 179 | ;; |
| 156 | ;; Just like other modes, too, this mode offers to call your functions | 180 | ;; Just like other modes, too, this mode offers to call your |
| 157 | ;; before it goes about its business. This variable will be inspected | 181 | ;; functions before it goes about its business. This variable |
| 158 | ;; for any functions you may wish to have called once the other TODO | 182 | ;; will be inspected for any functions you may wish to have |
| 159 | ;; mode preparations have been completed. | 183 | ;; called once the other TODO mode preparations have been |
| 160 | ;; | 184 | ;; completed. |
| 161 | ;; Variables todo-insert-threshold | 185 | ;; |
| 162 | ;; | 186 | ;; Variable todo-insert-threshold |
| 163 | ;; Another nifty feature is the insertion accuracy. If you have 8 | 187 | ;; |
| 164 | ;; items in your TODO list, then you may get asked 4 questions by the | 188 | ;; Another nifty feature is the insertion accuracy. If you have |
| 165 | ;; binary insertion algorithm. However, you may not really have a | 189 | ;; 8 items in your TODO list, then you may get asked 4 questions |
| 166 | ;; need for such accurate priorities amongst your TODO items. If you | 190 | ;; by the binary insertion algorithm. However, you may not |
| 167 | ;; now think about the binary insertion halfing the size of the window | 191 | ;; really have a need for such accurate priorities amongst your |
| 168 | ;; each time, then the threshhold is the window size at which it will | 192 | ;; TODO items. If you now think about the binary insertion |
| 169 | ;; stop. If you set the threshhold to zero, the upper and lower bound | 193 | ;; halfing the size of the window each time, then the threshhold |
| 170 | ;; will coincide at the end of the loop and you will insert your item | 194 | ;; is the window size at which it will stop. If you set the |
| 171 | ;; just before that point. If you set the threshhold to i.e. 8, it | 195 | ;; threshhold to zero, the upper and lower bound will coincide at |
| 172 | ;; will stop as soon as the window size drops below that amount and | 196 | ;; the end of the loop and you will insert your item just before |
| 173 | ;; will insert the item in the approximate centre of that window. I | 197 | ;; that point. If you set the threshhold to i.e. 8, it will stop |
| 174 | ;; got the idea for this feature after reading a very helpful e-mail | 198 | ;; as soon as the window size drops below that amount and will |
| 175 | ;; reply from Trey Jackson <trey@cs.berkeley.edu> who corrected some | 199 | ;; insert the item in the approximate centre of that window. I |
| 176 | ;; of my awful coding and pointed me towards some good reading. | 200 | ;; got the idea for this feature after reading a very helpful |
| 177 | ;; Thanks Trey! | 201 | ;; e-mail reply from Trey Jackson <trey@cs.berkeley.edu> who |
| 202 | ;; corrected some of my awful coding and pointed me towards some | ||
| 203 | ;; good reading. Thanks Trey! | ||
| 178 | ;; | 204 | ;; |
| 179 | ;; Things to do | 205 | ;; Things to do |
| 180 | ;; | 206 | ;; |
| 181 | ;; o licence / version function | 207 | ;; These originally were my ideas, but now also include all the |
| 208 | ;; suggestions that I included before forgetting them: | ||
| 209 | ;; | ||
| 210 | ;; o Automatic save of top-priorities to file, for inclusion in | ||
| 211 | ;; .diary, at save of .todo-do, ref. automatic save of .bbdb | ||
| 212 | ;; in gnus | ||
| 213 | ;; o Fancy fonts for todo/top-priority buffer | ||
| 214 | ;; o Remove todo-prefix option in todo-top-priorities | ||
| 215 | ;; o Rename category | ||
| 216 | ;; o Move entry from one category to another one | ||
| 217 | ;; o Entries which both have the generic */* prefix and a | ||
| 218 | ;; "deadline" entry which are understood by diary, indicating | ||
| 219 | ;; an event (unless marked by &) | ||
| 220 | ;; o The optional COUNT variable of todo-forward-item should be | ||
| 221 | ;; applied to the other functions performing similar tasks | ||
| 222 | ;; o Modularization could be done for repeaded elements of | ||
| 223 | ;; the code, like the completing-read lines of code. | ||
| 224 | ;; o license / version function | ||
| 182 | ;; o export to diary file | 225 | ;; o export to diary file |
| 183 | ;; o todo-report-bug | 226 | ;; o todo-report-bug |
| 184 | ;; o GNATS support | 227 | ;; o GNATS support |
| 185 | ;; o elide multiline | 228 | ;; o elide multiline (as in bbdb, or, to a lesser degree, in |
| 186 | ;; o rewrite complete package to store data as lisp objects and have | 229 | ;; outline mode) |
| 187 | ;; display modes for display, for diary export, etc. | 230 | ;; o rewrite complete package to store data as lisp objects |
| 188 | ;; (Richard Stallman pointed out this is a bad idea) | 231 | ;; and have display modes for display, for diary export, |
| 189 | ;; o base todo-mode.el on generic-mode.el instead | 232 | ;; etc. (Richard Stallman pointed out this is a bad idea) |
| 233 | ;; o so base todo-mode.el on generic-mode.el instead | ||
| 190 | ;; | 234 | ;; |
| 191 | ;; History and Gossip | 235 | ;; History and Gossip |
| 192 | ;; | 236 | ;; |
| 193 | ;; Many thanks to all the ones who have contributed to the evolution | 237 | ;; Many thanks to all the ones who have contributed to the |
| 194 | ;; of this package! I hope I have listed all of you somewhere in the | 238 | ;; evolution of this package! I hope I have listed all of you |
| 195 | ;; documentation or at least in the RCS history! | 239 | ;; somewhere in the documentation or at least in the RCS history! |
| 196 | ;; | 240 | ;; |
| 197 | ;; Enjoy this package and express your gratitude by sending nice things | 241 | ;; Enjoy this package and express your gratitude by sending nice |
| 198 | ;; to my parents' address! | 242 | ;; things to my parents' address! |
| 199 | ;; | 243 | ;; |
| 200 | ;; Oliver Seidel | 244 | ;; Oliver Seidel |
| 201 | ;; (O Seidel, Lessingstr. 8, 65760 Eschborn, Federal Republic of Germany) | 245 | ;; (Lessingstr. 8, 65760 Eschborn, Federal Republic of Germany) |
| 202 | ;; | 246 | ;; |
| 203 | 247 | ||
| 204 | ;; --------------------------------------------------------------------------- | 248 | ;; --------------------------------------------------------------------------- |
| 205 | 249 | ||
| 206 | ;; --------------------------------------------------------------------------- | ||
| 207 | |||
| 208 | ;;; Change Log: | 250 | ;;; Change Log: |
| 209 | 251 | ||
| 210 | ;; $Log: todo-mode.el,v $ | 252 | ;; $Log: todo-mode.el,v $ |
| 253 | ;; Revision 1.19 1997/10/16 21:21:16 os10000 | ||
| 254 | ;; Jari Aalto <jari.aalto@poboxes.com> writes: | ||
| 255 | ;; | ||
| 256 | ;; I just downloaded your package and after reading the docs I | ||
| 257 | ;; decided to do some reformatting. Hope you don't mind. Now | ||
| 258 | ;; they are in such a format that the html page can be | ||
| 259 | ;; automatically generated from the source file. As an example, I | ||
| 260 | ;; generated the attached page using the following command: | ||
| 261 | ;; ripdoc.pls < todo-mode.el | t2html.pls -a "Oliver.Seidel" -e \ | ||
| 262 | ;; Oliver.Seidel@cl.cam.ac.uk -simple | ||
| 263 | ;; | ||
| 264 | ;; And of course I appreciate it. Jari's stuff can be found at: | ||
| 265 | ;; ftp://cs.uta.fi/pub/ssjaaa/, while I'm making the rev 1.18 page | ||
| 266 | ;; available at http://www.cl.cam.ac.uk/users/os10000/doc/todo-mode.html | ||
| 267 | ;; (That link will be valid until 10/1998 or slightly longer.) | ||
| 268 | ;; | ||
| 211 | ;; Revision 1.18 1997/10/15 17:18:11 os10000 | 269 | ;; Revision 1.18 1997/10/15 17:18:11 os10000 |
| 212 | ;; Everything seems to work in Harald Melands Emacs 20.02 and | 270 | ;; Everything seems to work in Harald Melands Emacs 20.02 and |
| 213 | ;; my Emacs 19.34. Beware of the spelling in some of the | 271 | ;; my Emacs 19.34. Beware of the spelling in some of the |
| @@ -310,6 +368,19 @@ | |||
| 310 | (defvar todo-insert-threshold 0 "*TODO mode insertion accuracy.") | 368 | (defvar todo-insert-threshold 0 "*TODO mode insertion accuracy.") |
| 311 | (defvar todo-edit-buffer " *TODO Edit*" "TODO Edit buffer name.") | 369 | (defvar todo-edit-buffer " *TODO Edit*" "TODO Edit buffer name.") |
| 312 | 370 | ||
| 371 | (defvar todo-print-function 'ps-print-buffer-with-faces | ||
| 372 | "*Function to print the current buffer.") | ||
| 373 | (defvar todo-show-priorities 1 | ||
| 374 | "*Default number of priorities to show by | ||
| 375 | \\[todo-top-priorities]. 0 means show all entries.") | ||
| 376 | (defvar todo-print-priorities 0 | ||
| 377 | "*Default number of priorities to print by | ||
| 378 | \\[todo-print]. 0 means print all entries.") | ||
| 379 | (defvar todo-remove-separator t | ||
| 380 | "*Non-nil removes category separators in | ||
| 381 | \\[todo-top-priorities] and \\[todo-print].") | ||
| 382 | |||
| 383 | |||
| 313 | ;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de> | 384 | ;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de> |
| 314 | ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p". | 385 | ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p". |
| 315 | ;; | 386 | ;; |
| @@ -318,6 +389,15 @@ | |||
| 318 | "TODO mode time string format for done entries. | 389 | "TODO mode time string format for done entries. |
| 319 | For details see the variable `time-stamp-format'.") | 390 | For details see the variable `time-stamp-format'.") |
| 320 | 391 | ||
| 392 | (defvar todo-entry-prefix-function 'todo-entry-timestamp-initials | ||
| 393 | "*Function producing text to insert at start of todo entry.") | ||
| 394 | (defvar todo-initials (or (getenv "INITIALS") (user-login-name)) | ||
| 395 | "*Initials of todo item author.") | ||
| 396 | |||
| 397 | (defun todo-entry-timestamp-initials () | ||
| 398 | (let ((time-stamp-format todo-time-string-format)) | ||
| 399 | (concat (time-stamp-string) " " todo-initials ": "))) | ||
| 400 | |||
| 321 | ;; --------------------------------------------------------------------------- | 401 | ;; --------------------------------------------------------------------------- |
| 322 | 402 | ||
| 323 | ;; Get some outside help ... | 403 | ;; Get some outside help ... |
| @@ -330,13 +410,25 @@ For details see the variable `time-stamp-format'.") | |||
| 330 | ;; Set up some helpful context ... | 410 | ;; Set up some helpful context ... |
| 331 | 411 | ||
| 332 | (defvar todo-categories nil "TODO categories.") | 412 | (defvar todo-categories nil "TODO categories.") |
| 333 | (defvar todo-cats nil | 413 | (defvar todo-cats nil "Old variable for holding the |
| 334 | "Old variable for holding the TODO categories. Use `todo-categories' instead.") | 414 | TODO categories. Use `todo-categories' instead.") |
| 335 | (defvar todo-previous-line 0 "Previous line that I asked about.") | 415 | (defvar todo-previous-line 0 "Previous line that I asked about.") |
| 336 | (defvar todo-previous-answer 0 "Previous answer that I got.") | 416 | (defvar todo-previous-answer 0 "Previous answer that I got.") |
| 337 | (defvar todo-mode-map nil "TODO mode keymap.") | 417 | (defvar todo-mode-map nil "TODO mode keymap.") |
| 338 | (defvar todo-category-number 0 "TODO category number.") | 418 | (defvar todo-category-number 0 "TODO category number.") |
| 339 | 419 | ||
| 420 | |||
| 421 | (defvar todo-category-sep (make-string 75 ?-) | ||
| 422 | "Category separator.") | ||
| 423 | (defvar todo-category-beg " --- " | ||
| 424 | "Category start separator to be prepended onto category name.") | ||
| 425 | (defvar todo-category-end "--- End" | ||
| 426 | "Separator after a category.") | ||
| 427 | (defvar todo-header "-*- mode: todo; " | ||
| 428 | "Header of todo files.") | ||
| 429 | |||
| 430 | |||
| 431 | |||
| 340 | ;; --------------------------------------------------------------------------- | 432 | ;; --------------------------------------------------------------------------- |
| 341 | 433 | ||
| 342 | (if todo-mode-map | 434 | (if todo-mode-map |
| @@ -347,15 +439,19 @@ For details see the variable `time-stamp-format'.") | |||
| 347 | (define-key map "-" 'todo-backward-category) | 439 | (define-key map "-" 'todo-backward-category) |
| 348 | (define-key map "e" 'todo-edit-item) | 440 | (define-key map "e" 'todo-edit-item) |
| 349 | (define-key map "E" 'todo-edit-multiline) | 441 | (define-key map "E" 'todo-edit-multiline) |
| 442 | (define-key map "d" 'todo-file-item) ;done/delete | ||
| 350 | (define-key map "f" 'todo-file-item) | 443 | (define-key map "f" 'todo-file-item) |
| 351 | (define-key map "i" 'todo-insert-item) | 444 | (define-key map "i" 'todo-insert-item) |
| 445 | (define-key map "j" 'todo-jump-to-category) | ||
| 352 | (define-key map "k" 'todo-delete-item) | 446 | (define-key map "k" 'todo-delete-item) |
| 353 | (define-key map "l" 'todo-lower-item) | 447 | (define-key map "l" 'todo-lower-item) |
| 354 | (define-key map "n" 'todo-forward-item) | 448 | (define-key map "n" 'todo-forward-item) |
| 355 | (define-key map "p" 'todo-backward-item) | 449 | (define-key map "p" 'todo-backward-item) |
| 450 | (define-key map "P" 'todo-print) | ||
| 356 | (define-key map "q" 'todo-quit) | 451 | (define-key map "q" 'todo-quit) |
| 357 | (define-key map "r" 'todo-raise-item) | 452 | (define-key map "r" 'todo-raise-item) |
| 358 | (define-key map "s" 'todo-save) | 453 | (define-key map "s" 'todo-save) |
| 454 | (define-key map "t" 'todo-top-priorities) | ||
| 359 | (setq todo-mode-map map))) | 455 | (setq todo-mode-map map))) |
| 360 | 456 | ||
| 361 | (defun todo-category-select () | 457 | (defun todo-category-select () |
| @@ -366,9 +462,11 @@ For details see the variable `time-stamp-format'.") | |||
| 366 | (widen) | 462 | (widen) |
| 367 | (goto-char (point-min)) | 463 | (goto-char (point-min)) |
| 368 | (search-forward-regexp | 464 | (search-forward-regexp |
| 369 | (concat "^" (regexp-quote (concat todo-prefix " --- " name)))) | 465 | (concat "^" |
| 466 | (regexp-quote (concat todo-prefix todo-category-beg name)) | ||
| 467 | "$")) | ||
| 370 | (let ((begin (1+ (point-at-eol)))) | 468 | (let ((begin (1+ (point-at-eol)))) |
| 371 | (search-forward-regexp "^--- End") | 469 | (search-forward-regexp (concat "^" todo-category-end)) |
| 372 | (narrow-to-region begin (point-at-bol)) | 470 | (narrow-to-region begin (point-at-bol)) |
| 373 | (goto-char (point-min))))) | 471 | (goto-char (point-min))))) |
| 374 | (defalias 'todo-cat-slct 'todo-category-select) | 472 | (defalias 'todo-cat-slct 'todo-category-select) |
| @@ -393,10 +491,13 @@ For details see the variable `time-stamp-format'.") | |||
| 393 | (message "")) | 491 | (message "")) |
| 394 | (defalias 'todo-cmd-prev 'todo-backward-item) | 492 | (defalias 'todo-cmd-prev 'todo-backward-item) |
| 395 | 493 | ||
| 396 | (defun todo-forward-item () "Select next entry of TODO list." | 494 | (defun todo-forward-item (&optional count) |
| 397 | (interactive) | 495 | "Select Nth next entry of TODO list." |
| 496 | (interactive "P") | ||
| 497 | (if (listp count) (setq count (car count))) | ||
| 398 | (end-of-line) | 498 | (end-of-line) |
| 399 | (search-forward-regexp (concat "^" (regexp-quote todo-prefix)) nil 'goto-end) | 499 | (search-forward-regexp (concat "^" (regexp-quote todo-prefix)) |
| 500 | nil 'goto-end count) | ||
| 400 | (beginning-of-line) | 501 | (beginning-of-line) |
| 401 | (message "")) | 502 | (message "")) |
| 402 | (defalias 'todo-cmd-next 'todo-forward-item) | 503 | (defalias 'todo-cmd-next 'todo-forward-item) |
| @@ -430,12 +531,14 @@ For details see the variable `time-stamp-format'.") | |||
| 430 | "Set up a buffer for editing a multiline TODO list entry." | 531 | "Set up a buffer for editing a multiline TODO list entry." |
| 431 | (interactive) | 532 | (interactive) |
| 432 | (let ((buffer-name (generate-new-buffer-name todo-edit-buffer))) | 533 | (let ((buffer-name (generate-new-buffer-name todo-edit-buffer))) |
| 433 | (switch-to-buffer (make-indirect-buffer (file-name-nondirectory todo-file-do) | 534 | (switch-to-buffer |
| 434 | buffer-name)) | 535 | (make-indirect-buffer |
| 536 | (file-name-nondirectory todo-file-do) buffer-name)) | ||
| 435 | (message "To exit, simply kill this buffer and return to list.") | 537 | (message "To exit, simply kill this buffer and return to list.") |
| 436 | (todo-edit-mode) | 538 | (todo-edit-mode) |
| 437 | (narrow-to-region (todo-item-start) (todo-item-end)))) | 539 | (narrow-to-region (todo-item-start) (todo-item-end)))) |
| 438 | 540 | ||
| 541 | ;;;### autoload | ||
| 439 | (defun todo-add-category (cat) "Add a new category to the TODO list." | 542 | (defun todo-add-category (cat) "Add a new category to the TODO list." |
| 440 | (interactive) | 543 | (interactive) |
| 441 | (save-window-excursion | 544 | (save-window-excursion |
| @@ -452,21 +555,29 @@ For details see the variable `time-stamp-format'.") | |||
| 452 | (kill-line))) | 555 | (kill-line))) |
| 453 | (insert (format "todo-categories: %S; -*-" todo-categories)) | 556 | (insert (format "todo-categories: %S; -*-" todo-categories)) |
| 454 | (forward-char 1) | 557 | (forward-char 1) |
| 455 | (insert (format "%s --- %s\n--- End\n%s %s\n" | 558 | (insert (format "%s%s%s\n%s\n%s %s\n" |
| 456 | todo-prefix cat todo-prefix (make-string 75 ?-)))) | 559 | todo-prefix todo-category-beg cat |
| 560 | todo-category-end | ||
| 561 | todo-prefix todo-category-sep))) | ||
| 457 | 0) | 562 | 0) |
| 458 | 563 | ||
| 564 | ;;;### autoload | ||
| 459 | (defun todo-insert-item () | 565 | (defun todo-insert-item () |
| 460 | "Insert new TODO list entry." | 566 | "Insert new TODO list entry." |
| 461 | (interactive) | 567 | (interactive) |
| 462 | (let* ((new-item (concat todo-prefix " " | 568 | (let* ((new-item (concat todo-prefix " " |
| 463 | (read-from-minibuffer "New TODO entry: "))) | 569 | (read-from-minibuffer |
| 570 | "New TODO entry: " | ||
| 571 | (if todo-entry-prefix-function | ||
| 572 | (funcall todo-entry-prefix-function))))) | ||
| 464 | (categories todo-categories) | 573 | (categories todo-categories) |
| 465 | (history (cons 'categories (1+ todo-category-number))) | 574 | (history (cons 'categories (1+ todo-category-number))) |
| 466 | (category (completing-read "Category: " | 575 | (category (completing-read |
| 467 | (todo-category-alist) nil nil | 576 | (concat "Category [" |
| 468 | (nth todo-category-number todo-categories) | 577 | (nth todo-category-number todo-categories) "]: ") |
| 469 | history))) | 578 | (todo-category-alist) nil nil nil history))) |
| 579 | (if (string= "" category) | ||
| 580 | (setq category (nth todo-category-number todo-categories))) | ||
| 470 | (let ((cat-exists (member category todo-categories))) | 581 | (let ((cat-exists (member category todo-categories))) |
| 471 | (setq todo-category-number | 582 | (setq todo-category-number |
| 472 | (if cat-exists | 583 | (if cat-exists |
| @@ -534,7 +645,8 @@ For details see the variable `time-stamp-format'.") | |||
| 534 | 645 | ||
| 535 | (defun todo-lower-item () "Lower priority of current entry." | 646 | (defun todo-lower-item () "Lower priority of current entry." |
| 536 | (interactive) | 647 | (interactive) |
| 537 | (if (> (count-lines (point) (point-max)) 1) ; Assume there is a final newline | 648 | (if (> (count-lines (point) (point-max)) 1) |
| 649 | ;; Assume there is a final newline | ||
| 538 | (let ((item (todo-item-string))) | 650 | (let ((item (todo-item-string))) |
| 539 | (todo-remove-item) | 651 | (todo-remove-item) |
| 540 | (todo-forward-item) | 652 | (todo-forward-item) |
| @@ -552,16 +664,18 @@ For details see the variable `time-stamp-format'.") | |||
| 552 | (if (> (length comment) 0) | 664 | (if (> (length comment) 0) |
| 553 | (progn | 665 | (progn |
| 554 | (goto-char (todo-item-end)) | 666 | (goto-char (todo-item-end)) |
| 555 | (insert (if (save-excursion (beginning-of-line) | 667 | (insert |
| 556 | (looking-at (regexp-quote todo-prefix))) | 668 | (if (save-excursion (beginning-of-line) |
| 557 | " " | 669 | (looking-at (regexp-quote todo-prefix))) |
| 558 | "\n\t") | 670 | " " |
| 559 | "(" (nth todo-category-number todo-categories) ": " | 671 | "\n\t") |
| 560 | comment ")\n"))) | 672 | "(" (nth todo-category-number todo-categories) ": " |
| 673 | comment ")\n"))) | ||
| 561 | (goto-char (todo-item-start)) | 674 | (goto-char (todo-item-start)) |
| 562 | (let ((temp-point (point))) | 675 | (let ((temp-point (point))) |
| 563 | (if (looking-at (regexp-quote todo-prefix)) | 676 | (if (looking-at (regexp-quote todo-prefix)) |
| 564 | (replace-match (time-stamp-string)) ; Standard prefix -> timestamp | 677 | (replace-match (time-stamp-string)) |
| 678 | ;; Standard prefix -> timestamp | ||
| 565 | ;; Else prefix non-standard item start with timestamp | 679 | ;; Else prefix non-standard item start with timestamp |
| 566 | (insert (time-stamp-string))) | 680 | (insert (time-stamp-string))) |
| 567 | (append-to-file temp-point (todo-item-end) todo-file-done) | 681 | (append-to-file temp-point (todo-item-end) todo-file-done) |
| @@ -574,6 +688,108 @@ For details see the variable `time-stamp-format'.") | |||
| 574 | 688 | ||
| 575 | ;; Utility functions: | 689 | ;; Utility functions: |
| 576 | 690 | ||
| 691 | |||
| 692 | ;;;###autoload | ||
| 693 | (defun todo-top-priorities (&optional nof-priorities category-pr-page) | ||
| 694 | "List top priorities for each category. | ||
| 695 | |||
| 696 | Number of entries for each category is given by NOF-PRIORITIES which | ||
| 697 | defaults to \'todo-show-priorities\'. | ||
| 698 | |||
| 699 | If CATEGORY-PR-PAGE is non-nil, a page separator \'^L\' is inserted | ||
| 700 | between each category." | ||
| 701 | |||
| 702 | (interactive "P") | ||
| 703 | (or nof-priorities (setq nof-priorities todo-show-priorities)) | ||
| 704 | (if (listp nof-priorities) ;universal argument | ||
| 705 | (setq nof-priorities (car nof-priorities))) | ||
| 706 | (let ((todo-print-buffer-name "*Tmp*") | ||
| 707 | ;;(todo-print-category-number 0) | ||
| 708 | (todo-category-break (if category-pr-page "" "")) | ||
| 709 | (cat-end | ||
| 710 | (concat | ||
| 711 | (if todo-remove-separator | ||
| 712 | (concat todo-category-end "\n" | ||
| 713 | (regexp-quote todo-prefix) " " todo-category-sep "\n") | ||
| 714 | (concat todo-category-end "\n")))) | ||
| 715 | beg end) | ||
| 716 | (todo-show) | ||
| 717 | (save-excursion | ||
| 718 | (save-restriction | ||
| 719 | (widen) | ||
| 720 | (copy-to-buffer todo-print-buffer-name (point-min) (point-max)) | ||
| 721 | (set-buffer todo-print-buffer-name) | ||
| 722 | (goto-char (point-min)) | ||
| 723 | (if (re-search-forward (regexp-quote todo-header) nil t) | ||
| 724 | (progn | ||
| 725 | (beginning-of-line 1) | ||
| 726 | (kill-line))) ;Remove mode line | ||
| 727 | (while (re-search-forward ;Find category start | ||
| 728 | (regexp-quote (concat todo-prefix todo-category-beg)) | ||
| 729 | nil t) | ||
| 730 | (setq beg (+ (point-at-eol) 1)) ;Start of first entry. | ||
| 731 | (re-search-forward cat-end nil t) | ||
| 732 | (setq end (match-beginning 0)) | ||
| 733 | (replace-match todo-category-break) | ||
| 734 | (narrow-to-region beg end) ;In case we have too few entries. | ||
| 735 | (goto-char (point-min)) | ||
| 736 | (if (= 0 nof-priorities) ;Traverse entries. | ||
| 737 | (goto-char end) ;All entries | ||
| 738 | (todo-forward-item nof-priorities)) | ||
| 739 | (setq beg (point)) | ||
| 740 | (delete-region beg end) | ||
| 741 | (widen)) | ||
| 742 | (goto-char (point-min)) ;Due to display buffer | ||
| 743 | )) | ||
| 744 | ;; Could have used switch-to-buffer as it has a norecord argument, | ||
| 745 | ;; which is nice when we are called from e.g. todo-print. | ||
| 746 | ;; Else we could have used pop-to-buffer should be used. | ||
| 747 | (display-buffer todo-print-buffer-name) | ||
| 748 | ;;(switch-to-buffer todo-print-buffer-name t) | ||
| 749 | (message "Type C-x 1 to remove %s window. M-C-v to scroll the help." | ||
| 750 | todo-print-buffer-name) | ||
| 751 | )) | ||
| 752 | |||
| 753 | ;;;###autoload | ||
| 754 | (defun todo-print (&optional category-pr-page) | ||
| 755 | "Print todo summary using \\\[todo-print-function]. | ||
| 756 | If CATEGORY-PR-PAGE is non-nil, a page separator \'^L\' is inserted | ||
| 757 | between each category. | ||
| 758 | |||
| 759 | Number of entries for each category is given by | ||
| 760 | \'todo-print-priorities\'." | ||
| 761 | (interactive "P") | ||
| 762 | (save-window-excursion | ||
| 763 | (save-excursion | ||
| 764 | (save-restriction | ||
| 765 | (todo-top-priorities todo-print-priorities | ||
| 766 | category-pr-page) | ||
| 767 | (if todo-print-function | ||
| 768 | (progn | ||
| 769 | (funcall todo-print-function) | ||
| 770 | (message "Todo printing done.")) | ||
| 771 | (message "") ; To get rid of message from | ||
| 772 | ; todo-top-priorities. | ||
| 773 | ))))) | ||
| 774 | |||
| 775 | (defun todo-jump-to-category () | ||
| 776 | "Jump to a category. Default is previous category." | ||
| 777 | (interactive) | ||
| 778 | (let* ((categories todo-categories) | ||
| 779 | (history (cons 'categories (1+ todo-category-number))) | ||
| 780 | (category (completing-read | ||
| 781 | (concat "Category [" | ||
| 782 | (nth todo-category-number todo-categories) "]: ") | ||
| 783 | (todo-category-alist) nil nil nil history))) | ||
| 784 | (if (string= "" category) | ||
| 785 | (setq category (nth todo-category-number todo-categories))) | ||
| 786 | (setq todo-category-number | ||
| 787 | (if (member category todo-categories) | ||
| 788 | (- (length todo-categories) | ||
| 789 | (length (member category todo-categories))) | ||
| 790 | (todo-add-category category))) | ||
| 791 | (todo-show))) | ||
| 792 | |||
| 577 | (defun todo-line-string () "Return current line in buffer as a string." | 793 | (defun todo-line-string () "Return current line in buffer as a string." |
| 578 | (buffer-substring (point-at-bol) (point-at-eol))) | 794 | (buffer-substring (point-at-bol) (point-at-eol))) |
| 579 | 795 | ||
| @@ -596,7 +812,8 @@ For details see the variable `time-stamp-format'.") | |||
| 596 | (defun todo-item-end () "Return point at end of current TODO list item." | 812 | (defun todo-item-end () "Return point at end of current TODO list item." |
| 597 | (save-excursion | 813 | (save-excursion |
| 598 | (end-of-line) | 814 | (end-of-line) |
| 599 | (search-forward-regexp (concat "^" (regexp-quote todo-prefix)) nil 'goto-end) | 815 | (search-forward-regexp |
| 816 | (concat "^" (regexp-quote todo-prefix)) nil 'goto-end) | ||
| 600 | (1- (point-at-bol)))) | 817 | (1- (point-at-bol)))) |
| 601 | 818 | ||
| 602 | (defun todo-remove-item () "Delete the current entry from the TODO list." | 819 | (defun todo-remove-item () "Delete the current entry from the TODO list." |
| @@ -661,6 +878,9 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | |||
| 661 | '("Todo" | 878 | '("Todo" |
| 662 | ["Next category" todo-forward-category t] | 879 | ["Next category" todo-forward-category t] |
| 663 | ["Previous category" todo-backward-category t] | 880 | ["Previous category" todo-backward-category t] |
| 881 | ["Jump to category" todo-jump-to-category t] | ||
| 882 | ["Show top priority items" todo-top-priorities t] | ||
| 883 | ["Print categories" todo-print t] | ||
| 664 | "---" | 884 | "---" |
| 665 | ["Edit item" todo-edit-item t] | 885 | ["Edit item" todo-edit-item t] |
| 666 | ["File item" todo-file-item t] | 886 | ["File item" todo-file-item t] |
| @@ -678,6 +898,8 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | |||
| 678 | ["Quit" todo-quit t] | 898 | ["Quit" todo-quit t] |
| 679 | )) | 899 | )) |
| 680 | 900 | ||
| 901 | ;; As calendar reads .todo-do before todo-mode is loaded. | ||
| 902 | ;;;### autoload | ||
| 681 | (defun todo-mode () "Major mode for editing TODO lists.\n\n\\{todo-mode-map}" | 903 | (defun todo-mode () "Major mode for editing TODO lists.\n\n\\{todo-mode-map}" |
| 682 | (interactive) | 904 | (interactive) |
| 683 | (setq major-mode 'todo-mode) | 905 | (setq major-mode 'todo-mode) |
| @@ -693,6 +915,7 @@ If SEPARATORS is absent, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." | |||
| 693 | (setq mode-name "TODO Edit") | 915 | (setq mode-name "TODO Edit") |
| 694 | (run-hooks 'todo-edit-mode-hook)) | 916 | (run-hooks 'todo-edit-mode-hook)) |
| 695 | 917 | ||
| 918 | ;;;### autoload | ||
| 696 | (defun todo-show () "Show TODO list." | 919 | (defun todo-show () "Show TODO list." |
| 697 | (interactive) | 920 | (interactive) |
| 698 | (if (file-exists-p todo-file-do) | 921 | (if (file-exists-p todo-file-do) |