From 3fd348cbfd4fd5ebc266a1c412551d65dff09ac1 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 26 Jul 2020 22:45:50 +0100 Subject: [PATCH] el/dot-emacs.el: Make fill-prefix patterns much fancier. Now we can call out to Lisp to make decisions about where point is. --- el/dot-emacs.el | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 8 deletions(-) diff --git a/el/dot-emacs.el b/el/dot-emacs.el index 5bde809..f86044d 100644 --- a/el/dot-emacs.el +++ b/el/dot-emacs.el @@ -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 -- 2.11.0