Commit | Line | Data |
---|---|---|
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 | ;; --------------------------------------------------------------------------- |