(gud): Fix defgroup doc.
[bpt/emacs.git] / lisp / calendar / todo-mode.el
CommitLineData
3cb152f9
OS
1;; todomode.el -- major mode for editing Todo-List files
2
3;; ---------------------------------------------------------------------------
4
5;; Note: You may copy this file freely for non-commercial use; otherwise,
6;; please contact (address) O Seidel, Lessingstr 8, Eschborn, FRG
7;; (e-mail ) Oliver.Seidel@cl.cam.ac.uk (2 Aug 1997)
8
8cdc3b3d 9;; $Id: todomode.el,v 1.3 1997/08/03 12:47:26 os10000 Exp os10000 $
3cb152f9 10;;
384af0dd 11;; $Log: todomode.el,v $
8cdc3b3d
OS
12;; Revision 1.3 1997/08/03 12:47:26 os10000
13;; Cleaned up variables, prefix and cursor position.
14;;
7e6ed9b9
OS
15;; Revision 1.2 1997/08/03 12:15:28 os10000
16;; It appears to work.
17;;
384af0dd
OS
18;; Revision 1.1 1997/08/03 12:15:13 os10000
19;; Initial revision
3cb152f9
OS
20;;
21
22;; ---------------------------------------------------------------------------
23
7e6ed9b9
OS
24;; Description:
25;;
26;; To get this to work, make emacs execute the line "(require 'todomode)"
27;; and maybe initialise the variables below on startup.
28;;
29;; Then you have the following facilities available:
30;;
31;; M-x todo-mode will enter the todo list screen, here type
32;; p for the previous entry
33;; n for the next entry
34;; q to save the list and exit the buffer
35;; e to edit the current entry
36;; i to insert a new entry
37;; k to kill the current entry
8cdc3b3d
OS
38;; r raise current entryk's priority
39;; l lower the current entry's priority
7e6ed9b9
OS
40;; f to file the current entry, including a
41;; comment and timestamp
42;;
43;; I would recommend to add the following bindings to your global keymap:
44;;
45;; (global-set-key "\C-ct" 'todo-mode)
46;; (global-set-key "\C-ci" 'todo-cmd-inst)
47;;
48;; 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
50;; project.
51;;
52;; I would also recommend that you execute the command
53;;
54;; (setq todo-prefix "*/* ")
55;;
56;; to have all your entries prefixed in such a way that the diary displays
57;; them every day.
58
59;; ---------------------------------------------------------------------------
60
3cb152f9
OS
61;; User-configurable variables:
62
7e6ed9b9
OS
63(defvar todo-prefix "" "TODO mode prefix when creating entries")
64(defvar todo-file-do "~/.todo-do" "TODO mode filename of list file")
3cb152f9
OS
65(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.")
67
68;; ---------------------------------------------------------------------------
69
70(require 'time-stamp)
71
72(defvar todo-begin (point-min) "TODO mode beginning of line")
73(defvar todo-end (point-min) "TODO mode end of line")
74
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)
81(define-key todo-mode-map "i" 'todo-cmd-inst)
82(define-key todo-mode-map "k" 'todo-cmd-kill)
8cdc3b3d
OS
83(define-key todo-mode-map "r" 'todo-cmd-rais)
84(define-key todo-mode-map "l" 'todo-cmd-lowr)
3cb152f9
OS
85(define-key todo-mode-map "f" 'todo-cmd-file)
86
87(defun todo-cmd-prev () "Select previous entry."
88 (interactive)
89 (forward-line -1)
90 (beginning-of-line nil)
91 (message "")
92 )
93
94(defun todo-cmd-next () "Select next entry."
95 (interactive)
96 (forward-line 1)
97 (beginning-of-line nil)
98 (message "")
99 )
100
101(defun todo-cmd-done () "Done with todo list for now."
102 (interactive)
7e6ed9b9
OS
103 (beginning-of-line nil)
104 (message "")
3cb152f9
OS
105 (save-buffer)
106 (bury-buffer)
107 )
108
109(defun todo-line () "Find current line in buffer."
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
115(defun todo-cmd-edit () "Edit current todo list entry."
116 (interactive)
117 (setq todo-entry (todo-line))
118 (delete-region todo-begin todo-end)
119 (insert (read-from-minibuffer "Edit: " todo-entry))
120 (beginning-of-line nil)
121 (message "")
122 )
123
124(defvar todo-prv-lne 0 "previous line that I asked about.")
125(defvar todo-prv-ans 0 "previous answer that I got.")
126
127(defun todo-ask (lne) "Ask whether entry is more important than at LNE."
128 (if (not (equal todo-prv-lne lne) )
129 (progn
130 (setq todo-prv-lne lne)
131 (goto-line todo-prv-lne)
132 (setq todo-prv-ans (y-or-n-p (concat "More important than '" (todo-line) "'? ")))
133 )
134 )
135 todo-prv-ans
136 )
137
138(defun todo-cmd-inst () "Insert new todo list entry."
139 (interactive)
7e6ed9b9
OS
140 (beginning-of-line nil)
141 (setq todo-entry (concat "*/* " (read-from-minibuffer "New TODO entry: ")))
3cb152f9
OS
142 (save-window-excursion
143 (find-file todo-file-do)
144 (setq todo-prv-lne 0)
145 (let* ((todo-fst 1)
146 (todo-lst (+ 1 (count-lines (point-min) (point-max)))))
147 (while (< todo-fst todo-lst)
148 (setq todo-cur (/ (+ todo-fst todo-lst) 2))
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 )
156 (insert (concat todo-entry "\n"))
157 (forward-char -1)
158 )
159 (beginning-of-line nil)
160 (message "")
161 )
162
163(defun todo-cmd-kill () "Delete current todo list entry."
164 (interactive)
165 (if (> (count-lines (point-min) (point-max)) 0)
166 (progn
167 (setq todo-entry (todo-line))
168 (setq 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)))
170 )
171 (message "No entry to delete.")
172 )
173 (beginning-of-line nil)
174 (message "")
175 )
176
8cdc3b3d
OS
177(defun todo-cmd-rais () "Raise priority of current entry."
178 (interactive)
179 (if (> (count-lines (point-min) (point-max)) 0)
180 (progn
181 (setq todo-entry (todo-line))
182 (delete-region todo-begin (+ 1 todo-end))
183 (forward-line -1)
184 (insert (concat todo-entry "\n"))
185 (forward-char -1)
186 )
187 (message "No entry to raise.")
188 )
189 (beginning-of-line nil)
190 (message "")
191 )
192
193(defun todo-cmd-lowr () "Lower priority of current entry."
194 (interactive)
195 (if (> (count-lines (point-min) (point-max)) 0)
196 (progn
197 (setq todo-entry (todo-line))
198 (delete-region todo-begin (+ 1 todo-end))
199 (forward-line 1)
200 (insert (concat todo-entry "\n"))
201 (forward-char -1)
202 )
203 (message "No entry to raise.")
204 )
205 (beginning-of-line nil)
206 (message "")
207 )
208
3cb152f9
OS
209(defun todo-cmd-file () "File away the current todo list entry."
210 (interactive)
211 (if (> (count-lines (point-min) (point-max)) 0)
212 (progn
213 (setq time-stamp-format " %2d, %y, %02I:%02M%p %b")
214 (setq tmp (time-stamp-string))
215 (beginning-of-line nil)
216 (insert (concat (substring tmp 19 22) (substring tmp 0 19)))
217 (end-of-line nil)
218 (insert (concat " (" (read-from-minibuffer "Comment: ") ")"))
219 (todo-line)
220 (append-to-file todo-begin (+ 1 todo-end) todo-file-done)
221 (delete-region todo-begin (+ 1 todo-end))
222 (forward-char -1)
223 )
224 (message "No entry to delete.")
225 )
226 (beginning-of-line nil)
227 (message "")
228 )
229
230;; ---------------------------------------------------------------------------
231
232(defun todo-mode ()
233 "Major mode for editing TODO lists.\n\n\\{todo-mode-map}"
234 (interactive)
235 (find-file todo-file-do)
236 (setq major-mode 'todo-mode)
237 (setq mode-name "TODO")
238 (use-local-map todo-mode-map)
7e6ed9b9 239 (beginning-of-line nil)
3cb152f9
OS
240 (run-hooks 'todo-mode-hook) )
241
242(provide 'todomode)
243
244;; ---------------------------------------------------------------------------
245
246;;; todomode.el ends here
247
248;; ---------------------------------------------------------------------------