Mercurial > emacs
comparison lisp/textmodes/refill.el @ 32750:dd36de87245d
*** empty log message ***
author | Dave Love <fx@gnu.org> |
---|---|
date | Sun, 22 Oct 2000 16:28:19 +0000 |
parents | |
children | f7e7454c16a0 |
comparison
equal
deleted
inserted
replaced
32749:a1310ae57748 | 32750:dd36de87245d |
---|---|
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. | |
77 Set by `refill-after-change-function' in `after-change-hooks' and | |
78 unset by `refill-post-command-function' in `post-command-hooks'. This | |
79 ensures refilling is only done once per command that causes a change, | |
80 regardless of the number of after-change calls from commands doing | |
81 complex 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. | |
134 With prefix arg, turn Refill mode on iff arg is positive. | |
135 | |
136 When Refill mode is on, the current paragraph will be formatted when | |
137 changes are made within it. Self-inserting characters only cause | |
138 refilling 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 |