home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / m / modeline.zip / MODELINE.EL next >
Text File  |  1993-03-25  |  25KB  |  637 lines

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