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 | ||
9 | ;; $Id:$ | |
10 | ;; | |
11 | ;; $Log:$ | |
12 | ;; | |
13 | ||
14 | ;; --------------------------------------------------------------------------- | |
15 | ||
16 | ;; User-configurable variables: | |
17 | ||
18 | (defvar todo-file-do "~/.todo-do" "TODO mode filename of list file") | |
19 | (defvar todo-file-done "~/.todo-done" "TODO mode filename of archive file") | |
20 | (defvar todo-mode-hook nil "Hooks invoked when the *TODO* buffer is created.") | |
21 | ||
22 | ;; --------------------------------------------------------------------------- | |
23 | ||
24 | (require 'time-stamp) | |
25 | ||
26 | (defvar todo-begin (point-min) "TODO mode beginning of line") | |
27 | (defvar todo-end (point-min) "TODO mode end of line") | |
28 | ||
29 | (setq todo-mode-map (make-keymap)) | |
30 | (suppress-keymap todo-mode-map) | |
31 | (define-key todo-mode-map "p" 'todo-cmd-prev) | |
32 | (define-key todo-mode-map "n" 'todo-cmd-next) | |
33 | (define-key todo-mode-map "q" 'todo-cmd-done) | |
34 | (define-key todo-mode-map "e" 'todo-cmd-edit) | |
35 | (define-key todo-mode-map "i" 'todo-cmd-inst) | |
36 | (define-key todo-mode-map "k" 'todo-cmd-kill) | |
37 | (define-key todo-mode-map "f" 'todo-cmd-file) | |
38 | ||
39 | (defun todo-cmd-prev () "Select previous entry." | |
40 | (interactive) | |
41 | (forward-line -1) | |
42 | (beginning-of-line nil) | |
43 | (message "") | |
44 | ) | |
45 | ||
46 | (defun todo-cmd-next () "Select next entry." | |
47 | (interactive) | |
48 | (forward-line 1) | |
49 | (beginning-of-line nil) | |
50 | (message "") | |
51 | ) | |
52 | ||
53 | (defun todo-cmd-done () "Done with todo list for now." | |
54 | (interactive) | |
55 | (save-buffer) | |
56 | (bury-buffer) | |
57 | ) | |
58 | ||
59 | (defun todo-line () "Find current line in buffer." | |
60 | (end-of-line nil) (setq todo-end (point)) | |
61 | (beginning-of-line nil) (setq todo-begin (point)) | |
62 | (buffer-substring todo-begin todo-end) | |
63 | ) | |
64 | ||
65 | (defun todo-cmd-edit () "Edit current todo list entry." | |
66 | (interactive) | |
67 | (setq todo-entry (todo-line)) | |
68 | (delete-region todo-begin todo-end) | |
69 | (insert (read-from-minibuffer "Edit: " todo-entry)) | |
70 | (beginning-of-line nil) | |
71 | (message "") | |
72 | ) | |
73 | ||
74 | (defvar todo-prv-lne 0 "previous line that I asked about.") | |
75 | (defvar todo-prv-ans 0 "previous answer that I got.") | |
76 | ||
77 | (defun todo-ask (lne) "Ask whether entry is more important than at LNE." | |
78 | (if (not (equal todo-prv-lne lne) ) | |
79 | (progn | |
80 | (setq todo-prv-lne lne) | |
81 | (goto-line todo-prv-lne) | |
82 | (setq todo-prv-ans (y-or-n-p (concat "More important than '" (todo-line) "'? "))) | |
83 | ) | |
84 | ) | |
85 | todo-prv-ans | |
86 | ) | |
87 | ||
88 | (defun todo-cmd-inst () "Insert new todo list entry." | |
89 | (interactive) | |
90 | (setq todo-entry (read-from-minibuffer "New TODO entry: ")) | |
91 | (save-window-excursion | |
92 | (find-file todo-file-do) | |
93 | (setq todo-prv-lne 0) | |
94 | (let* ((todo-fst 1) | |
95 | (todo-lst (+ 1 (count-lines (point-min) (point-max))))) | |
96 | (while (< todo-fst todo-lst) | |
97 | (setq todo-cur (/ (+ todo-fst todo-lst) 2)) | |
98 | (setq todo-ans (if (< todo-cur todo-lst) (todo-ask todo-cur) nil)) | |
99 | (if todo-ans | |
100 | (setq todo-lst todo-cur) | |
101 | (setq todo-fst (+ todo-cur 1))) | |
102 | ) | |
103 | (goto-line todo-fst) | |
104 | ) | |
105 | (insert (concat todo-entry "\n")) | |
106 | (forward-char -1) | |
107 | ) | |
108 | (beginning-of-line nil) | |
109 | (message "") | |
110 | ) | |
111 | ||
112 | (defun todo-cmd-kill () "Delete current todo list entry." | |
113 | (interactive) | |
114 | (if (> (count-lines (point-min) (point-max)) 0) | |
115 | (progn | |
116 | (setq todo-entry (todo-line)) | |
117 | (setq todo-answer (y-or-n-p (concat "Permanently remove '" todo-entry "'? "))) | |
118 | (if todo-answer (progn (delete-region todo-begin (+ 1 todo-end)) (forward-char -1))) | |
119 | ) | |
120 | (message "No entry to delete.") | |
121 | ) | |
122 | (beginning-of-line nil) | |
123 | (message "") | |
124 | ) | |
125 | ||
126 | (defun todo-cmd-file () "File away the current todo list entry." | |
127 | (interactive) | |
128 | (if (> (count-lines (point-min) (point-max)) 0) | |
129 | (progn | |
130 | (setq time-stamp-format " %2d, %y, %02I:%02M%p %b") | |
131 | (setq tmp (time-stamp-string)) | |
132 | (beginning-of-line nil) | |
133 | (insert (concat (substring tmp 19 22) (substring tmp 0 19))) | |
134 | (end-of-line nil) | |
135 | (insert (concat " (" (read-from-minibuffer "Comment: ") ")")) | |
136 | (todo-line) | |
137 | (append-to-file todo-begin (+ 1 todo-end) todo-file-done) | |
138 | (delete-region todo-begin (+ 1 todo-end)) | |
139 | (forward-char -1) | |
140 | ) | |
141 | (message "No entry to delete.") | |
142 | ) | |
143 | (beginning-of-line nil) | |
144 | (message "") | |
145 | ) | |
146 | ||
147 | ;; --------------------------------------------------------------------------- | |
148 | ||
149 | (defun todo-mode () | |
150 | "Major mode for editing TODO lists.\n\n\\{todo-mode-map}" | |
151 | (interactive) | |
152 | (find-file todo-file-do) | |
153 | (setq major-mode 'todo-mode) | |
154 | (setq mode-name "TODO") | |
155 | (use-local-map todo-mode-map) | |
156 | (run-hooks 'todo-mode-hook) ) | |
157 | ||
158 | (provide 'todomode) | |
159 | ||
160 | ;; --------------------------------------------------------------------------- | |
161 | ||
162 | ;;; todomode.el ends here | |
163 | ||
164 | ;; --------------------------------------------------------------------------- |