home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / gnu / emacs / sources / 896 < prev    next >
Encoding:
Internet Message Format  |  1992-12-21  |  21.4 KB

  1. Path: sparky!uunet!spool.mu.edu!agate!agate.berkeley.edu!dodd
  2. From: dodd@mycenae.cchem.berkeley.edu (Lawrence R. Dodd)
  3. Newsgroups: gnu.emacs.sources
  4. Subject: update for mode-line.el (v 2.50)
  5. Date: 19 Dec 92 14:40:20
  6. Organization: Dept of Chemical Engineering, Polytechnic Univ, NY, USA
  7. Lines: 545
  8. Distribution: gnu
  9. Message-ID: <DODD.92Dec19144020@mycenae.cchem.berkeley.edu>
  10. NNTP-Posting-Host: mycenae.cchem.berkeley.edu
  11. Summary: v 2.50 of mode-line.el, more robust
  12. Keywords: mode line, abbreviated file paths
  13.  
  14.  
  15. Hello,
  16.  
  17.   Here is the latest release of mode-line.el (version 2.50). This version
  18.   fixes a couple of bugs that make mode-line.el much more robust than any of
  19.   the earlier versions.  Also added is a toggle feature to scroll through
  20.   various mode line displays (bound to C-c C-t).
  21.  
  22.                      share and enjoy,
  23.                             Larry
  24.                             dodd@roebling.poly.edu
  25.                    
  26. P.S. Happy holidays.
  27.  
  28. <file: ~/lisp/mode-line.el>
  29. ........................... cut along dotted line ...........................
  30. ;; mode-line.el - code for including abbreviated file paths in mode line
  31.  
  32. (defconst mode-line-version (substring "$Revision: 2.50 $" 11 -2)
  33.   "$Id: mode-line.el,v 2.50 1992/12/19 22:30:50 dodd Stable $")
  34.  
  35. ;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  36. ;;
  37. ;; This program is free software; you can redistribute it and/or modify
  38. ;; it under the terms of the GNU General Public License as published by
  39. ;; the Free Software Foundation; either version 1, or (at your option)
  40. ;; any later version.
  41. ;;
  42. ;; This program is distributed in the hope that it will be useful,
  43. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  44. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  45. ;; GNU General Public License for more details.
  46. ;;
  47. ;; You should have received a copy of the GNU General Public License
  48. ;; along with this program; if not, write to the Free Software
  49. ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  50.  
  51. ;; LCD Archive Entry:
  52. ;; mode-line|Lawrence R. Dodd|dodd@roebling.poly.edu|
  53. ;; code for including abbreviated file paths in mode line|
  54. ;; $Date: 1992/12/19 22:30:50 $|$Revision: 2.50 $|~/????/mode-line.el.Z|
  55.  
  56. ;;; MAINTAINER OF mode-line.el:
  57. ;;;  
  58. ;;; Lawrence R. Dodd
  59. ;;; dodd@roebling.poly.edu
  60. ;;; 
  61. ;;; Please send bug reports, comments, suggestions, and any smart remarks
  62. ;;; concerning this code to the above e-mail address. Please be sure to
  63. ;;; mention the value of the variable `mode-line-version' *or* simply type
  64. ;;; `M-x mode-line-submit-report' and let mode-line.el do it for you.
  65.  
  66. ;;; CONTRIBUTORS TO mode-line.el:
  67. ;;;
  68. ;;; Lawrence R. Dodd
  69. ;;; dodd@roebling.poly.edu
  70. ;;;
  71. ;;; Robert McLay 
  72. ;;; mclay@cfdlab.ae.utexas.edu
  73. ;;; (for much beta-testing)
  74. ;;;
  75. ;;; Crys Rides (a.k.a., James C. Ghering) 
  76. ;;; crys@cave.tcp.com
  77. ;;; (for suggesting and testing of view-mode support)
  78.  
  79. ;;; VERSION:
  80. ;;;
  81. ;;; $LastEditDate: "Sat Dec 19 17:30:30 1992"$
  82. ;;; $Id: mode-line.el,v 2.50 1992/12/19 22:30:50 dodd Stable $
  83. ;;; $Revision: 2.50 $ 
  84.  
  85. ;;; HISTORY:
  86. ;;; 
  87. ;;; Derived from prettymodeln.el.  That file was checked in as version 2.1 of
  88. ;;; mode-line.el.  This is a cleaned, debugged, and more robust version of
  89. ;;; that original code containing with more features and more documentation. I
  90. ;;; would have named this prettymodeln++.el but that is too many letters and I
  91. ;;; besides I hack Fortran.
  92. ;;;
  93. ;;; AUTHOR OF prettymodeln.el: 
  94. ;;; 
  95. ;;; Andy Gaynor (a.k.a., Silver)
  96. ;;; gaynor@paul.rutgers.edu ...!rutgers!paul.rutgers.edu!gaynor
  97. ;;; 
  98. ;;;                               _   /|  Splthlt...
  99. ;;;                    Ahckthph!  \`o_@'
  100. ;;;                                 (_)
  101. ;;;                                  U   Ptooey!
  102. ;;;
  103. ;;; Created: 13 Sep 87 18:34:59 GMT
  104.  
  105. ;;; INSTALLATION/USAGE:
  106. ;;;
  107. ;;;   o  save as mode-line.el in the GNU emacs load-path
  108. ;;;   o  stick this in your ~/.emacs:
  109. ;;;
  110. ;;;                (require 'mode-line) 
  111. ;;;   
  112. ;;;   o  use C-c C-t to scroll through different mode lines manually
  113. ;;;      (with argument it will scroll through automatically)
  114.  
  115. ;;; ADVANCED USAGE:
  116. ;;;
  117. ;;;   o  same as above but also stick something _like_ the following inside 
  118. ;;;      your ~/.emacs:
  119. ;;; 
  120. ;;;   (setq file-name-abbreviation-alist
  121. ;;;         (list 
  122. ;;;          (cons  (concat "^" (expand-file-name "~") 
  123. ;;;                         "/" "special/")  "special:")
  124. ;;;          (cons  (concat "^" (expand-file-name "~") "/")  "~/")
  125. ;;;          '("^/dodd@roebling.poly.edu:/home/dodd/" . "Roebling:")
  126. ;;;          '("^/joe@\\([a-zA-Z0-9.]*\\).\\(edu\\|gov\\):/home/joe/" . "\\1:")
  127. ;;;          '("^.*/\\([^/]*/\\)" . "\\1")))  
  128. ;;; 
  129. ;;; The explanation of above is as follows. If I am editing a file called
  130. ;;; `filename' this list of associations will be attempted in this order: if
  131. ;;; the full path to `filename' is
  132. ;;; 
  133. ;;; (1) `/myhomedirectory/special/filename' display as `special:filename' 
  134. ;;;      (this is useful for much used sub-sub-directories)
  135. ;;; (2) `/myhomedirectory/filename' display as `~/filename' 
  136. ;;;      (this eliminates those long paths to your home directory)
  137. ;;; (3) `/user@machine.edu:/anything/filename' display as `Machine:filename' 
  138. ;;;     (this is _extremely_ useful with ange-ftp)
  139. ;;; (4) `/user@regexp.edu:/anything/filename' display as `regexp:filename' 
  140. ;;;     (this is the same as above but attempts to use a regular expression)
  141. ;;; (5) `/snafu/barfoo/filename' display as `barfoo:filename' 
  142. ;;;     (this shows just the current directory and is done for any path that
  143. ;;;     does not match one of the above)
  144.  
  145. ;;; SEE ALSO: 
  146. ;;; 
  147. ;;; For more information on the filename associations list, after
  148. ;;; loading, do `M-x describe-variable file-name-abbreviation-alist'
  149.  
  150. ;;; MOTIVATION:
  151. ;;; 
  152. ;;; Buffer names in the mode line are not very informative. When files with
  153. ;;; the same name are being visited in different directories the mode line
  154. ;;; shows names like "Makefile," "Makefile<2>," "Makefile<3>," and so on.  The
  155. ;;; zeroth order correction is to use the file name and directory in the mode
  156. ;;; line.  However, long file names with full directory paths (for example
  157. ;;; /u2/luser/foobar/bletch/src/0.1/foobar/Makefile) in the mode line are a
  158. ;;; pain in the ass.  They suck up the whole mode line, and are a strain on
  159. ;;; the eyes to differentiate. We would like to display things like
  160. ;;; "foobar/Makefile," "barfoo/Makefile," "conserve/Makefile," and so on in
  161. ;;; the mode line.
  162. ;;;
  163. ;;; You will find here a mode line formatting scheme that is fairly nice.  It
  164. ;;; displays the buffer name if the buffer is not associated with a file.
  165. ;;; Otherwise, it displays the file name, but only after abbreviating it as
  166. ;;; per a list of abbreviations that you provide.
  167.  
  168. ;;; LOGIC: 
  169. ;;; 
  170. ;;; Set up the mode line by making mode-line-buffer-identification local to
  171. ;;; every buffer.  Various hooks will abbreviate the buffer-file-name to
  172. ;;; something a little easier to read.
  173. ;;; 
  174. ;;;   `buffer-file-name' == the original file name   
  175. ;;;   `file-name-abbreviation-alist' == list of abbreviations
  176. ;;;   `abbreviate-mode-line-buffer-identification' == what hooks call      
  177. ;;;   `string-replace-regexp-in-alist' == means of abbreviation
  178.  
  179. ;;; KNOWN BUG WITH SUGGESTED PATCH:
  180. ;;; 
  181. ;;;   Sebastian Kremer's Tree Dired (v 6.0, available via anonymous ftp from
  182. ;;;   ftp.uni-koeln.de[134.95.80.1]:/pub/gnu/emacs/diredall.tar.Z) is an
  183. ;;;   improvement over the distribution dired for reasons too numerous to
  184. ;;;   mention. One major improvement is that Kremer's Dired correctly renames
  185. ;;;   any buffers visiting a file that is renamed using dired-mode.
  186. ;;; 
  187. ;;;   Unfortunately, it uses `set-visited-file-name' in the function
  188. ;;;   `dired-rename-file', which does not use `write-hooks'. The result being
  189. ;;;   that while the buffer is renamed, the mode line is not updated properly
  190. ;;;   after a dired-do-move (key r).  The patch is to force a call to
  191. ;;;   `abbreviate-mode-line-buffer-identification' after the call to
  192. ;;;   `set-visited-file-name' in the function `dired-rename-file':
  193. ;;;
  194. ;;;      (defun dired-rename-file (from to ok-flag)
  195. ;;;                                ...
  196. ;;;                        [material not shown]
  197. ;;;                                ...
  198. ;;;              (let ((modflag (buffer-modified-p)))
  199. ;;;                (set-visited-file-name to)   ; kills write-file-hooks
  200. ;;;     +          ;; for mode-line.el
  201. ;;;     +          (and (memq 'abbreviate-mode-line-buffer-identification
  202. ;;;     +                     write-file-hooks)
  203. ;;;     +                 (abbreviate-mode-line-buffer-identification)) 
  204. ;;;                (set-buffer-modified-p modflag))))
  205. ;;;                                ...
  206. ;;;                        [material not shown]
  207. ;;;                                ...
  208.  
  209. ;;; We need to load the default `view' package (be it view.el or new-view.el)
  210. ;;; so that `view-hook' will be defined when we append to it below.
  211.  
  212. (require 'view)
  213.  
  214. ;;; We need to use kill-fix.el, by Joe Wells (jbw@cs.bu.edu), in order to
  215. ;;; preserve some mode-line's variables when the major mode of a buffer is
  216. ;;; changed. The next section contains a copy of kill-fix.el.  The copyright
  217. ;;; notice at the top of this file should be considered as a replacement for
  218. ;;; the one found in kill-fix.el.
  219.  
  220. ;;; Note that instead of this page, the statement "(require 'kill-fix)" could
  221. ;;; be used if the the user already has a copy of kill-fix.el. That code is
  222. ;;; available via anonymous ftp to archive.cis.ohio-state.edu [128.146.8.52]
  223. ;;; in /pub/gnu/emacs/elisp-archive/as-is/kill-fix.el.Z.
  224.  
  225. ;; -----------
  226. ;; kill-fix.el - enhancement to kill-all-local-variables
  227. ;; Author: Joe Wells (jbw@cs.bu.edu)
  228. ;; Date: 18 Jan 89 22:16:15 GMT
  229.  
  230. ;; save the original subr function definition of kill-all-local-variables
  231. (or (fboundp 'original-kill-all-local-variables)
  232.     (fset 'original-kill-all-local-variables
  233.           (symbol-function 'kill-all-local-variables)))
  234.  
  235. (defun kill-all-local-variables ()
  236.   "Eliminate all the buffer-local variable values of the current
  237. buffer.  This buffer will then see the default values of all
  238. variables.  NOTE: This function has been modified to ignore
  239. buffer-local variables whose preserved property is non-nil."
  240.   (let ((oldvars (buffer-local-variables)))
  241.     (original-kill-all-local-variables)
  242.     (while oldvars
  243.       (let ((var (car (car oldvars))))
  244.         (cond ((get var 'preserved)
  245.                (make-local-variable var)
  246.                (set var (cdr (car oldvars))))))
  247.       (setq oldvars (cdr oldvars)))))
  248.  
  249. (provide 'kill-fix)
  250. ;; -----------
  251.  
  252. ;;; GENERAL DISPLAY STUFF:
  253.  
  254. ;;; This makes the mode line display the day, date, time of day, and average
  255. ;;; number of processes. The increment for time update is 30 seconds, also
  256. ;;; `Mail' appears if there is any unread mail.  Users may wish to comment
  257. ;;; this stuff out.
  258.  
  259. (setq display-time-interval 30)
  260. (setq display-time-day-and-date t)
  261. (display-time)
  262.  
  263. ;;; Customize mode-line-format and its constituents. 
  264.  
  265. ;;; Make sure you use mode-line-buffer-identification to identify the buffer
  266. ;;; in your mode-line-format.  This variable must be buffer-local (if it is
  267. ;;; not already).
  268.  
  269. ;;; Note that mode-line-buffer-identification must be used to identify the
  270. ;;; buffer.  mode-line-modified is retained because it is in emacs' own
  271. ;;; default mode-line-format, and emacs might do some clever tricks with it.
  272.  
  273. (make-variable-buffer-local 'mode-line-modified)
  274. (setq-default mode-line-modified '("%*%*-"))
  275.  
  276. (make-variable-buffer-local 'mode-line-buffer-identification)
  277. (setq-default mode-line-buffer-identification '("%b"))
  278.  
  279. ;; create a new buffer-local variable to keep track of the current state of 
  280. ;; the mode line for use by mode-line-toggle-display.
  281.  
  282. (make-variable-buffer-local 'mode-line-state)
  283.  
  284. (defvar mode-line-state "buffer-name"
  285.   "A buffer-local variable to keep track of the current state of the mode line
  286. for use by mode-line-toggle-display.")
  287.  
  288. (setq-default mode-line-state "buffer-name")
  289.  
  290. ;; KLUDGE
  291.  
  292. ;; If the user changes the major mode of a buffer the variables
  293. ;; `mode-line-buffer-identification' and `mode-line-state' are set to their
  294. ;; default values. We use Joe Wells' kill-fix.el to preserve these variables
  295. ;; when the major mode of a buffer is changed.
  296.  
  297. (put 'mode-line-buffer-identification 'preserved t)
  298. (put 'mode-line-state 'preserved t)
  299.  
  300. ;;; now the define the organization of the mode-line-format
  301.  
  302. (setq-default mode-line-format
  303.   '("--"
  304.     mode-line-modified
  305.     " "
  306.     mode-line-buffer-identification
  307.     " %[("
  308.     (-10 . mode-name) ; truncate mode name to 10 chars, it got too long - LRD
  309.     minor-mode-alist
  310.     "%n"
  311.     mode-line-process
  312.     " "
  313.     (-3 . "%p") ; make string at most 3 chars: `Top', `Bot', or `nn%' - LRD
  314.     ")%] "
  315.     global-mode-string
  316.     " %-"))
  317.  
  318. ;;; A big thankyou to Robert McLay (mclay@cfdlab.ae.utexas.edu) for help with
  319. ;;; the following - LRD.
  320.  
  321. ;;; Form home directory with a leading `^' and trailing `/' so if your home
  322. ;;; directory is /home/machine/user-name then home-dir is
  323. ;;; `^/home/machine/user-name/' (without the quotes) The leading `^' is need
  324. ;;; to match the leading end of the string.
  325.  
  326. ;;; (originally was not a user option because it was missing the `*' - LRD)
  327.  
  328. (defvar file-name-abbreviation-alist
  329.       (list 
  330.        (cons  (concat "^" (expand-file-name "~") "/")  "~/"))
  331.  
  332.   "*Alist of embedded filename patterns versus the corresponding desired
  333. abbreviations. Each element is of the form (<regexp> . <to-string>).
  334.  
  335. The package mode-line.el goes down this alist looking for matches to regular
  336. expression <regexp> in the full pathname of the file and replaces it with
  337. <to-string>.  This is then repeated for all <regexp> in the list. This fact
  338. can be exploited in forming the regular expressions. However, since the
  339. searching and replacing is done top-down, special cases should be put at the
  340. head of the list.
  341.  
  342. Examples:
  343.  
  344.   If the user often plays with the files in /u2/luser/foobar/bletch.
  345.   What the user may want to do is replace leading instances of this
  346.   path with just `bletch.'  To do this stick the association into
  347.   the alist
  348.  
  349.      (\"^/u2/luser/foobar/bletch\" . \"bletch\")
  350.  
  351.   Another good association is to display only the last directory in
  352.   the path if no other special case applies. This is done with the
  353.   following association
  354.  
  355.      (\"^.*/\\([^/]*/\\)\" . \"\\1\")
  356.  
  357.   Finally, one can also abbreviate those long filenames that result
  358.   when using ange-ftp
  359.  
  360.      (\"^/emily@roebling.poly.edu:/home/emily/\" . \"Roebling:\")
  361.  
  362.   The default entry for this variable removes the home directory
  363.   path and replaces it with ~/
  364.  
  365.      (cons  (concat \"^\" (expand-file-name \"~\") \"/\")  \"~/\")")
  366.  
  367. ;;;; DEFUNS
  368.  
  369. ;;; the function that makes the substitutions - this is the work-horse
  370.  
  371. (defun string-replace-regexp-in-alist (string replacement-alist)
  372.  
  373.    "Given a string STRING, replace *each* instance of <regexp> (cars of elements
  374. in REPLACEMENT-ALIST) with <to-string> (cdrs of elements in REPLACEMENT-ALIST)
  375. and return the new string. The above is different from simply replacing the
  376. first match in the alist and then leaving. This is why a temporary buffer is
  377. used."
  378.  
  379.    (save-excursion
  380.        
  381.      (let 
  382.  
  383.          ;; VARLIST - we need to generate a unique name for temporary buffer
  384.          ;; (originally just used `!@#$%^&*' which, believe or not, might not be
  385.          ;; unique - LRD)
  386.  
  387.          ((temp-buffer (get-buffer-create (make-temp-name "!@#$%^&*")))
  388.           (temp-alist replacement-alist) ; don't mess with incoming alist
  389.           (new-string)) ; this is the value to be returned 
  390.  
  391.        ;; create temporary buffer
  392.        (set-buffer temp-buffer)
  393.        
  394.        ;; insert incoming string (name of filename with full path name)
  395.        (insert string)
  396.        
  397.        ;; we want to make sure the temporary buffer is killed
  398.        (unwind-protect
  399.            
  400.            ;; BODY
  401.            (progn
  402.              
  403.              ;; walk down `temp-alist', removing as we go, until it is empty
  404.              (while temp-alist
  405.                
  406.                ;; go to beginning of temporary buffer
  407.                (goto-char (point-min))
  408.                
  409.                ;; search the temporary buffer for every occurrence of the
  410.                ;; regular expression stored in `(car (car temp-alist))' and
  411.                ;; replace it with the one stored in `(cdr (car temp-alist))'
  412.                ;; (code originally used replace-regexp - LRD)
  413.                
  414.                (while (re-search-forward (car (car temp-alist)) nil t)
  415.                  (replace-match (cdr (car temp-alist))))
  416.                
  417.                ;; decrement temp-alist and restart while-loop
  418.                (setq temp-alist (cdr temp-alist)))
  419.              
  420.              ;; set return string to what remains in the temporary buffer
  421.              (setq new-string (buffer-string)))
  422.          
  423.          ;; CLEAN UP - no matter what happens, remove the temporary buffer
  424.          (kill-buffer temp-buffer))
  425.      
  426.      ;; return value of converted string
  427.      new-string)))
  428.  
  429. ;;; function that creates the abbreviated identification and is called by the
  430. ;;; various hooks (originally returned non-nil values - LRD)
  431.  
  432. (defun abbreviate-mode-line-buffer-identification ()
  433.  
  434.   "Abbreviates mode-line-buffer-identification locally using the function
  435. string-replace-regexp-in-alist and the alist file-name-abbreviation-alist.
  436. This function will return nil always. This is needed for view-mode since it
  437. will call this function even if it is not visiting a file and its return value
  438. needs to be predictable (as opposed to garbage). A nil return is also needed
  439. for the write-file-hooks."
  440.  
  441.   (if buffer-file-name
  442.       (progn
  443.         (setq mode-line-buffer-identification
  444.               (list
  445.                (string-replace-regexp-in-alist buffer-file-name
  446.                                                file-name-abbreviation-alist)))
  447.         (setq mode-line-state "abbrev-file-name"))
  448.     (setq mode-line-state "buffer-name"))
  449.   ;; always return nil
  450.   nil)
  451.  
  452. ;;;; HOOKS
  453.  
  454. ;;; Add abbreviate-mode-line-buffer-identification to find-file-hooks,
  455. ;;; write-file-hooks, and view-hook but only if it has not been added already
  456. ;;; (originally overwrote find-file-hooks - LRD).
  457.  
  458. (or (memq 'abbreviate-mode-line-buffer-identification find-file-hooks)
  459.     (setq find-file-hooks
  460.           (append find-file-hooks
  461.                   '(abbreviate-mode-line-buffer-identification))))
  462.  
  463. (or (memq 'abbreviate-mode-line-buffer-identification view-hook)
  464.     (setq view-hook
  465.           (append view-hook
  466.                   '(abbreviate-mode-line-buffer-identification))))
  467.  
  468. (or (memq 'abbreviate-mode-line-buffer-identification write-file-hooks)
  469.     (setq write-file-hooks 
  470.           (append write-file-hooks
  471.                   '(abbreviate-mode-line-buffer-identification))))
  472.  
  473. ;;;; TOGGLE 
  474.  
  475. (define-key global-map "\C-c\C-t" 'mode-line-toggle-display)
  476.  
  477. (defun mode-line-toggle-display (arg)
  478.  
  479.   "Cycles the buffer descriptor currently being displayed in modeline. If
  480. filename is currently displayed as abbreviated, then display with full path.
  481. If full path is currently displayed, then display just the buffer name. If the
  482. buffer name is currently displayed, then display the abbreviated filename.
  483. With argument will scroll through displays automatically."
  484.  
  485.   (interactive "P")
  486.  
  487.   (if buffer-file-name
  488.  
  489.       (if arg
  490.  
  491.           ;; scroll display
  492.           (progn
  493.             (mode-line-toggle-display nil)
  494.             (sit-for 1)
  495.             (mode-line-toggle-display nil)
  496.             (sit-for 1)
  497.             (mode-line-toggle-display nil))
  498.  
  499.         ;; change display 
  500.         (progn
  501.           (if (string= mode-line-state "abbrev-file-name")
  502.               (progn (setq mode-line-buffer-identification (buffer-file-name))
  503.                      (setq mode-line-state "full-file-name"))
  504.             (if (string= mode-line-state "full-file-name")
  505.                 (progn (setq mode-line-buffer-identification '("Emacs: %b"))
  506.                        (setq mode-line-state "buffer-name"))
  507.               (progn (abbreviate-mode-line-buffer-identification)
  508.                      (setq mode-line-state "abbrev-file-name"))))
  509.         
  510.         ;; force redisplay of mode line
  511.         (set-buffer-modified-p (buffer-modified-p))))))
  512.  
  513. ;;;; BUG REPORTS
  514.  
  515. ;;; this section is provided for reports.
  516. ;;; adopted from Barry A. Warsaw's c++-mode.el
  517.  
  518. (defvar mode-line-mailer 'mail
  519.   "*Mail package to use to generate report mail buffer.")
  520.  
  521. (defconst mode-line-help-address "dodd@roebling.poly.edu"
  522.   "Address accepting submission of reports on mode-line.el.")
  523.  
  524. (defconst mode-line-maintainer "Larry"
  525.   "First name of person accepting submission of reports on mode-line.el.")
  526.  
  527. (defconst mode-line-file "mode-line.el"
  528.   "Name of file containing emacs lisp code.")
  529.  
  530. (defun mode-line-submit-report ()
  531.   "Submit via mail a report using the mailer in mode-line-mailer, filename in
  532. mode-line-file, to address in mode-line-help-address."
  533.   (interactive)
  534.   (funcall mode-line-mailer)
  535.   (insert mode-line-help-address)
  536.   (if (re-search-forward "^subject:[ \t]+" (point-max) 'move)
  537.       (insert "Report on " mode-line-file " " mode-line-version))
  538.   (if (not (re-search-forward mail-header-separator (point-max) 'move))
  539.       (progn (goto-char (point-max))
  540.              (insert "\n" mail-header-separator "\n")
  541.              (goto-char (point-max)))
  542.     (forward-line 1))
  543.   (set-mark (point)) ;user should see mark change
  544.   (insert "\n\n---------\n")
  545.   (insert (emacs-version) "\n")
  546.   (insert "code: " mode-line-file ",v " mode-line-version)
  547.   (insert "\n\n")
  548.   (insert "current value of file-name-abbreviation-alist:\n\n")
  549.   (insert (prin1-to-string file-name-abbreviation-alist))
  550.   (exchange-point-and-mark)
  551.   (insert "\n" mode-line-maintainer ",\n\n")
  552.   (message "please write the message"))
  553.  
  554. ;;;; provide the package
  555.  
  556. (provide 'mode-line)
  557. ........................... cut along dotted line ...........................
  558. <end file: ~/lisp/mode-line.el>
  559.