[comp.emacs] indentation in GNU

tale@pawl.rpi.edu (David C Lawrence) (09/08/89)

Edward Berard writes:
Edward>    1. Is there a way in emacs to create "hanging indents" like
Edward>       this one? What I would like is to be able to create a
Edward>       paragraph formatted like this one, and not have to shift
Edward>       each line, re-format, etc. myself.

In <1989Sep7.175620.16036@talos.uucp> kjones@talos.uucp (Kyle Jones) writes:
Kyle> Quite a while ago I wrote a package called "filladapt" that handles this
Kyle> correctly, and takes care of several other special cases where normal
Kyle> filling/word wrap fails.  I'll post it to the emacs groups
Kyle> today.

When I first read the request I expected Martin Neitzel (neitzel@pollux.UUCP)
to ship off a copy of gin-mode.el to Edward.  Perhaps he has; but now
that this one posting has seen about four follow-ups in the thread
perhaps it is also a good time to point out this package to the rest
of the net.  Here is Martin's summary of gin-mode:

;; Gnu Emacs supports filling of paragraphs and wrapping of lines with a
;; settable string to be used for the left margin, the variable
;; ``fill-prefix''.  Setting this variable by hand is fine, but can
;; become mildly annoying if it has to be changed often in a document.
;; However, the appropriate value for fill-prefix can be derived from
;; the layout of the current line in almost all cases.
;;
;; This package provides a function and a minor mode that ``guesses''
;; the indentation to be used for (auto-) filling.  It has proven to be
;; very handy in all text-mode variants.  It uses a simple but effective
;; heuristic to guess a fill-prefix based on the current line and two
;; (configurable) regular expressions.  Within gin-mode, I almost never
;; have to use "C-x." explicitly anymore.
;;
;; The two regexps control
;; 
;; 	* what line beginnings have to be taken as "fill-prefix" (my
;; 	  standard setup recognizes initial white space and typical
;; 	  mail-prefixes like ">" or "name> ").
;; 
;; 	* what line beginnings are really hanging indents.  The
;; 	  standard setup recognizes the stars used right here,
;; 	  enumerations, and some more...

I set gin-mode on by default in my text-mode-hook and find it very
useful.  I almost never have to muck with fill-prefix manually
anymore.  gin-mode is available in the elisp-archive on
tut.cis.ohio-state.edu under (I think) pub/gnu/emacs.

Dave
--
 (setq mail '("tale@pawl.rpi.edu" "tale@itsgw.rpi.edu" "tale@rpitsmts.bitnet"))

ecb@utrccm (ecb) (09/08/89)

on 7 Sep 89 19:15:15 GMT,
David C Lawrence <csd4.csd.uwm.edu!leah!rpi!rpi.edu!tale@bbn.COM> said:

    David> I set gin-mode on by default in my text-mode-hook and find
    David> it very useful.  I almost never have to muck with
    David> fill-prefix manually anymore.  gin-mode is available in the
    David> elisp-archive on tut.cis.ohio-state.edu under (I think)
    David> pub/gnu/emacs.

    David> Dave -- (setq mail '("tale@pawl.rpi.edu"
    David> "tale@itsgw.rpi.edu" "tale@rpitsmts.bitnet"))

Sounds nice! Could some kind soul post it for those of us who don't
have Internet access?


			Bud Boman
			(203) 727-7128
			ecb@utrccm.smc.utc.com

karl@triceratops.cis.ohio-state.edu (Karl Kleinpaste) (09/12/89)

ecb@utrccm writes:
|      David> I set gin-mode on...

|  Sounds nice! Could some kind soul post it for those of us who don't
|  have Internet access?

Please note that I don't intend to do this for any random thing people
mention.  But this is small, I'm not too busy just this instant, etc, etc...

--Karl

;To: unix-emacs@bbn.com
;Date: 16 May 89 17:01:35 GMT
;From: Martin Neitzel <infbs.UUCP!neitzel@eddie.mit.edu>
;Sender: arpa-unix-emacs-request@bbn.com
;Subject: gin-mode.el, witchcraft for fill-prefix
;Organization: TU Braunschweig,Informatik,West Germany
;Source-Info:  From (or Sender) name not authenticated.
;
;[a description of gin-mode follows the copyright stuff.]
;
;Please note:
;This is my first self-made minor-mode.  It runs quite smoothly here
;for some weeks now, but some parts of the code at least *look* arkward
;to me.  Everything is based on the suggestions given in the old '88
;version of the elisp manual.  It was a big help.  If something with
;gin-mode.el is wrong, it might be wise to extend the manual, but any
;blame goes to me, of course.
;
;							Martin Neitzel

;; gin-mode.el -- Set up minor mode with guess-indent stuff.
;; Copyright (C) Martin Neitzel, May 1989

;; This file is not yet part of GNU Emacs.

;; GNU Emacs 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
;; GNU Emacs, 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.


;; SUMMARY
;;
;; Gnu Emacs supports filling of paragraphs and wrapping of lines with a
;; settable string to be used for the left margin, the variable
;; ``fill-prefix''.  Setting this variable by hand is fine, but can
;; become mildly annoying if it has to be changed often in a document.
;; However, the appropriate value for fill-prefix can be derived from
;; the layout of the current line in almost all cases.
;;
;; This is a minor mode that ``guesses'' the indentation to be used
;; for (auto-) filling.  It has proven to be very handy in all text-mode
;; variants.  It uses a simple but effective heuristic to guess a
;; fill-prefix based on the current line and two (configurable) regular
;; expressions.  I almost never have to use "^X." explicitly anymore.
;; 
;; The two regexps control
;; 
;; 	* what line beginnings have to be taken as "fill-prefix" (my
;; 	  standard setup recognizes initial white space and typical
;; 	  mail-prefixes like ">" or "name> ").
;; 
;; 	* what line beginnings are really hanging indents.  The
;; 	  standard setup recognizes the stars used right here,
;; 	  enumerations, and some more...

;; The guessing stuff

(provide 'gin-mode)

(defvar gin-left-hang-indent-re
  "\\s *\\([-*]\\|([a-zA-Z0-9])\\|[a-zA-Z0-9]\\.?:]?\\)\\s +"
  "*Regexp that defines a hanging indent of a paragraph.
If it is seen by gin-guess-prefix, the next lines are indented with
white space beyond the hanging indent.  Setting this variable makes
it buffer-local.")

(defvar gin-retain-indent-re
  "[a-zA-Z]*>+[ \t]*\\|[ \t]+"
  "*Regexp that defines how a fill-prefix can look like.
If such a string is seen by gin-guess-prefix in the current line,
the next line will be indented with it, too.  Setting this variable
makes it buffer-local.")

(defun gin-guess-prefix ()
  "Try to figure out the prefix for the next line."
  (save-excursion
    (beginning-of-line)
    (cond ((looking-at gin-left-hang-indent-re)
	   (let ((beg (point))
		 indent-size
		 (indent-prefix ""))
	     (re-search-forward gin-left-hang-indent-re)
	     (setq indent-size (current-column))
	     ;; First gather tabs as needed ...
	     (if indent-tabs-mode
		 (while (>= indent-size tab-width)
		   (setq indent-prefix (concat indent-prefix "\t"))
		   (setq indent-size (- indent-size tab-width))))
	     ;; ... then append the rest as spaces:
	     (while (> indent-size 0)
	       (setq indent-prefix (concat indent-prefix " "))
	       (setq indent-size (1- indent-size)))
	     indent-prefix))

	  ((looking-at gin-retain-indent-re)
	   (buffer-substring (match-beginning 0) (match-end 0)))

	  (t ""))))



;; Replacements for old functions dealing with the fill-prefix.
;; Their function values are stuffed into the original symbols.

(defun gin-fill-paragraph (arg)
  "fill-paragraph in Gin mode, tries to guess the appropriate fill-prefix.
With arg, also justify."
  (interactive "P")
  (if gin-mode
      (let ((fill-prefix (gin-guess-prefix)))
	(funcall 'gin-old-fill-paragraph arg))
    (funcall 'gin-old-fill-paragraph arg)))

(defun gin-do-auto-fill()
  (if gin-mode
      (let ((fill-prefix (gin-guess-prefix)))
	(funcall 'gin-old-do-auto-fill))
    (funcall 'gin-old-do-auto-fill)))



;; When loaded for the first time, install our minor mode indicator

(defconst gin-old-fill-paragraph nil
  "Keeps the true fill-paragraph function during Gin mode.")

(defconst gin-old-do-auto-fill nil
  "Keeps the true do-auto-fill function during Gin mode.")

(defun gin-overlay-functions()
  "Undermine emacs with Gin stuff."
  (fset 'fill-paragraph (symbol-function 'gin-fill-paragraph))
  (fset 'do-auto-fill (symbol-function 'gin-do-auto-fill)))

(defun gin-restore-originals ()
  "Throw gin-mode functions out everywhere."
  (fset 'fill-paragraph (symbol-function 'gin-old-fill-paragraph))
  (fset 'do-auto-fill (symbol-function 'gin-old-do-auto-fill)))

(if (boundp 'gin-mode)
    nil
  (setq minor-mode-alist (cons '(gin-mode " Gin") 
			       minor-mode-alist))
  (make-variable-buffer-local 'gin-mode)
  (set-default 'gin-mode nil)
  (make-variable-buffer-local 'gin-left-hang-indent-re)
  (make-variable-buffer-local 'gin-retain-indent-re)
  (fset 'gin-old-fill-paragraph (symbol-function 'fill-paragraph))
  (fset 'gin-old-do-auto-fill (symbol-function 'do-auto-fill))
  (gin-overlay-functions))

  

(defun gin-mode (arg) 
  "Minor mode to guess indentations.
Toggle gin-mode, or turn it on iff optional ARG is positiv.

Gin mode adds the capability to \"guess\" a suitable indent for
filling based on the current line.  The line is matched against the
two regexps 'gin-left-hang-indent-re' and 'gin-retain-indent-re', see
their documentation.

When Gin mode is active, auto-filling and fill-paragraph will both use
a \"guessed\" value as fill-prefix."

  (interactive "P")
  (setq gin-mode
	(if (null arg) (not gin-mode)
	  (> (prefix-numeric-value arg) 0)))
  (set-buffer-modified-p (buffer-modified-p)))