aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Love2000-10-22 16:28:19 +0000
committerDave Love2000-10-22 16:28:19 +0000
commitaaaf7be7c82ab15c9171beae789f7f355bf7e459 (patch)
tree89fb73e5b5a4973f2119fe4df3ed04192fbee884
parent5392d654c4f0213b9e125b3bd87d4051058536c8 (diff)
downloademacs-aaaf7be7c82ab15c9171beae789f7f355bf7e459.tar.gz
emacs-aaaf7be7c82ab15c9171beae789f7f355bf7e459.zip
*** empty log message ***
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/textmodes/refill.el156
2 files changed, 160 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 89e4e75d7ef..0e2b2b2a62a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
12000-10-22 Dave Love <fx@gnu.org>
2
3 * textmodes/refill.el: New file.
4
12000-10-22 Andre Spiegel <spiegel@gnu.org> 52000-10-22 Andre Spiegel <spiegel@gnu.org>
2 6
3 * vc-hooks.el (vc-version-backup-file-name): New optional args 7 * vc-hooks.el (vc-version-backup-file-name): New optional args
diff --git a/lisp/textmodes/refill.el b/lisp/textmodes/refill.el
new file mode 100644
index 00000000000..ae9e41dae78
--- /dev/null
+++ b/lisp/textmodes/refill.el
@@ -0,0 +1,156 @@
1;;; refill.el --- `auto-fill' by refilling paragraphs on changes
2
3;; Copyright (C) 2000 Free Software Foundation, Inc.
4
5;; Author: Dave Love <fx@gnu.org>
6;; Keywords: wp
7
8;; This program is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2 of the License, or
11;; (at your option) any later version.
12;;
13;; This program is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with this program; if not, write to the
20;; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21;; Boston, MA 02111-1307, USA.
22
23;;; Commentary:
24
25;; Provides a mode where paragraphs are refilled after changes in them
26;; (using `after-change-hooks'). This gives something akin to typical
27;; word processor-style filling. We restrict refilling due to
28;; self-insertion to the characters which trigger auto-fill.
29
30;; It partly satisfies a todo item in enriched.el for some value of
31;; `without slowing down editing too much'. It doesn't attempt to do
32;; anything (using `window-size-change-functions'?) about resizing
33;; windows -- who cares?
34
35;; This implementation is probably fragile and missing some special
36;; cases -- not extensively tested. Yanking paragraph breaks, for
37;; instance, won't DTRT by refilling all the relevant paragraphs.
38
39;; You could do it a bit more efficiently (and robustly?) with just an
40;; auto-fill function, but that doesn't cope with changes other than
41;; through self-insertion. (Using auto-fill and after-change
42;; functions together didn't seem winning.) This could probably
43;; benefit from a less-general and faster `fill-paragraph-function',
44;; ideally as a primitive.
45
46;; The work is done in a local post-command hook but only if
47;; `refill-doit' has been set by the after-change function. Using
48;; `post-command-hooks' ensures simply that refilling only happens
49;; once per command.
50
51;; [Per Abrahamsen's maniac.el does a similar thing, but operates from
52;; post-command-hook. I don't understand the statement in it that
53;; after-change-hooks don't work for this purpose; perhaps there was
54;; some Emacs bug at the time. ISTR maniac has problems with
55;; whitespace at the end of paragraphs.]
56
57;;; Code:
58
59(defun refill-fill-paragraph (arg)
60 "Like `fill-paragraph' but don't delete whitespace at paragraph end."
61 ;; Should probably use a text property indicating previously-filled
62 ;; stuff to avoid filling before the point of change.
63 (let ((before (point)))
64 (save-excursion
65 (forward-paragraph)
66 (skip-syntax-backward "-")
67 (let ((end (point))
68 (beg (progn (backward-paragraph) (point))))
69 (goto-char before)
70 (save-restriction
71 (if use-hard-newlines
72 (fill-region beg end arg)
73 (fill-region-as-paragraph beg end arg)))))))
74
75(defvar refill-doit nil
76 "Non-nil means that `refill-post-command-function' does its processing.
77Set by `refill-after-change-function' in `after-change-hooks' and
78unset by `refill-post-command-function' in `post-command-hooks'. This
79ensures refilling is only done once per command that causes a change,
80regardless of the number of after-change calls from commands doing
81complex processing.")
82(make-variable-buffer-local 'refill-doit)
83
84(defun refill-after-change-function (beg end len)
85 "Function for `after-change-functions' which just sets `refill-doit'."
86 (unless undo-in-progress
87 (setq refill-doit t)))
88
89(defun refill-post-command-function ()
90 "Post-command function to do refilling (conditionally)."
91 (when refill-doit ; there was a change
92 ;; There's probably scope for more special cases here...
93 (cond
94 ((eq this-command 'self-insert-command)
95 ;; Respond to the same characters as auto-fill (other than
96 ;; newline, covered below).
97 (if (aref auto-fill-chars (char-before))
98 (refill-fill-paragraph nil)))
99 ((or (eq this-command 'quoted-insert)
100 (eq this-command 'fill-paragraph)
101 (eq this-command 'fill-region))
102 nil)
103 ((or (eq this-command 'newline)
104 (eq this-command 'newline-and-indent)
105 (eq this-command 'open-line))
106 ;; Don't zap what was just inserted.
107 (save-excursion
108 (beginning-of-line) ; for newline-and-indent
109 (skip-chars-backward "\n")
110 (save-restriction
111 (narrow-to-region (point-min) (point))
112 (refill-fill-paragraph nil)))
113 (widen)
114 (save-excursion
115 (skip-chars-forward "\n")
116 (save-restriction
117 (narrow-to-region (line-beginning-position) (point-max))
118 (refill-fill-paragraph nil))))
119 (t (refill-fill-paragraph nil)))
120 (setq refill-doit nil)))
121
122(defvar refill-mode nil
123 "Non-nil if Refill mode is active. Use `refill-mode' to toggle it.")
124(make-variable-buffer-local 'refill-mode)
125
126(defvar refill-mode-hook nil
127 "Normal hook run by function `refill-mode'.")
128
129(add-to-list 'minor-mode-alist '(refill-mode " Refill"))
130
131;;;###autoload
132(define-minor-mode refill-mode
133 "Toggle Refill minor mode.
134With prefix arg, turn Refill mode on iff arg is positive.
135
136When Refill mode is on, the current paragraph will be formatted when
137changes are made within it. Self-inserting characters only cause
138refilling if they would cause auto-filling."
139 nil " Refill" nil
140 ;; This provides the test for recursive paragraph filling.
141 (make-local-variable 'fill-paragraph-function)
142 (if refill-mode
143 (progn (add-hook (make-local-hook 'after-change-functions)
144 'refill-after-change-function nil t)
145 (add-hook (make-local-hook 'post-command-hook)
146 'refill-post-command-function nil t)
147 (set (make-local-variable 'fill-paragraph-function)
148 'refill-fill-paragraph)
149 (auto-fill-mode 0))
150 (remove-hook 'after-change-functions 'refill-after-change-function t)
151 (remove-hook 'post-command-hook 'refill-post-command-function t)
152 (setq fill-paragraph-function nil)))
153
154(provide 'refill)
155
156;;; refill.el ends here