X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9bcdf9a8fdae9bf6128fd45454ff1f0c785d5da2..d3857d85ab7e18b5dafdb6395e811bb566f8184b:/lisp/textmodes/fill.el diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el index a8a9852483..dfd471a87c 100644 --- a/lisp/textmodes/fill.el +++ b/lisp/textmodes/fill.el @@ -1,6 +1,6 @@ ;;; fill.el --- fill commands for Emacs -;; Copyright (C) 1985,86,92,94,95,96,97,1999,2001,2002 +;; Copyright (C) 1985,86,92,94,95,96,97,1999,2001,02,03,2004 ;; Free Software Foundation, Inc. ;; Maintainer: FSF @@ -30,6 +30,11 @@ ;;; Code: +(defgroup fill nil + "Indenting and filling text." + :link '(custom-manual "(emacs)Filling") + :group 'editing) + (defcustom fill-individual-varying-indent nil "*Controls criterion for a new paragraph in `fill-individual-paragraphs'. Non-nil means changing indent doesn't end a paragraph. @@ -49,13 +54,14 @@ A value of nil means that any change in indentation starts a new paragraph." If the function returns nil, then `fill-paragraph' does its normal work.") (defvar fill-paragraph-handle-comment t - "If non-nil, paragraph filling will try to pay attention to comments.") + "Non-nil means paragraph filling will try to pay attention to comments.") -(defvar enable-kinsoku t - "*Non-nil means enable \"kinsoku\" processing on filling paragraph. +(defcustom enable-kinsoku t + "*Non-nil means enable \"kinsoku\" processing on filling paragraphs. Kinsoku processing is designed to prevent certain characters from being placed at the beginning or end of a line by filling. -See the documentation of `kinsoku' for more information.") +See the documentation of `kinsoku' for more information." + :type 'boolean) (defun set-fill-prefix () "Set the fill prefix to the current line up to point. @@ -149,7 +155,7 @@ Leave one space between words, two at end of sentences or after colons and `sentence-end-without-period'). Remove indentation from each line." (interactive "*r") - (let ((end-spc-re (concat "\\(" sentence-end "\\) *\\| +"))) + (let ((end-spc-re (concat "\\(" (sentence-end) "\\) *\\| +"))) (save-excursion (goto-char beg) ;; Nuke tabs; they get screwed up in a fill. @@ -317,7 +323,7 @@ be tested. If it returns t, fill commands do not break the line there." :options '(fill-french-nobreak-p fill-single-word-nobreak-p)) (defcustom fill-nobreak-invisible nil - "Non-nil means that fill command do not break lines in invisible text." + "Non-nil means that fill commands do not break lines in invisible text." :type 'boolean :group 'fill) @@ -343,11 +349,16 @@ and `fill-nobreak-invisible'." (save-excursion (skip-chars-backward ". ") (and (looking-at "\\.") - (not (looking-at sentence-end)))) + (not (looking-at (sentence-end))))) ;; Don't split a line if the rest would look like a new paragraph. (unless use-hard-newlines (save-excursion - (skip-chars-forward " \t") (looking-at paragraph-start))) + (skip-chars-forward " \t") + ;; If this break point is at the end of the line, + ;; which can occur for auto-fill, don't consider the newline + ;; which follows as a reason to return t. + (and (not (eolp)) + (looking-at paragraph-start)))) (run-hook-with-args-until-success 'fill-nobreak-predicate))))) ;; Put `fill-find-break-point-function' property to charsets which @@ -365,7 +376,7 @@ and `fill-nobreak-invisible'." Don't move back past the buffer position LIMIT. This function is called when we are going to break the current line -after or before a non-ascii character. If the charset of the +after or before a non-ASCII character. If the charset of the character has the property `fill-find-break-point-function', this function calls the property value as a function with one arg LINEBEG. If the charset has no such property, do nothing." @@ -406,20 +417,30 @@ Point is moved to just past the fill prefix on the first line." (goto-char (match-end 0))) (setq from (point)))) +;; The `fill-space' property carries the string with which a newline +;; should be replaced when unbreaking a line (in fill-delete-newlines). +;; It is added to newline characters by fill-newline when the default +;; behavior of fill-delete-newlines is not what we want. +(add-to-list 'text-property-default-nonsticky '(fill-space . t)) + (defun fill-delete-newlines (from to justify nosqueeze squeeze-after) (goto-char from) ;; Make sure sentences ending at end of line get an extra space. ;; loses on split abbrevs ("Mr.\nSmith") (let ((eol-double-space-re (cond - ((not colon-double-space) (concat sentence-end "$")) + ((not colon-double-space) (concat (sentence-end) "$")) ;; Try to add the : inside the `sentence-end' regexp. - ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" sentence-end) - (concat (replace-match ".:" nil nil sentence-end 1) "$")) + ((string-match "\\[[^][]*\\(\\.\\)[^][]*\\]" (sentence-end)) + (concat (replace-match ".:" nil nil (sentence-end) 1) "$")) ;; Can't find the right spot to insert the colon. - (t "[.?!:][])}\"']*$")))) + (t "[.?!:][])}\"']*$"))) + (sentence-end-without-space-list + (string-to-list sentence-end-without-space))) (while (re-search-forward eol-double-space-re to t) (or (>= (point) to) (memq (char-before) '(?\t ?\ )) + (memq (char-after (match-beginning 0)) + sentence-end-without-space-list) (insert-and-inherit ?\ )))) (goto-char from) @@ -434,15 +455,17 @@ Point is moved to just past the fill prefix on the first line." ;; character preceding a newline has text property ;; `nospace-between-words'. (while (search-forward "\n" to t) - (let ((prev (char-before (match-beginning 0))) - (next (following-char))) - (if (and (or (aref (char-category-set next) ?|) - (aref (char-category-set prev) ?|)) - (or (get-charset-property (char-charset prev) - 'nospace-between-words) - (get-text-property (1- (match-beginning 0)) - 'nospace-between-words))) - (delete-char -1))))) + (if (get-text-property (match-beginning 0) 'fill-space) + (replace-match (get-text-property (match-beginning 0) 'fill-space)) + (let ((prev (char-before (match-beginning 0))) + (next (following-char))) + (if (and (or (aref (char-category-set next) ?|) + (aref (char-category-set prev) ?|)) + (or (get-charset-property (char-charset prev) + 'nospace-between-words) + (get-text-property (1- (match-beginning 0)) + 'nospace-between-words))) + (delete-char -1)))))) (goto-char from) (skip-chars-forward " \t") @@ -520,19 +543,17 @@ The break position will be always after LINEBEG and generally before point." ;; Replace whitespace here with one newline, then ;; indent to left margin. (skip-chars-backward " \t") - (if (and (= (following-char) ?\ ) - (or (aref (char-category-set (preceding-char)) ?|) - (looking-at "[ \t]+\\c|"))) - ;; We need one space at end of line so that - ;; further filling won't delete it. NOTE: We - ;; intentionally leave this one space to - ;; distinguish the case that user wants to put - ;; space between \c| characters. - (forward-char 1)) (insert ?\n) ;; Give newline the properties of the space(s) it replaces (set-text-properties (1- (point)) (point) (text-properties-at (point))) + (and (looking-at "\\( [ \t]*\\)\\(\\c|\\)?") + (or (aref (char-category-set (or (char-before (1- (point))) ?\000)) ?|) + (match-end 2)) + ;; When refilling later on, this newline would normally not be replaced + ;; by a space, so we need to mark it specially to re-install the space + ;; when we unfill. + (put-text-property (1- (point)) (point) 'fill-space (match-string 1))) ;; If we don't want breaks in invisible text, don't insert ;; an invisible newline. (if fill-nobreak-invisible @@ -722,7 +743,7 @@ If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling." ;; Then try our syntax-aware filling code. (and fill-paragraph-handle-comment ;; Our code only handles \n-terminated comments right now. - comment-start comment-start-skip (equal comment-end "") + comment-start (equal comment-end "") (let ((fill-paragraph-handle-comment nil)) (fill-comment-paragraph arg))) ;; If it all fails, default to the good ol' text paragraph filling. @@ -779,14 +800,29 @@ can take care of filling. JUSTIFY is used as in `fill-paragraph'." ;; Narrow to include only the comment, and then fill the region. (let* ((fill-prefix fill-prefix) - (comment-re (concat "[ \t]*\\(?:" comment-start-skip "\\)")) + (commark + (comment-string-strip (buffer-substring comstart comin) nil t)) + (comment-re + (if (string-match comment-start-skip (concat commark "a")) + (concat "[ \t]*" (regexp-quote commark) + ;; Make sure we only match comments that use + ;; the exact same comment marker. + "[^" (substring commark -1) "]") + ;; If the commark needs to be followed by some special + ;; set of characters (like @c in TeXinfo), we can't + ;; rely just on `commark'. + (concat "[ \t]*\\(?:" comment-start-skip "\\)"))) (comment-fill-prefix ; Compute a fill prefix. (save-excursion (goto-char comstart) (if has-code-and-comment - (concat (make-string (/ (current-column) tab-width) ?\t) - (make-string (% (current-column) tab-width) ?\ ) - (buffer-substring (point) comin)) + (concat + (if (not indent-tabs-mode) + (make-string (current-column) ?\ ) + (concat + (make-string (/ (current-column) tab-width) ?\t) + (make-string (% (current-column) tab-width) ?\ ))) + (buffer-substring (point) comin)) (buffer-substring (line-beginning-position) comin)))) beg end) (save-excursion @@ -801,7 +837,11 @@ can take care of filling. JUSTIFY is used as in `fill-paragraph'." (looking-at comment-re))) ;; We may have gone too far. Go forward again. (line-beginning-position - (if (looking-at (concat ".*\\(?:" comment-start-skip "\\)")) + (if (progn + (goto-char + (or (comment-search-forward (line-end-position) t) + (point))) + (looking-at comment-re)) 1 2)))) ;; Find the beginning of the first line past the region to fill. (save-excursion @@ -819,8 +859,13 @@ can take care of filling. JUSTIFY is used as in `fill-paragraph'." (concat paragraph-start "\\|[ \t]*\\(?:" comment-start-skip "\\)\\(?:" (default-value 'paragraph-start) "\\)")) - (paragraph-ignore-fill-prefix nil) - (fill-prefix comment-fill-prefix) + ;; We used to reply on fill-prefix to break paragraph at + ;; comment-starter changes, but it did not work for the + ;; first line (mixed comment&code). + ;; We now use comment-re instead to "manually" make sure + ;; we treat comment-marker changes as paragraph boundaries. + ;; (paragraph-ignore-fill-prefix nil) + ;; (fill-prefix comment-fill-prefix) (after-line (if has-code-and-comment (line-beginning-position 2)))) (setq end (progn (forward-paragraph) (point))) @@ -867,7 +912,7 @@ as specified by its text properties. The fourth arg NOSQUEEZE non-nil means to leave whitespace other than line breaks untouched, and fifth arg TO-EOP non-nil means to keep filling to the end of the paragraph (or next -hard newline, if `use-hard-newlines' is on). +hard newline, if variable `use-hard-newlines' is on). Return the fill-prefix used for filling the last paragraph. @@ -951,8 +996,8 @@ beginning and end of the region are not at paragraph breaks, they are moved to the beginning and end \(respectively) of the paragraphs they are in. -If `use-hard-newlines' is true, all hard newlines are taken to be paragraph -breaks. +If variable `use-hard-newlines' is true, all hard newlines are +taken to be paragraph breaks. When calling from a program, operates just on region between BEGIN and END, unless optional fourth arg WHOLE-PAR is non-nil. In that case bounds are @@ -1389,4 +1434,5 @@ Also, if CITATION-REGEXP is non-nil, don't fill header lines." "") string)) +;;; arch-tag: 727ad455-1161-4fa9-8df5-0f74b179216d ;;; fill.el ends here