;; Created: 29 Jul 2015
;; Keywords: lisp
;; Compatibility: GNU Emacs 25
-;; Version: 0.1.2
+;; Version: 0.1.3
;; Package-Requires: ((emacs "25"))
(mapc
(pcase-lambda (`(,symbol . ,fun))
(when-let ((doc (documentation fun)))
- (insert "\n\n-- ")
+ (insert "\n\n\n-- ")
(setq doc (help-fns--signature symbol doc fun fun nil))
(insert "\n" (or doc "Not documented."))))
(reverse el-search--pcase-macros))
(goto-char (match-end 0)))
(t (forward-char))))
-(defun el-search--search-pattern (pattern &optional noerror)
- "Search elisp buffer with `pcase' PATTERN.
-Set point to the beginning of the occurrence found and return
-point. Optional second argument, if non-nil, means if fail just
-return nil (no error)."
-
- (let ((matcher (el-search--matcher pattern)) (match-beg nil) (opoint (point)) current-expr)
+(defun el-search--search-pattern-1 (matcher &optional noerror)
+ (let ((match-beg nil) (opoint (point)) current-expr)
;; when inside a string or comment, move past it
(let ((syntax-here (syntax-ppss)))
(if noerror nil (signal 'end-of-buffer nil)))
match-beg))
+(defun el-search--search-pattern (pattern &optional noerror)
+ "Search elisp buffer with `pcase' PATTERN.
+Set point to the beginning of the occurrence found and return
+point. Optional second argument, if non-nil, means if fail just
+return nil (no error)."
+ (el-search--search-pattern-1 (el-search--matcher pattern) noerror))
+
(defun el-search--do-subsexps (pos do-fun &optional ret-fun bound)
;; In current buffer, for any expression start between POS and BOUND
;; or (point-max), in order, call two argument function DO-FUN with
`(and (pred symbolp)
(app symbol-name (string ,@regexps))))
+(defun el-search--contains-p (matcher exp)
+ "Return non-nil when tree EXP contains a match for MATCHER.
+Recurse on all types of sequences. In the positive case the
+return value is (t elt), where ELT is a matching element found in
+EXP."
+ (if (el-search--match-p matcher exp)
+ (list t exp)
+ (and (sequencep exp)
+ (let ((try-match (apply-partially #'el-search--contains-p matcher)))
+ (if (consp exp)
+ (or (funcall try-match (car exp))
+ (funcall try-match (cdr exp)))
+ (cl-some try-match exp))))))
+
+(el-search-defpattern contains (&rest patterns)
+ "Matches trees that contain a match for all PATTERNs.
+Searches any tree of sequences recursively for matches. Objects
+of any kind matched by all PATTERNs are also matched.
+
+ Example: (contains (string \"H\") 17) matches ((\"Hallo\") x (5 [1 17]))"
+ (cond
+ ((null patterns) '_)
+ ((null (cdr patterns))
+ (let ((pattern (car patterns)))
+ `(app ,(apply-partially #'el-search--contains-p (el-search--matcher pattern))
+ (,'\` (t (,'\, ,pattern))))))
+ (t `(and ,@(mapcar (lambda (pattern) `(contains ,pattern)) patterns)))))
+
(el-search-defpattern not (pattern)
"Matches any object that is not matched by PATTERN."
`(app ,(apply-partially #'el-search--match-p (el-search--matcher pattern))
Additional `pcase' pattern types to be used with this command can
be defined with `el-search-defpattern'.
-The following additional pattern types are currently defined:\n"
+The following additional pattern types are currently defined:"
(interactive (list (if (and (eq this-command last-command)
el-search-success)
el-search-current-pattern
(when (and (eq this-command last-command) el-search-success)
(el-search--skip-expression nil t))
(setq el-search-success nil)
- (message "%s" (substitute-command-keys "Type \\[el-search-pattern] to repeat"))
(when (condition-case nil
(el-search--search-pattern pattern)
(end-of-buffer (message "No match")
(el-search-search-and-replace-pattern from to mapping))
(defun el-search--take-over-from-isearch ()
- (let ((other-end isearch-other-end)
- (input isearch-string))
- (isearch-exit)
- (when (and other-end (< other-end (point)))
- (goto-char other-end))
- input))
+ (prog1 isearch-string (isearch-exit)))
;;;###autoload
(defun el-search-search-from-isearch ()