Commit | Line | Data |
---|---|---|
7c896f63 | 1 | ;;; todo-mode.el -- Major mode for editing TODO list files |
3cb152f9 | 2 | |
7c896f63 | 3 | ;; Copyright (C) 1997 Free Software Foundation, Inc. |
3cb152f9 | 4 | |
7c896f63 OS |
5 | ;; Author: Oliver.Seidel@cl.cam.ac.uk (was valid on Aug 2, 1997) |
6 | ;; Created: 2 Aug 1997 | |
7 | ;; Version: $Id:$ | |
8 | ;; Keywords: Categorised TODO list editor, todo-mode | |
3cb152f9 | 9 | |
7c896f63 | 10 | ;; This file is part of GNU Emacs. |
595b2334 | 11 | |
7c896f63 | 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
595b2334 OS |
13 | ;; it under the terms of the GNU General Public License as published by |
14 | ;; the Free Software Foundation; either version 2, or (at your option) | |
15 | ;; any later version. | |
7c896f63 OS |
16 | |
17 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
595b2334 OS |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
7c896f63 | 21 | |
595b2334 OS |
22 | ;; You should have received a copy of the GNU General Public License |
23 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
24 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
25 | ;; Boston, MA 02111-1307, USA. | |
26 | ||
27 | ;; --------------------------------------------------------------------------- | |
28 | ||
7c896f63 OS |
29 | ;;; Commentary: |
30 | ||
579e1c67 OS |
31 | ;; Quickstart Installation: |
32 | ;; ======================== | |
595b2334 | 33 | ;; |
579e1c67 | 34 | ;; To get this to work, make emacs execute the line |
3d8105fb | 35 | ;; |
7c896f63 | 36 | ;; (require 'todo-mode) ;; load the TODO package |
a360be79 | 37 | ;; |
7c896f63 OS |
38 | ;; You may now enter new items by typing "M-x todo-cmd-inst", or enter |
39 | ;; your the TODO list file by typing "M-x todo-show". | |
40 | ;; | |
41 | ;; The TODO list file has a special format and some auxiliary information, | |
42 | ;; which will be added by the todo-show function if it attempts to visit | |
43 | ;; an un-initialised file. Hence it is recommended to use the todo-show | |
44 | ;; function for the first time, in order to initialise the file, but it | |
45 | ;; is not necessary afterwards. | |
46 | ;; | |
47 | ;; As these commands are quite long to type, I would recommend the addition | |
48 | ;; of two bindings to your to your global keymap. I personally have the | |
49 | ;; following in my initialisation file: | |
da2ee685 | 50 | ;; |
579e1c67 OS |
51 | ;; (global-set-key "\C-ct" 'todo-show) ;; switch to TODO buffer |
52 | ;; (global-set-key "\C-ci" 'todo-cmd-inst) ;; insert new item | |
8cdc3b3d | 53 | ;; |
7c896f63 OS |
54 | ;; Note, however, that this recommendation has prompted some criticism, |
55 | ;; since the keys C-c LETTER are reserved for user functions. I believe | |
56 | ;; my recommendation is acceptable, since the Emacs Lisp Manual *Tips* | |
57 | ;; section also details that the mode itself should not bind any functions | |
58 | ;; to those keys. The express aim of the above two bindings is to work | |
59 | ;; outside the mode, which doesn't need the show function and offers | |
60 | ;; a different binding for the insert function. They serve as shortcuts | |
61 | ;; and are not even needed (since the TODO mode will be entered by | |
62 | ;; visiting the TODO file, and later by switching to its buffer). | |
63 | ;; | |
64 | ;; | |
65 | ;; | |
66 | ;; Pre-Requisites | |
67 | ;; ============== | |
68 | ;; | |
69 | ;; This package will require the following packages to be available on | |
70 | ;; the load-path: | |
71 | ;; - time-stamp | |
72 | ;; - easymenu | |
73 | ;; | |
7e6ed9b9 | 74 | ;; |
3cb152f9 | 75 | ;; |
7e6ed9b9 | 76 | ;; Description: |
579e1c67 | 77 | ;; ============ |
7e6ed9b9 | 78 | ;; |
579e1c67 OS |
79 | ;; TODO is a major mode for EMACS which offers functionality to treat |
80 | ;; most lines in one buffer as a list of items one has to do. There | |
81 | ;; are facilities to add new items, which are categorised, to edit or | |
82 | ;; even delete items from the buffer. The buffer contents are currently | |
83 | ;; compatible with the diary, so that the list of todo-items will show | |
84 | ;; up in the FANCY diary mode. | |
7e6ed9b9 | 85 | ;; |
579e1c67 OS |
86 | ;; Notice: Besides the major mode, this file also exports the function |
87 | ;; "todo-show" which will change to the one specific TODO file that has | |
88 | ;; been specified in the todo-file-do variable. If this file does not | |
89 | ;; conform to the TODO mode conventions, the todo-show function will add | |
90 | ;; the appropriate header and footer. I don't anticipate this to cause | |
91 | ;; much grief, but be warned, in case you attempt to read a plain text file. | |
92 | ;; | |
93 | ;; | |
94 | ;; | |
95 | ;; Operation: | |
96 | ;; ========== | |
a360be79 OS |
97 | ;; |
98 | ;; You will have the following facilities available: | |
7e6ed9b9 | 99 | ;; |
03944ca7 OS |
100 | ;; M-x todo-show will enter the todo list screen, here type |
101 | ;; | |
da2ee685 OS |
102 | ;; + to go to next category |
103 | ;; - to go to previous category | |
7e6ed9b9 | 104 | ;; e to edit the current entry |
da2ee685 OS |
105 | ;; f to file the current entry, including a |
106 | ;; comment and timestamp | |
7e6ed9b9 OS |
107 | ;; i to insert a new entry |
108 | ;; k to kill the current entry | |
cf1ebf43 | 109 | ;; l to lower the current entry's priority |
da2ee685 OS |
110 | ;; n for the next entry |
111 | ;; p for the previous entry | |
112 | ;; q to save the list and exit the buffer | |
cf1ebf43 | 113 | ;; r to raise the current entry's priority |
da2ee685 | 114 | ;; s to save the list |
7e6ed9b9 | 115 | ;; |
a360be79 OS |
116 | ;; When you add a new entry, you are asked for the text and then for the |
117 | ;; category. I for example have categories for things that I want to do | |
118 | ;; in the office (like mail my mum), that I want to do in town (like buy | |
119 | ;; cornflakes) and things I want to do at home (move my suitcases). The | |
120 | ;; categories can be selected with the cursor keys and if you type in the | |
121 | ;; name of a category which didn't exist before, an empty category of the | |
03944ca7 | 122 | ;; desired name will be added and filled with the new entry. |
a360be79 | 123 | ;; |
7e6ed9b9 | 124 | ;; |
7e6ed9b9 | 125 | ;; |
579e1c67 OS |
126 | ;; Configuration: |
127 | ;; ============== | |
7e6ed9b9 | 128 | ;; |
579e1c67 OS |
129 | ;; --- todo-prefix |
130 | ;; | |
131 | ;; I would like to recommend that you use the prefix "*/*" (by | |
132 | ;; leaving the variable 'todo-prefix' untouched) so that the diary | |
133 | ;; displays each entry every day. | |
a360be79 | 134 | ;; |
03944ca7 OS |
135 | ;; To understand what I mean, please read the documentation that goes |
136 | ;; with the calendar since that will tell you how you can set up the | |
137 | ;; fancy diary display and use the #include command to include your | |
138 | ;; todo list file as part of your diary. | |
a360be79 | 139 | ;; |
579e1c67 OS |
140 | ;; |
141 | ;; --- todo-file-do | |
142 | ;; | |
143 | ;; This variable is fairly self-explanatory. You have to store your TODO | |
144 | ;; list somewhere. This variable tells the package where to go and find | |
145 | ;; this file. | |
146 | ;; | |
147 | ;; | |
148 | ;; --- todo-file-done | |
149 | ;; | |
150 | ;; Even when you're done, you may wish to retain the entries. Given | |
151 | ;; that they're timestamped and you are offered to add a comment, this | |
152 | ;; can make a useful diary of past events. It will even blend in with | |
153 | ;; the EMACS diary package. So anyway, this variable holds the name | |
154 | ;; of the file for the filed todo-items. | |
155 | ;; | |
156 | ;; | |
157 | ;; --- todo-mode-hook | |
158 | ;; | |
159 | ;; Just like other modes, too, this mode offers to call your functions | |
160 | ;; before it goes about its business. This variable will be inspected | |
161 | ;; for any functions you may wish to have called once the other TODO | |
162 | ;; mode preparations have been completed. | |
163 | ;; | |
164 | ;; | |
165 | ;; --- todo-ins-thresh | |
166 | ;; | |
3d8105fb OS |
167 | ;; Another nifty feature is the insertion accuracy. If you have 8 items |
168 | ;; in your TODO list, then you may get asked 4 questions by the binary | |
169 | ;; insertion algorithm. However, you may not really have a need for such | |
170 | ;; accurate priorities amongst your TODO items. If you now think about | |
171 | ;; the binary insertion halfing the size of the window each time, then | |
172 | ;; the threshhold is the window size at which it will stop. If you set | |
173 | ;; the threshhold to zero, the upper and lower bound will coincide at the | |
174 | ;; end of the loop and you will insert your item just before that point. | |
175 | ;; If you set the threshhold to i.e. 8, it will stop as soon as the window | |
176 | ;; size drops below that amount and will insert the item in the approximate | |
177 | ;; centre of that window. I got the idea for this feature after reading | |
7c896f63 | 178 | ;; a very helpful e-mail reply from Trey Jackson <trey@cs.berkeley.edu> |
3d8105fb OS |
179 | ;; who corrected some of my awful coding and pointed me towards some good |
180 | ;; reading. Thanks Trey! | |
181 | ;; | |
579e1c67 OS |
182 | ;; |
183 | ;; | |
7c896f63 OS |
184 | ;; |
185 | ;; Things to do: | |
186 | ;; ============= | |
187 | ;; | |
188 | ;; - licence / version function | |
189 | ;; - export to diary file | |
190 | ;; - todo-report-bug | |
191 | ;; - GNATS support | |
192 | ;; - add idea from Urban Boquist <boquist@cs.chalmers.se>: multi-line-entries | |
193 | ;; - 'e' opens buffer for multi-line entry | |
194 | ;; - elide multiline | |
195 | ;; - rewrite complete package to store data as lisp objects and have | |
196 | ;; display modes for display, for diary export, etc. | |
197 | ;; | |
198 | ;; | |
199 | ;; | |
579e1c67 OS |
200 | ;; History and Gossip: |
201 | ;; =================== | |
202 | ;; | |
cf1ebf43 OS |
203 | ;; Many thanks to all the ones who have contributed to the evolution of this |
204 | ;; package! I hope I have listed all of you somewhere in the documentation | |
205 | ;; or at least in the RCS history! | |
206 | ;; | |
cf1ebf43 OS |
207 | ;; Enjoy this package and express your gratitude by sending nice things |
208 | ;; to my parents' address! | |
a360be79 OS |
209 | ;; |
210 | ;; Oliver Seidel | |
579e1c67 | 211 | ;; |
cf1ebf43 | 212 | ;; (O Seidel, Lessingstr. 8, 65760 Eschborn, Federal Republic of Germany) |
579e1c67 OS |
213 | ;; |
214 | ||
215 | ;; --------------------------------------------------------------------------- | |
216 | ||
7c896f63 OS |
217 | ;; --------------------------------------------------------------------------- |
218 | ||
219 | ;;; Change Log: | |
220 | ||
221 | ;; $Log: todo-mode.el,v $ | |
222 | ;; Revision 1.12 1997/08/06 10:56:15 os10000 | |
223 | ;; Fixed header, typos, layout, documentation. | |
579e1c67 | 224 | ;; |
cf1ebf43 OS |
225 | ;; Revision 1.11 1997/08/06 09:14:25 os10000 |
226 | ;; Applied patch from Istvan Marko <istvan@cmdmail.amd.com> | |
227 | ;; to make menus work anywhere. | |
228 | ;; | |
49c48a1b OS |
229 | ;; Revision 1.10 1997/08/06 08:56:03 os10000 |
230 | ;; Acted upon suggestion from Shane Holder <holder@rsn.hp.com>: | |
231 | ;; Cancelling the editing of an entry will not delete it any more. | |
232 | ;; | |
03944ca7 OS |
233 | ;; Revision 1.9 1997/08/06 08:12:03 os10000 |
234 | ;; Improved documentation. Broke some lines to comply with | |
235 | ;; Richard Stallman's email to please keep in sync with the | |
236 | ;; rest of the Emacs distribution files. | |
237 | ;; | |
579e1c67 | 238 | ;; Revision 1.8 1997/08/05 22:39:04 os10000 |
7c896f63 | 239 | ;; Made todo-mode.el available under GPL. |
579e1c67 OS |
240 | ;; |
241 | ;; Revision 1.7 1997/08/05 22:34:14 os10000 | |
242 | ;; Fixed insertion routine with help from Trey Jackson | |
7c896f63 | 243 | ;; <trey@cs.berkeley.edu>; added todo-ins-thresh; |
579e1c67 OS |
244 | ;; fixed keyboard layout to remove unwanted keys. |
245 | ;; | |
246 | ;; Revision 1.6 1997/08/05 16:47:01 os10000 | |
247 | ;; Incorporated menus for XEmacs from Allan.Cochrane@soton.sc.philips.com, | |
248 | ;; fixed TYPO, fixed todo-file-cmd, cleaned up rcs history. | |
249 | ;; | |
250 | ;; Revision 1.5 1997/08/05 14:43:39 os10000 | |
251 | ;; Added improvements from Ron Gut <rgut@aware.com>. | |
252 | ;; Added category management. | |
253 | ;; | |
254 | ;; Revision 1.4 1997/08/04 16:18:45 os10000 | |
255 | ;; Added Raise/Lower item. | |
256 | ;; | |
257 | ;; Revision 1.3 1997/08/03 12:47:26 os10000 | |
258 | ;; Cleaned up variables, prefix and cursor position. | |
259 | ;; | |
260 | ;; Revision 1.2 1997/08/03 12:15:28 os10000 | |
261 | ;; It appears to work. | |
262 | ;; | |
263 | ;; Revision 1.1 1997/08/03 12:15:13 os10000 | |
264 | ;; Initial revision | |
265 | ;; | |
7e6ed9b9 OS |
266 | |
267 | ;; --------------------------------------------------------------------------- | |
268 | ||
7c896f63 OS |
269 | ;;; Code: |
270 | ||
3cb152f9 OS |
271 | ;; User-configurable variables: |
272 | ||
cf1ebf43 OS |
273 | (defvar todo-prefix "*/*" "TODO mode prefix for entries.") |
274 | (defvar todo-file-do "~/.todo-do" "TODO mode list file.") | |
275 | (defvar todo-file-done "~/.todo-done" "TODO mode archive file.") | |
276 | (defvar todo-mode-hook nil "TODO mode hooks.") | |
277 | (defvar todo-ins-thresh 0 "TODO mode insertion accuracy.") | |
3cb152f9 | 278 | |
7c896f63 OS |
279 | |
280 | ;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de> | |
281 | ;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p". | |
282 | ;; | |
283 | (defvar todo-time-string-format "%y-%02m-%02d %02H:%02M" | |
284 | "TODO mode time string format for done entries. | |
285 | For details see the variable `time-stamp-format'.") | |
286 | ||
3cb152f9 OS |
287 | ;; --------------------------------------------------------------------------- |
288 | ||
49c48a1b OS |
289 | ;; Get some outside help ... |
290 | ||
3cb152f9 | 291 | (require 'time-stamp) |
49c48a1b OS |
292 | (require 'easymenu) |
293 | ||
294 | ;; --------------------------------------------------------------------------- | |
3cb152f9 | 295 | |
cf1ebf43 OS |
296 | ;; Set up some helpful context ... |
297 | ||
298 | (defvar todo-cats nil "TODO categories.") | |
299 | (defvar todo-prv-lne 0 "previous line that I asked about.") | |
300 | (defvar todo-prv-ans 0 "previous answer that I got.") | |
301 | (defvar todo-mode-map nil "TODO mode keymap.") | |
302 | (defvar todo-category-number 0 "TODO category number.") | |
303 | ||
304 | ;; --------------------------------------------------------------------------- | |
305 | ||
3d8105fb OS |
306 | (if todo-mode-map |
307 | nil | |
308 | (let ((map (make-keymap))) | |
309 | (suppress-keymap map t) | |
310 | (define-key map "+" 'todo-cmd-forw) | |
311 | (define-key map "-" 'todo-cmd-back) | |
312 | (define-key map "e" 'todo-cmd-edit) | |
313 | (define-key map "f" 'todo-cmd-file) | |
314 | (define-key map "i" 'todo-cmd-inst) | |
315 | (define-key map "k" 'todo-cmd-kill) | |
316 | (define-key map "l" 'todo-cmd-lowr) | |
317 | (define-key map "n" 'todo-cmd-next) | |
318 | (define-key map "p" 'todo-cmd-prev) | |
319 | (define-key map "q" 'todo-cmd-done) | |
320 | (define-key map "r" 'todo-cmd-rais) | |
321 | (define-key map "s" 'todo-cmd-save) | |
322 | (setq todo-mode-map map))) | |
3cb152f9 | 323 | |
da2ee685 OS |
324 | (defun todo-cat-slct () |
325 | (let ((todo-category-name (nth todo-category-number todo-cats))) | |
579e1c67 OS |
326 | (setq mode-line-buffer-identification |
327 | (concat "Category: " todo-category-name)) | |
da2ee685 OS |
328 | (widen) |
329 | (goto-char (point-min)) | |
330 | (search-forward (concat "--- " todo-category-name)) | |
331 | (setq begin (+ (point-at-eol) 1)) | |
332 | (search-forward "--- End") | |
333 | (narrow-to-region begin (point-at-bol)) | |
cf1ebf43 | 334 | (goto-char (point-min)))) |
da2ee685 OS |
335 | |
336 | (defun todo-cmd-forw () "Go forward to TODO list of next category." | |
337 | (interactive) | |
338 | (let ((todo-cat-cnt (- (length todo-cats) 1))) | |
339 | (setq todo-category-number (if (< todo-category-number todo-cat-cnt) | |
340 | (+ todo-category-number 1) 0)) | |
cf1ebf43 | 341 | (todo-cat-slct))) |
da2ee685 OS |
342 | |
343 | (defun todo-cmd-back () "Go back to TODO list of previous category." | |
344 | (interactive) | |
345 | (let ((todo-cat-cnt (- (length todo-cats) 1))) | |
346 | (setq todo-category-number (if (> todo-category-number 0) | |
347 | (- todo-category-number 1) todo-cat-cnt)) | |
cf1ebf43 | 348 | (todo-cat-slct))) |
da2ee685 OS |
349 | |
350 | (defun todo-cmd-prev () "Select previous entry of TODO list." | |
3cb152f9 OS |
351 | (interactive) |
352 | (forward-line -1) | |
353 | (beginning-of-line nil) | |
cf1ebf43 | 354 | (message "")) |
3cb152f9 | 355 | |
da2ee685 | 356 | (defun todo-cmd-next () "Select next entry of TODO list." |
3cb152f9 OS |
357 | (interactive) |
358 | (forward-line 1) | |
359 | (beginning-of-line nil) | |
cf1ebf43 | 360 | (message "")) |
3cb152f9 | 361 | |
da2ee685 OS |
362 | (defun todo-cmd-save () "Save the TODO list." |
363 | (interactive) | |
cf1ebf43 | 364 | (save-buffer)) |
da2ee685 OS |
365 | |
366 | (defun todo-cmd-done () "Done with TODO list for now." | |
3cb152f9 | 367 | (interactive) |
da2ee685 OS |
368 | (widen) |
369 | (save-buffer) | |
7e6ed9b9 OS |
370 | (beginning-of-line nil) |
371 | (message "") | |
cf1ebf43 | 372 | (bury-buffer)) |
3cb152f9 | 373 | |
579e1c67 OS |
374 | (defun todo-line () "Find current line in buffer." |
375 | (buffer-substring (point-at-bol) (point-at-eol))) | |
3cb152f9 | 376 | |
da2ee685 | 377 | (defun todo-cmd-edit () "Edit current TODO list entry." |
3cb152f9 | 378 | (interactive) |
03944ca7 | 379 | (let ((todo-entry (read-from-minibuffer "Edit: " (todo-line)))) |
da2ee685 | 380 | (delete-region (point-at-bol) (point-at-eol)) |
03944ca7 | 381 | (insert todo-entry) |
da2ee685 | 382 | (beginning-of-line nil) |
03944ca7 | 383 | (message ""))) |
3cb152f9 | 384 | |
da2ee685 | 385 | (defun todo-add-category (cat) "Add a new category to the TODO list." |
3cb152f9 | 386 | (interactive) |
3cb152f9 | 387 | (save-window-excursion |
da2ee685 | 388 | (setq todo-cats (cons cat todo-cats)) |
3cb152f9 | 389 | (find-file todo-file-do) |
da2ee685 OS |
390 | (widen) |
391 | (goto-char (point-min)) | |
392 | (let ((posn (search-forward "-*- mode: todo; " 17 t))) | |
393 | (if (not (null posn)) (goto-char posn)) | |
579e1c67 OS |
394 | (if (equal posn nil) |
395 | (progn | |
396 | (insert "-*- mode: todo; \n") | |
397 | (forward-char -1)) | |
398 | (kill-line))) | |
da2ee685 OS |
399 | (insert (format "todo-cats: %S; -*-" todo-cats)) |
400 | (forward-char 1) | |
579e1c67 | 401 | (insert (format "%s --- %s\n--- End\n%s %s\n" |
cf1ebf43 OS |
402 | todo-prefix cat todo-prefix (make-string 75 ?-)))) |
403 | 0) | |
da2ee685 | 404 | |
3d8105fb OS |
405 | (defun todo-cmd-inst () |
406 | "Insert new TODO list entry." | |
da2ee685 | 407 | (interactive) |
3cb152f9 | 408 | (beginning-of-line nil) |
579e1c67 OS |
409 | (let* ((todo-entry (concat todo-prefix " " |
410 | (read-from-minibuffer "New TODO entry: "))) | |
3d8105fb OS |
411 | (temp-catgs todo-cats) |
412 | (todo-hstry (cons 'temp-catgs (+ todo-category-number 1)))) | |
da2ee685 OS |
413 | (save-window-excursion |
414 | (setq todo-category | |
3d8105fb OS |
415 | (read-from-minibuffer "Category: " |
416 | (nth todo-category-number todo-cats) | |
417 | nil nil todo-hstry)) | |
418 | ||
419 | (let ((cat-exists (member todo-category todo-cats))) | |
420 | (setq todo-category-number | |
421 | (if cat-exists | |
422 | (- (length todo-cats) (length cat-exists)) | |
423 | (todo-add-category todo-category)))) | |
da2ee685 OS |
424 | (todo-show) |
425 | (setq todo-prv-lne 0) | |
3d8105fb OS |
426 | |
427 | (let ((todo-fst 1) | |
428 | (todo-lst (+ 1 (count-lines (point-min) (point-max))))) | |
429 | (while (> (- todo-lst todo-fst) todo-ins-thresh) | |
430 | (let* ((todo-cur (/ (+ todo-fst todo-lst) 2)) | |
579e1c67 | 431 | (todo-ans (if (< todo-cur todo-lst) |
7c896f63 | 432 | (todo-ask-p todo-cur) nil))) |
3d8105fb OS |
433 | (if todo-ans |
434 | (setq todo-lst todo-cur) | |
435 | (setq todo-fst (+ todo-cur 1))))) | |
436 | ||
437 | (setq todo-fst (/ (+ todo-fst todo-lst) 2)) | |
438 | ;; goto-line doesn't have the desired behavior in a narrowed buffer | |
439 | (goto-char (point-min)) | |
3d8105fb OS |
440 | (forward-line (- todo-fst 1))) |
441 | ||
da2ee685 | 442 | (insert (concat todo-entry "\n")) |
3d8105fb | 443 | (forward-line -1)) |
da2ee685 | 444 | (beginning-of-line nil) |
7c896f63 | 445 | (save-buffer) |
3d8105fb OS |
446 | (message ""))) |
447 | ||
7c896f63 | 448 | (defun todo-ask-p (lne) |
3d8105fb OS |
449 | "Ask whether entry is more important than at LNE." |
450 | (if (not (equal todo-prv-lne lne)) | |
451 | (progn | |
452 | (setq todo-prv-lne lne) | |
453 | (goto-char (point-min)) | |
454 | (forward-line (- todo-prv-lne 1)) | |
579e1c67 OS |
455 | (setq todo-prv-ans (y-or-n-p |
456 | (concat "More important than '" | |
457 | (todo-line) "'? "))))) | |
3d8105fb | 458 | todo-prv-ans) |
3cb152f9 | 459 | |
da2ee685 | 460 | (defun todo-cmd-kill () "Delete current TODO list entry." |
3cb152f9 OS |
461 | (interactive) |
462 | (if (> (count-lines (point-min) (point-max)) 0) | |
463 | (progn | |
da2ee685 | 464 | (let* ((todo-entry (todo-line)) |
579e1c67 OS |
465 | (todo-answer (y-or-n-p (concat "Permanently remove '" |
466 | todo-entry "'? ")))) | |
da2ee685 OS |
467 | (if todo-answer |
468 | (progn | |
469 | (delete-region (point-at-bol) (+ 1 (point-at-eol))) | |
cf1ebf43 OS |
470 | (forward-line -1)))) |
471 | (message "")) | |
7c896f63 | 472 | (error "No TODO list entry to delete")) |
cf1ebf43 | 473 | (beginning-of-line nil)) |
3cb152f9 | 474 | |
8cdc3b3d OS |
475 | (defun todo-cmd-rais () "Raise priority of current entry." |
476 | (interactive) | |
477 | (if (> (count-lines (point-min) (point-max)) 0) | |
478 | (progn | |
479 | (setq todo-entry (todo-line)) | |
da2ee685 | 480 | (delete-region (point-at-bol) (+ 1 (point-at-eol))) |
8cdc3b3d OS |
481 | (forward-line -1) |
482 | (insert (concat todo-entry "\n")) | |
da2ee685 | 483 | (forward-line -1) |
cf1ebf43 | 484 | (message "")) |
7c896f63 | 485 | (error "No TODO list entry to raise")) |
cf1ebf43 | 486 | (beginning-of-line nil)) |
8cdc3b3d OS |
487 | |
488 | (defun todo-cmd-lowr () "Lower priority of current entry." | |
489 | (interactive) | |
490 | (if (> (count-lines (point-min) (point-max)) 0) | |
491 | (progn | |
492 | (setq todo-entry (todo-line)) | |
da2ee685 | 493 | (delete-region (point-at-bol) (+ 1 (point-at-eol))) |
8cdc3b3d OS |
494 | (forward-line 1) |
495 | (insert (concat todo-entry "\n")) | |
da2ee685 | 496 | (forward-line -1) |
cf1ebf43 | 497 | (message "")) |
7c896f63 | 498 | (error "No TODO list entry to lower")) |
cf1ebf43 | 499 | (beginning-of-line nil)) |
8cdc3b3d | 500 | |
da2ee685 | 501 | (defun todo-cmd-file () "File away the current TODO list entry." |
3cb152f9 OS |
502 | (interactive) |
503 | (if (> (count-lines (point-min) (point-max)) 0) | |
504 | (progn | |
7c896f63 OS |
505 | (let ((todo-comment (read-from-minibuffer "Comment: ")) |
506 | (time-stamp-format todo-time-string-format)) | |
da2ee685 | 507 | (beginning-of-line nil) |
a360be79 | 508 | (delete-region (point-at-bol) (search-forward todo-prefix)) |
da2ee685 OS |
509 | (insert (time-stamp-string)) |
510 | (end-of-line nil) | |
7c896f63 | 511 | (insert (concat " (" todo-comment ")")) |
da2ee685 OS |
512 | (append-to-file (point-at-bol) (+ 1 (point-at-eol)) todo-file-done) |
513 | (delete-region (point-at-bol) (+ 1 (point-at-eol))) | |
cf1ebf43 OS |
514 | (forward-line -1)) |
515 | (message "")) | |
7c896f63 | 516 | (error "No TODO list entry to file away")) |
cf1ebf43 | 517 | (beginning-of-line nil)) |
3cb152f9 OS |
518 | |
519 | ;; --------------------------------------------------------------------------- | |
520 | ||
da2ee685 OS |
521 | ;; utility functions: These are available in XEmacs, but not in Emacs 19.34 |
522 | ||
523 | (if (not (fboundp 'point-at-bol)) | |
524 | (defun point-at-bol () | |
525 | (save-excursion | |
526 | (beginning-of-line) | |
527 | (point)))) | |
528 | ||
529 | (if (not (fboundp 'point-at-eol)) | |
530 | (defun point-at-eol () | |
531 | (save-excursion | |
532 | (end-of-line) | |
533 | (point)))) | |
534 | ||
535 | ;; --------------------------------------------------------------------------- | |
536 | ||
49c48a1b | 537 | (easy-menu-define todo-menu todo-mode-map "Todo Menu" |
7c896f63 OS |
538 | '("Todo" |
539 | ["Next category" todo-cmd-forw t] | |
540 | ["Previous category" todo-cmd-back t] | |
541 | "---" | |
542 | ["Edit item" todo-cmd-edit t] | |
543 | ["File item" todo-cmd-file t] | |
544 | ["Insert new item" todo-cmd-inst t] | |
545 | ["Kill item" todo-cmd-kill t] | |
546 | "---" | |
547 | ["Lower item priority" todo-cmd-lowr t] | |
548 | ["Raise item priority" todo-cmd-rais t] | |
549 | "---" | |
550 | ["Next item" todo-cmd-next t] | |
551 | ["Previous item" todo-cmd-prev t] | |
552 | "---" | |
553 | ["Save" todo-cmd-save t] | |
554 | "---" | |
555 | ["Quit" todo-cmd-done t] | |
556 | )) | |
a360be79 | 557 | |
da2ee685 | 558 | (defun todo-mode () "Major mode for editing TODO lists.\n\n\\{todo-mode-map}" |
3cb152f9 | 559 | (interactive) |
3cb152f9 OS |
560 | (setq major-mode 'todo-mode) |
561 | (setq mode-name "TODO") | |
562 | (use-local-map todo-mode-map) | |
49c48a1b OS |
563 | (easy-menu-add todo-menu) |
564 | (run-hooks 'todo-mode-hook)) | |
da2ee685 OS |
565 | |
566 | (defun todo-show () "Show TODO list." | |
567 | (interactive) | |
568 | (find-file todo-file-do) | |
569 | (if (null todo-cats) | |
570 | (progn | |
571 | (todo-add-category "Todo") | |
572 | (goto-char (point-min)) | |
573 | (goto-char (search-forward "--- End")) | |
574 | (let ((bol (point-at-bol))) | |
575 | (forward-line 1) | |
576 | (let* ((eol (+ (point-at-eol) 1)) | |
577 | (mrkr (buffer-substring bol eol))) | |
578 | (delete-region bol eol) | |
579 | (goto-char (point-max)) | |
cf1ebf43 | 580 | (insert mrkr))) |
da2ee685 OS |
581 | (save-buffer) |
582 | (kill-buffer (current-buffer)) | |
cf1ebf43 | 583 | (find-file todo-file-do))) |
7e6ed9b9 | 584 | (beginning-of-line nil) |
cf1ebf43 | 585 | (todo-cat-slct)) |
3cb152f9 | 586 | |
7c896f63 | 587 | (provide 'todo-mode) |
3cb152f9 OS |
588 | |
589 | ;; --------------------------------------------------------------------------- | |
590 | ||
7c896f63 | 591 | ;;; todo-mode.el ends here |
3cb152f9 OS |
592 | |
593 | ;; --------------------------------------------------------------------------- |