emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Filling woes


From: Alan Mackenzie
Subject: Filling woes
Date: Tue, 17 May 2005 20:20:11 +0000 (GMT)

Hi, Emacs!

I wanted to enhance text-mode (for my own use only, not as a
contribution), so that it would recognise a list of items begun by
parenthesized roman numerals as list items, and fill them as below:

(i) The paragraph recognition code should regard each such list item as a
  distinct paragraph, so that M-q and friends leave the paragraph
  structure intact;
(ii) Filling, including the auto-fill variety, should indent the second
  and subsequent lines of a "roman paragraph" by two spaces.

Should be easy, shouldn't it?  Well, yes, but it took me many hours.  I
wasn't able to understand the documentation (Emacs manual's pages "Fill
Prefix", "Adaptive Fill";  Elisp's "Adaptive Fill").  It was too vague
for me to get anything definite out of.  In particular, there was no
clear description of how Emacs determines the fill prefix for a
paragraph; only inadequate disjoint descriptions of the pertinent
variables.  In the end I had to edebugger my way through the filling
code.

And there I found something which I think should be changed:  In the
function `fill-context-prefix' (whose purpose is determining the fill
prefix in the given region (usually a paragraph)), the code first tries
to match the start of a line against `adaptive-fill-regexp' and if it
fails, funcalls `adaptive-fill-function', if non-nil.

This is crazy!  The default value for `adaptive-fiill-regexp' matches the
null string, so if I want to use `adaptive-fill-function', I've got to
somehow clobber this regexp.  Having done that, I would have to
incorporate its functionality into my `adaptive-fill-function'.  YUCK!!!

Surely `adaptive-fill-function' should be tried first.  MUST be tried
first.  Surely?  Or have I missed something significant in the filling
mechanism?

Once I'd put this change into fill.el (see the patch below), I was able
to get the formatting I wanted with this code in my .emacs:

#########################################################################
;; Stuff for formatting "Roman lists" in text-mode
(defconst roman-u (regexp-opt '("i" "ii" "iii" "iv" "v" "vi" "vii" "viii" 
"ix")))
(defconst roman-t (regexp-opt '("x" "xx" "xxx" "xl" "l" "lx" "lxx" "lxxx" 
"xc")))
(defconst roman
  (concat "\\(\\(" roman-t "\\)\\(" roman-u "\\)?\\)\\|\\(" roman-u "\\)"))
(defconst p-roman (concat "(\\(" roman "\\))"))
(defconst opt-nl-p-roman (concat "\n?" p-roman )) ; backward-paragraph can go 
to the blank line before.

(defun roman-adaptive-fill-prefix ()
  "Return a string of 2 spaces iff we're in a \"Roman list\" item."
  (save-excursion
    (forward-line 0)
    (unless (and (looking-at paragraph-start) (not (looking-at 
paragraph-separate)))
      (backward-paragraph))
    (if (looking-at opt-nl-p-roman) "  ")))

(defun enable-paren-lists ()
  (setq paragraph-start (concat p-roman "\\|" paragraph-start)
        adaptive-fill-function 'roman-adaptive-fill-prefix))

(add-hook 'text-mode-hook 'enable-paren-lists)
#########################################################################

Here is the patch to fill.el.  (I've only tested with the equivalent
patch on 21.3's fill.el, though.)

2005-05-17  Alan Mackenzie  <address@hidden>

        * fill.el (fill-context-prefix): Try `adaptive-fill-function'
        BEFORE `adaptive-fill-regexp' when determining a fill prefix.
        (adaptive-file-function): Minor amendment to doc-string.


*** fill-1.175.el       Sat May 14 19:51:44 2005
--- fill-1.175.acm.el   Tue May 17 19:37:57 2005
***************
*** 114,120 ****
  
  (defcustom adaptive-fill-function nil
    "*Function to call to choose a fill prefix for a paragraph, or nil.
! This function is used when `adaptive-fill-regexp' does not match."
    :type '(choice (const nil) function)
    :group 'fill)
  
--- 114,120 ----
  
  (defcustom adaptive-fill-function nil
    "*Function to call to choose a fill prefix for a paragraph, or nil.
! nil means the function has not determined the fill prefix."
    :type '(choice (const nil) function)
    :group 'fill)
  
***************
*** 229,237 ****
            ;; Also setting first-line-prefix to nil prevents
            ;; second-line-prefix from being used.
            (cond ;; ((looking-at paragraph-start) nil)
                  ((and adaptive-fill-regexp (looking-at adaptive-fill-regexp))
!                  (match-string-no-properties 0))
!                 (adaptive-fill-function (funcall adaptive-fill-function))))
        (forward-line 1)
        (if (< (point) to)
        (progn
--- 229,237 ----
            ;; Also setting first-line-prefix to nil prevents
            ;; second-line-prefix from being used.
            (cond ;; ((looking-at paragraph-start) nil)
+                 ((and adaptive-fill-function (funcall 
adaptive-fill-function)))
                  ((and adaptive-fill-regexp (looking-at adaptive-fill-regexp))
!                  (match-string-no-properties 0))))
        (forward-line 1)
        (if (< (point) to)
        (progn
***************
*** 239,249 ****
          (setq start (point))
          (setq second-line-prefix
                (cond ((looking-at paragraph-start) nil) ;Can it happen ? -stef
                      ((and adaptive-fill-regexp
                            (looking-at adaptive-fill-regexp))
!                      (buffer-substring-no-properties start (match-end 0)))
!                     (adaptive-fill-function
!                      (funcall adaptive-fill-function))))
          ;; If we get a fill prefix from the second line,
          ;; make sure it or something compatible is on the first line too.
          (when second-line-prefix
--- 239,249 ----
          (setq start (point))
          (setq second-line-prefix
                (cond ((looking-at paragraph-start) nil) ;Can it happen ? -stef
+                     ((and adaptive-fill-function
+                           (funcall adaptive-fill-function)))
                      ((and adaptive-fill-regexp
                            (looking-at adaptive-fill-regexp))
!                      (buffer-substring-no-properties start (match-end 0)))))
          ;; If we get a fill prefix from the second line,
          ;; make sure it or something compatible is on the first line too.
          (when second-line-prefix

-- 
Alan Mackenzie (Munich, Germany)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]