home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / gin-mode.el < prev    next >
Encoding:
Text File  |  1989-06-18  |  6.5 KB  |  183 lines

  1. ;To: unix-emacs@bbn.com
  2. ;Date: 16 May 89 17:01:35 GMT
  3. ;From: Martin Neitzel <infbs.UUCP!neitzel@eddie.mit.edu>
  4. ;Sender: arpa-unix-emacs-request@bbn.com
  5. ;Subject: gin-mode.el, witchcraft for fill-prefix
  6. ;Organization: TU Braunschweig,Informatik,West Germany
  7. ;Source-Info:  From (or Sender) name not authenticated.
  8. ;
  9. ;[a description of gin-mode follows the copyright stuff.]
  10. ;
  11. ;Please note:
  12. ;This is my first self-made minor-mode.  It runs quite smoothly here
  13. ;for some weeks now, but some parts of the code at least *look* arkward
  14. ;to me.  Everything is based on the suggestions given in the old '88
  15. ;version of the elisp manual.  It was a big help.  If something with
  16. ;gin-mode.el is wrong, it might be wise to extend the manual, but any
  17. ;blame goes to me, of course.
  18. ;
  19. ;                            Martin Neitzel
  20.  
  21. ;; gin-mode.el -- Set up minor mode with guess-indent stuff.
  22. ;; Copyright (C) Martin Neitzel, May 1989
  23.  
  24. ;; This file is not yet part of GNU Emacs.
  25.  
  26. ;; GNU Emacs is distributed in the hope that it will be useful,
  27. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  28. ;; accepts responsibility to anyone for the consequences of using it
  29. ;; or for whether it serves any particular purpose or works at all,
  30. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  31. ;; License for full details.
  32.  
  33. ;; Everyone is granted permission to copy, modify and redistribute
  34. ;; GNU Emacs, but only under the conditions described in the
  35. ;; GNU Emacs General Public License.   A copy of this license is
  36. ;; supposed to have been given to you along with GNU Emacs so you
  37. ;; can know your rights and responsibilities.  It should be in a
  38. ;; file named COPYING.  Among other things, the copyright notice
  39. ;; and this notice must be preserved on all copies.
  40.  
  41.  
  42. ;; SUMMARY
  43. ;;
  44. ;; Gnu Emacs supports filling of paragraphs and wrapping of lines with a
  45. ;; settable string to be used for the left margin, the variable
  46. ;; ``fill-prefix''.  Setting this variable by hand is fine, but can
  47. ;; become mildly annoying if it has to be changed often in a document.
  48. ;; However, the appropriate value for fill-prefix can be derived from
  49. ;; the layout of the current line in almost all cases.
  50. ;;
  51. ;; This is a minor mode that ``guesses'' the indentation to be used
  52. ;; for (auto-) filling.  It has proven to be very handy in all text-mode
  53. ;; variants.  It uses a simple but effective heuristic to guess a
  54. ;; fill-prefix based on the current line and two (configurable) regular
  55. ;; expressions.  I almost never have to use "^X." explicitly anymore.
  56. ;; 
  57. ;; The two regexps control
  58. ;; 
  59. ;;     * what line beginnings have to be taken as "fill-prefix" (my
  60. ;;       standard setup recognizes initial white space and typical
  61. ;;       mail-prefixes like ">" or "name> ").
  62. ;; 
  63. ;;     * what line beginnings are really hanging indents.  The
  64. ;;       standard setup recognizes the stars used right here,
  65. ;;       enumerations, and some more...
  66.  
  67. ;; The guessing stuff
  68.  
  69. (provide 'gin-mode)
  70.  
  71. (defvar gin-left-hang-indent-re
  72.   "\\s *\\([-*]\\|([a-zA-Z0-9])\\|[a-zA-Z0-9]\\.?:]?\\)\\s +"
  73.   "*Regexp that defines a hanging indent of a paragraph.
  74. If it is seen by gin-guess-prefix, the next lines are indented with
  75. white space beyond the hanging indent.  Setting this variable makes
  76. it buffer-local.")
  77.  
  78. (defvar gin-retain-indent-re
  79.   "[a-zA-Z]*>+[ \t]*\\|[ \t]+"
  80.   "*Regexp that defines how a fill-prefix can look like.
  81. If such a string is seen by gin-guess-prefix in the current line,
  82. the next line will be indented with it, too.  Setting this variable
  83. makes it buffer-local.")
  84.  
  85. (defun gin-guess-prefix ()
  86.   "Try to figure out the prefix for the next line."
  87.   (save-excursion
  88.     (beginning-of-line)
  89.     (cond ((looking-at gin-left-hang-indent-re)
  90.        (let ((beg (point))
  91.          indent-size
  92.          (indent-prefix ""))
  93.          (re-search-forward gin-left-hang-indent-re)
  94.          (setq indent-size (current-column))
  95.          ;; First gather tabs as needed ...
  96.          (if indent-tabs-mode
  97.          (while (>= indent-size tab-width)
  98.            (setq indent-prefix (concat indent-prefix "\t"))
  99.            (setq indent-size (- indent-size tab-width))))
  100.          ;; ... then append the rest as spaces:
  101.          (while (> indent-size 0)
  102.            (setq indent-prefix (concat indent-prefix " "))
  103.            (setq indent-size (1- indent-size)))
  104.          indent-prefix))
  105.  
  106.       ((looking-at gin-retain-indent-re)
  107.        (buffer-substring (match-beginning 0) (match-end 0)))
  108.  
  109.       (t ""))))
  110.  
  111.  
  112.  
  113. ;; Replacements for old functions dealing with the fill-prefix.
  114. ;; Their function values are stuffed into the original symbols.
  115.  
  116. (defun gin-fill-paragraph (arg)
  117.   "fill-paragraph in Gin mode, tries to guess the appropriate fill-prefix.
  118. With arg, also justify."
  119.   (interactive "P")
  120.   (if gin-mode
  121.       (let ((fill-prefix (gin-guess-prefix)))
  122.     (funcall 'gin-old-fill-paragraph arg))
  123.     (funcall 'gin-old-fill-paragraph arg)))
  124.  
  125. (defun gin-do-auto-fill()
  126.   (if gin-mode
  127.       (let ((fill-prefix (gin-guess-prefix)))
  128.     (funcall 'gin-old-do-auto-fill))
  129.     (funcall 'gin-old-do-auto-fill)))
  130.  
  131.  
  132.  
  133. ;; When loaded for the first time, install our minor mode indicator
  134.  
  135. (defconst gin-old-fill-paragraph nil
  136.   "Keeps the true fill-paragraph function during Gin mode.")
  137.  
  138. (defconst gin-old-do-auto-fill nil
  139.   "Keeps the true do-auto-fill function during Gin mode.")
  140.  
  141. (defun gin-overlay-functions()
  142.   "Undermine emacs with Gin stuff."
  143.   (fset 'fill-paragraph (symbol-function 'gin-fill-paragraph))
  144.   (fset 'do-auto-fill (symbol-function 'gin-do-auto-fill)))
  145.  
  146. (defun gin-restore-originals ()
  147.   "Throw gin-mode functions out everywhere."
  148.   (fset 'fill-paragraph (symbol-function 'gin-old-fill-paragraph))
  149.   (fset 'do-auto-fill (symbol-function 'gin-old-do-auto-fill)))
  150.  
  151. (if (boundp 'gin-mode)
  152.     nil
  153.   (setq minor-mode-alist (cons '(gin-mode " Gin") 
  154.                    minor-mode-alist))
  155.   (make-variable-buffer-local 'gin-mode)
  156.   (set-default 'gin-mode nil)
  157.   (make-variable-buffer-local 'gin-left-hang-indent-re)
  158.   (make-variable-buffer-local 'gin-retain-indent-re)
  159.   (fset 'gin-old-fill-paragraph (symbol-function 'fill-paragraph))
  160.   (fset 'gin-old-do-auto-fill (symbol-function 'do-auto-fill))
  161.   (gin-overlay-functions))
  162.  
  163.   
  164.  
  165. (defun gin-mode (arg) 
  166.   "Minor mode to guess indentations.
  167. Toggle gin-mode, or turn it on iff optional ARG is positiv.
  168.  
  169. Gin mode adds the capability to \"guess\" a suitable indent for
  170. filling based on the current line.  The line is matched against the
  171. two regexps 'gin-left-hang-indent-re' and 'gin-retain-indent-re', see
  172. their documentation.
  173.  
  174. When Gin mode is active, auto-filling and fill-paragraph will both use
  175. a \"guessed\" value as fill-prefix."
  176.  
  177.   (interactive "P")
  178.   (setq gin-mode
  179.     (if (null arg) (not gin-mode)
  180.       (> (prefix-numeric-value arg) 0)))
  181.   (set-buffer-modified-p (buffer-modified-p)))
  182.  
  183.