From b2a237d3378cb98e3493e93c1e82cc8f6d87bd78 Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Thu, 13 Oct 2016 13:28:14 +0200 Subject: [PATCH] magit-section-match: fix when SECTION is nil When SECTION is nil, then the current section is now used. That was already supposed to happen, but was broken. Rename the helper function `magit-section-match-1' to `magit-section-match-2' and create a new `magit-section-match-1'. Adjust related macros which (used to) call `magit-section-match'. Replace one use of `magit-section-when' with `magit-section-match'. (Due to the bug fixed here, that would previously not have worked.) Also improve the documentation of `magit-section-match' and `magit-section-when'. --- Documentation/magit.org | 20 +++++++------ Documentation/magit.texi | 20 +++++++------ lisp/magit-section.el | 62 ++++++++++++++++++++++------------------ lisp/magit.el | 2 +- 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/Documentation/magit.org b/Documentation/magit.org index e2722b6305..027657ca52 100644 --- a/Documentation/magit.org +++ b/Documentation/magit.org @@ -5894,17 +5894,18 @@ And now for the asynchronous variants. - Function: magit-section-match condition &optional section Return ~t~ if SECTION matches CONDITION. SECTION defaults to the - section at point. + section at point. If SECTION is not specified and there also is no + section at point, then return ~nil~. - Conditions can take the following forms: + CONDITION can take the following forms: - ~(CONDITION...)~ matches if any of the CONDITIONs matches. - ~[TYPE...]~ - matches if the first TYPE matches the type of the section at - point, the second matches that of its parent, and so on. + matches if the first TYPE matches the type of the section, the + second matches that of its parent, and so on. - ~[* TYPE...]~ @@ -5913,7 +5914,8 @@ And now for the asynchronous variants. - ~TYPE~ - matches TYPE regardless of its parents. + matches sections of TYPE regardless of the types of the parent + sections. Each TYPE is a symbol. Note that it is not necessary to specify all TYPEs up to the root section as printed by ~magit-describe-type~, @@ -5923,9 +5925,11 @@ And now for the asynchronous variants. If the section at point matches CONDITION evaluate BODY. - If the section matches evaluate BODY forms sequentially and return - the value of the last one, or if there are no BODY forms return the - value of the section. If the section does not match return nil. + If the section matches, then evaluate BODY forms sequentially with + ~it~ bound to the section and return the value of the last form. If + there are no BODY forms, then return the value of the section. If + the section does not match or if there is no section at point then + return nil. See ~magit-section-match~ for the forms CONDITION can take. diff --git a/Documentation/magit.texi b/Documentation/magit.texi index 0fe8e0806a..755a43e5bc 100644 --- a/Documentation/magit.texi +++ b/Documentation/magit.texi @@ -7942,9 +7942,10 @@ returned by @code{magit-section-ident}. @defun magit-section-match condition &optional section Return @code{t} if SECTION matches CONDITION. SECTION defaults to the -section at point. +section at point. If SECTION is not specified and there also is no +section at point, then return @code{nil}. -Conditions can take the following forms: +CONDITION can take the following forms: @itemize @item @code{(CONDITION...)} @@ -7955,8 +7956,8 @@ matches if any of the CONDITIONs matches. @item @code{[TYPE...]} -matches if the first TYPE matches the type of the section at -point, the second matches that of its parent, and so on. +matches if the first TYPE matches the type of the section, the +second matches that of its parent, and so on. @item @@ -7969,7 +7970,8 @@ their child sections. @item @code{TYPE} -matches TYPE regardless of its parents. +matches sections of TYPE regardless of the types of the parent +sections. @end itemize Each TYPE is a symbol. Note that it is not necessary to specify all TYPEs up to the root section as printed by @code{magit-describe-type}, @@ -7980,9 +7982,11 @@ unless of course you want to be that precise. If the section at point matches CONDITION evaluate BODY. -If the section matches evaluate BODY forms sequentially and return -the value of the last one, or if there are no BODY forms return the -value of the section. If the section does not match return nil. +If the section matches, then evaluate BODY forms sequentially with +@code{it} bound to the section and return the value of the last form. If +there are no BODY forms, then return the value of the section. If +the section does not match or if there is no section at point then +return nil. See @code{magit-section-match} for the forms CONDITION can take. @end defun diff --git a/lisp/magit-section.el b/lisp/magit-section.el index 6f25ccd23e..ce25bc3930 100644 --- a/lisp/magit-section.el +++ b/lisp/magit-section.el @@ -533,18 +533,23 @@ This command is intended for debugging purposes." ;;; Match -(defun magit-section-match (condition &optional section) +(cl-defun magit-section-match + (condition &optional (section (magit-current-section))) "Return t if SECTION matches CONDITION. -SECTION defaults to the section at point. -Conditions can take the following forms: +SECTION defaults to the section at point. If SECTION is not +specified and there also is no section at point, then return +nil. + +CONDITION can take the following forms: (CONDITION...) matches if any of the CONDITIONs matches. [TYPE...] matches if the first TYPE matches the type - of the section at point, the second matches - that of its parent, and so on. + of the section, the second matches that of + its parent, and so on. [* TYPE...] matches sections that match [TYPE...] and also recursively all their child sections. - TYPE matches TYPE regardless of its parents. + TYPE matches sections of TYPE regardless of the + types of the parent sections. Each TYPE is a symbol. Note that it is not necessary to specify all TYPEs up to the root section as printed by @@ -552,41 +557,42 @@ all TYPEs up to the root section as printed by precise." ;; When recursing SECTION actually is a type list. Matching ;; macros also pass such a list instead of a section struct. - (let ((types (if (magit-section-p section) - (mapcar 'car (magit-section-ident section)) - section))) - (when (or types section (magit-current-section)) - (if (listp condition) - (--first (magit-section-match it types) condition) - (magit-section-match-1 (if (symbolp condition) - (list condition) - (append condition nil)) - types))))) - -(defun magit-section-match-1 (l1 l2) + (and section + (magit-section-match-1 condition + (mapcar #'car (magit-section-ident section))))) + +(defun magit-section-match-1 (condition type-list) + (if (listp condition) + (--first (magit-section-match-1 it type-list) condition) + (magit-section-match-2 (if (symbolp condition) + (list condition) + (append condition nil)) + type-list))) + +(defun magit-section-match-2 (l1 l2) (or (null l1) (if (eq (car l1) '*) - (or (magit-section-match-1 (cdr l1) l2) + (or (magit-section-match-2 (cdr l1) l2) (and l2 - (magit-section-match-1 l1 (cdr l2)))) + (magit-section-match-2 l1 (cdr l2)))) (and l2 (equal (car l1) (car l2)) - (magit-section-match-1 (cdr l1) (cdr l2)))))) + (magit-section-match-2 (cdr l1) (cdr l2)))))) (defmacro magit-section-when (condition &rest body) "If the section at point matches CONDITION evaluate BODY. -If the section matches evaluate BODY forms sequentially and -return the value of the last one, or if there are no BODY forms -return the value of the section. If the section does not match -return nil. +If the section matches, then evaluate BODY forms sequentially +with `it' bound to the section and return the value of the last +form. If there are no BODY forms, then return the value of the +section. If the section does not match or if there is no section +at point then return nil. See `magit-section-match' for the forms CONDITION can take." (declare (indent 1) (debug (sexp body))) `(--when-let (magit-current-section) - (when (magit-section-match ',condition - (mapcar 'car (magit-section-ident it))) + (when (magit-section-match ',condition it) ,@(or body '((magit-section-value it)))))) (defmacro magit-section-case (&rest clauses) @@ -610,7 +616,7 @@ at point." (,ident (and it (mapcar 'car (magit-section-ident it))))) (cond ,@(mapcar (lambda (clause) `(,(or (eq (car clause) t) - `(and it (magit-section-match + `(and it (magit-section-match-1 ',(car clause) ,ident))) ,@(cdr clause))) clauses))))) diff --git a/lisp/magit.el b/lisp/magit.el index 59530118cf..b53522a770 100644 --- a/lisp/magit.el +++ b/lisp/magit.el @@ -1009,7 +1009,7 @@ reference, but it is not checked out." (let ((ref (magit-section-value (magit-current-section)))) (if current-prefix-arg (magit-show-refs ref) - (if (magit-section-when [branch remote]) + (if (magit-section-match [branch remote]) (let ((start ref) (arg "-b")) (string-match "^[^/]+/\\(.+\\)" ref)