Mercurial > hg > xemacs-beta
comparison lisp/paragraphs.el @ 2549:9ec13301bb30
[xemacs-hg @ 2005-02-03 07:15:56 by ben]
behavior ws #5: paragraphs.el sync to 21.3
paragraphs.el: Sync to 21.3. Depends on easy-mmode in core.
author | ben |
---|---|
date | Thu, 03 Feb 2005 07:15:56 +0000 |
parents | d8c768dcca7a |
children | b880fa9b5d8a |
comparison
equal
deleted
inserted
replaced
2548:c4c8a36043be | 2549:9ec13301bb30 |
---|---|
1 ;;; paragraphs.el --- paragraph and sentence parsing. | 1 ;;; paragraphs.el --- paragraph and sentence parsing |
2 | 2 |
3 ;; Copyright (C) 1985, 86, 87, 91, 94, 95, 97, 2001 | 3 ;; Copyright (C) 1985, 86, 87, 91, 94, 95, 96, 1997, 1999, 2000, 2001 |
4 ;; Free Software Foundation, Inc. | 4 ;; Free Software Foundation, Inc. |
5 | 5 |
6 ;; Maintainer: FSF | 6 ;; Maintainer: FSF |
7 ;; Keywords: wp, dumped | 7 ;; Keywords: wp, dumped |
8 | 8 |
9 ;; This file is part of XEmacs. | 9 ;; This file is part of XEmacs. |
21 ;; You should have received a copy of the GNU General Public License | 21 ;; You should have received a copy of the GNU General Public License |
22 ;; along with XEmacs; see the file COPYING. If not, write to the Free | 22 ;; along with XEmacs; see the file COPYING. If not, write to the Free |
23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | 23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
24 ;; 02111-1307, USA. | 24 ;; 02111-1307, USA. |
25 | 25 |
26 ;;; Synched up with: FSF 19.34. | 26 ;;; Synched up with: FSF 21.3. |
27 | 27 |
28 ;;; Commentary: | 28 ;;; Commentary: |
29 | 29 |
30 ;; This file is dumped with XEmacs. | 30 ;; This file is dumped with XEmacs. |
31 | 31 |
35 ;; 06/11/1997 - Use char-(after|before) instead of | 35 ;; 06/11/1997 - Use char-(after|before) instead of |
36 ;; (following|preceding)-char. -slb | 36 ;; (following|preceding)-char. -slb |
37 | 37 |
38 ;;; Code: | 38 ;;; Code: |
39 | 39 |
40 (defvar use-hard-newlines nil | 40 (defgroup paragraphs nil |
41 "Non-nil means to distinguish hard and soft newlines. | 41 "Paragraph and sentence parsing." |
42 When this is non-nil, the functions `newline' and `open-line' add the | 42 :group 'editing) |
43 text-property `hard' to newlines that they insert. Also, a line is | 43 |
44 only considered as a candidate to match `paragraph-start' or | 44 (define-minor-mode use-hard-newlines |
45 `paragraph-separate' if it follows a hard newline. Newlines not | |
46 marked hard are called \"soft\", and are always internal to | |
47 paragraphs. The fill functions always insert soft newlines. | |
48 | |
49 Each buffer has its own value of this variable.") | |
50 (make-variable-buffer-local 'use-hard-newlines) | |
51 | |
52 (defun use-hard-newlines (&optional arg insert) | |
53 "Minor mode to distinguish hard and soft newlines. | 45 "Minor mode to distinguish hard and soft newlines. |
54 When active, the functions `newline' and `open-line' add the | 46 When active, the functions `newline' and `open-line' add the |
55 text-property `hard' to newlines that they insert, and a line is | 47 text-property `hard' to newlines that they insert, and a line is |
56 only considered as a candidate to match `paragraph-start' or | 48 only considered as a candidate to match `paragraph-start' or |
57 `paragraph-separate' if it follows a hard newline. | 49 `paragraph-separate' if it follows a hard newline. |
58 | 50 |
59 Prefix argument says to turn mode on if positive, off if negative. | 51 Prefix argument says to turn mode on if positive, off if negative. |
60 When the mode is turned on, if there are newlines in the buffer but no hard | 52 When the mode is turned on, if there are newlines in the buffer but no hard |
61 newlines, ask the user whether to mark as hard any newlines preceding a | 53 newlines, ask the user whether to mark as hard any newlines preceeding a |
62 `paragraph-start' line. From a program, second arg INSERT specifies whether | 54 `paragraph-start' line. From a program, second arg INSERT specifies whether |
63 to do this; it can be `never' to change nothing, t or `always' to force | 55 to do this; it can be `never' to change nothing, t or `always' to force |
64 marking, `guess' to try to do the right thing with no questions, nil | 56 marking, `guess' to try to do the right thing with no questions, nil |
65 or anything else to ask the user. | 57 or anything else to ask the user. |
66 | 58 |
67 Newlines not marked hard are called \"soft\", and are always internal | 59 Newlines not marked hard are called \"soft\", and are always internal |
68 to paragraphs. The fill functions insert and delete only soft newlines." | 60 to paragraphs. The fill functions insert and delete only soft newlines." |
69 (interactive (list current-prefix-arg nil)) | 61 :group 'paragraphs |
70 (if (or (<= (prefix-numeric-value arg) 0) | 62 :extra-args (insert) |
71 (and use-hard-newlines (null arg))) | 63 (when use-hard-newlines |
72 ;; Turn mode off | |
73 (setq use-hard-newlines nil) | |
74 ;; Turn mode on | 64 ;; Turn mode on |
75 ;; Intuit hard newlines -- | 65 ;; Intuit hard newlines -- |
76 ;; mark as hard any newlines preceding a paragraph-start line. | 66 ;; mark as hard any newlines preceding a paragraph-start line. |
77 (if (or (eq insert t) (eq insert 'always) | 67 (if (or (eq insert t) (eq insert 'always) |
78 (and (not (eq 'never insert)) | 68 (and (not (eq 'never insert)) |
79 (not use-hard-newlines) | |
80 (not (text-property-any (point-min) (point-max) 'hard t)) | 69 (not (text-property-any (point-min) (point-max) 'hard t)) |
81 (save-excursion | 70 (save-excursion |
82 (goto-char (point-min)) | 71 (goto-char (point-min)) |
83 (search-forward "\n" nil t)) | 72 (search-forward "\n" nil t)) |
84 (or (eq insert 'guess) | 73 (or (eq insert 'guess) |
86 (save-excursion | 75 (save-excursion |
87 (goto-char (point-min)) | 76 (goto-char (point-min)) |
88 (while (search-forward "\n" nil t) | 77 (while (search-forward "\n" nil t) |
89 (let ((pos (point))) | 78 (let ((pos (point))) |
90 (move-to-left-margin) | 79 (move-to-left-margin) |
91 (if (looking-at paragraph-start) | 80 (when (looking-at paragraph-start) |
92 (progn | 81 (set-hard-newline-properties (1- pos) pos)) |
93 (set-hard-newline-properties (1- pos) pos) | 82 ;; If paragraph-separate, newline after it is hard too. |
94 ;; If paragraph-separate, newline after it is hard too. | 83 (when (looking-at paragraph-separate) |
95 (if (looking-at paragraph-separate) | 84 (set-hard-newline-properties (1- pos) pos) |
96 (progn | 85 (end-of-line) |
97 (end-of-line) | 86 (unless (eobp) |
98 (if (not (eobp)) | 87 (set-hard-newline-properties (point) (1+ (point))))))))))) |
99 (set-hard-newline-properties | 88 |
100 (point) (1+ (point)))))))))))) | 89 (defcustom paragraph-start "\f\\|[ \t]*$" "\ |
101 (setq use-hard-newlines t))) | |
102 | |
103 (defconst paragraph-start "[ \t\n\f]" "\ | |
104 *Regexp for beginning of a line that starts OR separates paragraphs. | 90 *Regexp for beginning of a line that starts OR separates paragraphs. |
105 This regexp should match lines that separate paragraphs | 91 This regexp should match lines that separate paragraphs |
106 and should also match lines that start a paragraph | 92 and should also match lines that start a paragraph |
107 \(and are part of that paragraph). | 93 \(and are part of that paragraph). |
108 | 94 |
113 | 99 |
114 The variable `paragraph-separate' specifies how to distinguish | 100 The variable `paragraph-separate' specifies how to distinguish |
115 lines that start paragraphs from lines that separate them. | 101 lines that start paragraphs from lines that separate them. |
116 | 102 |
117 If the variable `use-hard-newlines' is non-nil, then only lines following a | 103 If the variable `use-hard-newlines' is non-nil, then only lines following a |
118 hard newline are considered to match.") | 104 hard newline are considered to match." |
105 :group 'paragraphs | |
106 :type 'regexp) | |
119 | 107 |
120 ;; paragraph-start requires a hard newline, but paragraph-separate does not: | 108 ;; paragraph-start requires a hard newline, but paragraph-separate does not: |
121 ;; It is assumed that paragraph-separate is distinctive enough to be believed | 109 ;; It is assumed that paragraph-separate is distinctive enough to be believed |
122 ;; whenever it occurs, while it is reasonable to set paragraph-start to | 110 ;; whenever it occurs, while it is reasonable to set paragraph-start to |
123 ;; something very minimal, even including "." (which makes every hard newline | 111 ;; something very minimal, even including "." (which makes every hard newline |
124 ;; start a new paragraph). | 112 ;; start a new paragraph). |
125 | 113 |
126 (defconst paragraph-separate "[ \t\f]*$" "\ | 114 (defcustom paragraph-separate "[ \t\f]*$" |
127 *Regexp for beginning of a line that separates paragraphs. | 115 "*Regexp for beginning of a line that separates paragraphs. |
128 If you change this, you may have to change `paragraph-start' also. | 116 If you change this, you may have to change `paragraph-start' also. |
129 | 117 |
130 A line matching this is not part of any paragraph. | 118 A line matching this is not part of any paragraph. |
131 | 119 |
132 This is matched against the text at the left margin, which is not necessarily | 120 This is matched against the text at the left margin, which is not necessarily |
133 the beginning of the line, so it should not use \"^\" as an anchor. This | 121 the beginning of the line, so it should not use \"^\" as an anchor. This |
134 ensures that the paragraph functions will work equally within a region of | 122 ensures that the paragraph functions will work equally within a region of |
135 text indented by a margin setting.") | 123 text indented by a margin setting." |
136 | 124 :group 'paragraphs |
137 (defconst sentence-end "[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" "\ | 125 :type 'regexp) |
138 *Regexp describing the end of a sentence. | 126 |
127 (defcustom sentence-end-double-space t | |
128 "*Non-nil means a single space does not end a sentence. | |
129 This is relevant for filling. See also `sentence-end-without-period' | |
130 and `colon-double-space'. | |
131 | |
132 This variable applies only to filling, not motion commands. To | |
133 change the behavior of motion commands, see `sentence-end'. | |
134 | |
135 If you change this, you should also change `sentence-end'. See Info | |
136 node `Sentences'." | |
137 :type 'boolean | |
138 :group 'fill) | |
139 | |
140 (defcustom sentence-end-without-period nil | |
141 "*Non-nil means a sentence will end without a period. | |
142 For example, a sentence in Thai text ends with double space but | |
143 without a period." | |
144 :type 'boolean | |
145 :group 'fill) | |
146 | |
147 (defcustom sentence-end | |
148 (purecopy | |
149 ;; This is a bit stupid since it's not auto-updated when the | |
150 ;; other variables are changes, but it's still useful info. | |
151 (concat (if sentence-end-without-period "\\w \\|") | |
152 "[.?!$B!#!%!)!*$A!##.#?#!$(0!$!%!)!*$(G!$!%!)!*(B][]\"')}]*" | |
153 (if sentence-end-double-space | |
154 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)") | |
155 "[ \t\n]*")) | |
156 "*Regexp describing the end of a sentence. | |
157 The value includes the whitespace following the sentence. | |
139 All paragraph boundaries also end sentences, regardless. | 158 All paragraph boundaries also end sentences, regardless. |
140 | 159 |
141 In order to be recognized as the end of a sentence, the ending period, | 160 The default value specifies that in order to be recognized as the end |
142 question mark, or exclamation point must be followed by two spaces, | 161 of a sentence, the ending period, question mark, or exclamation point |
143 unless it's inside some sort of quotes or parenthesis.") | 162 must be followed by two spaces, unless it's inside some sort of quotes |
144 | 163 or parenthesis. |
145 (defconst page-delimiter "^\014" "\ | 164 |
146 *Regexp describing line-beginnings that separate pages.") | 165 See also the variable `sentence-end-double-space', the variable |
147 | 166 `sentence-end-without-period' and Info node `Sentences'." |
148 (defvar paragraph-ignore-fill-prefix nil "\ | 167 :group 'paragraphs |
149 Non-nil means the paragraph commands are not affected by `fill-prefix'. | 168 :type 'regexp) |
150 This is desirable in modes where blank lines are the paragraph delimiters.") | 169 |
170 (defcustom page-delimiter "^\014" | |
171 "*Regexp describing line-beginnings that separate pages." | |
172 :group 'paragraphs | |
173 :type 'regexp) | |
174 | |
175 (defcustom paragraph-ignore-fill-prefix nil | |
176 "*Non-nil means the paragraph commands are not affected by `fill-prefix'. | |
177 This is desirable in modes where blank lines are the paragraph delimiters." | |
178 :group 'paragraphs | |
179 :type 'boolean) | |
151 | 180 |
152 (defun forward-paragraph (&optional arg) | 181 (defun forward-paragraph (&optional arg) |
153 "Move forward to end of paragraph. | 182 "Move forward to end of paragraph. |
154 With arg N, do it N times; negative arg -N means move backward N paragraphs. | 183 With argument ARG, do it ARG times; |
184 a negative argument ARG = -N means move backward N paragraphs. | |
155 | 185 |
156 A line which `paragraph-start' matches either separates paragraphs | 186 A line which `paragraph-start' matches either separates paragraphs |
157 \(if `paragraph-separate' matches it also) or is the first line of a paragraph. | 187 \(if `paragraph-separate' matches it also) or is the first line of a paragraph. |
158 A paragraph end is the beginning of a line which is not part of the paragraph | 188 A paragraph end is the beginning of a line which is not part of the paragraph |
159 to which the end of the previous line belongs, or the end of the buffer." | 189 to which the end of the previous line belongs, or the end of the buffer. |
190 Returns the count of paragraphs left to move." | |
160 (interactive "_p") ; XEmacs | 191 (interactive "_p") ; XEmacs |
161 (or arg (setq arg 1)) | 192 (or arg (setq arg 1)) |
162 (let* ((fill-prefix-regexp | 193 (let* ((opoint (point)) |
194 (fill-prefix-regexp | |
163 (and fill-prefix (not (equal fill-prefix "")) | 195 (and fill-prefix (not (equal fill-prefix "")) |
164 (not paragraph-ignore-fill-prefix) | 196 (not paragraph-ignore-fill-prefix) |
165 (regexp-quote fill-prefix))) | 197 (regexp-quote fill-prefix))) |
166 ;; Remove ^ from paragraph-start and paragraph-sep if they are there. | 198 ;; Remove ^ from paragraph-start and paragraph-sep if they are there. |
167 ;; These regexps shouldn't be anchored, because we look for them | 199 ;; These regexps shouldn't be anchored, because we look for them |
168 ;; starting at the left-margin. This allows paragraph commands to | 200 ;; starting at the left-margin. This allows paragraph commands to |
169 ;; work normally with indented text. | 201 ;; work normally with indented text. |
170 ;; This hack will not find problem cases like "whatever\\|^something". | 202 ;; This hack will not find problem cases like "whatever\\|^something". |
171 (paragraph-start (if (and (not (equal "" paragraph-start)) | 203 (parstart (if (and (not (equal "" paragraph-start)) |
172 (equal ?^ (aref paragraph-start 0))) | 204 (equal ?^ (aref paragraph-start 0))) |
173 (substring paragraph-start 1) | 205 (substring paragraph-start 1) |
174 paragraph-start)) | 206 paragraph-start)) |
175 (paragraph-separate (if (and (not (equal "" paragraph-start)) | 207 (parsep (if (and (not (equal "" paragraph-separate)) |
176 (equal ?^ (aref paragraph-separate 0))) | 208 (equal ?^ (aref paragraph-separate 0))) |
177 (substring paragraph-separate 1) | 209 (substring paragraph-separate 1) |
178 paragraph-separate)) | 210 paragraph-separate)) |
179 (paragraph-separate | 211 (parsep |
180 (if fill-prefix-regexp | 212 (if fill-prefix-regexp |
181 (concat paragraph-separate "\\|" | 213 (concat parsep "\\|" |
182 fill-prefix-regexp "[ \t]*$") | 214 fill-prefix-regexp "[ \t]*$") |
183 paragraph-separate)) | 215 parsep)) |
184 ;; This is used for searching. | 216 ;; This is used for searching. |
185 (sp-paragraph-start (concat "^[ \t]*\\(" paragraph-start "\\)")) | 217 (sp-parstart (concat "^[ \t]*\\(?:" parstart "\\|" parsep "\\)")) |
186 start) | 218 start found-start) |
187 (while (and (< arg 0) (not (bobp))) | 219 (while (and (< arg 0) (not (bobp))) |
188 (if (and (not (looking-at paragraph-separate)) | 220 (if (and (not (looking-at parsep)) |
189 (re-search-backward "^\n" (max (1- (point)) (point-min)) t) | 221 (re-search-backward "^\n" (max (1- (point)) (point-min)) t) |
190 (looking-at paragraph-separate)) | 222 (looking-at parsep)) |
191 nil | 223 (setq arg (1+ arg)) |
192 (setq start (point)) | 224 (setq start (point)) |
193 ;; Move back over paragraph-separating lines. | 225 ;; Move back over paragraph-separating lines. |
194 (backward-char 1) (beginning-of-line) | 226 (backward-char 1) (beginning-of-line) |
195 (while (and (not (bobp)) | 227 (while (and (not (bobp)) |
196 (progn (move-to-left-margin) | 228 (progn (move-to-left-margin) |
197 (looking-at paragraph-separate))) | 229 (looking-at parsep))) |
198 (forward-line -1)) | 230 (forward-line -1)) |
199 (if (bobp) | 231 (if (bobp) |
200 nil | 232 nil |
233 (setq arg (1+ arg)) | |
201 ;; Go to end of the previous (non-separating) line. | 234 ;; Go to end of the previous (non-separating) line. |
202 (end-of-line) | 235 (end-of-line) |
203 ;; Search back for line that starts or separates paragraphs. | 236 ;; Search back for line that starts or separates paragraphs. |
204 (if (if fill-prefix-regexp | 237 (if (if fill-prefix-regexp |
205 ;; There is a fill prefix; it overrides paragraph-start. | 238 ;; There is a fill prefix; it overrides parstart. |
206 (let (multiple-lines) | 239 (let (multiple-lines) |
207 (while (and (progn (beginning-of-line) (not (bobp))) | 240 (while (and (progn (beginning-of-line) (not (bobp))) |
208 (progn (move-to-left-margin) | 241 (progn (move-to-left-margin) |
209 (not (looking-at paragraph-separate))) | 242 (not (looking-at parsep))) |
210 (looking-at fill-prefix-regexp)) | 243 (looking-at fill-prefix-regexp)) |
211 (if (not (= (point) start)) | 244 (unless (= (point) start) |
212 (setq multiple-lines t)) | 245 (setq multiple-lines t)) |
213 (forward-line -1)) | 246 (forward-line -1)) |
214 (move-to-left-margin) | 247 (move-to-left-margin) |
215 ;; Don't move back over a line before the paragraph | 248 ;; This deleted code caused a long hanging-indent line |
216 ;; which doesn't start with fill-prefix | 249 ;; not to be filled together with the following lines. |
217 ;; unless that is the only line we've moved over. | 250 ;; ;; Don't move back over a line before the paragraph |
218 (and (not (looking-at fill-prefix-regexp)) | 251 ;; ;; which doesn't start with fill-prefix |
219 multiple-lines | 252 ;; ;; unless that is the only line we've moved over. |
220 (forward-line 1)) | 253 ;; (and (not (looking-at fill-prefix-regexp)) |
254 ;; multiple-lines | |
255 ;; (forward-line 1)) | |
221 (not (bobp))) | 256 (not (bobp))) |
222 (while (and (re-search-backward sp-paragraph-start nil 1) | 257 (while (and (re-search-backward sp-parstart nil 1) |
258 (setq found-start t) | |
223 ;; Found a candidate, but need to check if it is a | 259 ;; Found a candidate, but need to check if it is a |
224 ;; REAL paragraph-start. | 260 ;; REAL parstart. |
225 (not (bobp)) | |
226 (progn (setq start (point)) | 261 (progn (setq start (point)) |
227 (move-to-left-margin) | 262 (move-to-left-margin) |
228 (not (looking-at paragraph-separate))) | 263 (not (looking-at parsep))) |
229 (or (not (looking-at paragraph-start)) | 264 (not (and (looking-at parstart) |
230 (and use-hard-newlines | 265 (or (not use-hard-newlines) |
231 (not (get-text-property (1- start) | 266 (get-text-property (1- start) 'hard) |
232 'hard))))) | 267 (bobp))))) |
268 (setq found-start nil) | |
233 (goto-char start)) | 269 (goto-char start)) |
234 (> (point) (point-min))) | 270 found-start) |
235 ;; Found one. | 271 ;; Found one. |
236 (progn | 272 (progn |
237 ;; Move forward over paragraph separators. | 273 ;; Move forward over paragraph separators. |
238 ;; We know this cannot reach the place we started | 274 ;; We know this cannot reach the place we started |
239 ;; because we know we moved back over a non-separator. | 275 ;; because we know we moved back over a non-separator. |
240 (while (and (not (eobp)) | 276 (while (and (not (eobp)) |
241 (progn (move-to-left-margin) | 277 (progn (move-to-left-margin) |
242 (looking-at paragraph-separate))) | 278 (looking-at parsep))) |
243 (forward-line 1)) | 279 (forward-line 1)) |
244 ;; If line before paragraph is just margin, back up to there. | 280 ;; If line before paragraph is just margin, back up to there. |
245 (end-of-line 0) | 281 (end-of-line 0) |
246 (if (> (current-column) (current-left-margin)) | 282 (if (> (current-column) (current-left-margin)) |
247 (forward-char 1) | 283 (forward-char 1) |
248 (skip-chars-backward " \t") | 284 (skip-chars-backward " \t") |
249 (if (not (bolp)) | 285 (if (not (bolp)) |
250 (forward-line 1)))) | 286 (forward-line 1)))) |
251 ;; No starter or separator line => use buffer beg. | 287 ;; No starter or separator line => use buffer beg. |
252 (goto-char (point-min))))) | 288 (goto-char (point-min)))))) |
253 (setq arg (1+ arg))) | 289 |
254 (while (and (> arg 0) (not (eobp))) | 290 (while (and (> arg 0) (not (eobp))) |
255 ;; Move forward over separator lines, and one more line. | 291 ;; Move forward over separator lines... |
256 (while (prog1 (and (not (eobp)) | 292 (while (and (not (eobp)) |
257 (progn (move-to-left-margin) (not (eobp))) | 293 (progn (move-to-left-margin) (not (eobp))) |
258 (looking-at paragraph-separate)) | 294 (looking-at parsep)) |
259 (forward-line 1))) | 295 (forward-line 1)) |
296 (unless (eobp) (setq arg (1- arg))) | |
297 ;; ... and one more line. | |
298 (forward-line 1) | |
260 (if fill-prefix-regexp | 299 (if fill-prefix-regexp |
261 ;; There is a fill prefix; it overrides paragraph-start. | 300 ;; There is a fill prefix; it overrides parstart. |
262 (while (and (not (eobp)) | 301 (while (and (not (eobp)) |
263 (progn (move-to-left-margin) (not (eobp))) | 302 (progn (move-to-left-margin) (not (eobp))) |
264 (not (looking-at paragraph-separate)) | 303 (not (looking-at parsep)) |
265 (looking-at fill-prefix-regexp)) | 304 (looking-at fill-prefix-regexp)) |
266 (forward-line 1)) | 305 (forward-line 1)) |
267 (while (and (re-search-forward sp-paragraph-start nil 1) | 306 (while (and (re-search-forward sp-parstart nil 1) |
268 (progn (setq start (match-beginning 0)) | 307 (progn (setq start (match-beginning 0)) |
269 (goto-char start) | 308 (goto-char start) |
270 (not (eobp))) | 309 (not (eobp))) |
271 (progn (move-to-left-margin) | 310 (progn (move-to-left-margin) |
272 (not (looking-at paragraph-separate))) | 311 (not (looking-at parsep))) |
273 (or (not (looking-at paragraph-start)) | 312 (or (not (looking-at parstart)) |
274 (and use-hard-newlines | 313 (and use-hard-newlines |
275 (not (get-text-property (1- start) 'hard))))) | 314 (not (get-text-property (1- start) 'hard))))) |
276 (forward-char 1)) | 315 (forward-char 1)) |
277 (if (< (point) (point-max)) | 316 (if (< (point) (point-max)) |
278 (goto-char start))) | 317 (goto-char start)))) |
279 (setq arg (1- arg))))) | 318 (constrain-to-field nil opoint t) |
319 ;; Return the number of steps that could not be done. | |
320 arg)) | |
280 | 321 |
281 (defun backward-paragraph (&optional arg) | 322 (defun backward-paragraph (&optional arg) |
282 "Move backward to start of paragraph. | 323 "Move backward to start of paragraph. |
283 With arg N, do it N times; negative arg -N means move forward N paragraphs. | 324 With argument ARG, do it ARG times; |
325 a negative argument ARG = -N means move forward N paragraphs. | |
284 | 326 |
285 A paragraph start is the beginning of a line which is a | 327 A paragraph start is the beginning of a line which is a |
286 `first-line-of-paragraph' or which is ordinary text and follows a | 328 `first-line-of-paragraph' or which is ordinary text and follows a |
287 paragraph-separating line; except: if the first real line of a | 329 paragraph-separating line; except: if the first real line of a |
288 paragraph is preceded by a blank line, the paragraph starts at that | 330 paragraph is preceded by a blank line, the paragraph starts at that |
294 (forward-paragraph (- arg))) | 336 (forward-paragraph (- arg))) |
295 | 337 |
296 (defun mark-paragraph (&optional arg) | 338 (defun mark-paragraph (&optional arg) |
297 "Put point at beginning of this paragraph, mark at end. | 339 "Put point at beginning of this paragraph, mark at end. |
298 The paragraph marked is the one that contains point or follows point. | 340 The paragraph marked is the one that contains point or follows point. |
299 With arg N, puts mark at end of following N paragraphs; | 341 |
300 negative arg -N means point is put at end of this paragraph, mark is put | 342 With argument ARG, puts mark at end of a following paragraph, so that |
301 at beginning of this or a previous paragraph." | 343 the number of paragraphs marked equals ARG. |
344 | |
345 If ARG is negative, point is put at end of this paragraph, mark is put | |
346 at beginning of this or a previous paragraph. | |
347 | |
348 If this command is repeated, it marks the next ARG paragraphs after (or | |
349 before, if arg is negative) the ones already marked." | |
302 (interactive "p") | 350 (interactive "p") |
303 (unless arg (setq arg 1)) | 351 (unless arg (setq arg 1)) |
304 (when (zerop arg) | 352 (when (zerop arg) |
305 (error "Cannot mark zero paragraphs")) | 353 (error "Cannot mark zero paragraphs")) |
306 (forward-paragraph arg) | 354 (cond ((and (eq last-command this-command) (mark t)) |
307 (push-mark nil t t) | 355 (set-mark |
308 (backward-paragraph arg)) | 356 (save-excursion |
357 (goto-char (mark)) | |
358 (forward-paragraph arg) | |
359 (point)))) | |
360 (t | |
361 (forward-paragraph arg) | |
362 (push-mark nil t t) | |
363 (backward-paragraph arg)))) | |
309 | 364 |
310 (defun kill-paragraph (arg) | 365 (defun kill-paragraph (arg) |
311 "Kill forward to end of paragraph. | 366 "Kill forward to end of paragraph. |
312 With arg N, kill forward to Nth end of paragraph; | 367 With arg N, kill forward to Nth end of paragraph; |
313 negative arg -N means kill backward to Nth start of paragraph." | 368 negative arg -N means kill backward to Nth start of paragraph." |
357 | 412 |
358 The variable `sentence-end' is a regular expression that matches ends of | 413 The variable `sentence-end' is a regular expression that matches ends of |
359 sentences. A paragraph boundary also terminates a sentence." | 414 sentences. A paragraph boundary also terminates a sentence." |
360 (interactive "_p") ; XEmacs | 415 (interactive "_p") ; XEmacs |
361 (or arg (setq arg 1)) | 416 (or arg (setq arg 1)) |
362 (while (< arg 0) | 417 (let ((opoint (point))) |
363 (let ((par-beg (save-excursion (start-of-paragraph-text) (point)))) | 418 (while (< arg 0) |
364 (if (re-search-backward (concat sentence-end "[^ \t\n]") par-beg t) | 419 (let ((pos (point)) |
365 (goto-char (1- (match-end 0))) | 420 (par-beg (save-excursion (start-of-paragraph-text) (point)))) |
366 (goto-char par-beg))) | 421 (if (and (re-search-backward sentence-end par-beg t) |
367 (setq arg (1+ arg))) | 422 (or (< (match-end 0) pos) |
368 (while (> arg 0) | 423 (re-search-backward sentence-end par-beg t))) |
369 (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) | 424 (goto-char (match-end 0)) |
370 (if (re-search-forward sentence-end par-end t) | 425 (goto-char par-beg))) |
371 (skip-chars-backward " \t\n") | 426 (setq arg (1+ arg))) |
372 (goto-char par-end))) | 427 (while (> arg 0) |
373 (setq arg (1- arg)))) | 428 (let ((par-end (save-excursion (end-of-paragraph-text) (point)))) |
429 (if (re-search-forward sentence-end par-end t) | |
430 (skip-chars-backward " \t\n") | |
431 (goto-char par-end))) | |
432 (setq arg (1- arg))) | |
433 (constrain-to-field nil opoint t))) | |
374 | 434 |
375 (defun backward-sentence (&optional arg) | 435 (defun backward-sentence (&optional arg) |
376 "Move backward to start of sentence. With arg, do it arg times. | 436 "Move backward to start of sentence. With arg, do it arg times. |
377 See `forward-sentence' for more information." | 437 See `forward-sentence' for more information." |
378 (interactive "_p") ; XEmacs | 438 (interactive "_p") ; XEmacs |
390 With arg, repeat, or kill forward to Nth end of sentence if negative arg -N." | 450 With arg, repeat, or kill forward to Nth end of sentence if negative arg -N." |
391 (interactive "*p") ; XEmacs | 451 (interactive "*p") ; XEmacs |
392 (kill-region (point) (progn (backward-sentence arg) (point)))) | 452 (kill-region (point) (progn (backward-sentence arg) (point)))) |
393 | 453 |
394 (defun mark-end-of-sentence (arg) | 454 (defun mark-end-of-sentence (arg) |
395 "Put mark at end of sentence. Arg works as in `forward-sentence'." | 455 "Put mark at end of sentence. Arg works as in `forward-sentence'. |
456 If this command is repeated, it marks the next ARG sentences after the | |
457 ones already marked." | |
396 (interactive "p") | 458 (interactive "p") |
397 ;; FSF Version: | 459 ;; FSF Version: |
398 ; (push-mark | 460 ; (push-mark |
399 ; (save-excursion | 461 ; (save-excursion |
400 ; (forward-sentence arg) | 462 ; (if (and (eq last-command this-command) (mark t)) |
401 ; (point)) | 463 ; (goto-char (mark))) |
402 ; nil t)) | 464 ; (forward-sentence arg) |
465 ; (point)) | |
466 ; nil t)) | |
403 (mark-something 'mark-end-of-sentence 'forward-sentence arg)) | 467 (mark-something 'mark-end-of-sentence 'forward-sentence arg)) |
404 | 468 |
405 (defun mark-end-of-line (arg) | 469 (defun mark-end-of-line (arg) |
406 "Put mark at end of line. Arg works as in `end-of-line'." | 470 "Put mark at end of line. Arg works as in `end-of-line'." |
407 (interactive "p") | 471 (interactive "p") |
408 (mark-something 'mark-end-of-line 'end-of-line arg)) | 472 (mark-something 'mark-end-of-line 'end-of-line arg)) |
409 | 473 |
410 | |
411 (defun transpose-sentences (arg) | 474 (defun transpose-sentences (arg) |
412 "Interchange this (next) and previous sentence." | 475 "Interchange this (next) and previous sentence." |
413 (interactive "*p") | 476 (interactive "*p") |
414 (transpose-subr 'forward-sentence arg)) | 477 (transpose-subr 'forward-sentence arg)) |
415 | 478 |
479 ;;; Local Variables: | |
480 ;;; coding: iso-2022-7bit | |
481 ;;; End: | |
482 | |
416 ;;; paragraphs.el ends here | 483 ;;; paragraphs.el ends here |