;;; fill-colons.el --- wrapper for fill-region-as-paragraph

;; Author: Noah Friedman <friedman@prep.ai.mit.edu>
;; Maintainer: friedman@prep.ai.mit.edu
;; Keywords: extensions
;; Created: 1995-11-22
;; Public domain

;; $Id: fill-colons.el,v 1.1 1995/11/22 23:41:51 friedman Exp $

;;; Commentary:

;; fill-region-as-paragraph preserves two spaces after the end of
;; sentences, but it only leaves a single space after colons.
;; This wrapper finds colons (and other chars as specified below), saves
;; them and converts them to periods, then calls the original fill
;; function.  Then it restores the characters at those saved positions.
;; The effect of all this is to preserve double spaces after colons.

;;; Code:

(defvar my-fill-region-as-paragraph-double-space-chars '(?:))

(or (fboundp 'my-fill-region-as-paragraph-orig)
    (fset 'my-fill-region-as-paragraph-orig
          (symbol-function 'fill-region-as-paragraph)))

(defun my-fill-region-as-paragraph (from to &optional justify &rest args)
  (interactive (list (region-beginning) (region-end)
		     (if current-prefix-arg 'full)))
  (let ((orig-buffer-modified-p (buffer-modified-p))
        (match-data (match-data))
        (insert-fn (if (fboundp 'insert-before-markers-and-inherit)
                       'insert-before-markers-and-inherit
                     'insert-before-markers))
        (replacements nil)
        (re (concat "["
                    (mapconcat 'char-to-string
                               my-fill-region-as-paragraph-double-space-chars
                               "")
                    "]"))
        return-result
        buffer-modified-p
        marker
        )
    (unwind-protect
        (progn
          (save-excursion
            (save-restriction
              (narrow-to-region from to)
              (goto-char (point-min))
              (while (re-search-forward re nil t)
                (backward-char 1)
                (setq marker (point-marker))
                (setq replacements (cons (cons marker (char-after marker))
                                         replacements))
                (funcall insert-fn ".")
                (delete-char 1))))
          (set-buffer-modified-p nil)
          (setq return-result
                (if (interactive-p)
                    (call-interactively 'my-fill-region-as-paragraph-orig)
                  (apply 'my-fill-region-as-paragraph-orig
                         from to justify args))))
      (save-excursion
        (save-restriction
          (setq buffer-modified-p (buffer-modified-p))
          (widen)
          (while replacements
            (goto-char (1- (car (car replacements))))
            (funcall insert-fn (cdr (car replacements)))
            (delete-char 1)
            (setq replacements (cdr replacements)))
          ;; If buffer was not modified by orig fill function, restore
          ;; the original buffer modification state
          (or buffer-modified-p
              (set-buffer-modified-p orig-buffer-modified-p)))))
      return-result))

(fset 'fill-region-as-paragraph 'my-fill-region-as-paragraph)

;; fill-colons.el ends here
