Mercurial > hg > xemacs-beta
comparison lisp/hyperbole/wrolo.el @ 36:c53a95d3c46d r19-15b101
Import from CVS: tag r19-15b101
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:53:38 +0200 |
parents | 4103f0995bd7 |
children | 131b0175ea99 |
comparison
equal
deleted
inserted
replaced
35:279432d5c479 | 36:c53a95d3c46d |
---|---|
13 ;; contracts for InfoDock, Emacs and XEmacs. | 13 ;; contracts for InfoDock, Emacs and XEmacs. |
14 ;; E-mail: <info@infodock.com> Web: http://www.infodock.com | 14 ;; E-mail: <info@infodock.com> Web: http://www.infodock.com |
15 ;; Tel: +1 408-243-3300 | 15 ;; Tel: +1 408-243-3300 |
16 ;; | 16 ;; |
17 ;; ORIG-DATE: 7-Jun-89 at 22:08:29 | 17 ;; ORIG-DATE: 7-Jun-89 at 22:08:29 |
18 ;; LAST-MOD: 17-Feb-97 at 15:32:20 by Bob Weiner | 18 ;; LAST-MOD: 14-Mar-97 at 01:32:23 by Bob Weiner |
19 ;; | 19 ;; |
20 ;; This file is part of Hyperbole. | 20 ;; This file is part of Hyperbole. |
21 ;; Available for use and distribution under the same terms as GNU Emacs. | 21 ;; Available for use and distribution under the same terms as GNU Emacs. |
22 ;; | 22 ;; |
23 ;; Copyright (C) 1989, '90, '91, '92, '95 Free Software Foundation, Inc. | 23 ;; Copyright (C) 1989, '90, '91, '92, '95, '96, '97 Free Software Foundation, Inc. |
24 ;; Copyright (C) 1996 InfoDock Associates | |
25 ;; | 24 ;; |
26 ;; DESCRIPTION: | 25 ;; DESCRIPTION: |
27 ;; | 26 ;; |
28 ;; The `put whatever you feel like into it' rolodex. | 27 ;; The `put whatever you feel like into it' rolodex. |
29 ;; | 28 ;; |
61 ;; wrolo as part of Hyperbole, this file in unneeded and so not included.) | 60 ;; wrolo as part of Hyperbole, this file in unneeded and so not included.) |
62 ;; | 61 ;; |
63 ;; | 62 ;; |
64 ;; SETUP: | 63 ;; SETUP: |
65 ;; | 64 ;; |
66 ;; The variable 'rolo-file-list' is a list of files to search for | 65 ;; The variable `rolo-file-list' is a list of files to search for |
67 ;; matching rolodex entries. To add personal files to rolo-file-list, | 66 ;; matching rolodex entries. To add personal files to rolo-file-list, |
68 ;; when you find these functions are useful for any sort of list lookup, | 67 ;; when you find these functions are useful for any sort of list lookup, |
69 ;; add the following to your ~/.emacs file (substituting where you see | 68 ;; add the following to your ~/.emacs file (substituting where you see |
70 ;; <fileN>): | 69 ;; <fileN>): |
71 ;; | 70 ;; |
72 ;; (setq rolo-file-list (append rolo-file-list '("<file1>" "<file2>"))) | 71 ;; (setq rolo-file-list (append rolo-file-list '("<file1>" "<file2>"))) |
73 ;; | 72 ;; |
74 ;; We recommend that entries in 'rolo-file-list' have ".otl" suffixes | 73 ;; We recommend that entries in `rolo-file-list' have ".otl" suffixes |
75 ;; so that they do not conflict with file names that other rolodex | 74 ;; so that they do not conflict with file names that other rolodex |
76 ;; programs might use and so that they are edited in 'outline-mode' by | 75 ;; programs might use and so that they are edited in `outline-mode' by |
77 ;; default. If you want the latter behavior, uncomment and add something | 76 ;; default. If you want the latter behavior, uncomment and add something |
78 ;; like the following to one of your GNU Emacs initialization files: | 77 ;; like the following to one of your GNU Emacs initialization files: |
79 ;; | 78 ;; |
80 ;; ;; Add to the list of suffixes that causes automatic mode invocation | 79 ;; ;; Add to the list of suffixes that causes automatic mode invocation |
81 ;; (setq auto-mode-alist | 80 ;; (setq auto-mode-alist |
96 ;; | 95 ;; |
97 ;; When adding an entry from within a buffer containing a mail | 96 ;; When adding an entry from within a buffer containing a mail |
98 ;; message, the rolodex add function will extract the sender's name | 97 ;; message, the rolodex add function will extract the sender's name |
99 ;; and e-mail address and prompt you with the name as a default. If | 98 ;; and e-mail address and prompt you with the name as a default. If |
100 ;; you accept it, it will enter the name and the email address using | 99 ;; you accept it, it will enter the name and the email address using |
101 ;; the format given by the 'rolo-email-format' variable. See its | 100 ;; the format given by the `rolo-email-format' variable. See its |
102 ;; documentation if you want to change its value. | 101 ;; documentation if you want to change its value. |
103 ;; | 102 ;; |
104 ;; | 103 ;; |
105 ;; If you use Hyperbole V2.3 or greater, then no other rolodex setup | 104 ;; If you use Hyperbole V2.3 or greater, then no other rolodex setup |
106 ;; is necessary, simply select the "Rolo/" menu item from the top | 105 ;; is necessary, simply select the "Rolo/" menu item from the top |
137 ;; | 136 ;; |
138 ;; For any of these commands that prompt you for a name, you may use the form | 137 ;; For any of these commands that prompt you for a name, you may use the form |
139 ;; parent/child to locate a child entry below a parent entry, e.g. | 138 ;; parent/child to locate a child entry below a parent entry, e.g. |
140 ;; from the example near the top, we could give Company/Manager/Underlings. | 139 ;; from the example near the top, we could give Company/Manager/Underlings. |
141 ;; | 140 ;; |
142 ;; Here is a snippet from our group rolodex file. The ';'s should be | 141 ;; Here is a snippet from our group rolodex file. The `;'s should be |
143 ;; removed of course and the '*'s should begin at the start of the | 142 ;; removed of course and the `*'s should begin at the start of the |
144 ;; line. If a rolodex file begins with two separator lines whose | 143 ;; line. If a rolodex file begins with two separator lines whose |
145 ;; first three characters are "===", then these lines and any text | 144 ;; first three characters are "===", then these lines and any text |
146 ;; between them are prepended to the output buffer whenever any | 145 ;; between them are prepended to the output buffer whenever any |
147 ;; entries are retrieved from that file. | 146 ;; entries are retrieved from that file. |
148 ;; | 147 ;; |
158 ;; | 157 ;; |
159 ;; | 158 ;; |
160 ;; FOR PROGRAMMERS: | 159 ;; FOR PROGRAMMERS: |
161 ;; | 160 ;; |
162 ;; Entries in rolodex files are separated by patterns matching | 161 ;; Entries in rolodex files are separated by patterns matching |
163 ;; 'rolo-entry-regexp'. Each entry may have any number of sub-entries | 162 ;; `rolo-entry-regexp'. Each entry may have any number of sub-entries |
164 ;; which represent the next level down in the entry hierarchy. | 163 ;; which represent the next level down in the entry hierarchy. |
165 ;; Sub-entries' separator patterns are always longer than their parents'. | 164 ;; Sub-entries' separator patterns are always longer than their parents'. |
166 ;; For example, if an entry began with '*' then its sub-entries would begin | 165 ;; For example, if an entry began with `*' then its sub-entries would begin |
167 ;; with '**' and so on. Blank lines in rolodex files will not end up where | 166 ;; with `**' and so on. Blank lines in rolodex files will not end up where |
168 ;; you want them if you use the rolo-sort commands; therefore, blank lines | 167 ;; you want them if you use the rolo-sort commands; therefore, blank lines |
169 ;; are not recommended. If you change the value of | 168 ;; are not recommended. If you change the value of |
170 ;; 'rolo-entry-regexp', you will have to modify 'rolo-sort'. | 169 ;; `rolo-entry-regexp', you will have to modify `rolo-sort'. |
171 ;; | 170 ;; |
172 ;; The following additional functions are provided: | 171 ;; The following additional functions are provided: |
173 ;; | 172 ;; |
174 ;; 'rolo-sort-level' sorts a specific level of entries in a rolodex file; | 173 ;; `rolo-sort-level' sorts a specific level of entries in a rolodex file; |
175 ;; 'rolo-map-level' runs a user specified function on a specific level of | 174 ;; `rolo-map-level' runs a user specified function on a specific level of |
176 ;; entries in a rolodex file; | 175 ;; entries in a rolodex file; |
177 ;; 'rolo-fgrep-file', same as 'rolo-fgrep' but operates on a single file; | 176 ;; `rolo-fgrep-file', same as `rolo-fgrep' but operates on a single file; |
178 ;; 'rolo-grep-file', same as 'rolo-grep' but operates on a single file; | 177 ;; `rolo-grep-file', same as `rolo-grep' but operates on a single file; |
179 ;; 'rolo-display-matches', display last set of rolodex matches, if any; | 178 ;; `rolo-display-matches', display last set of rolodex matches, if any; |
180 ;; 'rolo-toggle-narrow-to-entry' toggles between display of current entry | 179 ;; `rolo-toggle-narrow-to-entry' toggles between display of current entry |
181 ;; and display of all matching entries. | 180 ;; and display of all matching entries. |
182 ;; | 181 ;; |
183 ;; | 182 ;; |
184 ;; MOD HISTORY: | 183 ;; MOD HISTORY: |
185 ;; | 184 ;; |
186 ;; 12/17/89 | 185 ;; 12/17/89 |
187 ;; Added internal 'rolo-shrink-window' function for use in | 186 ;; Added internal `rolo-shrink-window' function for use in |
188 ;; compressing/uncompressing the rolo view window to/from a size just | 187 ;; compressing/uncompressing the rolo view window to/from a size just |
189 ;; large enough for the selected entry. This is useful when a search | 188 ;; large enough for the selected entry. This is useful when a search |
190 ;; turns up more entries than desired. | 189 ;; turns up more entries than desired. |
191 ;; | 190 ;; |
192 ;; 02/21/90 | 191 ;; 02/21/90 |
193 ;; Modified 'rolo-grep-file' and 'rolo-map-level' so they only set buffers | 192 ;; Modified `rolo-grep-file' and `rolo-map-level' so they only set buffers |
194 ;; read-only the first time they are read in. This way, if someone edits a | 193 ;; read-only the first time they are read in. This way, if someone edits a |
195 ;; rolodex file and then does a rolo-fgrep or other function, the buffer | 194 ;; rolodex file and then does a rolo-fgrep or other function, the buffer |
196 ;; will not be back in read-only mode. | 195 ;; will not be back in read-only mode. |
197 ;; | 196 ;; |
198 ;; 04/18/91 | 197 ;; 04/18/91 |
199 ;; Modified 'rolo-grep-file' to expand any hidden entries in rolo file | 198 ;; Modified `rolo-grep-file' to expand any hidden entries in rolo file |
200 ;; before doing a search. | 199 ;; before doing a search. |
201 ;; | 200 ;; |
202 ;; 12/24/91 | 201 ;; 12/24/91 |
203 ;; Added Hyperbole button support. | 202 ;; Added Hyperbole button support. |
204 ;; | 203 ;; |
258 "*Non-nil means kill rolodex file buffers after searching them for entries. | 257 "*Non-nil means kill rolodex file buffers after searching them for entries. |
259 Only unmodified buffers are killed.") | 258 Only unmodified buffers are killed.") |
260 | 259 |
261 (defvar rolo-save-buffers-after-use t | 260 (defvar rolo-save-buffers-after-use t |
262 "*Non-nil means save rolodex file after an entry is killed.") | 261 "*Non-nil means save rolodex file after an entry is killed.") |
262 | |
263 ;; Insert or update the entry date each time an entry is added or edited. | |
264 (add-hook 'wrolo-add-hook 'rolo-set-date) | |
265 (add-hook 'wrolo-edit-hook 'rolo-set-date) | |
263 | 266 |
264 (defvar wrolo-yank-reformat-function nil | 267 (defvar wrolo-yank-reformat-function nil |
265 "*Value is a function of two arguments, START and END, invoked after a rolo-yank. | 268 "*Value is a function of two arguments, START and END, invoked after a rolo-yank. |
266 It should reformat the region given by the arguments to some preferred style. | 269 It should reformat the region given by the arguments to some preferred style. |
267 Default value is nil, meaning no reformmating is done.") | 270 Default value is nil, meaning no reformmating is done.") |
288 (list (if (and email name | 291 (list (if (and email name |
289 (string-match (concat "\\`" (regexp-quote entry)) name)) | 292 (string-match (concat "\\`" (regexp-quote entry)) name)) |
290 (format rolo-email-format entry email) entry) | 293 (format rolo-email-format entry email) entry) |
291 current-prefix-arg)))) | 294 current-prefix-arg)))) |
292 (if (or (not (stringp name)) (string= name "")) | 295 (if (or (not (stringp name)) (string= name "")) |
293 (error "(rolo-add): Invalid name: '%s'" name)) | 296 (error "(rolo-add): Invalid name: `%s'" name)) |
294 (if (and (interactive-p) file) | 297 (if (and (interactive-p) file) |
295 (setq file (completing-read "File to add to: " | 298 (setq file (completing-read "File to add to: " |
296 (mapcar 'list rolo-file-list)))) | 299 (mapcar 'list rolo-file-list)))) |
297 (if (null file) (setq file (car rolo-file-list))) | 300 (if (null file) (setq file (car rolo-file-list))) |
298 (cond ((and file (or (not (stringp file)) (string= file ""))) | 301 (cond ((and file (or (not (stringp file)) (string= file ""))) |
299 (error "(rolo-add): Invalid file: '%s'" file)) | 302 (error "(rolo-add): Invalid file: `%s'" file)) |
300 ((and (file-exists-p file) (not (file-readable-p file))) | 303 ((and (file-exists-p file) (not (file-readable-p file))) |
301 (error "(rolo-add): File not readable: '%s'" file)) | 304 (error "(rolo-add): File not readable: `%s'" file)) |
302 ((not (file-writable-p file)) | 305 ((not (file-writable-p file)) |
303 (error "(rolo-add): File not writable: '%s'" file))) | 306 (error "(rolo-add): File not writable: `%s'" file))) |
304 (set-buffer (or (get-file-buffer file) (find-file-noselect file))) | 307 (set-buffer (or (get-file-buffer file) (find-file-noselect file))) |
305 (if (interactive-p) (message "Locating insertion point for '%s'..." name)) | 308 (if (interactive-p) (message "Locating insertion point for `%s'..." name)) |
306 (let ((parent "") (level "") end) | 309 (let ((parent "") (level "") end) |
307 (widen) (goto-char 1) | 310 (widen) (goto-char 1) |
308 (while (setq end (string-match "/" name)) | 311 (while (setq end (string-match "/" name)) |
309 (setq parent (substring name 0 end) | 312 (setq parent (substring name 0 end) |
310 name (substring name (min (1+ end) (length name)))) | 313 name (substring name (min (1+ end) (length name)))) |
311 (if (re-search-forward | 314 (if (re-search-forward |
312 (concat "\\(" rolo-entry-regexp "\\)[ \t]*" | 315 (concat "\\(" rolo-entry-regexp "\\)[ \t]*" |
313 (regexp-quote parent)) nil t) | 316 (regexp-quote parent)) nil t) |
314 (setq level (buffer-substring (match-beginning 1) | 317 (setq level (buffer-substring (match-beginning 1) |
315 (match-end 1))) | 318 (match-end 1))) |
316 (error "(rolo-add): '%s' category not found in \"%s\"." | 319 (error "(rolo-add): `%s' category not found in \"%s\"." |
317 parent file))) | 320 parent file))) |
318 (narrow-to-region (point) | 321 (narrow-to-region (point) |
319 (progn (rolo-to-entry-end t level) (point))) | 322 (progn (rolo-to-entry-end t level) (point))) |
320 (goto-char (point-min)) | 323 (goto-char (point-min)) |
321 (let* ((len (length name)) | 324 (let* ((len (length name)) |
354 ;; restore it. | 357 ;; restore it. |
355 (let ((opoint (point))) | 358 (let ((opoint (point))) |
356 (widen) | 359 (widen) |
357 (rolo-to-buffer (current-buffer)) | 360 (rolo-to-buffer (current-buffer)) |
358 (goto-char opoint)) | 361 (goto-char opoint)) |
362 (run-hooks 'wrolo-add-hook) | |
359 (if (interactive-p) | 363 (if (interactive-p) |
360 (message "Edit entry at point."))))) | 364 (message "Edit entry at point."))))) |
361 | 365 |
362 ;;;###autoload | 366 ;;;###autoload |
363 (defun rolo-display-matches (&optional display-buf return-to-buffer) | 367 (defun rolo-display-matches (&optional display-buf return-to-buffer) |
364 "Display optional DISPLAY-BUF buffer of previously found rolodex matches. | 368 "Display optional DISPLAY-BUF buffer of previously found rolodex matches. |
365 If DISPLAY-BUF is nil, use the value in 'rolo-display-buffer'. | 369 If DISPLAY-BUF is nil, use the value in `rolo-display-buffer'. |
366 Second arg RETURN-TO-BUFFER is the buffer to leave point within after the display." | 370 Second arg RETURN-TO-BUFFER is the buffer to leave point within after the display." |
367 (interactive) | 371 (interactive) |
368 (or display-buf (setq display-buf (get-buffer rolo-display-buffer))) | 372 (or display-buf (setq display-buf (get-buffer rolo-display-buffer))) |
369 (if display-buf nil | 373 (if display-buf nil |
370 (error "(rolo-display-matches): Search the rolodex first.")) | 374 (error "(rolo-display-matches): Search the rolodex first.")) |
389 ;; been specified. Use {q} to quit and restore display. | 393 ;; been specified. Use {q} to quit and restore display. |
390 (if return-to-buffer (rolo-to-buffer return-to-buffer t))) | 394 (if return-to-buffer (rolo-to-buffer return-to-buffer t))) |
391 | 395 |
392 ;;;###autoload | 396 ;;;###autoload |
393 (defun rolo-edit (&optional name file) | 397 (defun rolo-edit (&optional name file) |
394 "Edits a rolodex entry given by optional NAME within 'rolo-file-list'. | 398 "Edits a rolodex entry given by optional NAME within `rolo-file-list'. |
395 With prefix argument, prompts for optional FILE to locate entry within. | 399 With prefix argument, prompts for optional FILE to locate entry within. |
396 With no NAME arg, simply displays FILE or first entry in 'rolo-file-list' in an | 400 With no NAME arg, simply displays FILE or first entry in `rolo-file-list' in an |
397 editable mode. NAME may be of the form: parent/child to edit child below a | 401 editable mode. NAME may be of the form: parent/child to edit child below a |
398 parent entry which begins with the parent string." | 402 parent entry which begins with the parent string." |
399 (interactive "sName to edit in rolo: \nP") | 403 (interactive "sName to edit in rolo: \nP") |
400 (if (string-equal name "") (setq name nil)) | 404 (if (string-equal name "") (setq name nil)) |
401 (and name (not (stringp name)) | 405 (and name (not (stringp name)) |
402 (error "(rolo-edit): Invalid name: '%s'" name)) | 406 (error "(rolo-edit): Invalid name: `%s'" name)) |
403 (if (and (interactive-p) current-prefix-arg) | 407 (if (and (interactive-p) current-prefix-arg) |
404 (if (= (length rolo-file-list) 1) | 408 (if (= (length rolo-file-list) 1) |
405 (setq file (car rolo-file-list)) | 409 (setq file (car rolo-file-list)) |
406 (setq file (completing-read "Entry's File: " | 410 (setq file (completing-read "Entry's File: " |
407 (mapcar 'list rolo-file-list))))) | 411 (mapcar 'list rolo-file-list))))) |
408 (let ((found-point) (file-list (if file (list file) rolo-file-list))) | 412 (let ((found-point) (file-list (if file (list file) rolo-file-list))) |
409 (or file (setq file (car file-list))) | 413 (or file (setq file (car file-list))) |
410 (if (null name) | 414 (if (null name) |
411 (progn (if (not (file-writable-p file)) | 415 (progn (if (not (file-writable-p file)) |
412 (error "(rolo-edit): File not writable: '%s'" file)) | 416 (error "(rolo-edit): File not writable: `%s'" file)) |
413 (find-file-other-window file) (setq buffer-read-only nil)) | 417 (find-file-other-window file) (setq buffer-read-only nil)) |
414 (if (setq found-point (rolo-to name file-list)) | 418 (if (setq found-point (rolo-to name file-list)) |
415 (progn | 419 (progn |
416 (setq file buffer-file-name) | 420 (setq file buffer-file-name) |
417 (if (file-writable-p file) | 421 (if (file-writable-p file) |
418 (setq buffer-read-only nil) | 422 (setq buffer-read-only nil) |
419 (message | 423 (message |
420 "(rolo-edit): Entry found but file not writable: '%s'" file) | 424 "(rolo-edit): Entry found but file not writable: `%s'" file) |
421 (beep)) | 425 (beep)) |
422 (rolo-to-buffer (current-buffer))) | 426 (rolo-to-buffer (current-buffer))) |
423 (message "(rolo-edit): '%s' not found." name) | 427 (message "(rolo-edit): `%s' not found." name) |
424 (beep) | 428 (beep) |
425 (rolo-to-buffer (or (get-file-buffer (car file-list)) | 429 (rolo-to-buffer (or (get-file-buffer (car file-list)) |
426 (find-file-noselect (car file-list)))) | 430 (find-file-noselect (car file-list)))) |
427 (setq buffer-read-only nil)) | 431 (setq buffer-read-only nil)) |
428 (widen) | 432 (widen) |
429 ;; Rolo-to-buffer may have moved point from its desired location, so | 433 ;; Rolo-to-buffer may have moved point from its desired location, so |
430 ;; restore it. | 434 ;; restore it. |
431 (if found-point (goto-char found-point))))) | 435 (if found-point (goto-char found-point)) |
436 (run-hooks 'wrolo-edit-hook)))) | |
432 | 437 |
433 (defun rolo-edit-entry () | 438 (defun rolo-edit-entry () |
434 "Edit the source entry of the rolodex match buffer entry at point. | 439 "Edit the source entry of the rolodex match buffer entry at point. |
435 Returns entry name if found, else nil." | 440 Returns entry name if found, else nil." |
436 (interactive) | 441 (interactive) |
524 (error "(rolo-isearch): Use this command in the %s match buffer" | 529 (error "(rolo-isearch): Use this command in the %s match buffer" |
525 rolo-display-buffer))) | 530 rolo-display-buffer))) |
526 | 531 |
527 ;;;###autoload | 532 ;;;###autoload |
528 (defun rolo-kill (name &optional file) | 533 (defun rolo-kill (name &optional file) |
529 "Kills a rolodex entry given by NAME within 'rolo-file-list'. | 534 "Kills a rolodex entry given by NAME within `rolo-file-list'. |
530 With prefix argument, prompts for optional FILE to locate entry within. | 535 With prefix argument, prompts for optional FILE to locate entry within. |
531 NAME may be of the form: parent/child to kill child below a parent entry | 536 NAME may be of the form: parent/child to kill child below a parent entry |
532 which begins with the parent string. | 537 which begins with the parent string. |
533 Returns t if entry is killed, nil otherwise." | 538 Returns t if entry is killed, nil otherwise." |
534 (interactive "sName to kill in rolo: \nP") | 539 (interactive "sName to kill in rolo: \nP") |
535 (if (or (not (stringp name)) (string= name "")) | 540 (if (or (not (stringp name)) (string= name "")) |
536 (error "(rolo-kill): Invalid name: '%s'" name)) | 541 (error "(rolo-kill): Invalid name: `%s'" name)) |
537 (if (and (interactive-p) current-prefix-arg) | 542 (if (and (interactive-p) current-prefix-arg) |
538 (setq file (completing-read "Entry's File: " | 543 (setq file (completing-read "Entry's File: " |
539 (mapcar 'list rolo-file-list)))) | 544 (mapcar 'list rolo-file-list)))) |
540 (let ((file-list (if file (list file) rolo-file-list)) | 545 (let ((file-list (if file (list file) rolo-file-list)) |
541 (killed)) | 546 (killed)) |
570 (funcall kill-op start level) | 575 (funcall kill-op start level) |
571 (message "Killed")) | 576 (message "Killed")) |
572 (message "Aborted"))) | 577 (message "Aborted"))) |
573 (funcall kill-op start level))) | 578 (funcall kill-op start level))) |
574 (message | 579 (message |
575 "(rolo-kill): Entry found but file not writable: '%s'" file) | 580 "(rolo-kill): Entry found but file not writable: `%s'" file) |
576 (beep))) | 581 (beep))) |
577 (message "(rolo-kill): '%s' not found." name) | 582 (message "(rolo-kill): `%s' not found." name) |
578 (beep)) | 583 (beep)) |
579 killed)) | 584 killed)) |
580 | 585 |
581 (defun rolo-mail-to () | 586 (defun rolo-mail-to () |
582 "Start composing mail addressed to the first e-mail address at or after point." | 587 "Start composing mail addressed to the first e-mail address at or after point." |
628 (set-window-configuration *rolo-wconfig*))) | 633 (set-window-configuration *rolo-wconfig*))) |
629 | 634 |
630 ;;;###autoload | 635 ;;;###autoload |
631 (defun rolo-sort (&optional rolo-file) | 636 (defun rolo-sort (&optional rolo-file) |
632 "Sorts up to 14 levels of entries in ROLO-FILE (default is personal rolo). | 637 "Sorts up to 14 levels of entries in ROLO-FILE (default is personal rolo). |
633 Assumes entries are delimited by one or more '*'characters. | 638 Assumes entries are delimited by one or more `*'characters. |
634 Returns list of number of groupings at each entry level." | 639 Returns list of number of groupings at each entry level." |
635 (interactive | 640 (interactive |
636 (list (let ((default "") | 641 (list (let ((default "") |
637 (file)) | 642 (file)) |
638 (setq file | 643 (setq file |
680 (function (lambda (start end) (sort-lines nil start end))) | 685 (function (lambda (start end) (sort-lines nil start end))) |
681 rolo-file | 686 rolo-file |
682 level-regexp | 687 level-regexp |
683 max-groupings))) | 688 max-groupings))) |
684 | 689 |
690 ;;;###autoload | |
691 (defun rolo-toggle-datestamps (&optional arg) | |
692 "Toggle whether datestamps are updated when rolodex entries are modified. | |
693 With optional ARG, turn them on iff ARG is positive." | |
694 (interactive "P") | |
695 (if (or (and arg (<= (prefix-numeric-value arg) 0)) | |
696 (and (not (and arg (> (prefix-numeric-value arg) 0))) | |
697 (boundp 'wrolo-add-hook) (listp wrolo-add-hook) | |
698 (memq 'rolo-set-date wrolo-add-hook))) | |
699 (progn (remove-hook 'wrolo-add-hook 'rolo-set-date) | |
700 (remove-hook 'wrolo-edit-hook 'rolo-set-date) | |
701 (message "Rolodex date stamps are now turned off.")) | |
702 (add-hook 'wrolo-add-hook 'rolo-set-date) | |
703 (add-hook 'wrolo-edit-hook 'rolo-set-date) | |
704 (message "Rolodex date stamps are now turned on."))) | |
705 | |
685 (defun rolo-toggle-narrow-to-entry () | 706 (defun rolo-toggle-narrow-to-entry () |
686 "Toggle between display of current entry and display of all matched entries. | 707 "Toggle between display of current entry and display of all matched entries. |
687 Useful when bound to a mouse key." | 708 Useful when bound to a mouse key." |
688 (interactive) | 709 (interactive) |
689 (if (rolo-narrowed-p) | 710 (if (rolo-narrowed-p) |
781 (save-excursion | 802 (save-excursion |
782 (save-restriction | 803 (save-restriction |
783 (widen) | 804 (widen) |
784 (goto-char 1) | 805 (goto-char 1) |
785 ;; Ensure no entries in outline mode are hidden. | 806 ;; Ensure no entries in outline mode are hidden. |
786 ;; Uses 'show-all' function from outline.el. | 807 ;; Uses `show-all' function from outline.el. |
787 (and (search-forward "\C-m" nil t) | 808 (and (search-forward "\C-m" nil t) |
788 (show-all)) | 809 (show-all)) |
789 (if (re-search-forward rolo-hdr-regexp nil t 2) | 810 (if (re-search-forward rolo-hdr-regexp nil t 2) |
790 (progn (forward-line) | 811 (progn (forward-line) |
791 (setq hdr-pos (cons (point-min) (point))))) | 812 (setq hdr-pos (cons (point-min) (point))))) |
844 (let ((num-found 0) | 865 (let ((num-found 0) |
845 (exact-level-regexp (concat "^\\(" level-regexp "\\)[ \t\n]")) | 866 (exact-level-regexp (concat "^\\(" level-regexp "\\)[ \t\n]")) |
846 (outline-regexp rolo-entry-regexp) | 867 (outline-regexp rolo-entry-regexp) |
847 (buffer-read-only) | 868 (buffer-read-only) |
848 (level-len)) | 869 (level-len)) |
849 ;; Load 'outline' library since its functions are used here. | 870 ;; Load `outline' library since its functions are used here. |
850 (if (not (boundp 'outline-mode-map)) | 871 (if (not (boundp 'outline-mode-map)) |
851 (load-library "outline")) | 872 (load-library "outline")) |
852 (goto-char (point-min)) | 873 (goto-char (point-min)) |
853 ;; Pass buffer header if it exists | 874 ;; Pass buffer header if it exists |
854 (if (re-search-forward rolo-hdr-regexp nil t 2) | 875 (if (re-search-forward rolo-hdr-regexp nil t 2) |
888 end | 909 end |
889 (if (re-search-forward | 910 (if (re-search-forward |
890 rolo-entry-regexp nil t) | 911 rolo-entry-regexp nil t) |
891 (progn (beginning-of-line) (point)) | 912 (progn (beginning-of-line) (point)) |
892 (point-max)))) | 913 (point-max)))) |
893 ;; Remember last expression in 'progn' | 914 ;; Remember last expression in `progn' |
894 ;; must always return non-nil. | 915 ;; must always return non-nil. |
895 (goto-char start))) | 916 (goto-char start))) |
896 (not grouping-end))) | 917 (not grouping-end))) |
897 (let ((end (point))) | 918 (let ((end (point))) |
898 (goto-char grouping-start) | 919 (goto-char grouping-start) |
923 (car (memq (get-buffer (or (and (stringp rolo-buf) | 944 (car (memq (get-buffer (or (and (stringp rolo-buf) |
924 (get-file-buffer rolo-buf)) | 945 (get-file-buffer rolo-buf)) |
925 rolo-buf)) | 946 rolo-buf)) |
926 (buffer-list)))) | 947 (buffer-list)))) |
927 | 948 |
949 (defun rolo-current-date () | |
950 "Return the current date (a string) in a form used for rolodex entry insertion." | |
951 (let ((year-month-day (htz:date-parse (current-time-string)))) | |
952 (format "\t%02s/%02s/%s" | |
953 (aref year-month-day 1) | |
954 (aref year-month-day 2) | |
955 (aref year-month-day 0)))) | |
956 | |
928 (defun rolo-display-to-entry-end () | 957 (defun rolo-display-to-entry-end () |
929 "Go to end of current entry, ignoring sub-entries." | 958 "Go to end of current entry, ignoring sub-entries." |
930 (if (re-search-forward (concat rolo-hdr-regexp "\\|" | 959 (if (re-search-forward (concat rolo-hdr-regexp "\\|" |
931 rolo-entry-regexp) nil t) | 960 rolo-entry-regexp) nil t) |
932 (progn (beginning-of-line) (point)) | 961 (progn (beginning-of-line) (point)) |
950 (hproperty:but-add (match-beginning 0) (match-end 0) | 979 (hproperty:but-add (match-beginning 0) (match-end 0) |
951 (or rolo-highlight-face | 980 (or rolo-highlight-face |
952 hproperty:highlight-face))))))) | 981 hproperty:highlight-face))))))) |
953 | 982 |
954 (defun rolo-kill-buffer (&optional rolo-buf) | 983 (defun rolo-kill-buffer (&optional rolo-buf) |
955 "Kills optional ROLO-BUF if unchanged and 'rolo-kill-buffers-after-use' is t. | 984 "Kills optional ROLO-BUF if unchanged and `rolo-kill-buffers-after-use' is t. |
956 Default is current buffer." | 985 Default is current buffer." |
957 (or rolo-buf (setq rolo-buf (current-buffer))) | 986 (or rolo-buf (setq rolo-buf (current-buffer))) |
958 (and rolo-kill-buffers-after-use (not (buffer-modified-p rolo-buf)) | 987 (and rolo-kill-buffers-after-use (not (buffer-modified-p rolo-buf)) |
959 (kill-buffer rolo-buf))) | 988 (kill-buffer rolo-buf))) |
960 | 989 |
961 (defun rolo-name-and-email () | 990 (defun rolo-name-and-email () |
962 "If point is in a mail message, returns list of (name email-addr) of sender. | 991 "If point is in a mail message, returns list of (name email-addr) of sender. |
963 Name is returned as 'last, first-and-middle'." | 992 Name is returned as `last, first-and-middle'." |
964 (let ((email) (name) (from)) | 993 (let ((email) (name) (from)) |
965 (save-window-excursion | 994 (save-window-excursion |
966 (if (or (hmail:lister-p) (hnews:lister-p)) | 995 (if (or (hmail:lister-p) (hnews:lister-p)) |
967 (other-window 1)) | 996 (other-window 1)) |
968 (save-excursion | 997 (save-excursion |
994 (match-end 4))))))) | 1023 (match-end 4))))))) |
995 (if (or name email) | 1024 (if (or name email) |
996 (list name email)))) | 1025 (list name email)))) |
997 | 1026 |
998 (defun rolo-name-at () | 1027 (defun rolo-name-at () |
999 "If point is within an entry in 'rolo-display-buffer', returns entry, else nil." | 1028 "If point is within an entry in `rolo-display-buffer', returns entry, else nil." |
1000 (if (string-equal (buffer-name) rolo-display-buffer) | 1029 (if (string-equal (buffer-name) rolo-display-buffer) |
1001 (save-excursion | 1030 (save-excursion |
1002 (if (or (looking-at rolo-entry-regexp) | 1031 (if (or (looking-at rolo-entry-regexp) |
1003 (progn (end-of-line) | 1032 (progn (end-of-line) |
1004 (re-search-backward rolo-entry-regexp nil t))) | 1033 (re-search-backward rolo-entry-regexp nil t))) |
1011 | 1040 |
1012 (defun rolo-narrowed-p () | 1041 (defun rolo-narrowed-p () |
1013 (or (/= (point-min) 1) (/= (1+ (buffer-size)) (point-max)))) | 1042 (or (/= (point-min) 1) (/= (1+ (buffer-size)) (point-max)))) |
1014 | 1043 |
1015 (defun rolo-save-buffer (&optional rolo-buf) | 1044 (defun rolo-save-buffer (&optional rolo-buf) |
1016 "Saves optional ROLO-BUF if changed and 'rolo-save-buffers-after-use' is t. | 1045 "Saves optional ROLO-BUF if changed and `rolo-save-buffers-after-use' is t. |
1017 Default is current buffer. Used, for example, after a rolo entry is killed." | 1046 Default is current buffer. Used, for example, after a rolo entry is killed." |
1018 (or rolo-buf (setq rolo-buf (current-buffer))) | 1047 (or rolo-buf (setq rolo-buf (current-buffer))) |
1019 (and rolo-save-buffers-after-use (buffer-modified-p rolo-buf) | 1048 (and rolo-save-buffers-after-use (buffer-modified-p rolo-buf) |
1020 (set-buffer rolo-buf) (save-buffer))) | 1049 (set-buffer rolo-buf) (save-buffer))) |
1050 | |
1051 (defun rolo-set-date () | |
1052 "Add a line with the current date at the end of the current rolodex entry. | |
1053 Suitable for use as an entry in `wrolo-add-hook' and `wrolo-edit-hook'. | |
1054 The default date format is MM/DD/YYYY. Rewrite `rolo-current-date' to | |
1055 return a different format, if you prefer." | |
1056 (save-excursion | |
1057 (skip-chars-forward "*") | |
1058 (rolo-to-entry-end) | |
1059 (skip-chars-backward " \t\n\r\f") | |
1060 (skip-chars-backward "^\n\r\f") | |
1061 (if (looking-at "\\s-+[-0-9./]+\\s-*$") ;; a date | |
1062 (progn (delete-region (point) (match-end 0)) | |
1063 (insert (rolo-current-date))) | |
1064 (end-of-line) | |
1065 (insert "\n" (rolo-current-date))))) | |
1021 | 1066 |
1022 (defun rolo-shrink-window () | 1067 (defun rolo-shrink-window () |
1023 (let* ((lines (count-lines (point-min) (point-max))) | 1068 (let* ((lines (count-lines (point-min) (point-max))) |
1024 (height (window-height)) | 1069 (height (window-height)) |
1025 (window-min-height 2) | 1070 (window-min-height 2) |
1032 (max desired-shrinkage (- height (/ (frame-height) 2))) | 1077 (max desired-shrinkage (- height (/ (frame-height) 2))) |
1033 (min desired-shrinkage (- height window-min-height))))))) | 1078 (min desired-shrinkage (- height window-min-height))))))) |
1034 | 1079 |
1035 (defun rolo-to (name &optional file-list) | 1080 (defun rolo-to (name &optional file-list) |
1036 "Moves point to entry for NAME within optional FILE-LIST. | 1081 "Moves point to entry for NAME within optional FILE-LIST. |
1037 'rolo-file-list' is used as default when FILE-LIST is nil. | 1082 `rolo-file-list' is used as default when FILE-LIST is nil. |
1038 Leaves point immediately after match for NAME within entry. | 1083 Leaves point immediately after match for NAME within entry. |
1039 Switches internal current buffer but does not alter the frame. | 1084 Switches internal current buffer but does not alter the frame. |
1040 Returns point where matching entry begins or nil if not found." | 1085 Returns point where matching entry begins or nil if not found." |
1041 (or file-list (setq file-list rolo-file-list)) | 1086 (or file-list (setq file-list rolo-file-list)) |
1042 (let ((found) file) | 1087 (let ((found) file) |
1043 (while (and (not found) file-list) | 1088 (while (and (not found) file-list) |
1044 (setq file (car file-list) | 1089 (setq file (car file-list) |
1045 file-list (cdr file-list)) | 1090 file-list (cdr file-list)) |
1046 (cond ((and file (or (not (stringp file)) (string= file ""))) | 1091 (cond ((and file (or (not (stringp file)) (string= file ""))) |
1047 (error "(rolo-to): Invalid file: '%s'" file)) | 1092 (error "(rolo-to): Invalid file: `%s'" file)) |
1048 ((and (file-exists-p file) (not (file-readable-p file))) | 1093 ((and (file-exists-p file) (not (file-readable-p file))) |
1049 (error "(rolo-to): File not readable: '%s'" file))) | 1094 (error "(rolo-to): File not readable: `%s'" file))) |
1050 (set-buffer (or (get-file-buffer file) (find-file-noselect file))) | 1095 (set-buffer (or (get-file-buffer file) (find-file-noselect file))) |
1051 (let ((case-fold-search t) (real-name name) (parent "") (level) end) | 1096 (let ((case-fold-search t) (real-name name) (parent "") (level) end) |
1052 (widen) (goto-char 1) | 1097 (widen) (goto-char 1) |
1053 (while (setq end (string-match "/" name)) | 1098 (while (setq end (string-match "/" name)) |
1054 (setq level nil | 1099 (setq level nil |
1066 level)) | 1111 level)) |
1067 ((equal name real-name));; Try next file. | 1112 ((equal name real-name));; Try next file. |
1068 (t;; Found parent but not child | 1113 (t;; Found parent but not child |
1069 (setq buffer-read-only nil) | 1114 (setq buffer-read-only nil) |
1070 (rolo-to-buffer (current-buffer)) | 1115 (rolo-to-buffer (current-buffer)) |
1071 (error "(rolo-to): '%s' part of name not found in \"%s\"." | 1116 (error "(rolo-to): `%s' part of name not found in \"%s\"." |
1072 parent file))) | 1117 parent file))) |
1073 (if level | 1118 (if level |
1074 (narrow-to-region (point) | 1119 (narrow-to-region (point) |
1075 (save-excursion | 1120 (save-excursion |
1076 (rolo-to-entry-end t level) (point))))) | 1121 (rolo-to-entry-end t level) (point))))) |