el/dot-emacs.el: Make fill-prefix patterns much fancier.
[profile] / el / dot-emacs.el
index 5bde809..f86044d 100644 (file)
@@ -1196,14 +1196,28 @@ If there's no fill prefix currently set (by the `fill-prefix'
 variable) and there's a match from one of the regexps here, it
 gets used to set the fill-prefix for the current operation.
 
-The variable is a list of items of the form `REGEXP . PREFIX'; if
-the REGEXP matches, the PREFIX is used to set the fill prefix.
-It in turn is a list of things:
+The variable is a list of items of the form `PATTERN . PREFIX'; if
+the PATTERN matches, the PREFIX is used to set the fill prefix.
 
-  STRING -- insert a literal string
-  (match . N) -- insert the thing matched by bracketed subexpression N
-  (pad . N) -- a string of whitespace the same width as subexpression N
-  (expr . FORM) -- the result of evaluating FORM")
+A PATTERN is one of the following.
+
+  * STRING -- a regular expression, expected to match at point
+  * (eval . FORM) -- a Lisp form which must evaluate non-nil
+  * (if COND CONSEQ-PAT ALT-PAT) -- if COND evaluates non-nil, must match
+    CONSEQ-PAT; otherwise must match ALT-PAT
+  * (and PATTERN ...) -- must match all of the PATTERNs
+  * (or PATTERN ...) -- must match at least one PATTERN
+  * (not PATTERN) -- mustn't match (probably not useful)
+
+A PREFIX is a list of the following kinds of things:
+
+  * STRING -- insert a literal string
+  * (match . N) -- insert the thing matched by bracketed subexpression N
+  * (pad . N) -- a string of whitespace the same width as subexpression N
+  * (expr . FORM) -- the result of evaluating FORM
+
+Information about `bracketed subexpressions' comes from the match data,
+as modified during matching.")
 
 (make-variable-buffer-local 'mdw-fill-prefix)
 
@@ -1227,6 +1241,42 @@ This is mainly useful in `auto-fill-mode'.")
          (funcall tabfun (point-min) (point-max))
          (setq s (buffer-substring (point-min) (1- (point-max)))))))))
 
+(defun mdw-fill-prefix-match-p (pat)
+  "Return non-nil if PAT matches at the current position."
+  (cond ((stringp pat) (looking-at pat))
+       ((not (consp pat)) (error "Unknown pattern item `%S'" pat))
+       ((eq (car pat) 'eval) (eval (cdr pat)))
+       ((eq (car pat) 'if)
+        (if (or (null (cdr pat))
+                (null (cddr pat))
+                (null (cdddr pat))
+                (cddddr pat))
+            (error "Invalid `if' pattern `%S'" pat))
+        (mdw-fill-prefix-match-p (if (eval (cadr pat))
+                                     (caddr pat)
+                                   (cadddr pat))))
+       ((eq (car pat) 'and)
+        (let ((pats (cdr pat))
+              (ok t))
+          (while (and pats
+                      (or (mdw-fill-prefix-match-p (car pats))
+                          (setq ok nil)))
+            (setq pats (cdr pats)))
+          ok))
+       ((eq (car pat) 'or)
+        (let ((pats (cdr pat))
+              (ok nil))
+          (while (and pats
+                      (or (not (mdw-fill-prefix-match-p (car pats)))
+                          (progn (setq ok t) nil)))
+            (setq pats (cdr pats)))
+          ok))
+       ((eq (car pat) 'not)
+        (if (or (null (cdr pat)) (cddr pat))
+            (error "Invalid `not' pattern `%S'" pat))
+        (not (mdw-fill-prefix-match-p (car pats))))
+       (t (error "Unknown pattern form `%S'" pat))))
+
 (defun mdw-maybe-car (p)
   "If P is a pair, return (car P), otherwise just return P."
   (if (consp p) (car p) p))
@@ -1256,7 +1306,7 @@ context and return the static fill prefix to use.  Point must be
 at the start of a line, and match data must be saved."
   (let ((prefix nil))
     (while (cond ((null l) nil)
-                ((looking-at (caar l))
+                ((mdw-fill-prefix-match-p (caar l))
                  (setq prefix
                          (mdw-maybe-tabify
                           (apply #'concat