Mercurial > hg > xemacs-beta
diff lisp/packages/filladapt.el @ 108:360340f9fd5f r20-1b6
Import from CVS: tag r20-1b6
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:18:39 +0200 |
parents | 131b0175ea99 |
children | cca96a509cfe |
line wrap: on
line diff
--- a/lisp/packages/filladapt.el Mon Aug 13 09:17:27 2007 +0200 +++ b/lisp/packages/filladapt.el Mon Aug 13 09:18:39 2007 +0200 @@ -1,8 +1,5 @@ -;;; filladapt.el --- adaptive fill; replacement for fill commands - -;; Keywords: wp - -;;; Copyright (C) 1989, 1995, 1996 Kyle E. Jones +;;; Adaptive fill +;;; Copyright (C) 1989, 1995, 1996, 1997 Kyle E. Jones ;;; ;;; This program is free software; you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by @@ -19,18 +16,16 @@ ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA ;;; 02139, USA. ;;; -;;; Send bug reports to kyle@wonderworks.com - -;;; Synched up with: Not in FSF. +;;; Send bug reports to kyle_jones@wonderworks.com ;; LCD Archive Entry: ;; filladapt|Kyle Jones|kyle_jones@wonderworks.com| ;; Minor mode to adaptively set fill-prefix and overload filling functions| -;; 10-June-1996|2.08|~/packages/filladapt.el| +;; 10-June-1996|2.09|~/packages/filladapt.el| ;; These functions enhance the default behavior of Emacs' Auto Fill -;; mode and the commands fill-paragraph, lisp-fill-paragraph and -;; fill-region-as-paragraph. +;; mode and the commands fill-paragraph, lisp-fill-paragraph, +;; fill-region-as-paragraph and fill-region. ;; ;; The chief improvement is that the beginning of a line to be ;; filled is examined and, based on information gathered, an @@ -72,9 +67,12 @@ ;; filladapt-token-match-table ;; filladapt-token-conversion-table +(and (featurep 'filladapt) + (error "filladapt cannot be loaded twice in the same Emacs session.")) + (provide 'filladapt) -(defvar filladapt-version "2.08" +(defvar filladapt-version "2.09" "Version string for filladapt.") (defvar filladapt-mode nil @@ -86,6 +84,28 @@ "*String to display in the modeline when Filladapt mode is active. Set this to nil if you don't want a modeline indicator for Filladapt.") +(defvar filladapt-fill-column-tolerance nil + "*Tolerate filled paragraph lines ending this far from the fill column. +If any lines other than the last paragraph line end at a column +less than fill-column - filladapt-fill-column-tolerance, fill-column will +be adjusted using the filladapt-fill-column-*-fuzz variables and +the paragraph will be re-filled until the tolerance is achieved +or filladapt runs out of fuzz values to try. + +A nil value means behave normally, that is, don't try refilling +paragraphs to make filled line lengths fit within any particular +range.") + +(defvar filladapt-fill-column-forward-fuzz 5 + "*Try values from fill-column to fill-column plus this variable +when trying to make filled paragraph lines fall with the tolerance +range specified by filladapt-fill-column-tolerance.") + +(defvar filladapt-fill-column-backward-fuzz 5 + "*Try values from fill-column to fill-column minus this variable +when trying to make filled paragraph lines fall with the tolerance +range specified by filladapt-fill-column-tolerance.") + ;; install on minor-mode-alist (or (assq 'filladapt-mode minor-mode-alist) (setq minor-mode-alist (cons (list 'filladapt-mode @@ -94,76 +114,82 @@ (defvar filladapt-token-table '( + ;; this must be first + ("^" beginning-of-line) ;; Included text in news or mail replies - (">+" . citation->) + (">+" citation->) ;; Included text generated by SUPERCITE. We can't hope to match all ;; the possible variations, your mileage may vary. - ("[A-Za-z0-9][^'`\"< \t\n]*>[ \t]*" . supercite-citation) + ("[A-Za-z0-9][^'`\"< \t\n]*>[ \t]*" supercite-citation) ;; Lisp comments - (";+" . lisp-comment) + (";+" lisp-comment) ;; UNIX shell comments - ("#+" . sh-comment) + ("#+" sh-comment) ;; Postscript comments - ("%+" . postscript-comment) + ("%+" postscript-comment) ;; C++ comments - ("///*" . c++-comment) + ("///*" c++-comment) ;; Texinfo comments - ("@c[ \t]" . texinfo-comment) - ("@comment[ \t]" . texinfo-comment) + ("@c[ \t]" texinfo-comment) + ("@comment[ \t]" texinfo-comment) ;; Bullet types. ;; + ;; LaTex \item + ;; + ("\\\\item[ \t]" bullet) + ;; ;; 1. xxxxx ;; xxxxx ;; - ("[0-9]+\\.[ \t]" . bullet) + ("[0-9]+\\.[ \t]" bullet) ;; ;; 2.1.3 xxxxx xx x xx x ;; xxx ;; - ("[0-9]+\\(\\.[0-9]+\\)+[ \t]" . bullet) + ("[0-9]+\\(\\.[0-9]+\\)+[ \t]" bullet) ;; ;; a. xxxxxx xx ;; xxx xxx ;; - ("[A-Za-z]\\.[ \t]" . bullet) + ("[A-Za-z]\\.[ \t]" bullet) ;; ;; 1) xxxx x xx x xx or (1) xx xx x x xx xx ;; xx xx xxxx xxx xx x x xx x ;; - ("(?[0-9]+)[ \t]" . bullet) + ("(?[0-9]+)[ \t]" bullet) ;; ;; a) xxxx x xx x xx or (a) xx xx x x xx xx ;; xx xx xxxx xxx xx x x xx x ;; - ("(?[A-Za-z])[ \t]" . bullet) + ("(?[A-Za-z])[ \t]" bullet) ;; ;; 2a. xx x xxx x x xxx ;; xxx xx x xx x ;; - ("[0-9]+[A-Za-z]\\.[ \t]" . bullet) + ("[0-9]+[A-Za-z]\\.[ \t]" bullet) ;; ;; 1a) xxxx x xx x xx or (1a) xx xx x x xx xx ;; xx xx xxxx xxx xx x x xx x ;; - ("(?[0-9]+[A-Za-z])[ \t]" . bullet) + ("(?[0-9]+[A-Za-z])[ \t]" bullet) ;; ;; - xx xxx xxxx or * xx xx x xxx xxx ;; xxx xx xx x xxx x xx x x x ;; - ("[-~*+]+[ \t]" . bullet) + ("[-~*+]+[ \t]" bullet) ;; ;; o xx xxx xxxx xx x xx xxx x xxx xx x xxx ;; xxx xx xx ;; - ("o[ \t]" . bullet) + ("o[ \t]" bullet) ;; don't touch - ("[ \t]+" . space) - ("$" . end-of-line) + ("[ \t]+" space) + ("$" end-of-line) ) "Table of tokens filladapt knows about. Format is - ((REGEXP . SYM) ...) + ((REGEXP SYM) ...) filladapt uses this table to build a tokenized representation of the beginning of the current line. Each REGEXP is matched @@ -199,6 +225,7 @@ (texinfo-comment texinfo-comment) (bullet) (space bullet space) + (beginning-of-line beginning-of-line) ) "Table describing what tokens a certain token will match. @@ -261,6 +288,7 @@ (defvar filladapt-function-table (let ((assoc-list (list (cons 'fill-paragraph (symbol-function 'fill-paragraph)) + (cons 'fill-region (symbol-function 'fill-region)) (cons 'fill-region-as-paragraph (symbol-function 'fill-region-as-paragraph)) (cons 'do-auto-fill (symbol-function 'do-auto-fill))))) @@ -349,23 +377,91 @@ fill-prefix retval) (if (filladapt-adapt t nil) (progn - (setq retval (filladapt-funcall function arg)) + (if filladapt-fill-column-tolerance + (let* ((low (- fill-column + filladapt-fill-column-backward-fuzz)) + (high (+ fill-column + filladapt-fill-column-forward-fuzz)) + (old-fill-column fill-column) + (fill-column fill-column) + (lim (- high low)) + (done nil) + (sign 1) + (delta 0)) + (while (not done) + (setq retval (filladapt-funcall function arg)) + (if (filladapt-paragraph-within-fill-tolerance) + (setq done 'success) + (setq delta (1+ delta) + sign (* sign -1) + fill-column (+ fill-column (* delta sign))) + (while (and (<= delta lim) + (or (< fill-column low) + (> fill-column high))) + (setq delta (1+ delta) + sign (* sign -1) + fill-column (+ fill-column + (* delta sign)))) + (setq done (> delta lim)))) + ;; if the paragraph lines never fell + ;; within the tolerances, refill using + ;; the old fill-column. + (if (not (eq done 'success)) + (let ((fill-column old-fill-column)) + (setq retval (filladapt-funcall function arg))))) + (setq retval (filladapt-funcall function arg))) (run-hooks 'filladapt-fill-paragraph-post-hook) (throw 'done retval)))))) ;; filladapt-adapt failed, so do fill-paragraph normally. (filladapt-funcall function arg))) (defun fill-paragraph (arg) + "Fill paragraph at or after point. Prefix arg means justify as well. + +(This function has been overloaded with the `filladapt' version.) + +If `sentence-end-double-space' is non-nil, then period followed by one +space does not end a sentence, so don't break a line there. + +If `fill-paragraph-function' is non-nil, we call it (passing our +argument to it), and if it returns non-nil, we simply return its value." (interactive "*P") (let ((filladapt-inside-filladapt t)) (filladapt-fill-paragraph 'fill-paragraph arg))) (defun lisp-fill-paragraph (&optional arg) + "Like \\[fill-paragraph], but handle Emacs Lisp comments. + +(This function has been overloaded with the `filladapt' version.) + +If any of the current line is a comment, fill the comment or the +paragraph of it that point is in, preserving the comment's indentation +and initial semicolons." (interactive "*P") (let ((filladapt-inside-filladapt t)) (filladapt-fill-paragraph 'lisp-fill-paragraph arg))) -(defun fill-region-as-paragraph (beg end &optional justify nosqueeze squeeze-after) +(defun fill-region-as-paragraph (beg end &optional justify + nosqueeze squeeze-after) + "Fill the region as one paragraph. + +(This function has been overloaded with the `filladapt' version.) + +It removes any paragraph breaks in the region and extra newlines at the end, +indents and fills lines between the margins given by the +`current-left-margin' and `current-fill-column' functions. +It leaves point at the beginning of the line following the paragraph. + +Normally performs justification according to the `current-justification' +function, but with a prefix arg, does full justification instead. + +From a program, optional third arg JUSTIFY can specify any type of +justification. Fourth arg NOSQUEEZE non-nil means not to make spaces +between words canonical before filling. Fifth arg SQUEEZE-AFTER, if non-nil, +means don't canonicalize spaces before that position. + +If `sentence-end-double-space' is non-nil, then period followed by one +space does not end a sentence, so don't break a line there." (interactive "*r\nP") (if (and filladapt-mode (not filladapt-inside-filladapt)) (save-restriction @@ -373,6 +469,8 @@ (let ((filladapt-inside-filladapt t) line-start last-token) (goto-char beg) + (while (equal (char-after (point)) ?\n) + (delete-char 1)) (end-of-line) (while (zerop (forward-line)) (if (setq last-token @@ -405,9 +503,59 @@ ;; four args for Emacs 19.29 (filladapt-funcall 'fill-region-as-paragraph beg end justify nosqueeze) - ;; three args for the rest of the world. + ;; three args for the rest of the world. + (wrong-number-of-arguments + (filladapt-funcall 'fill-region-as-paragraph beg end justify))))))) + +(defun fill-region (beg end &optional justify nosqueeze to-eop) + "Fill each of the paragraphs in the region. + +(This function has been overloaded with the `filladapt' version.) + +Prefix arg (non-nil third arg, if called from program) means justify as well. + +Noninteractively, 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). + +If `sentence-end-double-space' is non-nil, then period followed by one +space does not end a sentence, so don't break a line there." + (interactive "*r\nP") + (if (and filladapt-mode (not filladapt-inside-filladapt)) + (save-restriction + (narrow-to-region beg end) + (let ((filladapt-inside-filladapt t) + start) + (goto-char beg) + (while (not (eobp)) + (setq start (point)) + (while (and (not (eobp)) (not (filladapt-parse-prefixes))) + (forward-line 1)) + (if (not (equal start (point))) + (progn + (save-restriction + (narrow-to-region start (point)) + (fill-region start (point) justify nosqueeze to-eop) + (goto-char (point-max))) + (if (and (not (bolp)) (not (eobp))) + (forward-line 1)))) + (if (filladapt-parse-prefixes) + (progn + (save-restriction + ;; for the clipping region + (filladapt-adapt t t) + (fill-paragraph justify) + (goto-char (point-max))) + (if (and (not (bolp)) (not (eobp))) + (forward-line 1))))))) + (condition-case nil + (filladapt-funcall 'fill-region beg end justify nosqueeze to-eop) (wrong-number-of-arguments - (filladapt-funcall 'fill-region-as-paragraph beg end justify))))))) + (condition-case nil + (filladapt-funcall 'fill-region beg end justify nosqueeze) + (wrong-number-of-arguments + (filladapt-funcall 'fill-region beg end justify))))))) (defvar zmacs-region-stays) ; for XEmacs @@ -463,7 +611,7 @@ (done nil) (old-point (point)) (case-fold-search nil) - token-table not-token-table) + token-table not-token-table moved) (catch 'done (while (not done) (setq not-token-table filladapt-not-token-table) @@ -477,14 +625,15 @@ (if (null (looking-at (car (car token-table)))) (setq token-table (cdr token-table)) (goto-char (match-end 0)) - (setq token-list (cons (list (cdr (car token-table)) + (setq token-list (cons (list (nth 1 (car token-table)) (current-column) (buffer-substring (match-beginning 0) (match-end 0))) token-list) - token-table nil - done (eq (point) old-point) + moved (not (eq (point) old-point)) + token-table (if moved nil (cdr token-table)) + done (not moved) old-point (point)))))) (nreverse token-list)))) @@ -584,6 +733,20 @@ (setq list (cdr list))) (apply (function concat) (nreverse prefix-list)) )) +(defun filladapt-paragraph-within-fill-tolerance () + (catch 'done + (save-excursion + (let ((low (- fill-column filladapt-fill-column-tolerance)) + (shortline nil)) + (goto-char (point-min)) + (while (not (eobp)) + (if shortline + (throw 'done nil) + (end-of-line) + (setq shortline (< (current-column) low)) + (forward-line 1))) + t )))) + (defun filladapt-convert-to-spaces (string) "Return a copy of STRING, with all non-tabs and non-space changed to spaces." (let ((i 0) @@ -710,10 +873,6 @@ ;; (interactive) (make-local-variable 'filladapt-debug) (setq filladapt-debug (not filladapt-debug)) - ;; make sure these faces exist at least - (make-face 'filladapt-debug-indentation-face-1) - (make-face 'filladapt-debug-indentation-face-2) - (make-face 'filladapt-debug-paragraph-face) (if (null filladapt-debug) (progn (mapcar (function (lambda (e) (filladapt-set-extent-endpoints e 1 1)))