aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2001-11-19 23:51:03 +0000
committerStefan Monnier2001-11-19 23:51:03 +0000
commit2f4fa275e8858f83712bee5ca6714945c70e358d (patch)
treeddcab55c6c57a47fbd27b13b24dcec0c689e7c7a
parent99b3bc616bf09f72d91f11f85c41cd08f52ca5bf (diff)
downloademacs-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.el218
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.
373The first line may not even have a fill prefix.
374Point 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,