Mercurial > hg > lib > markup
comparison emacs/diary.el @ 0:509549c55989
from elsewhere
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Tue, 25 May 2021 13:57:42 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509549c55989 |
---|---|
1 ;; Last edited: Wed Oct 24 17:08:20 1990 | |
2 ;; provide a simple diary facility on top of rmailsum | |
3 ;; Copyright (C) 1990 Henry S. Thompson | |
4 | |
5 ;; This file is part of GNU Emacs. | |
6 | |
7 ;; GNU Emacs is distributed in the hope that it will be useful, | |
8 ;; but WITHOUT ANY WARRANTY. No author or distributor | |
9 ;; accepts responsibility to anyone for the consequences of using it | |
10 ;; or for whether it serves any particular purpose or works at all, | |
11 ;; unless he says so in writing. Refer to the GNU Emacs General Public | |
12 ;; License for full details. | |
13 | |
14 ;; Everyone is granted permission to copy, modify and redistribute | |
15 ;; GNU Emacs, but only under the conditions described in the | |
16 ;; GNU Emacs General Public License. A copy of this license is | |
17 ;; supposed to have been given to you along with GNU Emacs so you | |
18 ;; can know your rights and responsibilities. It should be in a | |
19 ;; file named COPYING. Among other things, the copyright notice | |
20 ;; and this notice must be preserved on all copies. | |
21 | |
22 (provide 'diary) | |
23 (require 'mail-extras) | |
24 | |
25 (autoload 'sort-subr "sort") | |
26 | |
27 (defvar ht-diary-file-name "~/DIARY.babyl" | |
28 "default name of diary file") | |
29 | |
30 (defvar ht-Calendar-directory "~/Calendar") | |
31 | |
32 (defun xxx-date-lessp (date1 date2) | |
33 "Return T if DATE1 is earlyer than DATE2." | |
34 (string-lessp (gnus-comparable-date date1) | |
35 (gnus-comparable-date date2))) | |
36 | |
37 (defun xxx-comparable-date (date) | |
38 "Make comparable string by string-lessp from DATE." | |
39 (let ((month '(("JAN" . " 1")("FEB" . " 2")("MAR" . " 3") | |
40 ("APR" . " 4")("MAY" . " 5")("JUN" . " 6") | |
41 ("JUL" . " 7")("AUG" . " 8")("SEP" . " 9") | |
42 ("OCT" . "10")("NOV" . "11")("DEC" . "12"))) | |
43 (date (or date ""))) | |
44 ;; Can understand the following styles: | |
45 ;; (1) 14 Apr 89 03:20:12 GMT | |
46 ;; (2) Fri, 17 March 89 4:01:33 GMT | |
47 (if (string-match | |
48 "\\([0-9]+\\) \\([^ ,]+\\) \\([0-9]+\\) *\\([0-9:]*\\)" date) | |
49 (concat | |
50 ;; Year | |
51 (substring date (match-beginning 3) (match-end 3)) | |
52 ;; Month | |
53 (cdr | |
54 (assoc | |
55 (upcase (substring date | |
56 (match-beginning 2) | |
57 (+ 3 (match-beginning 2)))) | |
58 month)) | |
59 ;; Day | |
60 (format "%2d" (string-to-int | |
61 (substring date | |
62 (match-beginning 1) (match-end 1)))) | |
63 ;; Time | |
64 (substring date (match-beginning 4) (match-end 4))) | |
65 ;; Cannot understand DATE string. | |
66 date | |
67 ) | |
68 )) | |
69 | |
70 (defun update-default-diary (arg) "update a diary - with arg, the one for | |
71 this file. Without arg, the default (named in ht-diary-file-name)" | |
72 (interactive "P") | |
73 (if arg | |
74 (update-diary (current-buffer)) | |
75 (require-diary) | |
76 (update-diary (get-file-buffer ht-diary-file-name)))) | |
77 | |
78 (defun update-diary (buffer) | |
79 ;; (setq rmail-summary-buffer (get-buffer-create "*Diary*")) | |
80 (let ((obuf (current-buffer))) | |
81 (set-buffer buffer) | |
82 (if (not has-diary-summary) | |
83 (progn (make-local-variable 'has-diary-summary) | |
84 (setq has-diary-summary t))) | |
85 (rmail-summary) | |
86 (set-buffer obuf))) | |
87 | |
88 (defun do-diary-update () "rmail-summary-mode-hook calls this" | |
89 (if (save-excursion (set-buffer rbuf) | |
90 has-diary-summary) | |
91 (progn | |
92 (make-local-variable 'diary-summary-buffer) | |
93 (setq diary-summary-buffer t) | |
94 (setq description (concat "Diary " description)) | |
95 (setq buffer-read-only nil) | |
96 (sort-diary-hdrs) | |
97 (format-diary-hdrs) | |
98 (setq buffer-read-only t) | |
99 (not-modified) | |
100 (beginning-of-buffer) | |
101 (setq mesg nil) ; to go to earliest, not first in file | |
102 ))) | |
103 | |
104 (defun require-diary () | |
105 (if (not (get-file-buffer ht-diary-file-name)) | |
106 (progn (rmail-input ht-diary-file-name) | |
107 (rmail-show-message 1)) | |
108 )) | |
109 | |
110 (defvar diary-summary-buffer nil "flag to identify diary summaries") | |
111 (defvar has-diary-summary nil "flag to identify buffers with diary summaries") | |
112 | |
113 (defun sort-diary-hdrs () | |
114 (interactive) | |
115 (goto-char (point-min)) | |
116 (sort-subr nil 'forward-line 'end-of-line 'get-diary-hdr-date nil)) | |
117 | |
118 (defun format-diary-hdrs () | |
119 (goto-char (point-min)) | |
120 (while (< (point)(point-max)) | |
121 (forward-char 5) | |
122 (delete-char 35) | |
123 (looking-at " *\\([0-9]*\\) *\\([a-zA-Z]*\\) *\\([0-9]*\\) *\\([0-9]*\\)") | |
124 (if (match-beginning 0) | |
125 (let ((day (buffer-substring (match-beginning 1)(match-end 1))) | |
126 (month (capitalize (buffer-substring (match-beginning 2) | |
127 (min (+ (match-beginning 2) | |
128 3) | |
129 (match-end 2))))) | |
130 (year (buffer-substring (max | |
131 (- (match-end 3) 2) | |
132 (match-beginning 3)) | |
133 (match-end 3))) | |
134 (time (buffer-substring (match-beginning 4)(match-end 4)))) | |
135 (delete-char (+ 1 | |
136 (if (= (match-end 4) | |
137 (match-beginning 4)) | |
138 0 ; fix for no time case | |
139 1) | |
140 (- (match-end 4)(match-beginning 1)))) | |
141 (insert (format " %2s %3s %2s %4s " day month year time)))) | |
142 (forward-line 1)) | |
143 (goto-char (point-min))) | |
144 | |
145 (defun get-diary-hdr-date () | |
146 (looking-at " *[^ ]* *[^ ]* *[^ ]* *\\(.*\\)$") | |
147 (xxx-comparable-date (buffer-substring (match-beginning 1)(match-end 1)))) | |
148 | |
149 | |
150 (if (not (boundp 'rmail-edit-map)) | |
151 (load-library "rmailedit")) | |
152 (if (not (boundp 'rmail-summary-mode-map)) | |
153 (progn (load-library "rmailsum") | |
154 (rmail-summary-mode-fun1))) | |
155 (define-key rmail-edit-map "\C-c\C-c" 'ht-rmail-cease-edit) | |
156 (define-key rmail-edit-map "\C-c\C-]" 'ht-rmail-abort-edit) | |
157 ;(defvar diary-mode-map (copy-keymap rmail-summary-mode-map)) | |
158 ;(define-key diary-mode-map "s" 'diary-save) | |
159 (define-key rmail-mode-map "h" 'ht-rmail-summarise) | |
160 (setq rmail-summary-mode-hook 'do-diary-update) | |
161 | |
162 (defvar editing-diary-entry nil) | |
163 | |
164 (defun diary-save () | |
165 "save parent file and update" | |
166 (interactive) | |
167 (set-buffer rmail-buffer) | |
168 (rmail-expunge-and-save) | |
169 (if has-diary-summary (update-diary (current-buffer)))) | |
170 | |
171 (defun ht-rmail-summarise () | |
172 "Display a summary of all messages, one line per message. | |
173 If file is named as ht-diary-file-name, or the summary buffer is already | |
174 a diary summary, make it a Diary summary (see | |
175 \\[describe-mode] rmail-summary-mode for info)." | |
176 (interactive) | |
177 (if (eq (current-buffer) | |
178 (get-file-buffer ht-diary-file-name)) | |
179 (update-default-diary t) | |
180 (rmail-summary))) | |
181 | |
182 (defun edit-and-move-to-diary () | |
183 "try to add a date to subject field, move to diary on exit" | |
184 (interactive) | |
185 (make-local-variable 'editing-diary-entry) | |
186 (setq editing-diary-entry t) | |
187 (rmail-edit-current-message) | |
188 (goto-char (point-min)) | |
189 (search-forward "\n\n") | |
190 (let ((try-date (and | |
191 (re-search-forward | |
192 "[0-9][-0-9 ]*[- ][a-zA-Z][a-zA-Z]*[- 0-9]*" nil t) | |
193 (buffer-substring (match-beginning 0)(match-end 0))))) | |
194 (goto-char (point-min)) | |
195 (if (and (search-forward "Subject: " nil t) | |
196 try-date) | |
197 (progn (set-mark (point)) | |
198 (insert try-date))))) | |
199 | |
200 ;; private copy to simulate hook | |
201 (defun ht-rmail-cease-edit () | |
202 "check if diary edit, move if so" | |
203 (interactive) | |
204 (rmail-cease-edit) | |
205 (if editing-diary-entry | |
206 (progn (setq editing-diary-entry nil) | |
207 (ht-output-to-Calendar) | |
208 (rmail-output-to-rmail-file ht-diary-file-name 1) | |
209 (ht-rmail-delete-forward)))) | |
210 | |
211 ;; try to add a diary subject field line to the appropriate caleendar file | |
212 (defun ht-output-to-Calendar () | |
213 (goto-char (point-min)) | |
214 (search-forward "Subject: ") | |
215 (or (looking-at | |
216 "\\([0-9]+\\) \\([A-Za-z]+\\) \\([0-9]+\\) \\([0-9:]*\\) ?\\(.*\\)\n") | |
217 (error "not a recognisable diary line")) | |
218 (let ((day (buffer-substring (match-beginning 1) (match-end 1))) | |
219 (month (buffer-substring (match-beginning 2) (match-end 2))) | |
220 (year (buffer-substring (match-beginning 3) (match-end 3))) | |
221 (time (buffer-substring (match-beginning 4) (match-end 4))) | |
222 (message (buffer-substring (match-beginning 5) (match-end 5))) | |
223 (mb (match-beginning 4)) | |
224 (me (match-end 5)) | |
225 t-month ends) | |
226 (if (file-exists-p ht-Calendar-directory) | |
227 (let* ((year (if (string-match "^19" year) | |
228 year | |
229 (concat "19" year))) | |
230 (dfn (concat ht-Calendar-directory | |
231 "/xy" | |
232 year | |
233 "/xc" | |
234 day | |
235 (setq t-month (capitalize | |
236 (substring month 0 3))) | |
237 year)) | |
238 (buf (find-file-noselect dfn))) | |
239 (save-excursion | |
240 (set-buffer buf) | |
241 (goto-char (point-max)) | |
242 (if (not (bolp)) | |
243 (insert "\n")) | |
244 (if time | |
245 (insert time " ")) | |
246 (if (string-match " -- \\(.*\\)$" message) | |
247 (progn | |
248 (setq ends (substring message (match-beginning 1) | |
249 (match-end 1))) | |
250 (setq message (substring message 0 (match-beginning 0))))) | |
251 (insert message) | |
252 (let ((require-final-newline nil)) | |
253 (save-buffer))) | |
254 (if ends | |
255 ;; an end date also given | |
256 (if (string-match "\\([0-9]+\\) \\([A-Za-z]+\\)" ends) | |
257 (let ((e-day (substring ends (match-beginning 1) | |
258 (match-end 1))) | |
259 (e-month (substring ends (match-beginning 2) | |
260 (match-end 2))) | |
261 t-e-month msg) | |
262 (setq msg (concat | |
263 (substring message 0 | |
264 (string-match " " message)) | |
265 " continues")) | |
266 (if (string-equal (setq t-e-month | |
267 (capitalize | |
268 (substring e-month 0 3))) | |
269 t-month) | |
270 (fill-dates year t-month (1+ (car | |
271 (read-from-string day))) | |
272 (car | |
273 (read-from-string e-day)) | |
274 msg) | |
275 (fill-dates year t-month (1+ (car | |
276 (read-from-string day))) | |
277 (cdr (assoc t-month | |
278 '(("Jan" . 31) | |
279 ("Feb" . 28) | |
280 ("Mar" . 31) | |
281 ("Apr" . 30) | |
282 ("May" . 31) | |
283 ("Jun" . 30) | |
284 ("Jul" . 31) | |
285 ("Aug" . 31) | |
286 ("Sep" . 30) | |
287 ("Oct" . 31) | |
288 ("Nov" . 30) | |
289 ("Dec" . 31)))) | |
290 msg) | |
291 (fill-dates year t-e-month 1 | |
292 (car (read-from-string e-day)) | |
293 msg))) | |
294 (message "\C-g\C-gCouldn't parse end date: %s" ends))) | |
295 )))) | |
296 | |
297 (defun fill-dates (year month start end mesg) | |
298 "fill the dates between start and end with message in the calendar" | |
299 (let ((day start)) | |
300 (while (<= day end) | |
301 (let* ((dfn (concat ht-Calendar-directory | |
302 "/xy" | |
303 year | |
304 "/xc" | |
305 day | |
306 month | |
307 year)) | |
308 (buf (find-file-noselect dfn))) | |
309 (save-excursion | |
310 (set-buffer buf) | |
311 (goto-char (point-max)) | |
312 (if (not (bolp)) | |
313 (insert "\n")) | |
314 (insert mesg) | |
315 (let ((require-final-newline nil)) | |
316 (save-buffer)))) | |
317 (setq day (1+ day))))) | |
318 | |
319 ;; private copy | |
320 (defun ht-rmail-abort-edit () | |
321 "add a hook" | |
322 (interactive) | |
323 (setq editing-diary-entry nil) | |
324 (rmail-abort-edit)) | |
325 | |
326 (defun rmail-edit-current-message () | |
327 "Edit the contents of this message." | |
328 (interactive) | |
329 (rmail-edit-mode) | |
330 (make-local-variable 'rmail-old-text) | |
331 (setq rmail-old-text (buffer-substring (point-min) (point-max))) | |
332 (setq buffer-read-only nil) | |
333 (set-buffer-modified-p (buffer-modified-p)) | |
334 ;; Make mode line update. | |
335 (if (and (eq (key-binding "\C-c\C-c") 'ht-rmail-cease-edit) | |
336 (eq (key-binding "\C-c\C-]") 'ht-rmail-abort-edit)) | |
337 (if editing-diary-entry | |
338 (message "Editing: Type C-c C-c to move to diary and return to Rmail, C-c C-] to abort") | |
339 (message "Editing: Type C-c C-c to return to Rmail, C-c C-] to abort")) | |
340 (message (substitute-command-keys | |
341 "Editing: Type \\[rmail-cease-edit] to return to Rmail, \\[rmail-abort-edit] to abort")))) |