From: desmedt@rulfsw.leidenuniv.nl
Subject: search and insert e-mail address
Organization: Leiden University Faculty of Social Sciences
Date: 22 Jul 92 11:25:49 +0100

I have written a small package to search an e-mail address and insert
it into a mail buffer.

It works in a simple but effective way.  You write the name to be
looked for in the To: field, then press C-C C-A, and a menu buffer
will appear with all addresses that match the name.  You can move
through the menu buffer and select one, which then replaces what was
the To: field.

This package presupposes the existence of a data file that has, on
each line, a name, followed by one or more tabs, followed by an e-mail
address.

Enjoy and send comments.

Koenraad de Smedt
Leiden University
-----------------------------------------------------

;;; insert-address

;;; inserts address in To: field of a mail buffer.
;;; gets search string from "To: " field, if none prompts user.
;;; uses agrep to search in datafile.
;;; (K. de Smedt, June 1992)

(defvar address-file-list (list "/usr/users/desmedt/data/net.data"))

(defvar address-search-command "/usr/local/bin/agrep")

(defvar address-search-options (list "-h" "-i"))

(defvar address-mode-map nil "Local keymap for mail address buffers.")

(if address-mode-map
    nil
  (setq address-mode-map (make-keymap))
  (suppress-keymap address-mode-map t)
  (define-key address-mode-map "y" 'pick-address)
  (define-key address-mode-map "Y" 'pick-address)
  (define-key address-mode-map "n" 'next-address)
  (define-key address-mode-map "N" 'next-address)
  (define-key address-mode-map " " 'next-address)
  (define-key address-mode-map "p" 'previous-address)
  (define-key address-mode-map "P" 'previous-address)
  (define-key address-mode-map "q" 'abort-address)
  (define-key address-mode-map "Q" 'abort-address)
  (define-key address-mode-map "\r" 'abort-address))

(put 'address-mode 'mode-class 'special)

(defun address-mode ()
  "Mode for choosing a mail address.
Type y to pick an address.
Type n to move to next address.
Type q to quit."
  (interactive)
  (kill-all-local-variables)
  (setq major-mode 'address-mode)
  (setq mode-name "Choose Address")
  (setq buffer-read-only t)
  (use-local-map address-mode-map))

(defun insert-address ()
  "Find and insert address in mail buffer"
  (interactive)
  (save-excursion
    (mail-to)				;move to To: field
    (let ((eol (point)))
      (beginning-of-line)
      (search-forward "To: ")
      (let ((name
	     (if (or (= (point) eol)
		     (bolp))		;nothing in To: field?
		 (read-string "To: ")
	       (buffer-substring (point) eol))))
	(let ((old-buffer (current-buffer))
	      (address
	       (choose-address name)))	;choose address
	  (if address			;insert if found
	      (progn (switch-to-buffer old-buffer)
		     (beginning-of-line)
		     (kill-line)
		     (insert "To: ")
		     (insert address))
	    (message "No addresses found")))))))

(defun choose-address (name)
  "Find possible addresses for a name, choose one."
  (interactive "sName: ")
  (let ((buffer "Mail address list"))
    (switch-to-buffer buffer)		;pop-to-buffer?
    (setq buffer-read-only nil)
    (erase-buffer)
    (apply 'call-process
	   (append
	    (list address-search-command ;process command
		  nil			;input
		  buffer	       	;buffer
		  t)			;redisplay?
	    address-search-options	;command options
	    (list name)			;arg: search string
	    address-file-list))		;args: file names
    (if (bobp)				;empty?
	(progn (kill-buffer (current-buffer))
	       nil)
      (progn
	(beginning-of-buffer)
	(address-mode)
	(message "y=yes, n=next, q=quit")
	(recursive-edit)
	(get-register 'address)
	))))

;;; the user commands

(defun pick-address ()
  "Extract the address from a line containing
last-name, first-names (comment)TABSaddress (comment)"
  (interactive)
  (end-of-line)
  (search-backward "\t")
  (forward-char)
  (let ((begin (point)))
    (re-search-forward "[ \n\\(]")	;look for comment or eol
    (backward-char)
    (set-register 'address (buffer-substring begin (point)))
    (kill-buffer (current-buffer))
    (exit-recursive-edit)))
    
(defun next-address ()
  "Go to next line."
  (interactive)
  (forward-line)
  (beginning-of-line)
  (if (eobp) (beginning-of-buffer)))

(defun previous-address ()
  "Go to previous line."
  (interactive)
  (if (bobp)
      (end-of-buffer))
  (forward-line -1))

(defun abort-address ()
  "Abort selection."
  (interactive)
  (set-register 'address nil)
  (kill-buffer (current-buffer))
  (abort-recursive-edit)
  nil)

(if mail-mode-map
    (define-key mail-mode-map "\C-c\C-a" 'insert-address))
Newsgroups: comp.emacs,comp.unix.aix