comparison lisp/paragraphs.el @ 5493:f62141fe007d

Sync paragraphs.el to FSF 23.1.92 -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-02-19 Ben Wing <ben@xemacs.org> * paragraphs.el: * paragraphs.el (use-hard-newlines): * paragraphs.el (paragraph-start): * paragraphs.el (paragraph-separate): * paragraphs.el (sentence-end-double-space): * paragraphs.el (sentence-end-without-period): * paragraphs.el (sentence-end-without-space): New. * paragraphs.el (sentence-end): * paragraphs.el (sentence-end-base): New. * paragraphs.el (page-delimiter): * paragraphs.el (paragraph-ignore-fill-prefix): * paragraphs.el (forward-paragraph): * paragraphs.el (backward-paragraph): * paragraphs.el (mark-paragraph): * paragraphs.el (forward-sentence): * paragraphs.el (repunctuate-sentences): New. Sync with FSF 23.1.92.
author Ben Wing <ben@xemacs.org>
date Fri, 19 Feb 2010 22:41:03 -0600
parents b4f4e0cc90f1
children 1f0b15040456
comparison
equal deleted inserted replaced
5492:e82f5b7010fe 5493:f62141fe007d
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, 96, 1997, 1999, 2000, 2001 3 ;; Copyright (C) 1985-87, 1991, 1994-97, 1999-2010 Free Software Foundation, Inc.
4 ;; Free Software Foundation, Inc. 4 ;; Copyright (C) 2010 Ben Wing.
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.
10 10
11 ;; XEmacs is free software; you can redistribute it and/or modify it 11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; under the terms of the GNU General Public License as published by 12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option) 13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; any later version. 14 ;; (at your option) any later version.
15 15
16 ;; XEmacs is distributed in the hope that it will be useful, but 16 ;; XEmacs is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of 17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details. 19 ;; General Public License for more details.
20 20
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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 23
24 ;; 02111-1307, USA. 24 ;;; Synced up with: FSF 23.1.92.
25 25 ;;; Synced by: Ben Wing, 2-17-10.
26 ;;; Synched up with: FSF 21.3.
27 26
28 ;;; Commentary: 27 ;;; Commentary:
29 28
30 ;; This file is dumped with XEmacs. 29 ;; This file is dumped with XEmacs.
31 30
39 38
40 (defgroup paragraphs nil 39 (defgroup paragraphs nil
41 "Paragraph and sentence parsing." 40 "Paragraph and sentence parsing."
42 :group 'editing) 41 :group 'editing)
43 42
43 (put 'use-hard-newlines 'permanent-local t)
44 (define-minor-mode use-hard-newlines 44 (define-minor-mode use-hard-newlines
45 "Minor mode to distinguish hard and soft newlines. 45 "Minor mode to distinguish hard and soft newlines.
46 When active, the functions `newline' and `open-line' add the 46 When active, the functions `newline' and `open-line' add the
47 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
48 only considered as a candidate to match `paragraph-start' or 48 only considered as a candidate to match `paragraph-start' or
102 102
103 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
104 hard newline are considered to match." 104 hard newline are considered to match."
105 :group 'paragraphs 105 :group 'paragraphs
106 :type 'regexp) 106 :type 'regexp)
107 (put 'paragraph-start 'safe-local-variable 'stringp)
107 108
108 ;; paragraph-start requires a hard newline, but paragraph-separate does not: 109 ;; paragraph-start requires a hard newline, but paragraph-separate does not:
109 ;; It is assumed that paragraph-separate is distinctive enough to be believed 110 ;; It is assumed that paragraph-separate is distinctive enough to be believed
110 ;; whenever it occurs, while it is reasonable to set paragraph-start to 111 ;; whenever it occurs, while it is reasonable to set paragraph-start to
111 ;; something very minimal, even including "." (which makes every hard newline 112 ;; something very minimal, even including "." (which makes every hard newline
121 the beginning of the line, so it should not use \"^\" as an anchor. This 122 the beginning of the line, so it should not use \"^\" as an anchor. This
122 ensures that the paragraph functions will work equally within a region of 123 ensures that the paragraph functions will work equally within a region of
123 text indented by a margin setting." 124 text indented by a margin setting."
124 :group 'paragraphs 125 :group 'paragraphs
125 :type 'regexp) 126 :type 'regexp)
127 (put 'paragraph-separate 'safe-local-variable 'stringp)
126 128
127 (defcustom sentence-end-double-space t 129 (defcustom sentence-end-double-space t
128 "*Non-nil means a single space does not end a sentence. 130 "*Non-nil means a single space does not end a sentence.
129 This is relevant for filling. See also `sentence-end-without-period' 131 This is relevant for filling. See also `sentence-end-without-period'
130 and `colon-double-space'. 132 and `colon-double-space'.
131 133
132 This variable applies only to filling, not motion commands. To 134 This variable applies only to filling, not motion commands. To
133 change the behavior of motion commands, see `sentence-end'. 135 change the behavior of motion commands, see `sentence-end'.
134 136
135 If you change this, you should also change `sentence-end'. See Info 137 This value is used by the function `sentence-end' to construct the
136 node `Sentences'." 138 regexp describing the end of a sentence, when the value of the variable
139 `sentence-end' is nil. See Info node `(lispref)Standard Regexps'."
137 :type 'boolean 140 :type 'boolean
138 :group 'fill) 141 :group 'fill)
142 (put 'sentence-end-double-space 'safe-local-variable 'booleanp)
139 143
140 (defcustom sentence-end-without-period nil 144 (defcustom sentence-end-without-period nil
141 "*Non-nil means a sentence will end without a period. 145 "*Non-nil means a sentence will end without a period.
142 For example, a sentence in Thai text ends with double space but 146 For example, a sentence in Thai text ends with double space but
143 without a period." 147 without a period.
148
149 This value is used by the function `sentence-end' to construct the
150 regexp describing the end of a sentence, when the value of the variable
151 `sentence-end' is nil. See Info node `(lispref)Standard Regexps'."
144 :type 'boolean 152 :type 'boolean
145 :group 'fill) 153 :group 'fill)
146 154 (put 'sentence-end-without-period 'safe-local-variable 'booleanp)
147 (defcustom sentence-end 155
148 (purecopy 156 (defcustom sentence-end-without-space
149 ;; This is a bit stupid since it's not auto-updated when the 157 (cond ((featurep 'unicode-internal)
150 ;; other variables are changed, but it's still useful info. 158 (decode-coding-string "\343\200\202\357\274\216\357\274\237\357\274\201" 'utf-8))
151 (concat (if sentence-end-without-period "\\w \\|") 159 ((featurep 'mule)
152 "[.?!" 160 (decode-coding-string "\033$B!#!%!)!*\033$A!##.#?#!\033$(0!$!%!)!*\033$(G!$!%!)!*\033(B" 'iso-2022-7bit))
153 (if (featurep 'mule) 161 (t ""))
154 (decode-coding-string "\033$B!#!%!)!*\033$A!##.#?#!\033$(0!$!%!)!*\033$(G!$!%!)!*\033(B" 'iso-2022-7bit) 162 "String of characters that end sentence without following spaces.
155 "") 163
156 "][]\"')}]*" 164 This value is used by the function `sentence-end' to construct the
157 (if sentence-end-double-space 165 regexp describing the end of a sentence, when the value of the variable
158 "\\($\\| $\\|\t\\| \\)" "\\($\\|[\t ]\\)") 166 `sentence-end' is nil. See Info node `(lispref)Standard Regexps'."
159 "[ \t\n]*")) 167 :group 'paragraphs
160 "*Regexp describing the end of a sentence. 168 :type 'string)
169 (put 'sentence-end-without-space 'safe-local-variable 'stringp)
170
171 (defcustom sentence-end nil
172 "Regexp describing the end of a sentence.
161 The value includes the whitespace following the sentence. 173 The value includes the whitespace following the sentence.
162 All paragraph boundaries also end sentences, regardless. 174 All paragraph boundaries also end sentences, regardless.
163 175
164 The default value specifies that in order to be recognized as the end 176 The value nil means to use the default value defined by the
165 of a sentence, the ending period, question mark, or exclamation point 177 function `sentence-end'. You should always use this function
166 must be followed by two spaces, unless it's inside some sort of quotes 178 to obtain the value of this variable."
167 or parenthesis. 179 :group 'paragraphs
168 180 :type '(choice regexp (const :tag "Use default value" nil)))
169 See also the variable `sentence-end-double-space', the variable 181 (put 'sentence-end 'safe-local-variable 'string-or-null-p)
170 `sentence-end-without-period' and Info node `Sentences'." 182
171 :group 'paragraphs 183 (defcustom sentence-end-base "[.?!][]\"'”)}]*"
172 :type 'regexp) 184 "Regexp matching the basic end of a sentence, not including following space."
185 :group 'paragraphs
186 :type 'string
187 :version "22.1")
188 (put 'sentence-end-base 'safe-local-variable 'stringp)
189
190 (defun sentence-end ()
191 "Return the regexp describing the end of a sentence.
192
193 This function returns either the value of the variable `sentence-end'
194 if it is non-nil, or the default value constructed from the
195 variables `sentence-end-base', `sentence-end-double-space',
196 `sentence-end-without-period' and `sentence-end-without-space'.
197
198 The default value specifies that in order to be recognized as the
199 end of a sentence, the ending period, question mark, or exclamation point
200 must be followed by two spaces, with perhaps some closing delimiters
201 in between. See Info node `(elisp)Standard Regexps'."
202 (or sentence-end
203 ;; We accept non-break space along with space.
204 (concat (if sentence-end-without-period "\\w[ \u00a0][ \u00a0]\\|")
205 "\\("
206 sentence-end-base
207 (if sentence-end-double-space
208 "\\($\\|[ \u00a0]$\\|\t\\|[ \u00a0][ \u00a0]\\)" "\\($\\|[\t \u00a0]\\)")
209 "\\|[" sentence-end-without-space "]+"
210 "\\)"
211 "[ \u00a0\t\n]*")))
173 212
174 (defcustom page-delimiter "^\014" 213 (defcustom page-delimiter "^\014"
175 "*Regexp describing line-beginnings that separate pages." 214 "*Regexp describing line-beginnings that separate pages."
176 :group 'paragraphs 215 :group 'paragraphs
177 :type 'regexp) 216 :type 'regexp)
217 (put 'page-delimiter 'safe-local-variable 'stringp)
178 218
179 (defcustom paragraph-ignore-fill-prefix nil 219 (defcustom paragraph-ignore-fill-prefix nil
180 "*Non-nil means the paragraph commands are not affected by `fill-prefix'. 220 "*Non-nil means the paragraph commands are not affected by `fill-prefix'.
181 This is desirable in modes where blank lines are the paragraph delimiters." 221 This is desirable in modes where blank lines are the paragraph delimiters."
182 :group 'paragraphs 222 :group 'paragraphs
183 :type 'boolean) 223 :type 'boolean)
224 (put 'paragraph-ignore-fill-prefix 'safe-local-variable 'booleanp)
184 225
185 (defun forward-paragraph (&optional arg) 226 (defun forward-paragraph (&optional arg)
186 "Move forward to end of paragraph. 227 "Move forward to end of paragraph.
187 With argument ARG, do it ARG times; 228 With argument ARG, do it ARG times;
188 a negative argument ARG = -N means move backward N paragraphs. 229 a negative argument ARG = -N means move backward N paragraphs.
190 A line which `paragraph-start' matches either separates paragraphs 231 A line which `paragraph-start' matches either separates paragraphs
191 \(if `paragraph-separate' matches it also) or is the first line of a paragraph. 232 \(if `paragraph-separate' matches it also) or is the first line of a paragraph.
192 A paragraph end is the beginning of a line which is not part of the paragraph 233 A paragraph end is the beginning of a line which is not part of the paragraph
193 to which the end of the previous line belongs, or the end of the buffer. 234 to which the end of the previous line belongs, or the end of the buffer.
194 Returns the count of paragraphs left to move." 235 Returns the count of paragraphs left to move."
236 ;; #### MERGE! FSF Has (interactive "^p")
195 (interactive "_p") ; XEmacs 237 (interactive "_p") ; XEmacs
196 (or arg (setq arg 1)) 238 (or arg (setq arg 1))
197 (let* ((opoint (point)) 239 (let* ((opoint (point))
198 (fill-prefix-regexp 240 (fill-prefix-regexp
199 (and fill-prefix (not (equal fill-prefix "")) 241 (and fill-prefix (not (equal fill-prefix ""))
265 (progn (setq start (point)) 307 (progn (setq start (point))
266 (move-to-left-margin) 308 (move-to-left-margin)
267 (not (looking-at parsep))) 309 (not (looking-at parsep)))
268 (not (and (looking-at parstart) 310 (not (and (looking-at parstart)
269 (or (not use-hard-newlines) 311 (or (not use-hard-newlines)
312 ;; #### XEmacs: We've reversed
313 ;; the order of the following two --
314 ;; does it matter?
270 (get-text-property (1- start) 'hard) 315 (get-text-property (1- start) 'hard)
271 (bobp))))) 316 (bobp)))))
272 (setq found-start nil) 317 (setq found-start nil)
273 (goto-char start)) 318 (goto-char start))
274 found-start) 319 found-start)
331 "Move backward to start of paragraph. 376 "Move backward to start of paragraph.
332 With argument ARG, do it ARG times; 377 With argument ARG, do it ARG times;
333 a negative argument ARG = -N means move forward N paragraphs. 378 a negative argument ARG = -N means move forward N paragraphs.
334 379
335 A paragraph start is the beginning of a line which is a 380 A paragraph start is the beginning of a line which is a
336 `first-line-of-paragraph' or which is ordinary text and follows a 381 `paragraph-start' or which is ordinary text and follows a
337 paragraph-separating line; except: if the first real line of a 382 `paragraph-separate'ing line; except: if the first real line of a
338 paragraph is preceded by a blank line, the paragraph starts at that 383 paragraph is preceded by a blank line, the paragraph starts at that
339 blank line. 384 blank line.
340 385
341 See `forward-paragraph' for more information." 386 See `forward-paragraph' for more information."
387 ;; #### MERGE! FSF Has (interactive "^p")
342 (interactive "_p") ; XEmacs 388 (interactive "_p") ; XEmacs
343 (or arg (setq arg 1)) 389 (or arg (setq arg 1))
344 (forward-paragraph (- arg))) 390 (forward-paragraph (- arg)))
345 391
346 (defun mark-paragraph (&optional arg) 392 (defun mark-paragraph (&optional arg allow-extend)
347 "Put point at beginning of this paragraph, mark at end. 393 "Put point at beginning of this paragraph, mark at end.
348 The paragraph marked is the one that contains point or follows point. 394 The paragraph marked is the one that contains point or follows point.
349 395
350 With argument ARG, puts mark at end of a following paragraph, so that 396 With argument ARG, puts mark at end of a following paragraph, so that
351 the number of paragraphs marked equals ARG. 397 the number of paragraphs marked equals ARG.
353 If ARG is negative, point is put at end of this paragraph, mark is put 399 If ARG is negative, point is put at end of this paragraph, mark is put
354 at beginning of this or a previous paragraph. 400 at beginning of this or a previous paragraph.
355 401
356 If this command is repeated, it marks the next ARG paragraphs after (or 402 If this command is repeated, it marks the next ARG paragraphs after (or
357 before, if arg is negative) the ones already marked." 403 before, if arg is negative) the ones already marked."
358 (interactive "p") 404 (interactive "p\np")
359 (unless arg (setq arg 1)) 405 (unless arg (setq arg 1))
360 (when (zerop arg) 406 (when (zerop arg)
361 (error "Cannot mark zero paragraphs")) 407 (error "Cannot mark zero paragraphs"))
362 (cond ((and (eq last-command this-command) (mark t)) 408 (cond ((and allow-extend
409 (eq last-command this-command) (mark t))
363 (set-mark 410 (set-mark
364 (save-excursion 411 (save-excursion
365 (goto-char (mark)) 412 (goto-char (mark))
366 (forward-paragraph arg) 413 (forward-paragraph arg)
367 (point)))) 414 (point))))
413 (forward-char 1) 460 (forward-char 1)
414 (if (< (point) (point-max)) 461 (if (< (point) (point-max))
415 (end-of-paragraph-text)))))) 462 (end-of-paragraph-text))))))
416 463
417 (defun forward-sentence (&optional arg) 464 (defun forward-sentence (&optional arg)
418 "Move forward to next `sentence-end'. With argument, repeat. 465 "Move forward to next end of sentence. With argument, repeat.
419 With negative argument, move backward repeatedly to `sentence-beginning'. 466 With negative argument, move backward repeatedly to start of sentence.
420 467
421 The variable `sentence-end' is a regular expression that matches ends of 468 The variable `sentence-end' is a regular expression that matches ends of
422 sentences. A paragraph boundary also terminates a sentence." 469 sentences. Also, every paragraph boundary terminates sentences as well."
470 ;; #### MERGE! FSF Has (interactive "^p")
423 (interactive "_p") ; XEmacs 471 (interactive "_p") ; XEmacs
424 (or arg (setq arg 1)) 472 (or arg (setq arg 1))
425 (let ((opoint (point))) 473 (let ((opoint (point))
474 (sentence-end (sentence-end)))
426 (while (< arg 0) 475 (while (< arg 0)
427 (let ((pos (point)) 476 (let ((pos (point))
428 (par-beg (save-excursion (start-of-paragraph-text) (point)))) 477 ;; We used to use (start-of-paragraph-text), but this can
478 ;; prevent sentence-end from matching if it is anchored at
479 ;; BOL and the paragraph starts indented.
480 (par-beg (save-excursion (backward-paragraph) (point))))
429 (if (and (re-search-backward sentence-end par-beg t) 481 (if (and (re-search-backward sentence-end par-beg t)
430 (or (< (match-end 0) pos) 482 (or (< (match-end 0) pos)
431 (re-search-backward sentence-end par-beg t))) 483 (re-search-backward sentence-end par-beg t)))
432 (goto-char (match-end 0)) 484 (goto-char (match-end 0))
433 (goto-char par-beg))) 485 (goto-char par-beg)))
442 (constrain-to-field nil opoint t) 494 (constrain-to-field nil opoint t)
443 (error 495 (error
444 'void-function 496 'void-function
445 "constrain-to-field not available; is xemacs-base installed?")))) 497 "constrain-to-field not available; is xemacs-base installed?"))))
446 498
499 (defun repunctuate-sentences ()
500 "Put two spaces at the end of sentences from point to the end of buffer.
501 It works using `query-replace-regexp'."
502 (interactive)
503 (query-replace-regexp "\\([]\"')]?\\)\\([.?!]\\)\\([]\"')]?\\) +"
504 "\\1\\2\\3 "))
505
506
447 (defun backward-sentence (&optional arg) 507 (defun backward-sentence (&optional arg)
448 "Move backward to start of sentence. With arg, do it arg times. 508 "Move backward to start of sentence. With arg, do it arg times.
449 See `forward-sentence' for more information." 509 See `forward-sentence' for more information."
510 ;; #### MERGE! FSF Has (interactive "^p")
450 (interactive "_p") ; XEmacs 511 (interactive "_p") ; XEmacs
451 (or arg (setq arg 1)) 512 (or arg (setq arg 1))
452 (forward-sentence (- arg))) 513 (forward-sentence (- arg)))
453 514
454 (defun kill-sentence (&optional arg) 515 (defun kill-sentence (&optional arg)
486 (defun transpose-sentences (arg) 547 (defun transpose-sentences (arg)
487 "Interchange this (next) and previous sentence." 548 "Interchange this (next) and previous sentence."
488 (interactive "*p") 549 (interactive "*p")
489 (transpose-subr 'forward-sentence arg)) 550 (transpose-subr 'forward-sentence arg))
490 551
491 ;;; Local Variables: 552 ;; Local Variables:
492 ;;; coding: iso-2022-7bit 553 ;; coding: utf-8
493 ;;; End: 554 ;; End:
494 555
495 ;;; paragraphs.el ends here 556 ;;; paragraphs.el ends here