Mercurial > hg > xemacs-beta
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 |