[comp.emacs] GNU Emacs Lisp Code Directory/Formatting Package

dsill@RELAY.NSWC.NAVY.MIL (02/17/89)

Yes, it's that time again.  Here's an elisp package containing two
functions that work with the Directory.  The Directory itself will be
posted separately.

format-lisp-code-directory, provided by Ashwin Ram, produces a report
of the entire Directory much like the ones I used to send out (only
better, I think.)

lisp-dir-apropos, my second piece of elisp code, pops up a window with
formatted entries matching a given topic.  For example, M-x
lisp-dir-apropos <RET> apropos produces:

 Name		 Description			 Author		 Date	  /Version  Contact
--------------------------------------------------------------------------------------------
 lisp-code-directory
		 Lisp code directory formatter and apropos functions
						 Ashwin Ram,Dave Sill
								 89-02-16 /1.0	    Ram-Ashwin@cs.yale.edu,dsill@relay.nswc.navy.mil
 super-apropos	 Hackers hound dog		 Lynn Slater	 88-06-15 /	    lrs@esl.com
 unix-apropos	 Man -k interface		 Henry Kautz	 88-09-06 /	    (U) allegra!kautz

BTW, the header in the following file was created and updated by Lynn
Slater's header.el.  Thanks, Lynn.

So, without further ado...
;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; lisp-code-directory.el --- Lisp code directory formatter and apropos functions
;; Authors         : Ashwin Ram (Ram-Ashwin@cs.yale.edu)
;;                 ; Dave Sill (dsill@relay.nswc.nay.mil)
;; Created On      : Wed Jan 25, 1989
;; Last Modified By: dsill
;; Last Modified On: Thu Feb 16 11:03:36 1989
;; Update Count    : 2
;; Status          : No known bugs.
;; Version         : 1.0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; History 		
;; 16-Feb-1989		dsill	
;;    Added lisp-dir-apropos function

(require 'picture)

(defun format-lisp-code-directory ()
   "Convert GNU Emacs Lisp code directory into something a human could read."
   (interactive)
   (insert " GNU Emacs Lisp code directory.  " (current-time-string) ".\n\n")
   (delete-region (progn (beginning-of-line) (point)) (progn (end-of-line) (point)))
   (format-lisp-code-directory-line "Name" "Author" "Contact" "Description" "Date" "Version")
   (let ((col (current-column)))
      (insert "\n")
      (insert-char ?- (1+ col)))
   (while (re-search-forward "\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)" nil t)
      (let ((name (buffer-substring (match-beginning 1) (match-end 1)))
            (author (buffer-substring (match-beginning 2) (match-end 2)))
            (contact (buffer-substring (match-beginning 3) (match-end 3)))
            (description (buffer-substring (match-beginning 4) (match-end 4)))
            (date (buffer-substring (match-beginning 5) (match-end 5)))
            (version (buffer-substring (match-beginning 6) (match-end 6))))
         (delete-region (progn (beginning-of-line) (point)) (progn (end-of-line) (point)))
         (format-lisp-code-directory-line name author contact description date version))))

(defun format-lisp-code-directory-line (name author contact description date version)
   "Format one line of GNU Emacs Lisp code directory.
Provided as a separate function for customizability.  Should not insert final newline."
   (insert-at-column 1  name)
   (insert-at-column 17 description)
   (insert-at-column 49 author)
   (insert-at-column 65 date)
   (insert-at-column 74 "/")
   (insert-at-column 75 version)
   (insert-at-column 84 contact))
   
(defun insert-at-column (col string)
   (if (> (current-column) col) (insert "\n"))
   (move-to-column-force col)
   (insert string))

(defvar lisp-code-directory "~/gelcd/datafile"
  "Database of free lisp code.  Entries are in the form:
Name|Author|Contact|Description|Date|Version")

(defvar lisp-dir-apropos-buffer "*Lisp Directory Apropos*"
  "Buffer containing apropos formatted entries of the Lisp Code Directory.")

(defun lisp-dir-apropos (topic)
  "Display entries in the Lisp Code Directory apropos for TOPIC"
  (interactive (list
		(read-string (concat "Lisp Directory apropos ("
				     (current-word) "): "))))
  (if (equal "" topic) (setq topic (current-word)))
  (pop-to-buffer lisp-dir-apropos-buffer)
  (setq buffer-read-only nil)
  (erase-buffer)
  (buffer-flush-undo (current-buffer))
  (insert-file lisp-code-directory)
  (delete-non-matching-lines topic)
  (insert "\n")
  (goto-char (point-min))
  (format-lisp-code-directory-line "Name" "Author" "Contact" "Description" "Date" "Version")
  (let ((col (current-column)))
    (insert "\n")
    (insert-char ?- (1+ col)))
  (while (re-search-forward "\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)|\\(.*\\)" nil t)
    (let ((name (buffer-substring (match-beginning 1) (match-end 1)))
	  (author (buffer-substring (match-beginning 2) (match-end 2)))
	  (contact (buffer-substring (match-beginning 3) (match-end 3)))
	  (description (buffer-substring (match-beginning 4) (match-end 4)))
	  (date (buffer-substring (match-beginning 5) (match-end 5)))
	  (version (buffer-substring (match-beginning 6) (match-end 6))))
      (delete-region (progn (beginning-of-line) (point)) (progn (end-of-line) (point)))
      (format-lisp-code-directory-line name author contact description date version)))
  (goto-char (point-min)))

;; Snatched from unix-apropos by Henry Kautz
(defun current-word ()
   "Word cursor is over, as a string."
   (save-excursion
      (let (beg end)
	 (re-search-backward "\\w" nil 2)
	 (re-search-backward "\\b" nil 2)
	 (setq beg (point))
	 (re-search-forward "\\w*\\b" nil 2)
	 (setq end (point))
	 (buffer-substring beg end))))