(put 'eval-expression 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'set-goal-column 'disabled nil)

(autoload 'report-emacs-bug "emacsbug" "" t)

;;(setq debug-end-pos 1)
;;(setq debug-check-symbol 'paragraph-start)
;;
;;(open-termscript "~/.escript")
;;
;;(open-dribble-file "~/.dribble")

;;(setq default-major-mode 'text-mode)

(if (file-exists-p "~/.abbrev_defs")
    (read-abbrev-file "~/.abbrev_defs")
  (if (file-exists-p "~tower/.abbrev_defs")
      (read-abbrev-file "~tower/.abbrev_defs")))

(if (file-exists-p "~/pers/phones")
    (progn (find-file "~/pers/phones")
	   (bury-buffer)))

(if (file-exists-p "~/calendar")
    (progn (find-file "~/calendar")
	   (bury-buffer)))

(if (< emacs-version-major 19)
    (progn
      (autoload 'ftp-list-directory "ftp" "" t))
  (progn
    (autoload 'update-dns-serial "~roland/elisp/19/update-dns" nil t)
					; i don't use these losing terminals
    (global-set-key "\e\e" 'eval-expression) ; default is ESC :
    (global-set-key "\M-[" 'backward-paragraph) ; default is ESC {
    (global-set-key "\M-]" 'forward-paragraph) ; default is ESC {
    (setq
     view-read-only t			;19 new feature
     user-mail-address "tower@ai.mit.edu" ;19.27 new feature
     mail-from-style 'parens		;19 new feature for user-mail-address
     message-log-max t			;19 new feature
     find-file-visit-truename t		;19 new feature
     resize-minibuffer-mode t		;19 new feature
     enable-local-eval t		;19 new feature
     rmail-summary-window-size (/ (screen-height) 3) ;19 new feature
     system-uses-terminfo nil		;kludge fix v19 shell/emacs interaction lossage
     add-log-keep-changes-together t	;19 new feature
     flyspell-mark-duplications-flag t	;20(?) new feature
     flyspell-sort-corrections t	;20(?) new feature
     change-log-version-info-enabled t	;21.1 new feature
     display-buffer-reuse-frames t	;21.? new feature
     )))

(setq rmail-default-file "/home/ai/tower/pers/tmp.xmail"
      explicit-shell-file-name "csh"
      truncate-partial-width-windows t
      echo-keystrokes 10
      search-exit-char ?\C-m		; default is ESC
      ask-about-buffer-names t
      enable-recursive-minibuffers t)	;; Real Man

(make-variable-buffer-local 'kept-old-versions)
(make-variable-buffer-local 'kept-new-versions)
(make-variable-buffer-local 'version-control)
(setq-default
 version-control t
 kept-old-versions 5			;2 is default
 kept-new-versions 10)			;2 is default
;;; backup-by-copying-when-linked t ;;; lose for original GNU Emacs files

(setq
 trim-versions-without-asking t
 delete-old-versions t			;v19.26+'s trim-versions-without-asking
 completion-ignored-extensions
 (append (list   ;;".i";; Pastel's .i's
	  ".cp" ".fn" ".ky" ".pg" ".tp" ".vr" ; texinfo.tex ...
	  ".sbin"			; Sparc
	  ) completion-ignored-extensions)
 auto-mode-alist
 (append
  auto-mode-alist
  '(
; alphabetical by mode
    ("\\.ada$" . ada-mode)
    ("\\.b32$" . bliss-mode)		;V Bliss-32
    ("\\.bli$" . bliss-mode)		;V Common Bliss
;(autoload 'c++-mode "c++-mode.elc" "c++ mode" t nil)
    ("\\.cc$" .		c++-mode)
    ("\\.cp$" .		c++-mode)	;Apple MPW C++ extension
    ("\\.hh$" .		c++-mode)
    ("\\.C$" .		c++-mode)
    ("\\.H$" .		c++-mode)
    ("\\.c\\+\\+$" .	c++-mode)
    ("\\.h\\+\\+$" .	c++-mode)
    ("\\.abbrev_def" . emacs-lisp-mode)
    ("\\.f$" .		fortran-mode)
    ("\\.F$" .		fortran-mode)
    ("\\.for$" .	fortran-mode)
    ("\\.fpp$" .	fortran-mode)
    ("\\.ftn$" .	fortran-mode)
    ("mout.*$" . mail-mode)
    ("\\.ms$" .		nroff-mode)
    ("\\.me$" .		nroff-mode)
    ("\\.mm$" .		nroff-mode)
    ("\\.mr$" .		nroff-mode)
    ("\\.man$" .	nroff-mode)
    ("\\.doc$" .	nroff-mode)
    ("\\.[1-8]+$" .	nroff-mode)
    ("\\.pl$" .	perl-mode)
    ("\\.txt$" .			text-mode)
    ("README.*$" .			text-mode)
    ("volunteers" .			text-mode)
    ("rnmail[0-9]+$" .			text-mode)
    ("article[0-9]*$" .			text-mode)
    ("letter[0-9]*$" .			text-mode)
    ("^/tmp/\\(post\\|fol\\)a[0-9]*" .	text-mode)
    ("Re[0-9][0-9][0-9][0-9][0-9]$" .	text-mode)
    )))

(setq tower-term (getenv "TERM"))
(cond
 ((equal "adm31" tower-term)
  (setq mode-line-inverse-video t))
 ((or (equal "wyse30" tower-term)
      (equal "wyse50" tower-term))
  (setq mode-line-inverse-video nil))
 ((not (or (equal "sun" tower-term)
	   (equal "h19" tower-term)
	   (equal "h19a" tower-term)
	   (equal "h19-a" tower-term)
	   (equal "vt100" tower-term)
	   (equal "vt100-am" tower-term) ;new termcap lossage Jan96
	   (equal "xterm" tower-term)
	   (equal "xterms" tower-term)))
  (setq inverse-video t)))

(if (getenv "LINES")
    (set-screen-height (string-to-int (getenv "LINES"))))

;; now in .emacs
;;; This starts up the emacs-server.  (I use it for rn.)
;;; Depends heavily on v18.  When this is in use,
;;; your EDITOR and DISPLAY variables should be (path of
;;; emacs library)/etc/emacsclient and display (~machine) your xemacs is on
;(if (or (equal "sun" tower-term) (equal "xterm" tower-term)
;	(equal "xterms" tower-term))
;    (progn (load-library "server")
;	   (server-start nil)))

(setq
 next-screen-context-lines 1
 require-final-newline "ask"
 track-eol t
 truncate-partial-width-windows nil)

(cond
 ((eq system-type 'unix-SVR4)
  (setq dired-listing-switches "-lba"
	list-directory-verbose-switches "-lbaF"
	list-directory-brief-switches "-abCF"))
 ((or (eq system-type 'netbsd)
      (eq system-type 'berkeley-unix)
      (equal (getenv "ARCH") "symmetry"))
  (setq dired-listing-switches "-lag"
	list-directory-verbose-switches "-laFg"
	list-directory-brief-switches "-aCFg"))
 (t
  (setq dired-listing-switches "-lbag"
	list-directory-verbose-switches "-lbaFg"
	list-directory-brief-switches "-abCFg")))

(setq-default mode-line-format
	      '( "%1*<%3p>" mode-line-buffer-identification
		 "%[(" mode-name minor-mode-alist "%n"
		 mode-line-process ")%]"
		 global-mode-string "%-"))

(fset 'skip-words-and-compare
   "fofoxcompare-windows
")
(fset 'insert70--nl
      "----------------------------------------------------------------------
" )

(defun switch-to-shell-other-window ()
  "go to *shell* buffer in other window"
  (interactive)
  (if (not (string-equal (buffer-name) "*shell*"))
      (progn (switch-to-buffer-other-window "*shell*")
	     (shell)))
  (end-of-buffer)
  (recenter -2))

(defun switch-to-rmail-buffer-other-window ()
  "'nuff said"
  (interactive)
  (if (not (string-equal (buffer-name) "RMAIL"))
      (switch-to-buffer-other-window "RMAIL")))

(global-set-key "\eg" 'goto-line)	;better then fill-region-OUCH!

(global-set-key "\C-c*"	'(lambda () (interactive)
			   (switch-to-buffer-other-window "*")))
(global-set-key "\C-c-"	'insert70--nl)
;(global-set-key "\C-c\C-b"	'electric-buffer-list)
(global-set-key "\C-c\t"	'shell-expand-file-name)
; "a" because "A" is like "^" the regex match beginning-of-line symbol
(global-set-key "\C-ca" '(lambda () (interactive)
			   (query-replace-regexp "^[ \t]*" "" nil)))
(global-set-key "\C-cb"	'bury-buffer)
(global-set-key "\C-cf" '(lambda () (interactive)
			   (picture-mode)
			   (picture-mode-exit)
			   (mail-fill-yanked-message-region)))
(global-set-key "\C-ch" '(lambda (lines) (interactive "NScreen lines: ")
			   (set-screen-height lines)))
(global-set-key "\C-ck" '(lambda () (interactive)
			   (kill-buffer (buffer-name (current-buffer)))
			   (delete-window)))
(global-set-key "\C-ci"	'insert-buffer)
(global-set-key "\C-cma"		;toggle abbrev-mode
                '(lambda () (interactive)
		   (abbrev-mode nil)))
(global-set-key "\C-cme" 'emacs-lisp-mode)
(global-set-key "\C-cmf"		;toggle auto-fill-mode
                '(lambda () (interactive)
		   (auto-fill-mode nil)))
(global-set-key "\C-cmm"
                '(lambda () (interactive)
		   (load-library "sendmail")
		   (mail-mode)))
(global-set-key "\C-cmp" 'picture-mode)
(global-set-key "\C-cmo" 'outline-mode)
(global-set-key "\C-cmt" 'text-mode)
(global-set-key "\C-cmv"		;view this buffer
		'(lambda () (interactive)
		   (view-buffer (buffer-name (current-buffer)))))
(global-set-key "\C-cp"
		'(lambda () (interactive)
		   (ispell-region (region-beginning) (region-end))))
(global-set-key "\C-cq"
		'(lambda (from to &optional delimited)
		   (interactive "sTags query replace (regexp): \nsTags query replace %s by: \nP") (switch-to-buffer-other-window "*")
		   (tags-query-replace from to delimited)))
(global-set-key "\C-cr"	'switch-to-rmail-buffer-other-window)
(global-set-key "\C-cs"	'(lambda (regexp)
			   (interactive "sTags search (regexp): ")
			   (switch-to-buffer-other-window "*")
			   (tags-search regexp)
			   (other-window 0)));
(global-set-key "\C-cu" 'sendmail-tower-reformat-ucbmail)
(global-set-key "\C-cv" 'scroll-other-window)
(global-set-key "\C-cx"	'query-replace-regexp)
(global-set-key "\C-cz"	'switch-to-shell-other-window)
(global-set-key "\C-hA"	'apropos)
(global-set-key "\C-x44"	'electric-command-history)
(global-set-key "\C-x4c"	'compile)
(global-set-key "\C-x4g"	'garbage-collect)
(global-set-key "\C-x4s"	'skip-words-and-compare)
(global-set-key "\C-x\C-u"	'advertised-undo) ; evil control key flutter !!
(global-set-key "\C-x\C-b"	'buffer-menu) ;wish list buffers (forward-line 2)

;;screen - be careful to not accidently exit GNU Emacs,
;;especially with an active RMAIL buffer
(if (getenv "STY")
    (progn
;;;SAVED in case I ever want to do this on v18 or earlier
;;;      (global-set-key 
;;;       "\C-x\C-c"
;;;       '(lambda () (interactive)
;;;	  "be careful to not accidently exit GNU Emacs from screen"
;;;;ALT	  (message "use C-c aqp or M-x save-buffers-kill-emacs RET")
;;;	  (if (yes-or-no-p "Screen is running, do you really want to exit ")
;;;	      (if (get-buffer "RMAIL")
;;;		  (if (yes-or-no-p 
;;;		       "RMAIL buffer exists, do you really want to exit "))
;;;		(save-buffers-kill-emacs))
;;;	    (save-buffers-kill-emacs))))
;;;      (global-set-key
;;;       "\C-xk"
;;;       '(lambda (arg) 
;;;;;lst cut:
;;;;; (interactive "sKill buffer: (no default) ")
;;;	  (interactive
;;;;;@@this longer "(interactive" doesn't work from other buffers.
;;;	   (let ((enable-recursive-minibuffers t)
;;;		 (name (buffer-name (current-buffer)))
;;;		 val)
;;;	     (setq val (completing-read
;;;			(format "Kill buffer: (default %s) " name)
;;;			(buffer-list) nil t))
;;;	     (list (if (equal val "")
;;;		       name 
;;;		     val))))
;;;	  "be careful to not accidently kill the RMAIL buffer"
;;;	  (if (and (string-equal arg "RMAIL")
;;;		   (yes-or-no-p
;;;		    "RMAIL buffer exists, do you really want to it "))
;;;	      (kill-buffer arg))
;;;	  (if (not (string-equal arg "RMAIL"))
;;;	      (kill-buffer arg))))
      (add-hook
       'kill-buffer-query-functions
       '(lambda () (interactive)
	  (if (string-equal (buffer-name (current-buffer)) "RMAIL")
	      (if (yes-or-no-p 
		   "Screen's running, do you really want to kill the RMAIL buffer? ")
		  t
		nil)
	    t)))
      (add-hook
       'kill-emacs-query-functions
       '(lambda () (interactive)
	  (if (get-buffer "RMAIL")
	      (if (yes-or-no-p
		   "Screen is running & RMAIL buffer exists, do you really want to exit? ")
		  t
		nil)
	    t)))
      (global-set-key "\C-caqp" `save-buffers-kill-emacs)))

;; time display
;;(setq display-time-day-and-date t)	;;use nil default
(if (not (or (equal (getenv "HOME") "/")	;; not if we're root
	     (equal (getenv "HOME") "/usr/spool/news")))
    (let ((process-connection-type nil)) ;pty's are limited, pipes aren't
      (display-time)))    ;; nice, but it uses a few cycles

; needs display-time loaded
(if (load-file-if-exists "~tower/.emacs.lisp/biff.el")
    (progn
      (biff 1)
      ;; run it right away:
      (biff-filter "NO-PROCESS" "NO-STRING")
      ;; i almost always know what the incoming mail is
      ;; (or am about to read it!) when i start up emacs,
      ;; so make the startup biff window go away:
      (let ((buffer (get-buffer "*biff*<2>")))
	(if (bufferp buffer)
	    (delete-windows-on buffer)))
      ))

;; same as in $el/simple.el except that c-N at end of buffer doesn't
;; create any new lines. That has always seemed a misfeature to me...
;;	-mly
;; in v19 just: (next-line-add-newlines nil)
(defun next-line (arg)
  ">>If on the last line of the buffer, just moves to the end of the buffer."
  (interactive "p")
  (if (= arg 1)
      (let ((opoint (point)))
	(forward-line 1)
	(if (or (= opoint (point))
		(not (eq (preceding-char) ?\n)))
	    (progn (goto-char (point-max))
		   (signal 'end-of-buffer ()))
	  (goto-char opoint)
	  (line-move arg)))
    (line-move arg))
  nil)
;renamed in 18.56
(if (not (fboundp 'line-move))
    (fset 'line-move 'next-line-internal))
;;Also:		jgk@osc.com (Joe Keane):
;;(global-set-key "\C-n"	'next-line-no-insert)
;;
;;(defun next-line-no-insert ()
;;  "Just like next-line, but doesn't insert a newline at the end of the buffer."
;;  (interactive)
;;  (and (save-excursion (zerop (forward-line 1)))
;;       (call-interactively 'next-line)))

;; mail stuff
(defun sendmail-tower-reformat-ucbmail (arg)
  "Take an ~m include message and reformat it.
With any argument, it does not reformat the headers of the current message.
Newer versions of BSD Mail included the headers of the message currently
being edited, older versions do not."
  (interactive "P")
  (goto-char (point-min))
  (replace-regexp "^	" "   " nil)
  (picture-mode)
  (picture-mode-exit)
  (goto-char (point-min))
  (search-forward "\n\n")
  (forward-char -1)
  (if arg
      (let ((beg (point)))
	(search-forward "\n\n")
	(forward-char -1)
	(narrow-to-region beg (point)))
    (narrow-to-region (point-min) (point)))
  (goto-char (point-min))
  (delete-non-matching-lines "^$\\|^\\(\\|   \\)\\(Date:\\|From:\\)")
  (widen)
  (search-forward "\n\n")
  (beginning-of-buffer)
  (forward-char 4)
  (exchange-point-and-mark)
  (if (not (get-buffer "RMAIL"))
      (text-mode)))			;using it via ~e from UCB mail

(defun rmail-save-and-gc ()
  "also garbage-collect"
  (interactive)
  (rmail-expunge-and-save)
  (sit-for 0)
  (garbage-collect))

(defun rmail-get-and-gc ()
  "also garbage-collect and fix display-time-string"
  (interactive)
  (rmail-get-new-mail)
  (and (boundp 'display-time-string)	; israel@brillig.umd.edu
       (stringp display-time-string)
       (setq display-time-string (remove-string " Mail" display-time-string)))
  (sit-for 0)
  (garbage-collect))

(defun remove-string (substring string)	; israel@brillig.umd.edu
  "Remove the first occurrence of SUBSTRING from STRING."
  (let ((loc (string-match substring string)))
    (if loc
	(concat (substring string 0 loc)
		(substring string  (+ (length substring) loc)))
      string)))

(defun rmail-summary-by-subjects (subjects)
  "Display a summary of all messages with the given SUBJECTS.
SUBJECTS is a string of names separated by commas."
  (interactive "sSubjects to summarize by: ")
  (rmail-new-summary
   (concat "subjects " subjects)
   'rmail-message-subjects-p
   (mail-comma-list-regexp subjects)))

(defun rmail-summary-other-buffer () 
  "switch to summary buffer in other window for this rmail-mode buffer."
  (interactive)
  (switch-to-buffer-other-window rmail-summary-buffer))

(defun one-window-if-RMAIL-summary-or-biff ()
  "if killing the RMAIL-summary or a biff buffer, also delete the window."
  (if (or (string-equal (buffer-name) "RMAIL-summary")
	  (string-match "OFF\\*biff\\*<[0-9]+>" (buffer-name)))
;; seems to create 0 length undeletable buffers everytime biff is triggered
	(delete-window)))

(add-hook 'kill-buffer-hook 'one-window-if-RMAIL-summary-or-biff)

(defun rmail-message-subjects-p (msg subjects)
  (save-restriction
    (goto-char (rmail-msgbeg msg))
    (search-forward "\n*** EOOH ***\n")
    (narrow-to-region (point) (progn (search-forward "\n\n") (point)))
    (string-match subjects (or (mail-fetch-field "Subject") ""))))

(defun rmail-mode-re-hook ()
  "(run-hooks 'rmail-mode-hook)"
  (interactive)
  (run-hooks 'rmail-mode-hook))

(defun rmail-mode-turn-off-edit-flags ()
  "turn off Fill and Abbrev mode line flags"
  (interactive)
  (auto-fill-mode -1)
  (abbrev-mode -1))

(defun rmail-show-Subject:-lines ()
  "show lines containing \"Subject:\"."
  (interactive)
  (list-matching-lines "Subject:"))

(defun rmail-quote-to-red-bean ()
  "Mail quote to cookie@red-bean.com"
  (interactive)
  (shell-command-on-region
   (region-beginning) (region-end)
   "Mail cookie@red-bean.com tower" nil))

(setq rmail-mode-hook
      (function
       (lambda ()
	 (progn
	   (load "rmailkwd")		; we almost alwasys use this
	   (load "rmailout")		; we almost alwasys use this
	   ;;for site-dependent (setq rmail-dont-reply-to-names ...)
	   ;;(load (expand-file-name "~/.rmail-dont") nil t)
	   (setq require-final-newline nil
		 mail-use-rfc822 t	; mly wrote this
		 version-control nil
		 kept-old-versions 0
		 kept-new-versions 3
		 mode-line-buffer-identification (list "Emacs: %b"))
	   (add-to-list 'search-ring "---\n")
	   (if (and (< emacs-version-major 19)
		    (equal rmail-last-file (expand-file-name "~/xmail")))
	       (setq rmail-last-file (expand-file-name "~/mbox")))
	   (if (fboundp 'rmail-mode-hook-gnulists)
	       (rmail-mode-hook-gnulists));; put in ~/.emacs
	   (local-set-key "*"	'tower-no-emacs-sex-list)
	   (local-set-key "="	'rmail-show-Subject:-lines)
	   (local-set-key "g"	'rmail-get-and-gc)
	   (local-set-key "H"	'rmail-mode-re-hook)
	   (local-set-key "I"	'rmail-summary-other-buffer)
	   (local-set-key "J"	'rmail-kill-region)
	   (local-set-key "M"	'rmail-setup-region)
	   (local-set-key "s"	'rmail-save-and-gc)
	   ;;Conflicts with gnulists usenet-ask:
	   ;;(local-set-key "U"	'undigestify-rmail-message-tower)
	   (local-set-key "W"	'rmail-mode-turn-off-edit-flags)
	;len's choices:
	;zap by message-id or subject
	   (local-set-key "z"	'rmail-kill-message-id)
	   (local-set-key "Z"	'rmail-kill-subject)
	   (local-set-key "|"	'rmail-quote-to-red-bean)
	;overload the label next and prev.
	;better than losing the ability to easily go to undeleted message.
	   (local-set-key "\e\C-n"	'rmail-next-message-with-subject)
	   (local-set-key "N"	'rmail-next-message-with-subject)
	   (local-set-key "\e\C-p"	'rmail-previous-message-with-subject)
	   (local-set-key "P"	'rmail-previous-message-with-subject)
	;Eric L. Raible <raible@ew09.nas.nasa.gov>:
	   (local-set-key "R"	'rmail-extract-rejected-message) ;r for resend
	   (if (fboundp 'rmail-mode-hook-local)
	       (rmail-mode-hook-local));; put in ~/.emacs
	   ))))

(setq rmail-show-message-hook
      (function
       (lambda ()
	 (progn
	   (rmail-mode-turn-off-edit-flags)))))

(setq rmail-ignored-headers
      (concat  rmail-ignored-headers "\\|^via:\\|^mail-from:\\|^origin:\\|^status:\\|^received:\\|^summary-line:\\|^distribution:\\|^lines:\\|^article-i.d.:\\|^nf-id:\\|^nf-from:\\|^references:\\|^[a-z-]*-version:\\|^[a-z-]*message-id:\\|^posted[a-z-]*:\\|^approved:\\|^x400-received:\\|^x-vm-v5-data:\\|^precedence:\\|^content-[a-z-]*:\\|^x-webtv-signature:\\|^importance:\\|x-priority:\\|x-msmail-priority:\\|x-mailer:\\|x-mimeole:"))

(setq mail-yank-ignored-headers
 (concat mail-yank-ignored-headers "\\|^fcc:\\|^path:\\|^apparently-to:\\|^sender:\\|^newsgroups:\\|^organization:\\|^home:\\|^reply-to:\\|^content-[^:]*:\\|^x-[^:]*:\\|^importance:"))

(defun tower-no-emacs-sex-list ()
  "Tell the befrauded folk there is not emacs sex list by tower.
C-x C-x will move between the To: line and the salutation."
  (interactive)
  (rmail-output "~/gnusenet/mbox.gnu.all.gnu.emacs.sex.adds")
  (gnulists-reply-setup)
  (insert "
Someone, somewhere got some wrong information.

I'm not running such a list.

Someone else is free to do so.

Or get an alt.emacs.sex created on USENET.

Where did you see the info about the list?  Could you send me a copy?

enjoy -len

Member, League for Programming Freedom.  Ask: lpf@uunet.uu.net
")
  (beginning-of-buffer)
  (forward-char 4)
  (exchange-point-and-mark))

;; changed so it works in gnulists' pseudo news mode:
;; @@ be nice if we fset the original definition so it's around
(defun tower-mail-position-on-field (field &optional soft)
"len's hacked version from version 18.59 sources"
  (let (end
	(case-fold-search t))
    (goto-char (point-min))
    (re-search-forward (concat "^" mail-header-separator "$\\|^$"))
    (setq end (match-beginning 0))
    (goto-char (point-min))
    (if (re-search-forward (concat "^" (regexp-quote field) ":") end t)
	(progn
	  (re-search-forward "^[^ \t]" nil 'move)
	  (beginning-of-line)
	  (skip-chars-backward "\n")
	  t)
      (or soft
	  (progn (goto-char end)
		 (skip-chars-backward "\n")
		 (insert "\n" field ": ")))
      nil)))

(defun mail-bcc-tower ()
  "Move point to end of BCC-field.  Create a BCC field with USER if none."
  (interactive)
  (expand-abbrev)
  (if (mail-bcc)
      (insert ",\n\t"))
  (insert (getenv "USER") "@ai.mit.edu"))

(defun mail-insert-headers-tower ()
  "insert noisy header lines"
  (interactive)
  (goto-char (point-min))
  (search-forward (concat "\n" mail-header-separator "\n"))
  (beginning-of-line -1)
  (insert mail-header-inserted-text))

(defun mail-yank-original-tower (arg)
  "calls mail-yank-original, then squashes consecutive blank lines into
one (i.e. just-one-line)."
  (interactive "P")
  (mail-yank-original arg)
  (goto-char (point-min))
  (replace-regexp "^[ 	]+$" "
" nil)
  (goto-char (point-min))
  (while (search-forward "\n\n\n" nil t)
    (goto-char (point-min))
    (replace-string "\n\n\n" "\n\n")
    (goto-char (point-min)))
  (goto-char (point-max)))

(defun mail-go-to-field (arg)
  "Move point to end of CC-field.  Create a CC field if none."
  (interactive "sHeader Field: ")
  (expand-abbrev)
  (or (mail-position-on-field arg t)
      (progn (mail-position-on-field "to")
	     (insert "\n" arg ": "))))

(defun mail-gnusenetfy-message-id ()
  "Prepend \"gnusenet\" to message id.  Used to handle weird cross-posting cases."
  (interactive)
  (mail-position-on-field "Message-Id")
  (let (end
	(case-fold-search t))
    (search-backward "\nMessage-Id: <")
    (setq end (match-end 0))
    (goto-char end)
    (insert "gnusenet")))

(defun mail-fill-yanked-message-region ()
  "This function assumes that the region is set right."
  (interactive)
  (save-window-excursion
    (save-excursion 
      (save-restriction
	(narrow-to-region (region-beginning) (region-end))
	(mail-fill-yanked-message)
	(widen)))))

(autoload 'mail-fill-yanked-message "sendmail" "" t)

(setq mail-mode-hook
      (function
       (lambda ()
	 ;; (indented-text-mode) ;; equivalent from text-mode.el
	 ;; (make-local-variable 'indent-line-function)
	 ;; (setq indent-line-function 'indent-relative-maybe)
	 ;; (local-set-key "\t"	'indent-relative)
	 ;; (local-set-key "\es"	'center-line)
	 ;; (local-set-key "\eS"	'center-paragraph)
	 (local-set-key "\C-c\C-fb" '(lambda () (interactive)
				       (mail-go-to-field "Resent-Bcc")))
	 (local-set-key "\C-c\C-fc" '(lambda () (interactive)
				       (mail-go-to-field "Resent-Cc")))
	 (local-set-key "\C-c\C-ff" '(lambda () (interactive)
				       (mail-go-to-field "Resent-From")))
         (local-set-key "\C-c\C-fi" '(lambda () (interactive)
                                       (progn
                                         (goto-char (point-min))
                                         (search-forward "\n\n")
                                         (backward-char 1)
                                         (insert mail-header-separator))))
	 (local-set-key "\C-c\C-fm" '(lambda () (interactive)
				       (mail-go-to-field "Resent-Message-Id")))
	 (local-set-key "\C-c\C-fs" '(lambda () (interactive)
				       (mail-go-to-field "Sender")))
	 (local-set-key "\C-c\C-ft" '(lambda () (interactive)
				       (mail-go-to-field "Resent-To")))
	 (local-set-key "\C-c\C-f\C-b"	'mail-bcc-tower)
;@@ should make this a C-u variation of \C-c\C-f\C-m
	 (local-set-key "\C-c\C-f\C-d"  'mail-gnusenetfy-message-id)
	 (local-set-key "\C-c\C-f\C-f" '(lambda () (interactive)
				       (mail-go-to-field "From")))
	 (local-set-key "\C-c\C-f\C-h"	'mail-insert-headers-tower)
	 (local-set-key "\C-c\C-f\C-m" '(lambda () (interactive)
					  (mail-go-to-field "Message-Id")))
	 (local-set-key "\C-c\C-f\C-r" '(lambda () (interactive)
					  (mail-go-to-field
					   "Return-Receipt-To")
					  (insert (getenv "USER")
						  "@ai.mit.edu")))
;@@ should add \C-c\C-f\C-s to do  or mabye C-u of \C-c\C-f\C-b
;@@    Sent-Via-Bcc-To:
;@@    X-Bcc:
;@@   Bcc:
	 (local-set-key "\C-c\C-y"	'mail-yank-original-tower)
	 (if (fboundp 'mail-mode-hook-local)
	     (mail-mode-hook-local))	; put in ~/.emacs
	 (setq mail-aliases nil)
	 (modify-syntax-entry ?% "_")	; to symbol
	 (abbrev-mode 1)
	 (auto-fill-mode 1)
	 )))

(setq mail-setup-hook
      (function
       (lambda ()
	 (if (fboundp 'mail-setup-hook-local)
	     (mail-setup-hook-local))	; put in ~/.emacs
	 (mail-position-on-field "To")
	 (if to
	     (progn (beginning-of-line)	;reply.  To: is probably right
		    (forward-char 4)
		    (set-mark (point))
		    (goto-char (point-max)))
	   (set-mark (point-max))))))

(setq text-mode-hook
      (function
       (lambda ()
	 (abbrev-mode 1)
	 (auto-fill-mode 1))))

(setq dired-mode-hook
      (function
       (lambda ()
	 (if (search-forward " .." nil t)
	     (dired-next-line 1)))))

(setq c-mode-hook
      (function
       (lambda ()
	 (abbrev-mode 1)
	 (setq blink-matching-paren-distance 100000))))

;;(setq texinfo-mode-hook
;;      (function
;;       (lambda ()
;;	 (local-set-key "\C-x4c"	'texinfo-format-buffer))))

(defun bg-bc ()				;emacs-byte-compile
  "byte compile an emacs-lisp file in the background"
  (interactive)
  (let ((buffer (get-buffer-create "*background-byte-compile*")))
    (set-buffer buffer)
    (if (get-buffer-process buffer)
	(progn
	  (discard-input)
	  (if (y-or-n-p (format "Kill process \"%s\" in %s? "
				(process-name (get-buffer-process buffer))
				(buffer-name buffer)))
	      (while (get-buffer-process buffer)
		(kill-process (get-buffer-process buffer)))
	    (error "Foo"))))
    (buffer-flush-undo (current-buffer))
    (erase-buffer)
    ;; this line only works in v18 -- you have to set mode-line-format in v17
    (setq mode-line-process '(": %s"))
    (let
	((process
	  (start-process
	   "background-byte-compile" buffer
	   "nemacs" "-batch" "-funcall" "batch-byte-compile-file"
	   (concat (buffer-file-name)))))
      ;(process-kill-without-query process)
      process)))

(setq emacs-lisp-mode-hook
      (function
       (lambda ()
	 (setq blink-matching-paren-distance 100000)
	 (local-set-key "\C-x4c"	'bg-bc))))

;;(setq news-ignored-headers
;;^Posting-Version:\\|^Relay-Version:\\|^References:\\|^Control:\\|^Xref:\\|
;;"^Article-I.D.:\\|^Expires:\\|^Date-Received:\\|^Lines:\\|^Posted:\\|^Message-ID:\\|^Nf-ID:\\|^Nf-From:\\|^Approved:\\|^Sender:")
(setq news-mode-hook
      (function
       (lambda ()
	 (cd "~/")
	 (define-key news-mode-map "d"	'news-next-message)
	 (setq news-max-plausible-gap 10);; 2 hasn't been reasonable on prep
	 )))

(setq news-reply-mode-hook mail-mode-hook)

; @@ may make this a universal arg to rmail-kill-region
; @@ really like to have pairs of start and end region strings to match
; @@ before we take the first "paragraph" after header
(defun rmail-setup-region ()
  "Sets the region in an rmail buffer to the first paragraph and the first
  line of the second paragraph after the header."
  (interactive)
  (goto-char (point-min))
  (search-forward "\n\n")
  (backward-char 2)
  (set-mark (point))
  ;; (sit-for 1) ;;debug
  (forward-char 3)
  (forward-paragraph)
  (end-of-line 2)
  (forward-char 1))

;;Date: Mon, 28 Mar 88 12:04:56 BST
;;From: mcvax!gec-epl.co.uk!J.A.House@uunet.uu.net
;;Sender: mcvax!gec-epl.co.uk!james@uunet.uu.net
;;To: bug-gnu-emacs@prep.ai.mit.edu
;;Subject: Shell file name completion
;;
;;  I am using emacs 18.41 on a SUN 3 running Sun UNIX 4.2 rel 3.2.
;;Since this UNIX provides file name completion, I found its absence in
;;Emacs shell mode a nuisance.
;;  I wrote the following function which seems to work quite well.
;;Since I'm not an expert in Emacs lisp this may not be the best way to
;;do filename completion.
;;
;;(provide 'shell-file-completion)

(defun shell-expand-file-name ()
  "Replace the csh file completion facilities.
  The current shell argument is completed as far as possible.
  If ambiguous (no expansion possible) then a list of possible
  expansions is displayed."
  (interactive)
  (let (start
	(end (point))
	file dir dirspec name
	;;@@ would like to use shell-prompt-pattern but it has a space at end
	(pattern (concat  "[\"#>\t :\n]\\|^"))
	expansion)
    ;; Find the start of this argument
    (re-search-backward pattern)
    (goto-char (match-end 0))
    (setq start (point))
    (setq file (substitute-in-file-name (buffer-substring start end)))
    (setq dirspec (file-name-directory file))
    (setq dir (or dirspec default-directory))
    (setq name (file-name-nondirectory file))
    (setq expansion (file-name-completion name dir))
    (delete-region start end) (if dirspec (insert dirspec))
    (cond
     ((stringp expansion)
      (insert expansion)
      (if (equal name expansion)
	  (with-output-to-temp-buffer " *Completions*"
	    (display-completion-list
	     (sort (file-name-all-completions name dir) 'string-lessp))))
      )
     (expansion
      (insert name)
      (message "Unique expansion"))
     (t
      (insert name)
      (message "No expansion")))))

;;Hope this proves useful.
;;
;;James House,
;;GEC Electical Projects Ltd.
;;Boughton Road, Rugby, CV21 1BU
;;England.
;;
;;Email: J.House@gec-epl.co.uk
;;Tel:   +44 788 2144
(defun cwd-shell-mode ()
  "Set shell-mode to display the current working directory."
  (interactive)
;OFF  (define-key shell-mode-map "\C-m"	'cwd-shell-send-input)
  (define-key shell-mode-map "\t"	'shell-expand-file-name)
;OFF  (make-local-variable 'current-working-directory)
  (setq fill-column 511)
;OFF  (setq current-working-directory default-directory)
  (setq mode-line-buffer-identification '("%7b"))
  (setq mode-line-format
	'( "-<%3p>"  mode-line-buffer-identification ; " "
;OFF	   current-working-directory " "
	   default-directory		; " "	;instead of OFF
	   "%[(" mode-name minor-mode-alist "%n"
	   mode-line-process ")%]"
	   global-mode-string "%-"))
  (setq shell-cd-regexp "cd\\|chdir")
  (setq shell-popd-regexp "popd\\|po")
  (setq shell-pushd-regexp "pushd\\|pu"))

(setq shell-mode-hook 'cwd-shell-mode)

;; doesn't work for a cd of directory in csh's $cdpath
;(defvar shell-set-directory-error-flag nil
;  "t indicates that shell-set-directory-error-hook was called by Emacs on last
;directory change shell command.")
;
;(setq shell-set-directory-error-hook
;      (function
;       (lambda ()
;	 (setq shell-set-directory-error-flag t))))

;OFF(defun cwd-shell-send-input ()
;OFF  "Pass input to the subshell, and update cwd's display."
;OFF  (interactive)
;OFF  (shell-send-input)			;allow it to do the normal job
;OFF  ;;  (if (equal shell-set-directory-error-flag t) ; see above
;OFF  ;;HACK: recover proper default-directory after next execution
;OFF  ;; by finding $cwd in tower's $prompt-see ~/.icshrc
;OFF  (save-excursion
;OFF    (let (dir)
;OFF      (goto-char last-input-start)
;OFF      (beginning-of-line)
;OFF      (skip-chars-forward "^/")
;OFF      (if (file-directory-p
;OFF	   (setq dir
;OFF		 (expand-file-name
;OFF		  (substitute-in-file-name
;OFF		   (buffer-substring
;OFF		    (point)
;OFF		    (progn
;OFF		      (skip-chars-forward "^ \t;")
;OFF		      (point)))))))
;OFF	  (cd dir))))			;side-effect:
;OFF					;      (setq default-directory dir)
;OFF  ;;    	 (setq shell-set-directory-error-flag nil)) ;; see above
;OFF  (setq current-working-directory default-directory))

;; Date: Wed, 2 Oct 85 01:57:36 EDT
;; From: Bruce Israel <israel@tove.umd.edu>
;; To: info-gnu-emacs@mit-prep.ARPA
;; Subject: Minibuffer completion
;;
;; Here is a really useful function that I wrote for minibuffer
;; completion.  It will complete as much as possible, exiting if there is
;; only one possibility.  If there are two or more, then it completes
;; until the two choices differ.  If there aren't any possibilities, then
;; it removes characters off the end of the completion string until it
;; gets to a point where completions are possible and stops there.
;;
;; I bind it to the SPACE key in the minibuffer, since I don't really
;; like completion by single words at all.  Following the function is the
;; function call that will bind it to the SPACE key.  Change the
;; character there if you want to bind it to something else.  Enjoy.
;;
;; (defun minibuffer-complete-exit-backup nil
;;    "Minibuffer completion, exiting on unique completion with backup."
;;    (interactive)
;;    (let (comp (complete t))
;;      (set-mark (dot-min))
;;      (while (null (setq comp (all-completions
;; 			      (region-to-string)
;; 			      minibuffer-completion-table
;; 			      minibuffer-completion-predicate)))
;;        (setq complete nil)
;;        (delete-backward-char 1 nil))
;;      (and complete (if (null (cdr comp)) (minibuffer-complete-and-exit)
;; 			(minibuffer-complete)))))
;; ; leave SPC as it is for now -len
;; (define-key minibuffer-local-must-match-map "\C-x "
;;      (define-key minibuffer-local-completion-map "\C-x "
;; 	  'minibuffer-complete-exit-backup))

(defun list-matching-lines (regexp &optional nlines)
  ;; I prefer the version 17 version without "-------".
  ;; 'occur' has been left with v18 behaviour
  "Show all lines containing of REGEXP following point.
Display each line with NLINES lines before and after.
NLINES defaults to 0.  Interactively it is the prefix arg."
  (interactive "sOccur (show lines matching regexp): \nP")
  (setq nlines (if nlines (prefix-numeric-value nlines) 0))
  (let ((first t))
    (with-output-to-temp-buffer "*Occur*"
      (save-excursion
	(while (re-search-forward regexp nil t)
	  (let ((buffer (current-buffer))
		(start
		 (save-excursion
		   (beginning-of-line)
		   (forward-line (- nlines))
		   (point)))
		(end
		 (save-excursion
		   (forward-line (1+ nlines))
		   (point))))
	    (save-excursion
	      (set-buffer standard-output)
	      ;;	 (or first
	      ;;	     (insert "--------\n"))
	      ;;	 (setq first nil)
	      (insert-buffer-substring buffer start end))
	    (forward-line 1)))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Command for GNU Emacs which displays line number.
;;; Copyright (c) 1987 Michael D. Prange
;;; Written by Michael D. Prange <mit-eddie!mit-erl!prange>.

;;; This file is not part of the GNU Emacs distribution (yet).

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY.  No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing.  Refer to the GNU Emacs General Public
;; License for full details.

;; Everyone is granted permission to copy, modify and redistribute
;; this file, but only under the conditions described in the
;; GNU Emacs General Public License.   A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities.  It should be in a
;; file named COPYING.  Among other things, the copyright notice
;; and this notice must be preserved on all copies.

(defun what-line ()
  "Print the line number of point in the buffer (and in the
narrowed region, if there is one)."
  (interactive)
  (save-excursion
    (let* ((point-min (point-min))
	   (lines-after-point-min
	    (progn (beginning-of-line)
		   (count-lines point-min (point)))))
      (save-restriction
	(widen)
	(if (= point-min (point-min))	;test for narrowing
	    (message "Line %d" (1+ lines-after-point-min))
	  (message "Line %d of buffer.  Line %d of narrowed region."
		   (+ 1 lines-after-point-min
		      (progn (goto-char point-min)
			     (beginning-of-line)
			     (count-lines 1 (point))))
		   (+ 1 lines-after-point-min)))))))

;; USE:
;;   M-x unix-apropos
;; (or help-key u)
;; prompts for keywords, and simulates man -k.  Pops up window of possible
;; unix documentation.  Move cursor to desired command and hit RETURN.

;;; This file is not part of the GNU Emacs distribution (yet).

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY.  No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing.  Refer to the GNU Emacs General Public
;; License for full details.

;; Everyone is granted permission to copy, modify and redistribute
;; this file, but only under the conditions described in the
;; GNU Emacs General Public License.   A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities.  It should be in a
;; file named COPYING.  Among other things, the copyright notice
;; and this notice must be preserved on all copies.

;;; MODIFICATION HISTORY:

;;; 9/1/88, created by  Henry Kautz
;;;                     uucp: allegra!kautz
;;; 9/2/88, H. Kautz eliminates use of man -k, added additional keywords,
;;;         added default topic based on word under cursor
;;; 9/6/88, H. Kautz added scroll-other-window, and chopped -ucb from
;;;         section numbers
;;; 9/12/88, H. Kautz defined "u" key in help-map, rather than in \C-h.
;;;         Made system use man -k if the whatis file can't be found.
;;;         Made use of section numbers optional
;;; 9/14/88 Aaron Larson (alarson@src.honeywell.com) added Scroll-man-
;;;         window-{up|down}
;;; 9/16/88 H. Kautz adds multiple man page windows, and fancier
;;;         scrolling


  (provide 'unix-apropos)

;;; User Customizable Parameters

  (defvar manual-unique-buffers t
    "*If non-nil, then put each man page in a uniquely named buffer.
You can have multiple man buffers on screen, and scroll them from
the *Unix Apropos* window")

  (defvar unix-apropos-popup-window t
    "*If non-nil, then when the unix-apropos command is invoked, always
create a new window (if possible), rather than possibly hiding a
currently visible window.  See also the m command in unix-apropos-mode.")

  (define-key help-map "u"	'unix-apropos)

  (defvar whatis-file-name "/usr/man/whatis"
    "*Text file containing index of all Unix documentation.  If this
file cannot be found, then the command 'man -k' is used to find
the appropriate information.")

  (defvar unix-apropos-supress-section-numbers nil
    "*Set to non-nil to supress use of section numbers with the
unix-apropos-get-man command.  Useful if your local installation is
sloppy about installing documentation in the correct section of /usr/man.")


;;; Main Program

  (defvar manual-entry-buffer "*Manual Entry*"
    "The name of the buffer most recently created to hold a manual
entry.")

  (defvar unix-apropos-last-topic ""
    "Contains the topic of currently active manual entry buffer")

					; Create the unix apropos keymap

  (progn
    (setq unix-apropos-map (make-sparse-keymap))
    (define-key unix-apropos-map "\C-M"	'unix-apropos-get-man)
    (define-key unix-apropos-map "m"	'unix-apropos-get-man-popup)
    (define-key unix-apropos-map "n"	'next-line)
    (define-key unix-apropos-map " "	'Scroll-man-window-up)
    (define-key unix-apropos-map "\C-?"	'Scroll-man-window-down)
    (define-key unix-apropos-map "p"	'previous-line)
    (define-key unix-apropos-map "u"	'unix-apropos)
    (define-key unix-apropos-map "x"	'unix-apropos-expunge)
    (define-key unix-apropos-map "a"	'unix-apropos-additional)
    (define-key unix-apropos-map "h"	'describe-mode)
    (define-key unix-apropos-map "?"	'describe-mode)
    )


(defun display-popup-buffer (buf)
  "Like display-buffer, but be careful not to hide any buffers when
popping up BUF.  Split the largest window if necessary to display BUF."
  (interactive "B")
  (setq buf (get-buffer-create buf))
  (cond
   ((get-buffer-window buf))
   ((eq (selected-window) (next-window))
    (display-buffer buf))
   (t (let ((not-done t) (w (next-window)) max-w
	    (max (1- (* 2 window-min-height))))
	(while not-done
	  (if (> (window-height w) max)
	      (progn
		(setq max (1+ (window-height w)))
		(setq max-w w)))
	  (if (eq w (selected-window))
	      (setq not-done nil))
	  (setq w (next-window w)))
	(if max-w
	    (let ((b (current-buffer)))
	      (select-window max-w)
	      (split-window-vertically)
	      (other-window 1)
	      (switch-to-buffer buf)
	      (pop-to-buffer b)
	      )
	  (display-buffer buf))))))


(defun unix-apropos-get-man-popup ()
  "like get-man, but allow multiple man buffers to appear simultaneously"
  (interactive)
  (unix-apropos-get-man t))

(defun unix-apropos-get-man (&optional popup)
  "Get the manual entry for the current line; returns
t if the buffer was already visible, otherwise nil"
  (interactive '(nil))
  (let (topic section already-visible)
    (interactive)
    (beginning-of-line 1)
    (looking-at "\\w*")
    (setq topic (buffer-substring (match-beginning 0) (match-end 0)))
    (if unix-apropos-supress-section-numbers
	(setq section nil)
      (progn
	(re-search-forward "(\\([^-)]*\\))")
	(setq section (downcase (buffer-substring
				 (match-beginning 1) (match-end 1))))
	))
    (beginning-of-line 1)
    (setq manual-entry-buffer
	  (if manual-unique-buffers
	      (concat "*Manual "
		      topic
		      (if section (concat "(" section ")*") "*"))
	    "*Manual Entry*"))
    (setq unix-apropos-last-topic topic)
    (if (and manual-unique-buffers (get-buffer manual-entry-buffer))
	(if (not (setq already-visible
		       (get-buffer-window manual-entry-buffer)))
	    (if popup
		(display-popup-buffer manual-entry-buffer)
	      (display-buffer manual-entry-buffer)))
      (progn
	(if popup (display-popup-buffer "*Manual Entry*"))
	(manual-entry topic section)
	(if manual-unique-buffers
	    (progn
	      (pop-to-buffer "*Manual Entry*")
	      (rename-buffer manual-entry-buffer)
	      (pop-to-buffer "*Manual Apropos*")))))
    already-visible))

(defun unix-apropos-expunge ()
  "kill all the Unix man buffers"
  (interactive)
  (mapcar (function
	   (lambda (b)
	     (if (string-match "^\\*Manual" (buffer-name b))
		 (progn
		   (if (and (get-buffer-window b)
			    (not (eq (next-window)
				     (selected-window))))
		       (delete-window (get-buffer-window b)))
		   (kill-buffer b)))))
	  (buffer-list)))

(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))))

(defun unix-apropos (topic)
  "Display apropos for TOPIC"
  (interactive (list
		(read-string (concat "Unix apropos ("
				     (current-word) "): "))))
  (if (equal "" topic) (setq topic (current-word)))
  (if unix-apropos-popup-window (display-popup-buffer "*Manual Apropos*"))
  (pop-to-buffer "*Manual Apropos*")
  (unix-apropos-mode))

(defun unix-apropos-additional (additional)
  "Read an additional keyword which further restricts the selection
of possible documentation"
  (interactive (list
		(read-string (concat "Additional keyword ("
				     (current-word) "): "))))
  (if (equal "" additional) (setq additional (current-word)))
  (goto-char (point-min))
  (let ((buffer-read-only nil))
    (delete-non-matching-lines additional)))


(defun scroll-window-containing-buffer (buffer &optional arg scroll-fun)
  (if (null scroll-fun) (setq scroll-fun 'scroll-up))
  (let ((orig-buffer (current-buffer)))
    (unwind-protect
	(if (get-buffer-window buffer)
	    (progn (pop-to-buffer buffer)
		   (funcall scroll-fun arg))
	  (error "Buffer %s does not exist!" buffer))
      (pop-to-buffer orig-buffer))))

(defun Scroll-man-window (arg scroll-fun)
  (and
   (or (looking-at unix-apropos-last-topic)
       (unix-apropos-get-man))
   (scroll-window-containing-buffer manual-entry-buffer
				    arg scroll-fun)))

(defun Scroll-man-window-up (arg)
  "Scroll up the man window corresponding to the current line, or
pop it up if not visible, or create it if non-existent"
  (interactive "P")
  (Scroll-man-window arg 'scroll-up))

(defun Scroll-man-window-down (arg)
  "Scroll down the man window corresponding to the current line, or
pop it up if not visible, or create it if non-existent"
  (interactive "P")
  (Scroll-man-window arg 'scroll-down))


(defun unix-apropos-mode ()
  "<return> = get manual entry; n = next line; p = previous line
m = split a window and then get a manual entry
x = expunge man page buffers; u = unix apropos; h = describe mode
a = constrain search by an additional keyword
<space> = scroll up manual entry; <delete> = scroll down manual entry"
  (setq buffer-read-only nil)
  (erase-buffer)
  (buffer-flush-undo (current-buffer))
  (use-local-map unix-apropos-map)
  (setq mode-name "Apropos")
  (setq major-mode 'unix-apropos-mode)
  (if (file-readable-p whatis-file-name)
      (progn
	(insert-file whatis-file-name)
	(goto-char (point-min))
	(delete-non-matching-lines topic))
    (progn
      (call-process "man" nil t nil "-k" topic)
      ))
  (setq buffer-read-only t)
  (goto-char (point-min))
  )

;; customiztion:

(setq unix-apropos-supress-section-numbers t)

;;;From ram-ashwin@yale.arpa Sat Feb  6 14:08:32 1988
;;;Date: Mon, 23 Nov 87 11:48:25 EST
;;;From: Ashwin Ram <ram-ashwin@yale.arpa>
;;;To: info-gnu-emacs@prep.ai.mit.edu
;;;Subject: Subject search in RMAIL
;;;
;;;I've written a subject search utility for RMAIL which others may find useful.
;;;You get the following:
;;;
;;;    M-n, M-p --- Show next (previous) message with same subject
;;;                 (Useful for following conversation threads about a given subject.)
;;;
;;;    k        --- Kill all messages with this subject
;;;                 (Useful for junking mailing list messages about a subject
;;;                 you're tired of.)
;;;
;;;
;;;--------------------------------------------------------------------------
;; Subject search mode for rmail.
;; (c) Ashwin Ram, 11/23/87.
;; This file is not part of the GNU Emacs distribution (yet)
;; but is distributed under the same conditions.

;; The basic function is one that searches for a nondeleted message with a given
;; SUBJECT (a regular expression):

(defun rmail-subject-search (subject &optional reverse)
  "Find next message whose subject matches the regular expression SUBJECT.
If optional argument REVERSE is non-nil, find previous message.
Returns number of message if found, or nil."
  (let ((current rmail-current-message)
	(found nil))
    (while (and (not found) (< 0 current) (< current rmail-total-messages))
      (setq current (if reverse (1- current) (1+ current)))
      (if (and (not (rmail-message-deleted-p current))
	       (let ((current-subject (save-excursion
					(save-restriction
					  (widen)
					  (narrow-to-region
					   (rmail-msgbeg current)
					   (rmail-msgend current))
					  (mail-fetch-field "Subject")))))
		 (and current-subject (string-match subject current-subject))))
	  (setq found current)))
    found))

;; Using this, I wrote functions to find the next (or previous) message with the
;; same subject as the current one (like "subject search mode (^N)" in rn(1)),
;; and to kill all messages with the same subject as the current one (like the
;; "k" command in rn(1)).  The match ignores a leading "Re: ", if any.

(defun rmail-next-message-with-subject (subject)
  "Show following message whose subject matches the regular expression SUBJECT,
which defaults to the subject of the current message.
(This is like the '^N' command of rn(1).)"
  (interactive (list (concat "^\\(Re: *\\|\\)"
                              (regexp-quote (rmail-deReify (or (mail-fetch-field "Subject")
                                                               (error "Current message has no subject"))))
                              "$")))
  (let ((next (rmail-subject-search subject)))
      (if next
          (rmail-show-message next)
          (message "No following message with subject %s" subject))))

(defun rmail-previous-message-with-subject (subject)
  "Show previous message whose subject matches the regular expression SUBJECT,
which defaults to the subject of the current message.
This is like the '^N' command of rn."
  (interactive (list (concat "^\\(Re: *\\|\\)"
			     (regexp-quote
			      (rmail-deReify
			       (or (mail-fetch-field "Subject")
				   (error "Current message has no subject"))))
			     "$")))
  (let ((previous (rmail-subject-search subject 'reverse)))
    (if previous
	(rmail-show-message previous)
      (message "No previous message with subject %s" subject))))

(defun rmail-kill-subject (subject)
  "Kills all following messages matching the regular expression SUBJECT, which
defaults to the subject of the current message.
This is like the 'k' command of rn.)"
  (interactive (list (concat "^\\(Re: *\\|\\)"
			     (regexp-quote (rmail-deReify (or (mail-fetch-field "Subject")
							      (error "Current message has no subject"))))
			     "$")))
  (rmail-delete-message)
  (let ((start rmail-current-message)
	(deleted (list rmail-current-message))
	(next (rmail-subject-search subject)))
    (while next
      (rmail-show-message next)
      (rmail-delete-message)
      (setq deleted (cons rmail-current-message deleted))
      (message "Deleted %s" deleted)
      (setq next (rmail-subject-search subject)))
    (rmail-show-message start)
    (rmail-next-undeleted-message 1)
    (if deleted
;;	(message "Deleted %s messages %s" (length deleted) (reverse deleted))
	(message "Deleted %s messages %s" (length deleted) deleted)
      (message "No nondeleted messages with subject %s" subject))))

;; This is a utility useful in itself (I use it to set up the subject line
;; correctly in rmail-reply, for example):

;; Utility.  Couldn't resist the pun.
(defun rmail-deReify (subject)
  "Strips a leading \"Re:\", if any, from SUBJECT."
  (if (and subject (string-match "^Re: *" subject))
      (substring subject (match-end 0))
    subject))

;; I usually bind the above functions as follows:

;;;;; K for Kill (as in RN(1)).
;;;(define-key rmail-mode-map "k"	'rmail-kill-subject)
;;;;; N for Next
;;;(define-key rmail-mode-map "\en"	'rmail-next-message-with-subject)
;;;;; P for Previous
;;;(define-key rmail-mode-map "\ep"	'rmail-previous-message-with-subject)

;;;---------------------------------------------------------------------------
;;;Comments, suggestions and improvements welcome.
;;;
;;;-- Ashwin Ram --
;;;
;;;ARPA:    Ram-Ashwin@cs.yale.edu
;;;UUCP:    {decvax,linus,seismo}!yale!Ram-Ashwin
;;;BITNET:  Ram@yalecs

;; adopted from the above
(defun rmail-message-id-search (message-id &optional reverse)
  "Find next message whose message-id matches the regular expression MESSAGE-ID.
If optional argument REVERSE is non-nil, find previous message.
Returns number of message if found, or nil."
  (let ((current rmail-current-message)
	(found nil))
    (while (and (not found) (< 0 current) (< current rmail-total-messages))
      (setq current (if reverse (1- current) (1+ current)))
      (if (and (not (rmail-message-deleted-p current))
	       (let ((current-message-id
		      (save-excursion
			(save-restriction
			  (widen)
			  (narrow-to-region
			   (rmail-msgbeg current) (rmail-msgend current))
			  (mail-fetch-field "Message-Id")))))
		 (and current-message-id
		      (string-match message-id current-message-id))))
	  (setq found current)))
    found))

(defun rmail-kill-message-id (message-id)
  "Kills all following messages matching the regular expression MESSAGE-ID,
which defaults to the message-id of the current message."
  (interactive (list (concat (regexp-quote
			      (or (mail-fetch-field "Message-Id")
				  (progn
				    (rmail-toggle-header)
				    (mail-fetch-field "Message-Id"))
				  (error "Current message has no message-id")))
			     "$")))
  (rmail-delete-message)
  (let ((start rmail-current-message)
	(deleted (list rmail-current-message))
	(next (rmail-message-id-search message-id)))
    (while next
      (rmail-show-message next)
      (rmail-delete-message)
      (setq deleted (cons rmail-current-message deleted))
      (message "Deleted %s" deleted)
      (setq next (rmail-message-id-search message-id)))
    (rmail-show-message start)
    (rmail-next-undeleted-message 1)
    (if deleted
;;	(message "Deleted %s messages %s" (length deleted) (reverse deleted))
	(message "Deleted %s messages %s" (length deleted) deleted)
      (message "No nondeleted messages with message-id %s" message-id))))

;; adopted from the above
(defun rmail-region-search (region &optional reverse)
  "Find next message whose region matches the regular expression REGION.
If optional argument REVERSE is non-nil, find previous message.
Returns number of message if found, or nil."
  (interactive)
  (let ((current rmail-current-message)
	(found nil)
	(found1 nil))
    (while (and (not found) (< 0 current) (< current rmail-total-messages))
      (setq current (if reverse (1- current) (1+ current)))
      (if (and (not (rmail-message-deleted-p current))
	       (progn
		 (save-excursion
		   (save-restriction
		     (widen)
		     (narrow-to-region
		      (rmail-msgbeg current) (rmail-msgend current))
		     (re-search-forward
		      region (rmail-msgend current) t)))))
	  (setq found current)))
    found))

(defun rmail-kill-region (region)
  "Kills all following messages matching the regular expression REGION,
which is the region of the current message between point and mark."
  (interactive (list (concat (regexp-quote
			      (if (equal (point) (mark))
				  (error "point is equal to mark")
				(if (< (point) (mark))
				    (buffer-substring (point) (mark))
				  (buffer-substring (mark) (point))))))))
  (rmail-delete-message)
  (let ((start rmail-current-message)
	(deleted (list rmail-current-message))
	(next (rmail-region-search region)))
    (while next
      (rmail-show-message next)
      (rmail-delete-message)
      (setq deleted (cons rmail-current-message deleted))
      (message "Deleted %s" deleted)
      (setq next (rmail-region-search region)))
    (rmail-show-message start)
    (rmail-next-undeleted-message 1)
    (if deleted
;;	(message "Deleted %s messages %s" (length deleted) (reverse deleted))
	(message "Deleted %s messages %s" (length deleted) deleted)
      (message "No nondeleted messages with region %s" region))))

;;;Date: Mon, 28 Nov 88 19:06:18 PST
;;;From: Eric L. Raible <raible@ew09.nas.nasa.gov>
;;;To: info-gnu-emacs@prep.ai.mit.edu
;;;Subject: rmail-extract-rejected-message
;;;Reply-To: raible@orville.nas.nasa.gov
;;;
;;;I think that anyone who uses rmail will find this to be a welcome addition.

;; tower added "Original":
  (defvar
    mail-unsent-separator
    "^   ----- Unsent message follows -----$\\|^   ----- Original message follows -----\n\n--.*\nContent-Type: message/rfc822\n")

;;;(setq rmail-mode-hook
;;;      '((lambda ()
;;;	  (define-key rmail-mode-map "e" 'rmail-extract-rejected-message))))

; I have modified rmail-extract-rejected-message from Raible's version -len
(defun rmail-extract-rejected-message ()
  "Create a message to be sent based on the current RMAIL message.
Any text in the RMAIL message before mail-unsend-separator is ignored.

This function can also be meaningfully used to messages that have *not*
been rejected.  Try it and see."
  (interactive)
  (rmail-beginning-of-message)
  (re-search-forward mail-unsent-separator nil t)
  (let* ((to   (rmail-get-field "To"))
	 (subj (rmail-get-field "Subject"))
	 (irp2 (rmail-get-field "In-reply-to"))
	 (cc   (rmail-get-field "Cc"))
	 (orig-message (buffer-substring
			(progn (re-search-forward "\n\n") (point))
			(point-max)))
	 (mail-setup-hook
	  (function
	   (lambda ()
	     (goto-char (point-max))
	     (insert orig-message)
	     (goto-char (point-min))
	     (insert
	      "X-Resent: ==== RESENT ====                ==== RESENT ====\n")
	     (mail-to)))))
    (rmail-beginning-of-message)
    (rmail-add-label "resent")		;added tower
    (mail-other-window nil to subj irp2 cc (current-buffer))
    (mail-insert-headers-tower)
    (goto-char (point-min))
    (if (mail-fetch-field "From")
	(progn (mail-position-on-field "From")
	       (re-search-backward "^From:" nil t ) (insert "Was-")))
    (goto-char (point-min))
    (if (mail-fetch-field "To")
	(progn (mail-position-on-field "To")
	       (re-search-backward "^To:" nil t ) (insert "Was-")))
    (goto-char (point-min))
    (if (mail-fetch-field "Cc")
	(progn (mail-position-on-field "Cc")
	       (re-search-backward "^Cc:" nil t ) (insert "Was-")))
    (mail-position-on-field "To") (insert "tower")
    (forward-char -5)))

(defun rmail-get-field (field-name)
  (save-excursion
    (let ((case-fold-search t))
      (if (re-search-forward (concat "^" field-name ": ") nil t)
	  (buffer-substring (point) (progn (end-of-line) (point)))))))
;;; end of extract

(defun compile-in-buffer (command another &optional dir)
  "compile-command COMMAND with the output in buffer *COMMAND*,
deleting it if it exists, first.
If ANOTHER is t wait for the COMMAND to finish before exiting (in case
we want to start up another compile-command).
If DIR is defined, cd to it first.
Often, used in ~/.emacs to examine system queues."
  (interactive)
  (let ((cbname (concat "*" command "*")))
    (switch-to-buffer "*compilation*")
    (if dir
	(cd dir))
    (compile command)
    (goto-char (point-min))
    (kill-buffer(get-buffer-create cbname))
    (rename-buffer cbname)
					; attempt to get rid of 2nd window on buffer cbname
    ;;    (bury-buffer (get-buffer cbname)) ; instead:
    (delete-other-windows)
    (if another
	(while (eq (process-status compilation-process) 'run)
	  (sleep-for 1)))))

(defun grep-in-buffer (args another &optional dir)
  "grep ARGS with the output in buffer *grep ARGS /dev/null*,
deleting it if it exists.
If ANOTHER is t wait for the grep to finish before exiting (in case
we want to start up another grep).  If DIR is defined, cd to it first.
Often, used in ~/.emacs to examine system logs."
  (compile-in-buffer (concat "grep -n " args " /dev/null") another dir))

(defun sh-n-buffer ()
  "pipe buffer through 'sh -n'"
  (interactive)
  (shell-command-on-region
   (point-min) (point-max) "sh -n" nil))

(defun bash-n-buffer ()
  "pipe buffer through 'bash -n'"
  (interactive)
  (shell-command-on-region
   (point-min) (point-max) "bash -n" nil))

(defun csh-n-buffer ()
  "pipe buffer through 'csh -nf'"
  (interactive)
  (shell-command-on-region
   (point-min) (point-max) "csh -nf" nil))

(defun cleanup-aliases-include-file ()
  "in a sendmail aliases :include: file,
formats one address per line, and removes unnecessary white space and commas
@@@BUG: handles \"nobody (address)\" wrong"
  (interactive)
  (setq fill-column 1)
  (goto-char (point-min))
  (replace-regexp "^[ 	]*" "" nil)
  (picture-mode)
  (picture-mode-exit)
  (goto-char (point-min))
  (replace-regexp ",$" "" nil)
  (goto-char (point-min))
  (fill-paragraph 1)
  (delete-matching-lines "^$")
  (save-buffer)
  (let ((bfn buffer-file-name))
    (find-alternate-file bfn)		;want a duplicate set of the addresses
    (goto-char (point-max))		;as the aliases backups had them
    (insert "\n\n\n")
    (goto-char (point-min))
    (delete-matching-lines "^$")
    (save-buffer)))

(defun rvsort-buffer ()
  "pipe buffer through 'revsort' script"
  (interactive)
  (let ((start-count (count-lines (point-min) (point-max))))
    (shell-command-on-region (point-min) (point-max) "revsort" t)
    (recenter -1)
    (message "revsort done: %d/%d lines before/after."
	     start-count (count-lines (point-min) (point-max)))))

(defun switch-if-bufferp (buffer-maybe)
  "If BUFFER-MAYBE exists, select it in the current window"
	   (if (bufferp (get-buffer buffer-maybe))
	       (switch-to-buffer buffer-maybe)
	     (message "buffer " %s "doesn't exist" buffer-maybe)))

;; Roland and Noah winnage:
(defun ivc-checkin-add-log ()
  (or (string-match "\.texi\(nfo\)?$" buffer-file-name)
      (let ((log (find-change-log)))
        (and log
             (file-exists-p log)
             (y-or-n-p (format "Update %s for %s changes? "
                               (file-relative-name log)
                               (file-relative-name buffer-file-name)))
             (progn
               (save-excursion (set-buffer (find-file-noselect log))
                               (setq buffer-read-only nil))
               (vc-comment-to-change-log nil log))))))

(add-hook 'vc-checkin-hook 'ivc-checkin-add-log)

;;(autoload 'html-mode "html-mode" "HTML major mode." t)
;;(or (assoc "\\.html$" auto-mode-alist)
;;   (setq auto-mode-alist (cons '("\\.html$" . html-mode)
;;                               auto-mode-alist)))
;;(or (assoc "\\.htm$" auto-mode-alist)
;;   (setq auto-mode-alist (cons '("\\.htm$" . html-mode)
;;                               auto-mode-alist)))
(autoload 'html-helper-mode "html-helper-mode" "HTML major mode." t)
(or (assoc "\\.html$" auto-mode-alist)
   (setq auto-mode-alist (cons '("\\.html$" . html-helper-mode)
                               auto-mode-alist)))
(or (assoc "\\.htm$" auto-mode-alist)
   (setq auto-mode-alist (cons '("\\.htm$" . html-helper-mode)
                               auto-mode-alist)))

(defun tower-html-helper-default-insert-timestamp ()
  "tower's timestamp insertion function"
  (let ((cst  	  (current-time-string)))
  (insert (substring cst 8 10) (substring cst 3 7) (substring cst 19 24)
	  " " user-login-name "\n")))

(if (equal (getenv "HOST") "gnudist")
    (load-file-if-exists (expand-file-name "~www/.emacs")))

(setq html-helper-mode-hook		;also html-helper-load-hook
      (function
       (lambda ()
	 (progn
	   (if (file-exists-p (expand-file-name "~/bin/dohtmlchek"))
	     (progn
	       (make-local-variable 'compile-command)
	       (setq compile-command
;;;;;;;;;;;;;;;;;;;;;(concat "/usr/local/bin/htmlchek ")
		     (concat (expand-file-name "~/bin/dohtmlchek")
			     " "
			     buffer-file-name))))
	   (setq html-helper-timestamp-hook
		 'tower-html-helper-default-insert-timestamp)
	   (setq html-helper-build-new-buffer t)
	   (setq html-helper-do-write-file-hooks t)
	   (setq html-helper-address-string
		 "<a href=\"http://www.ai.mit.edu/~tower/\">Len Tower</a><a href=\"mailto:tower@ai.mit.edu\">tower@ai.mit.edu</a>")
	   (setq tempo-interactive t)
	   (setq tempo-insert-string-functions 'upcase)
	   (setq tempo-insert-string-hook tempo-insert-string-functions)
	   ))))

; w3 maintainer: wmperry@spry.com
(setq w3-load-hook			;other w3-hooks exist
      (function
       (lambda ()
         (progn
	   (setq fill-column	78
;;being fixed:		 url-pgp/pem-entity user-mail-address
		 w3-show-headers t
		 w3-setup-done	t	;prevents w3-fetch/w3-do-setup
					; endlessly looping
		 )
;;	   (w3-fetch "http://www.gnu.ai.mit.edu")
;;	   (w3-fetch "http://www.art.net/whats_new.html")
;;	   (w3-fetch "http://www.lpf.org/Whatsnew/whatsnew.html")
;;;;	   (w3-fetch "http://sun4.cfcl.com:8873/")
;;	   (w3-fetch "http://www.ptf.com/")
;;	   (w3-fetch "http://www.delorie.com/gnu/")
	   ))))

;; EOF
