diff options
| author | Stefan Monnier | 2001-11-19 23:51:03 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2001-11-19 23:51:03 +0000 |
| commit | 2f4fa275e8858f83712bee5ca6714945c70e358d (patch) | |
| tree | ddcab55c6c57a47fbd27b13b24dcec0c689e7c7a | |
| parent | 99b3bc616bf09f72d91f11f85c41cd08f52ca5bf (diff) | |
| download | emacs-2f4fa275e8858f83712bee5ca6714945c70e358d.tar.gz emacs-2f4fa275e8858f83712bee5ca6714945c70e358d.zip | |
(fill-delete-prefix, fill-delete-newlines):
New functions, extracted from fill-region-as-paragraph.
(fill-region-as-paragraph): Use them.
Use an end marker instead of eob.
Ignore whitespace-only fill-prefixes when indenting according to mode.
Simply the loop that searches for spaces backwards.
| -rw-r--r-- | lisp/textmodes/fill.el | 218 |
1 files changed, 112 insertions, 106 deletions
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index dedceb730b6..2abda635f0d 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el | |||
| @@ -151,7 +151,7 @@ Remove indentation from each line." | |||
| 151 | ;; Blame the typist. | 151 | ;; Blame the typist. |
| 152 | (subst-char-in-region beg end ?\t ?\ ) | 152 | (subst-char-in-region beg end ?\t ?\ ) |
| 153 | (while (and (< (point) end) | 153 | (while (and (< (point) end) |
| 154 | (re-search-forward " *" end t)) | 154 | (re-search-forward " +" end t)) |
| 155 | (delete-region | 155 | (delete-region |
| 156 | (+ (match-beginning 0) | 156 | (+ (match-beginning 0) |
| 157 | ;; Determine number of spaces to leave: | 157 | ;; Determine number of spaces to leave: |
| @@ -173,11 +173,11 @@ Remove indentation from each line." | |||
| 173 | "[.?!:][])}\"']*$" | 173 | "[.?!:][])}\"']*$" |
| 174 | "[.?!][])}\"']*$"))) | 174 | "[.?!][])}\"']*$"))) |
| 175 | (while (and (< (point) end) | 175 | (while (and (< (point) end) |
| 176 | (re-search-forward eol-double-space-re end t)) | 176 | (re-search-forward eol-double-space-re end t)) |
| 177 | ;; We insert before markers in case a caller such as | 177 | ;; We insert before markers in case a caller such as |
| 178 | ;; do-auto-fill has done a save-excursion with point at the end | 178 | ;; do-auto-fill has done a save-excursion with point at the end |
| 179 | ;; of the line and wants it to stay at the end of the line. | 179 | ;; of the line and wants it to stay at the end of the line. |
| 180 | (insert-before-markers-and-inherit ? ))))) | 180 | (insert-before-markers-and-inherit ? ))))) |
| 181 | 181 | ||
| 182 | (defun fill-common-string-prefix (s1 s2) | 182 | (defun fill-common-string-prefix (s1 s2) |
| 183 | "Return the longest common prefix of strings S1 and S2, or nil if none." | 183 | "Return the longest common prefix of strings S1 and S2, or nil if none." |
| @@ -251,9 +251,9 @@ act as a paragraph-separator." | |||
| 251 | second-line-prefix)))) | 251 | second-line-prefix)))) |
| 252 | second-line-prefix | 252 | second-line-prefix |
| 253 | 253 | ||
| 254 | ;; Use the longest common substring of both prefixes, | 254 | ;; Use the longest common substring of both prefixes, |
| 255 | ;; if there is one. | 255 | ;; if there is one. |
| 256 | (fill-common-string-prefix first-line-prefix | 256 | (fill-common-string-prefix first-line-prefix |
| 257 | second-line-prefix)))) | 257 | second-line-prefix)))) |
| 258 | ;; If we get a fill prefix from a one-line paragraph, | 258 | ;; If we get a fill prefix from a one-line paragraph, |
| 259 | ;; maybe change it to whitespace, | 259 | ;; maybe change it to whitespace, |
| @@ -321,7 +321,7 @@ Can be customized with the variable `fill-nobreak-predicate'." | |||
| 321 | ;; The reason is that if a period ends up at the end of a | 321 | ;; The reason is that if a period ends up at the end of a |
| 322 | ;; line, further fills will assume it ends a sentence. | 322 | ;; line, further fills will assume it ends a sentence. |
| 323 | ;; If we now know it does not end a sentence, avoid putting | 323 | ;; If we now know it does not end a sentence, avoid putting |
| 324 | ;; it at the end of the line. | 324 | ;; it at the end of the line. |
| 325 | (and sentence-end-double-space | 325 | (and sentence-end-double-space |
| 326 | (save-excursion | 326 | (save-excursion |
| 327 | (skip-chars-backward ". ") | 327 | (skip-chars-backward ". ") |
| @@ -340,10 +340,10 @@ Can be customized with the variable `fill-nobreak-predicate'." | |||
| 340 | ;; Put `fill-find-break-point-function' property to charsets which | 340 | ;; Put `fill-find-break-point-function' property to charsets which |
| 341 | ;; require special functions to find line breaking point. | 341 | ;; require special functions to find line breaking point. |
| 342 | (dolist (pair '((katakana-jisx0201 . kinsoku) | 342 | (dolist (pair '((katakana-jisx0201 . kinsoku) |
| 343 | (chinese-gb2312 . kinsoku) | 343 | (chinese-gb2312 . kinsoku) |
| 344 | (japanese-jisx0208 . kinsoku) | 344 | (japanese-jisx0208 . kinsoku) |
| 345 | (japanese-jisx0212 . kinsoku) | 345 | (japanese-jisx0212 . kinsoku) |
| 346 | (chinese-big5-1 . kinsoku) | 346 | (chinese-big5-1 . kinsoku) |
| 347 | (chinese-big5-2 . kinsoku))) | 347 | (chinese-big5-2 . kinsoku))) |
| 348 | (put-charset-property (car pair) 'fill-find-break-point-function (cdr pair))) | 348 | (put-charset-property (car pair) 'fill-find-break-point-function (cdr pair))) |
| 349 | 349 | ||
| @@ -368,6 +368,79 @@ If the charset has no such property, do nothing." | |||
| 368 | (if (and func (fboundp func)) | 368 | (if (and func (fboundp func)) |
| 369 | (funcall func limit)))) | 369 | (funcall func limit)))) |
| 370 | 370 | ||
| 371 | (defun fill-delete-prefix (from to prefix) | ||
| 372 | "Delete the fill prefix from every line except the first. | ||
| 373 | The first line may not even have a fill prefix. | ||
| 374 | Point is moved to just past the fill prefix on the first line." | ||
| 375 | (goto-char from) | ||
| 376 | (let ((fpre (and prefix (not (equal prefix "")) | ||
| 377 | (concat "[ \t]*" | ||
| 378 | (replace-regexp-in-string | ||
| 379 | "[ \t]+" "[ \t]*" | ||
| 380 | (regexp-quote prefix)) | ||
| 381 | "[ \t]*")))) | ||
| 382 | (when fpre | ||
| 383 | (if (>= (+ (current-left-margin) (length prefix)) | ||
| 384 | (current-fill-column)) | ||
| 385 | (error "fill-prefix too long for specified width")) | ||
| 386 | (forward-line 1) | ||
| 387 | (while (< (point) to) | ||
| 388 | (if (looking-at fpre) | ||
| 389 | (delete-region (point) (match-end 0))) | ||
| 390 | (forward-line 1)) | ||
| 391 | (goto-char from) | ||
| 392 | (if (looking-at fpre) | ||
| 393 | (goto-char (match-end 0))) | ||
| 394 | (setq from (point)))) | ||
| 395 | ;; Remove indentation from lines other than the first. | ||
| 396 | (beginning-of-line 2) | ||
| 397 | (indent-region (point) to 0) | ||
| 398 | (goto-char from)) | ||
| 399 | |||
| 400 | (defun fill-delete-newlines (from to justify nosqueeze squeeze-after) | ||
| 401 | (goto-char from) | ||
| 402 | ;; Make sure sentences ending at end of line get an extra space. | ||
| 403 | ;; loses on split abbrevs ("Mr.\nSmith") | ||
| 404 | (let ((eol-double-space-re (if colon-double-space | ||
| 405 | "[.?!:][])}\"']*$" | ||
| 406 | "[.?!][])}\"']*$"))) | ||
| 407 | (while (re-search-forward eol-double-space-re to t) | ||
| 408 | (or (>= (point) to) (insert-and-inherit ?\ )))) | ||
| 409 | |||
| 410 | (goto-char from) | ||
| 411 | (if enable-multibyte-characters | ||
| 412 | ;; Delete unnecessay newlines surrounded by words. The | ||
| 413 | ;; character category `|' means that we can break a line | ||
| 414 | ;; at the character. And, charset property | ||
| 415 | ;; `nospace-between-words' tells how to concatenate | ||
| 416 | ;; words. If the value is non-nil, never put spaces | ||
| 417 | ;; between words, thus delete a newline between them. | ||
| 418 | ;; If the value is nil, delete a newline only when a | ||
| 419 | ;; character preceding a newline has text property | ||
| 420 | ;; `nospace-between-words'. | ||
| 421 | (while (search-forward "\n" to t) | ||
| 422 | (let ((prev (char-before (match-beginning 0))) | ||
| 423 | (next (following-char))) | ||
| 424 | (if (and (or (aref (char-category-set next) ?|) | ||
| 425 | (aref (char-category-set prev) ?|)) | ||
| 426 | (or (get-charset-property (char-charset prev) | ||
| 427 | 'nospace-between-words) | ||
| 428 | (get-text-property (1- (match-beginning 0)) | ||
| 429 | 'nospace-between-words))) | ||
| 430 | (delete-char -1))))) | ||
| 431 | |||
| 432 | (goto-char from) | ||
| 433 | (skip-chars-forward " \t") | ||
| 434 | ;; Then change all newlines to spaces. | ||
| 435 | (subst-char-in-region from to ?\n ?\ ) | ||
| 436 | (if (and nosqueeze (not (eq justify 'full))) | ||
| 437 | nil | ||
| 438 | (canonically-space-region (or squeeze-after (point)) to) | ||
| 439 | (goto-char to) | ||
| 440 | (delete-horizontal-space) | ||
| 441 | (insert-and-inherit " ")) | ||
| 442 | (goto-char from)) | ||
| 443 | |||
| 371 | (defun fill-region-as-paragraph (from to &optional justify | 444 | (defun fill-region-as-paragraph (from to &optional justify |
| 372 | nosqueeze squeeze-after) | 445 | nosqueeze squeeze-after) |
| 373 | "Fill the region as one paragraph. | 446 | "Fill the region as one paragraph. |
| @@ -421,7 +494,7 @@ space does not end a sentence, so don't break a line there." | |||
| 421 | (delete-backward-char 1) | 494 | (delete-backward-char 1) |
| 422 | (backward-char 1) | 495 | (backward-char 1) |
| 423 | (setq oneleft t))) | 496 | (setq oneleft t))) |
| 424 | (setq to (point)) | 497 | (setq to (copy-marker (point) t)) |
| 425 | ;; ;; If there was no newline, and there is text in the paragraph, then | 498 | ;; ;; If there was no newline, and there is text in the paragraph, then |
| 426 | ;; ;; create a newline. | 499 | ;; ;; create a newline. |
| 427 | ;; (if (and (not oneleft) (> to from-plus-indent)) | 500 | ;; (if (and (not oneleft) (> to from-plus-indent)) |
| @@ -436,16 +509,21 @@ space does not end a sentence, so don't break a line there." | |||
| 436 | ;; Never indent-according-to-mode with brain dead "indenting" functions. | 509 | ;; Never indent-according-to-mode with brain dead "indenting" functions. |
| 437 | (when (and fill-indent-according-to-mode | 510 | (when (and fill-indent-according-to-mode |
| 438 | (memq indent-line-function | 511 | (memq indent-line-function |
| 439 | '(indent-relative-maybe indent-relative | 512 | '(indent-relative-maybe indent-relative |
| 440 | indent-to-left-margin))) | 513 | indent-to-left-margin))) |
| 441 | (set (make-local-variable 'fill-indent-according-to-mode) nil)) | 514 | (set (make-local-variable 'fill-indent-according-to-mode) nil)) |
| 442 | 515 | ||
| 443 | ;; Don't let Adaptive Fill mode alter the fill prefix permanently. | 516 | ;; Don't let Adaptive Fill mode alter the fill prefix permanently. |
| 444 | (let ((fill-prefix fill-prefix)) | 517 | (let ((fill-prefix fill-prefix)) |
| 445 | ;; Figure out how this paragraph is indented, if desired. | 518 | ;; Figure out how this paragraph is indented, if desired. |
| 446 | (if (and adaptive-fill-mode | 519 | (when (and adaptive-fill-mode |
| 447 | (or (null fill-prefix) (string= fill-prefix ""))) | 520 | (or (null fill-prefix) (string= fill-prefix ""))) |
| 448 | (setq fill-prefix (fill-context-prefix from to))) | 521 | (setq fill-prefix (fill-context-prefix from to)) |
| 522 | ;; Ignore a white-space only fill-prefix | ||
| 523 | ;; if we indent-according-to-mode. | ||
| 524 | (when (and fill-prefix fill-indent-according-to-mode | ||
| 525 | (string-match "\\`[ \t]*\\'" fill-prefix)) | ||
| 526 | (setq fill-prefix nil))) | ||
| 449 | 527 | ||
| 450 | (save-restriction | 528 | (save-restriction |
| 451 | (goto-char from) | 529 | (goto-char from) |
| @@ -455,7 +533,7 @@ space does not end a sentence, so don't break a line there." | |||
| 455 | (if (not justify) ; filling disabled: just check indentation | 533 | (if (not justify) ; filling disabled: just check indentation |
| 456 | (progn | 534 | (progn |
| 457 | (goto-char from) | 535 | (goto-char from) |
| 458 | (while (not (eobp)) | 536 | (while (< (point) to) |
| 459 | (if (and (not (eolp)) | 537 | (if (and (not (eolp)) |
| 460 | (< (current-indentation) (current-left-margin))) | 538 | (< (current-indentation) (current-left-margin))) |
| 461 | (indent-to-left-margin)) | 539 | (indent-to-left-margin)) |
| @@ -467,77 +545,14 @@ space does not end a sentence, so don't break a line there." | |||
| 467 | (if (or (memq justify '(right center)) | 545 | (if (or (memq justify '(right center)) |
| 468 | (< (current-indentation) (current-left-margin))) | 546 | (< (current-indentation) (current-left-margin))) |
| 469 | (indent-to-left-margin)) | 547 | (indent-to-left-margin)) |
| 470 | ;; Delete the fill prefix from every line except the first. | 548 | ;; Delete the fill-prefix from every line. |
| 471 | ;; The first line may not even have a fill prefix. | 549 | (fill-delete-prefix from to fill-prefix) |
| 472 | (goto-char from) | 550 | (setq from (point)) |
| 473 | (let ((fpre (and fill-prefix (not (equal fill-prefix "")) | 551 | |
| 474 | (concat "[ \t]*" | ||
| 475 | (regexp-quote fill-prefix) | ||
| 476 | "[ \t]*")))) | ||
| 477 | (and fpre | ||
| 478 | (progn | ||
| 479 | (if (>= (+ (current-left-margin) (length fill-prefix)) | ||
| 480 | (current-fill-column)) | ||
| 481 | (error "fill-prefix too long for specified width")) | ||
| 482 | (goto-char from) | ||
| 483 | (forward-line 1) | ||
| 484 | (while (not (eobp)) | ||
| 485 | (if (looking-at fpre) | ||
| 486 | (delete-region (point) (match-end 0))) | ||
| 487 | (forward-line 1)) | ||
| 488 | (goto-char from) | ||
| 489 | (if (looking-at fpre) | ||
| 490 | (goto-char (match-end 0))) | ||
| 491 | (setq from (point))))) | ||
| 492 | ;; Remove indentation from lines other than the first. | ||
| 493 | (beginning-of-line 2) | ||
| 494 | (indent-region (point) (point-max) 0) | ||
| 495 | (goto-char from) | ||
| 496 | |||
| 497 | ;; FROM, and point, are now before the text to fill, | 552 | ;; FROM, and point, are now before the text to fill, |
| 498 | ;; but after any fill prefix on the first line. | 553 | ;; but after any fill prefix on the first line. |
| 499 | 554 | ||
| 500 | ;; Make sure sentences ending at end of line get an extra space. | 555 | (fill-delete-newlines from to justify nosqueeze squeeze-after) |
| 501 | ;; loses on split abbrevs ("Mr.\nSmith") | ||
| 502 | (let ((eol-double-space-re (if colon-double-space | ||
| 503 | "[.?!:][])}\"']*$" | ||
| 504 | "[.?!][])}\"']*$"))) | ||
| 505 | (while (re-search-forward eol-double-space-re nil t) | ||
| 506 | (or (eobp) (insert-and-inherit ?\ )))) | ||
| 507 | |||
| 508 | (goto-char from) | ||
| 509 | (if enable-multibyte-characters | ||
| 510 | ;; Delete unnecessay newlines surrounded by words. The | ||
| 511 | ;; character category `|' means that we can break a line | ||
| 512 | ;; at the character. And, charset property | ||
| 513 | ;; `nospace-between-words' tells how to concatenate | ||
| 514 | ;; words. If the value is non-nil, never put spaces | ||
| 515 | ;; between words, thus delete a newline between them. | ||
| 516 | ;; If the value is nil, delete a newline only when a | ||
| 517 | ;; character preceding a newline has text property | ||
| 518 | ;; `nospace-between-words'. | ||
| 519 | (while (search-forward "\n" nil t) | ||
| 520 | (let ((prev (char-before (match-beginning 0))) | ||
| 521 | (next (following-char))) | ||
| 522 | (if (and (or (aref (char-category-set next) ?|) | ||
| 523 | (aref (char-category-set prev) ?|)) | ||
| 524 | (or (get-charset-property (char-charset prev) | ||
| 525 | 'nospace-between-words) | ||
| 526 | (get-text-property (1- (match-beginning 0)) | ||
| 527 | 'nospace-between-words))) | ||
| 528 | (delete-char -1))))) | ||
| 529 | |||
| 530 | (goto-char from) | ||
| 531 | (skip-chars-forward " \t") | ||
| 532 | ;; Then change all newlines to spaces. | ||
| 533 | (subst-char-in-region from (point-max) ?\n ?\ ) | ||
| 534 | (if (and nosqueeze (not (eq justify 'full))) | ||
| 535 | nil | ||
| 536 | (canonically-space-region (or squeeze-after (point)) (point-max)) | ||
| 537 | (goto-char (point-max)) | ||
| 538 | (delete-horizontal-space) | ||
| 539 | (insert-and-inherit " ")) | ||
| 540 | (goto-char (point-min)) | ||
| 541 | 556 | ||
| 542 | ;; This is the actual filling loop. | 557 | ;; This is the actual filling loop. |
| 543 | (let ((prefixcol 0) linebeg) | 558 | (let ((prefixcol 0) linebeg) |
| @@ -552,24 +567,15 @@ space does not end a sentence, so don't break a line there." | |||
| 552 | ;; search space, \c| followed by a character, or \c| | 567 | ;; search space, \c| followed by a character, or \c| |
| 553 | ;; following a character. If not found, place | 568 | ;; following a character. If not found, place |
| 554 | ;; the point at linebeg. | 569 | ;; the point at linebeg. |
| 555 | (if (re-search-backward " \\|\\c|.\\|.\\c|" linebeg 0) | 570 | (while |
| 556 | ;; In case of space, we place the point at next to | 571 | (when (re-search-backward "[ \t]\\|\\c|.\\|.\\c|" linebeg 0) |
| 557 | ;; the point where the break occurs acutually, | 572 | ;; In case of space, we place the point at next to |
| 558 | ;; because we don't want to change the following | 573 | ;; the point where the break occurs actually, |
| 559 | ;; logic of original Emacs. In case of \c|, the | 574 | ;; because we don't want to change the following |
| 560 | ;; point is at the place where the break occurs. | 575 | ;; logic of original Emacs. In case of \c|, the |
| 561 | (forward-char 1)) | 576 | ;; point is at the place where the break occurs. |
| 562 | ;; Don't break after a period followed by just one space. | 577 | (forward-char 1) |
| 563 | ;; Move back to the previous place to break. | 578 | (when (fill-nobreak-p) (skip-chars-backward " \t")))) |
| 564 | ;; The reason is that if a period ends up at the end of a line, | ||
| 565 | ;; further fills will assume it ends a sentence. | ||
| 566 | ;; If we now know it does not end a sentence, | ||
| 567 | ;; avoid putting it at the end of the line. | ||
| 568 | (while (and (> (point) linebeg) | ||
| 569 | (fill-nobreak-p) | ||
| 570 | (skip-chars-backward " \t")) | ||
| 571 | (if (re-search-backward " \\|\\c|.\\|.\\c|" linebeg 0) | ||
| 572 | (forward-char 1))) | ||
| 573 | ;; If the left margin and fill prefix by themselves | 579 | ;; If the left margin and fill prefix by themselves |
| 574 | ;; pass the fill-column. or if they are zero | 580 | ;; pass the fill-column. or if they are zero |
| 575 | ;; but we have no room for even one word, | 581 | ;; but we have no room for even one word, |