;;
;; What:   Improved (rewritten) version of man.el
;; Author: Ken Duda <kkkken@athena.mit.edu>
;; Why:    Because everything should be done from emacs,
;; 	   including reading man pages.
;;
;; Note: this forks off a `man' process, which may be a little slower
;; than searching the man path oneself, but has a lot of advantages,
;; especially the user can keep working and it was easier to write 
;; this way.
;;

(defvar man-program "/usr/ucb/man")

(defun manual-entry (topic &optional section)
  "Display the Unix manual entry for TOPIC.
TOPIC is either the title of the entry, or has the form TITLE(SECTION)
where SECTION is the desired section of the manual, as in `tty(4)'."
  (interactive "sMan: ")
  (if (and (null section)
	   (string-match "\\`[ \t]*\\([^( \t]+\\)[ \t]*(\\(.+\\))[ \t]*\\'" topic))
      (setq section (substring topic (match-beginning 2)
				     (match-end 2))
	    topic (substring topic (match-beginning 1)
				   (match-end 1))))
  (let* ((bname (format "*%s%s man page*" topic (if section (concat "(" section ")") "")))
	 (buf (get-buffer bname)))
    (if buf
	(display-buffer buf)
      (let ((process-connection-type nil)) ;Use a pipe, not a tty.
	(set-process-sentinel
	 (apply 'start-process 
		(append 
		 (list "man" (generate-new-buffer bname) man-program)
		 (and section (list section))
		 (list topic)))
	 'man-sentinel))
      (message "Looking for man page ... "))))

(defun man-sentinel (proc state)
  "Process sentinel for a `man' process.  Determines if the 
man process succeeded; if so, it nukes the nroff bs and displays
the man page.  Otherwise, it informs the user of man's failure
and nukes the whole buffer."
  (let ((gotit nil))
    (save-excursion
      (set-buffer (process-buffer proc))
      (goto-char (point-min))
      (if (looking-at "No manual entry")
	  (progn
	    (message "Man page not found.")
	    (kill-buffer (process-buffer proc)))
	(setq gotit t)))
    (if gotit 
      (let ((w (selected-window)))
	(select-window (display-buffer (process-buffer proc)))
	(goto-char (point-min))
	(message "Making man page readable...")
	(while (re-search-forward ".\C-h" (point-max) t)
	  (replace-match ""))
	(setq buffer-read-only t)
	(goto-char (point-min))
	(set-buffer-modified-p nil)
	(let ((map (make-sparse-keymap)))
	  (use-local-map map)
	  (define-key map "\C-?" (function (lambda nil   
					     (let ((obuf (current-buffer)))
					       (switch-to-buffer (other-buffer))
					       (bury-buffer obuf))))))
	(select-window w)))))
