Skip to content

Commit

Permalink
magit-section-match: fix when SECTION is nil
Browse files Browse the repository at this point in the history
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'.
  • Loading branch information
tarsius committed Oct 13, 2016
1 parent 0da6d96 commit b2a237d
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 45 deletions.
20 changes: 12 additions & 8 deletions Documentation/magit.org
Expand Up @@ -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...]~

Expand All @@ -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~,
Expand All @@ -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.

Expand Down
20 changes: 12 additions & 8 deletions Documentation/magit.texi
Expand Up @@ -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...)}
Expand All @@ -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
Expand All @@ -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},
Expand All @@ -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
Expand Down
62 changes: 34 additions & 28 deletions lisp/magit-section.el
Expand Up @@ -533,60 +533,66 @@ 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
`magit-describe-type', unless of course you want to be that
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)
Expand All @@ -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)))))
Expand Down
2 changes: 1 addition & 1 deletion lisp/magit.el
Expand Up @@ -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)
Expand Down

0 comments on commit b2a237d

Please sign in to comment.