aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Seidel1997-08-05 14:43:39 +0000
committerOliver Seidel1997-08-05 14:43:39 +0000
commitda2ee6858f61cda1a41d73c90f47ee5f35338ab4 (patch)
treebd4650967b9d2941af9fc049a456e677ec09cead
parentf6aa627c0beb9d40338bb60c0fb0c44377e2376d (diff)
downloademacs-da2ee6858f61cda1a41d73c90f47ee5f35338ab4.tar.gz
emacs-da2ee6858f61cda1a41d73c90f47ee5f35338ab4.zip
Added improvements from Ron Gut <rgut@aware.com>.
Added category management.
-rw-r--r--lisp/calendar/todo-mode.el303
1 files changed, 212 insertions, 91 deletions
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 4fedb4e4ac8..fb5049c6008 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -1,4 +1,4 @@
1;; todomode.el -- major mode for editing Todo-List files 1; todomode.el -- major mode for editing TODO list files
2 2
3;; --------------------------------------------------------------------------- 3;; ---------------------------------------------------------------------------
4 4
@@ -6,9 +6,12 @@
6;; please contact (address) O Seidel, Lessingstr 8, Eschborn, FRG 6;; please contact (address) O Seidel, Lessingstr 8, Eschborn, FRG
7;; (e-mail ) Oliver.Seidel@cl.cam.ac.uk (2 Aug 1997) 7;; (e-mail ) Oliver.Seidel@cl.cam.ac.uk (2 Aug 1997)
8 8
9;; $Id: todomode.el,v 1.3 1997/08/03 12:47:26 os10000 Exp os10000 $ 9;; $Id: todomode.el,v 1.4 1997/08/04 16:18:45 os10000 Exp os10000 $
10;; 10;;
11;; $Log: todomode.el,v $ 11;; $Log: todomode.el,v $
12;; Revision 1.4 1997/08/04 16:18:45 os10000
13;; Added Raise/Lower item.
14;;
12;; Revision 1.3 1997/08/03 12:47:26 os10000 15;; Revision 1.3 1997/08/03 12:47:26 os10000
13;; Cleaned up variables, prefix and cursor position. 16;; Cleaned up variables, prefix and cursor position.
14;; 17;;
@@ -29,38 +32,38 @@
29;; Then you have the following facilities available: 32;; Then you have the following facilities available:
30;; 33;;
31;; M-x todo-mode will enter the todo list screen, here type 34;; M-x todo-mode will enter the todo list screen, here type
32;; p for the previous entry 35;; + to go to next category
33;; n for the next entry 36;; - to go to previous category
34;; q to save the list and exit the buffer
35;; e to edit the current entry 37;; e to edit the current entry
38;; f to file the current entry, including a
39;; comment and timestamp
36;; i to insert a new entry 40;; i to insert a new entry
37;; k to kill the current entry 41;; k to kill the current entry
38;; r raise current entryk's priority
39;; l lower the current entry's priority 42;; l lower the current entry's priority
40;; f to file the current entry, including a 43;; n for the next entry
41;; comment and timestamp 44;; p for the previous entry
45;; q to save the list and exit the buffer
46;; r raise current entryk's priority
47;; s to save the list
42;; 48;;
43;; I would recommend to add the following bindings to your global keymap: 49;; I would recommend to add the following bindings to your global keymap:
44;; 50;;
45;; (global-set-key "\C-ct" 'todo-mode) 51;; (global-set-key "\C-ct" 'todo-show)
46;; (global-set-key "\C-ci" 'todo-cmd-inst) 52;; (global-set-key "\C-ci" 'todo-cmd-inst)
47;; 53;;
48;; This will enable you to quickly find the todo-list, or to simply add an 54;; This will enable you to quickly find the todo-list, or to simply add an
49;; entry, without changing to it and getting sidetracked from your current 55;; entry, without changing to it and getting sidetracked from your current
50;; project. 56;; project.
51;; 57;;
52;; I would also recommend that you execute the command 58;; I would also recommend that use the prefix "*/*" (by leaving the
53;; 59;; variable 'todo-prefix' untouched) so that the diary displays
54;; (setq todo-prefix "*/* ") 60;; each entry every day.
55;;
56;; to have all your entries prefixed in such a way that the diary displays
57;; them every day.
58 61
59;; --------------------------------------------------------------------------- 62;; ---------------------------------------------------------------------------
60 63
61;; User-configurable variables: 64;; User-configurable variables:
62 65
63(defvar todo-prefix "" "TODO mode prefix when creating entries") 66(defvar todo-prefix "*/*" "TODO mode prefix when creating entries")
64(defvar todo-file-do "~/.todo-do" "TODO mode filename of list file") 67(defvar todo-file-do "~/.todo-do" "TODO mode filename of list file")
65(defvar todo-file-done "~/.todo-done" "TODO mode filename of archive file") 68(defvar todo-file-done "~/.todo-done" "TODO mode filename of archive file")
66(defvar todo-mode-hook nil "Hooks invoked when the *TODO* buffer is created.") 69(defvar todo-mode-hook nil "Hooks invoked when the *TODO* buffer is created.")
@@ -69,63 +72,96 @@
69 72
70(require 'time-stamp) 73(require 'time-stamp)
71 74
72(defvar todo-begin (point-min) "TODO mode beginning of line") 75(defvar todo-mode-map (make-sparse-keymap) "TODO mode keymap. See `todo-mode'")
73(defvar todo-end (point-min) "TODO mode end of line") 76(define-key todo-mode-map "+" 'todo-cmd-forw)
74 77(define-key todo-mode-map "-" 'todo-cmd-back)
75(setq todo-mode-map (make-keymap))
76(suppress-keymap todo-mode-map)
77(define-key todo-mode-map "p" 'todo-cmd-prev)
78(define-key todo-mode-map "n" 'todo-cmd-next)
79(define-key todo-mode-map "q" 'todo-cmd-done)
80(define-key todo-mode-map "e" 'todo-cmd-edit) 78(define-key todo-mode-map "e" 'todo-cmd-edit)
79(define-key todo-mode-map "f" 'todo-cmd-file)
81(define-key todo-mode-map "i" 'todo-cmd-inst) 80(define-key todo-mode-map "i" 'todo-cmd-inst)
82(define-key todo-mode-map "k" 'todo-cmd-kill) 81(define-key todo-mode-map "k" 'todo-cmd-kill)
83(define-key todo-mode-map "r" 'todo-cmd-rais)
84(define-key todo-mode-map "l" 'todo-cmd-lowr) 82(define-key todo-mode-map "l" 'todo-cmd-lowr)
85(define-key todo-mode-map "f" 'todo-cmd-file) 83(define-key todo-mode-map "n" 'todo-cmd-next)
84(define-key todo-mode-map "p" 'todo-cmd-prev)
85(define-key todo-mode-map "q" 'todo-cmd-done)
86(define-key todo-mode-map "r" 'todo-cmd-rais)
87(define-key todo-mode-map "s" 'todo-cmd-save)
86 88
87(defun todo-cmd-prev () "Select previous entry." 89(defun todo-cat-slct ()
90 (let ((todo-category-name (nth todo-category-number todo-cats)))
91 (setq mode-line-buffer-identification (concat "Category: " todo-category-name))
92 (widen)
93 (goto-char (point-min))
94 (search-forward (concat "--- " todo-category-name))
95 (setq begin (+ (point-at-eol) 1))
96 (search-forward "--- End")
97 (narrow-to-region begin (point-at-bol))
98 (goto-char (point-min))
99 )
100)
101
102(defun todo-cmd-forw () "Go forward to TODO list of next category."
103 (interactive)
104 (let ((todo-cat-cnt (- (length todo-cats) 1)))
105 (setq todo-category-number (if (< todo-category-number todo-cat-cnt)
106 (+ todo-category-number 1) 0))
107 (todo-cat-slct)
108 )
109 )
110
111(defun todo-cmd-back () "Go back to TODO list of previous category."
112 (interactive)
113 (let ((todo-cat-cnt (- (length todo-cats) 1)))
114 (setq todo-category-number (if (> todo-category-number 0)
115 (- todo-category-number 1) todo-cat-cnt))
116 (todo-cat-slct)
117 )
118 )
119
120(defun todo-cmd-prev () "Select previous entry of TODO list."
88 (interactive) 121 (interactive)
89 (forward-line -1) 122 (forward-line -1)
90 (beginning-of-line nil) 123 (beginning-of-line nil)
91 (message "") 124 (message "")
92 ) 125 )
93 126
94(defun todo-cmd-next () "Select next entry." 127(defun todo-cmd-next () "Select next entry of TODO list."
95 (interactive) 128 (interactive)
96 (forward-line 1) 129 (forward-line 1)
97 (beginning-of-line nil) 130 (beginning-of-line nil)
98 (message "") 131 (message "")
99 ) 132 )
100 133
101(defun todo-cmd-done () "Done with todo list for now." 134(defun todo-cmd-save () "Save the TODO list."
135 (interactive)
136 (save-buffer)
137 )
138
139(defun todo-cmd-done () "Done with TODO list for now."
102 (interactive) 140 (interactive)
141 (widen)
142 (save-buffer)
103 (beginning-of-line nil) 143 (beginning-of-line nil)
104 (message "") 144 (message "")
105 (save-buffer)
106 (bury-buffer) 145 (bury-buffer)
107 ) 146 )
108 147
109(defun todo-line () "Find current line in buffer." 148(defun todo-line () "Find current line in buffer." (buffer-substring (point-at-bol) (point-at-eol)))
110 (end-of-line nil) (setq todo-end (point))
111 (beginning-of-line nil) (setq todo-begin (point))
112 (buffer-substring todo-begin todo-end)
113 )
114 149
115(defun todo-cmd-edit () "Edit current todo list entry." 150(defun todo-cmd-edit () "Edit current TODO list entry."
116 (interactive) 151 (interactive)
117 (setq todo-entry (todo-line)) 152 (let ((todo-entry (todo-line)))
118 (delete-region todo-begin todo-end) 153 (delete-region (point-at-bol) (point-at-eol))
119 (insert (read-from-minibuffer "Edit: " todo-entry)) 154 (insert (read-from-minibuffer "Edit: " todo-entry))
120 (beginning-of-line nil) 155 (beginning-of-line nil)
121 (message "") 156 (message "")
157 )
122 ) 158 )
123 159
124(defvar todo-prv-lne 0 "previous line that I asked about.") 160(defvar todo-prv-lne 0 "previous line that I asked about.")
125(defvar todo-prv-ans 0 "previous answer that I got.") 161(defvar todo-prv-ans 0 "previous answer that I got.")
126 162
127(defun todo-ask (lne) "Ask whether entry is more important than at LNE." 163(defun todo-ask (lne) "Ask whether entry is more important than at LNE."
128 (if (not (equal todo-prv-lne lne) ) 164 (if (not (equal todo-prv-lne lne))
129 (progn 165 (progn
130 (setq todo-prv-lne lne) 166 (setq todo-prv-lne lne)
131 (goto-line todo-prv-lne) 167 (goto-line todo-prv-lne)
@@ -135,43 +171,86 @@
135 todo-prv-ans 171 todo-prv-ans
136 ) 172 )
137 173
138(defun todo-cmd-inst () "Insert new todo list entry." 174(defun todo-add-category (cat) "Add a new category to the TODO list."
139 (interactive) 175 (interactive)
140 (beginning-of-line nil)
141 (setq todo-entry (concat "*/* " (read-from-minibuffer "New TODO entry: ")))
142 (save-window-excursion 176 (save-window-excursion
177 (setq todo-cats (cons cat todo-cats))
143 (find-file todo-file-do) 178 (find-file todo-file-do)
144 (setq todo-prv-lne 0) 179 (widen)
145 (let* ((todo-fst 1) 180 (goto-char (point-min))
146 (todo-lst (+ 1 (count-lines (point-min) (point-max))))) 181 (let ((posn (search-forward "-*- mode: todo; " 17 t)))
147 (while (< todo-fst todo-lst) 182 (if (not (null posn)) (goto-char posn))
148 (setq todo-cur (/ (+ todo-fst todo-lst) 2)) 183 (if (equal posn nil) (progn (insert "-*- mode: todo; \n") (forward-char -1)) (kill-line))
149 (setq todo-ans (if (< todo-cur todo-lst) (todo-ask todo-cur) nil))
150 (if todo-ans
151 (setq todo-lst todo-cur)
152 (setq todo-fst (+ todo-cur 1)))
153 )
154 (goto-line todo-fst)
155 ) 184 )
156 (insert (concat todo-entry "\n")) 185 (insert (format "todo-cats: %S; -*-" todo-cats))
157 (forward-char -1) 186 (forward-char 1)
187 (insert (format "%s --- %s\n--- End\n%s %s\n" todo-prefix cat todo-prefix (make-string 75 ?-)))
158 ) 188 )
189 0
190 )
191
192(defun todo-cmd-inst () "Insert new TODO list entry."
193 (interactive)
159 (beginning-of-line nil) 194 (beginning-of-line nil)
160 (message "") 195 (let* ((todo-entry (concat todo-prefix " " (read-from-minibuffer "New TODO entry: ")))
196 (temp-catgs todo-cats)
197 (todo-hstry (cons 'temp-cats (+ todo-category-number 1))))
198 (save-window-excursion
199 (setq todo-category
200 (read-from-minibuffer "Category: " (nth todo-category-number todo-cats) nil nil todo-hstry))
201 (let* ((ltrgt todo-category)
202 (lnmbr 0)
203 (ltext (car todo-cats))
204 (lrest (cdr todo-cats)))
205 (setq ltext (car todo-cats))
206 (while (not (or (null lrest) (string-equal ltext ltrgt)))
207 (setq ltext (car lrest))
208 (setq lrest (cdr lrest))
209 (setq lnmbr (+ 1 lnmbr))
210 )
211 (setq todo-category-number
212 (if (string-equal ltext todo-category) lnmbr (todo-add-category todo-category)))
213 )
214 (todo-show)
215 (setq todo-prv-lne 0)
216 (let* ((todo-fst 1)
217 (todo-lst (+ 1 (count-lines (point-min) (point-max)))))
218 (while (< todo-fst todo-lst)
219 (let* ((todo-cur (/ (+ todo-fst todo-lst) 2))
220 (todo-ans (if (< todo-cur todo-lst) (todo-ask todo-cur) nil)))
221 (if todo-ans
222 (setq todo-lst todo-cur)
223 (setq todo-fst (+ todo-cur 1)))
224 )
225 )
226 (goto-line todo-fst)
227 )
228 (insert (concat todo-entry "\n"))
229 (forward-line -1)
230 )
231 (beginning-of-line nil)
232 (message "")
233 )
161 ) 234 )
162 235
163(defun todo-cmd-kill () "Delete current todo list entry." 236(defun todo-cmd-kill () "Delete current TODO list entry."
164 (interactive) 237 (interactive)
165 (if (> (count-lines (point-min) (point-max)) 0) 238 (if (> (count-lines (point-min) (point-max)) 0)
166 (progn 239 (progn
167 (setq todo-entry (todo-line)) 240 (let* ((todo-entry (todo-line))
168 (setq todo-answer (y-or-n-p (concat "Permanently remove '" todo-entry "'? "))) 241 (todo-answer (y-or-n-p (concat "Permanently remove '" todo-entry "'? "))))
169 (if todo-answer (progn (delete-region todo-begin (+ 1 todo-end)) (forward-char -1))) 242 (if todo-answer
243 (progn
244 (delete-region (point-at-bol) (+ 1 (point-at-eol)))
245 (forward-line -1)
246 )
247 )
248 )
249 (message "")
170 ) 250 )
171 (message "No entry to delete.") 251 (message "No TODO list entry to delete.")
172 ) 252 )
173 (beginning-of-line nil) 253 (beginning-of-line nil)
174 (message "")
175 ) 254 )
176 255
177(defun todo-cmd-rais () "Raise priority of current entry." 256(defun todo-cmd-rais () "Raise priority of current entry."
@@ -179,15 +258,15 @@
179 (if (> (count-lines (point-min) (point-max)) 0) 258 (if (> (count-lines (point-min) (point-max)) 0)
180 (progn 259 (progn
181 (setq todo-entry (todo-line)) 260 (setq todo-entry (todo-line))
182 (delete-region todo-begin (+ 1 todo-end)) 261 (delete-region (point-at-bol) (+ 1 (point-at-eol)))
183 (forward-line -1) 262 (forward-line -1)
184 (insert (concat todo-entry "\n")) 263 (insert (concat todo-entry "\n"))
185 (forward-char -1) 264 (forward-line -1)
265 (message "")
186 ) 266 )
187 (message "No entry to raise.") 267 (message "No TODO list entry to raise.")
188 ) 268 )
189 (beginning-of-line nil) 269 (beginning-of-line nil)
190 (message "")
191 ) 270 )
192 271
193(defun todo-cmd-lowr () "Lower priority of current entry." 272(defun todo-cmd-lowr () "Lower priority of current entry."
@@ -195,54 +274,96 @@
195 (if (> (count-lines (point-min) (point-max)) 0) 274 (if (> (count-lines (point-min) (point-max)) 0)
196 (progn 275 (progn
197 (setq todo-entry (todo-line)) 276 (setq todo-entry (todo-line))
198 (delete-region todo-begin (+ 1 todo-end)) 277 (delete-region (point-at-bol) (+ 1 (point-at-eol)))
199 (forward-line 1) 278 (forward-line 1)
200 (insert (concat todo-entry "\n")) 279 (insert (concat todo-entry "\n"))
201 (forward-char -1) 280 (forward-line -1)
281 (message "")
202 ) 282 )
203 (message "No entry to raise.") 283 (message "No TODO list entry to raise.")
204 ) 284 )
205 (beginning-of-line nil) 285 (beginning-of-line nil)
206 (message "")
207 ) 286 )
208 287
209(defun todo-cmd-file () "File away the current todo list entry." 288(defun todo-cmd-file () "File away the current TODO list entry."
210 (interactive) 289 (interactive)
211 (if (> (count-lines (point-min) (point-max)) 0) 290 (if (> (count-lines (point-min) (point-max)) 0)
212 (progn 291 (progn
213 (setq time-stamp-format " %2d, %y, %02I:%02M%p %b") 292 (let ((time-stamp-format "%3b %2d, %y, %02I:%02M%p"))
214 (setq tmp (time-stamp-string)) 293 (beginning-of-line nil)
215 (beginning-of-line nil) 294 (insert (time-stamp-string))
216 (insert (concat (substring tmp 19 22) (substring tmp 0 19))) 295 (end-of-line nil)
217 (end-of-line nil) 296 (insert (concat " (" (read-fromminibuffer "Comment: ") ")"))
218 (insert (concat " (" (read-from-minibuffer "Comment: ") ")")) 297 (append-to-file (point-at-bol) (+ 1 (point-at-eol)) todo-file-done)
219 (todo-line) 298 (delete-region (point-at-bol) (+ 1 (point-at-eol)))
220 (append-to-file todo-begin (+ 1 todo-end) todo-file-done) 299 (forward-line -1)
221 (delete-region todo-begin (+ 1 todo-end)) 300 )
222 (forward-char -1) 301 (message "")
223 ) 302 )
224 (message "No entry to delete.") 303 (message "No TODO list entry to delete.")
225 ) 304 )
226 (beginning-of-line nil) 305 (beginning-of-line nil)
227 (message "")
228 ) 306 )
229 307
230;; --------------------------------------------------------------------------- 308;; ---------------------------------------------------------------------------
231 309
232(defun todo-mode () 310;; utility functions: These are available in XEmacs, but not in Emacs 19.34
233 "Major mode for editing TODO lists.\n\n\\{todo-mode-map}" 311
312(if (not (fboundp 'point-at-bol))
313 (defun point-at-bol ()
314 (save-excursion
315 (beginning-of-line)
316 (point))))
317
318(if (not (fboundp 'point-at-eol))
319 (defun point-at-eol ()
320 (save-excursion
321 (end-of-line)
322 (point))))
323
324;; ---------------------------------------------------------------------------
325
326(defvar todo-cats nil "TODO categories.")
327(defvar todo-category-number 0 "TODO category number.")
328
329(defun todo-mode () "Major mode for editing TODO lists.\n\n\\{todo-mode-map}"
234 (interactive) 330 (interactive)
235 (find-file todo-file-do)
236 (setq major-mode 'todo-mode) 331 (setq major-mode 'todo-mode)
237 (setq mode-name "TODO") 332 (setq mode-name "TODO")
238 (use-local-map todo-mode-map) 333 (use-local-map todo-mode-map)
334 (run-hooks 'todo-mode-hook)
335 )
336
337(defun todo-show () "Show TODO list."
338 (interactive)
339 (find-file todo-file-do)
340 (if (null todo-cats)
341 (progn
342 (todo-add-category "Todo")
343 (goto-char (point-min))
344 (goto-char (search-forward "--- End"))
345 (let ((bol (point-at-bol)))
346 (forward-line 1)
347 (let* ((eol (+ (point-at-eol) 1))
348 (mrkr (buffer-substring bol eol)))
349 (delete-region bol eol)
350 (goto-char (point-max))
351 (insert mrkr)
352 )
353 )
354 (save-buffer)
355 (kill-buffer (current-buffer))
356 (find-file todo-file-do)
357 )
358 )
239 (beginning-of-line nil) 359 (beginning-of-line nil)
240 (run-hooks 'todo-mode-hook) ) 360 (todo-cat-slct)
361 )
241 362
242(provide 'todomode) 363(provide 'todomode)
243 364
244;; --------------------------------------------------------------------------- 365;; ---------------------------------------------------------------------------
245 366
246;;; todomode.el ends here 367;; todomode.el ends here
247 368
248;; --------------------------------------------------------------------------- 369;; ---------------------------------------------------------------------------