From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.bugs Subject: bug#26338: 26.0.50; Collect all matches for REGEXP in current buffer Date: Fri, 07 Apr 2017 23:47:16 +0900 Message-ID: <87a87sqnpn.fsf@calancha-pc> References: <8737dr6kxx.fsf@calancha-pc> <87h926cvgl.fsf@localhost> <87k272ow7g.fsf@calancha-pc> <87fuhpcbem.fsf@localhost> <87lgrheyvn.fsf@calancha-pc> <87pogsmefn.fsf@jane> <871st6342v.fsf@localhost> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1491576505 14278 195.159.176.226 (7 Apr 2017 14:48:25 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 7 Apr 2017 14:48:25 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.50 (gnu/linux) Cc: 26338@debbugs.gnu.org, tino.calancha@gmail.com, Marcin Borkowski , npostavs@users.sourceforge.net, Dmitry Gutov To: Juri Linkov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Fri Apr 07 16:48:18 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwVBK-00025U-90 for geb-bug-gnu-emacs@m.gmane.org; Fri, 07 Apr 2017 16:48:10 +0200 Original-Received: from localhost ([::1]:51288 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwVBP-0002Mi-TE for geb-bug-gnu-emacs@m.gmane.org; Fri, 07 Apr 2017 10:48:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39188) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cwVBG-0002KK-8R for bug-gnu-emacs@gnu.org; Fri, 07 Apr 2017 10:48:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cwVBC-0001Jw-Tx for bug-gnu-emacs@gnu.org; Fri, 07 Apr 2017 10:48:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:38476) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cwVBC-0001Jq-OI for bug-gnu-emacs@gnu.org; Fri, 07 Apr 2017 10:48:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1cwVBC-0000pU-JT for bug-gnu-emacs@gnu.org; Fri, 07 Apr 2017 10:48:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Tino Calancha Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 07 Apr 2017 14:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 26338 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 26338-submit@debbugs.gnu.org id=B26338.14915764503097 (code B ref 26338); Fri, 07 Apr 2017 14:48:02 +0000 Original-Received: (at 26338) by debbugs.gnu.org; 7 Apr 2017 14:47:30 +0000 Original-Received: from localhost ([127.0.0.1]:36665 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwVAg-0000nt-0c for submit@debbugs.gnu.org; Fri, 07 Apr 2017 10:47:30 -0400 Original-Received: from mail-pg0-f49.google.com ([74.125.83.49]:35635) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwVAe-0000ne-7K for 26338@debbugs.gnu.org; Fri, 07 Apr 2017 10:47:28 -0400 Original-Received: by mail-pg0-f49.google.com with SMTP id 81so68819803pgh.2 for <26338@debbugs.gnu.org>; Fri, 07 Apr 2017 07:47:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=oYXF1aZrMgfbb3GIZUwjbC5raKbKyq7vukaC16miGdY=; b=GsbhXPKSwy6BGWb+ojdJURw/I05FB8A9UFBKtr1cnMjGPlqYt+bM5qIrxWU7r3T6nV WKFToTiGA1q+iIts5XSD7Z3J4S6cyQta0R+vYF3fl3y81wrZC0k/8Nlmhoxx10Zf2yEh p3N+4zoK0ExahkeoN5vqmBZJnJjjQKyOaYLncvC+7lYS6Q7SJ3UnjSMaiMdQXEiAY+NN 8tPpve4sIce3s2jzCPJW4oDgsJUgvyxYBILDWff+AmoBdgGOBoWHTI0bBpSbED6nXMra PZpxdw/BdcPc9VlprRFdxt1KSgET17NDYM9stBVfSgD3HjcEfFMU0D729Pq0Pjy6rrdQ xchg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version; bh=oYXF1aZrMgfbb3GIZUwjbC5raKbKyq7vukaC16miGdY=; b=LBVn7PrnzToURPZslApcV7BIZ0IO8D/oYPnq4S8SSy33rK65KNMYGY+Uiu91ZXZcPm +5GaXeTIURZHBmqA8/DSz9J62ey6PL3/6gCtrJCXPxYa272yMarQreUIP0CjWfYPcn2e 7A6vw7ETvqSbN118ZoBr/K47bzF9AiYJIPQ6WhlCeiJeSTIlbydUiw33xfKa8LH4raBr JIFLBeY433VFzlUIefTFh4B/XYO+YIdS9IDOM1kKhNXeit8lOgDW76JBPfbqZPTJn1sh Cq5NJhPPYsAB5MQ3FKHcGVFRbj24qWV8WaQgXCboLxpt46wYsl9AkYipmMVslmtZLiDY 0xAw== X-Gm-Message-State: AFeK/H0C3/plP4Iz6Q3N/Tq1OwGf0UkrhC9Qhfvszd7tII2OPsen9Sb5YxelPrsREYo7wg== X-Received: by 10.84.231.9 with SMTP id f9mr49370546plk.191.1491576442205; Fri, 07 Apr 2017 07:47:22 -0700 (PDT) Original-Received: from calancha-pc (222.139.137.133.dy.bbexcite.jp. [133.137.139.222]) by smtp.gmail.com with ESMTPSA id g5sm10212435pfe.12.2017.04.07.07.47.19 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 07 Apr 2017 07:47:21 -0700 (PDT) In-Reply-To: <871st6342v.fsf@localhost> (Juri Linkov's message of "Thu, 06 Apr 2017 01:03:04 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:131336 Archived-At: Juri Linkov writes: >>> Sorry if this was said already, but why a macro and not a map-like >>> function? >> No special reason. It's the second idea which came to my mind after >> my initial proposal was declined. Maybe because is shorter to do: >> (with-collect-matches regexp) >> than >> (foo-collect-matches regexp nil #'identity) >> >> if you are just interested in the list of matches. Implementing it as >> a map function might be also nice. Don't see a big enthusiasm on >> the proposal, though :-( >> >> So far people think that it's easy to write a while loop. I wonder if they >> think the same about the existence of `dolist': the should >> never use it and always write a `while' loop instead. Don't think they >> do that anyway. >> >> I will repeat it once more. I find nice, having an operator returning >> a list with matches for REGEXP. If such operator, in addition, accepts >> a body of code or a function, then i find this operator very nice >> and elegant. > > A mapcar-like function presumes a lambda where you can process every > match as you need, but going this way you'd have a temptation to > implement an analogous API from other programming languages like e.g. > https://apidock.com/ruby/String/scan I am not crazy with the mapcar-like implemention either. Actually, I have changed my mind after nice Noah suggestion. He mentioned the possibility of extend `cl-loop' with a new clause to iterate on matches for a regexp. I think this clause fits well in cl-loop; this way we don't need to introduce a new function/macro name. --8<-----------------------------cut here---------------start------------->8--- commit 59e66771d13fce73ff5220ce3df677b9247c9c52 Author: Tino Calancha Date: Fri Apr 7 23:31:08 2017 +0900 New clause in cl-loop to iterate in the matches of a regexp Add new clause in cl-loop facility to loop over the matches for REGEXP in the current buffer (Bug#26338). * lisp/emacs-lisp/cl-macs.el (cl--parse-loop-clause): Add new clause. (cl-loop): update docstring. * doc/misc/cl.texi (For Clauses): Document the new clause. * etc/NEWS: Mention this change. diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 2339d57631..6c5c43ad09 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -2030,6 +2030,21 @@ For Clauses This clause iterates over a sequence, with @var{var} a @code{setf}-able reference onto the elements; see @code{in-ref} above. +@item for @var{var} being the matches of @var{regexp} +This clause iterates over the matches for @var{regexp} in the current buffer. +By default, @var{var} is bound to the full match. Optionally, @var{var} +might be bound to a subpart of the match. It's also possible to restrict +the loop to a given number of matches. For example, + +@example +(cl-loop for x being the matches of "^(defun \\(\\S +\\)" + using '(group 1 limit 10) + collect x) +@end example + +@noindent +collects the next 10 function names after point. + @item for @var{var} being the symbols [of @var{obarray}] This clause iterates over symbols, either over all interned symbols or over all symbols in @var{obarray}. The loop is executed with diff --git a/etc/NEWS b/etc/NEWS index aaca229d5c..03f6ecb88b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -862,6 +862,10 @@ instead of its first. * Lisp Changes in Emacs 26.1 +++ +** New clause in cl-loop to iterate in the matches for a regexp +in the current buffer. + ++++ ** Emacs now supports records for user-defined types, via the new functions 'copy-record', 'make-record', 'record', and 'recordp'. Records are now used internally to represent cl-defstruct and defclass diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 25c9f99992..50596c066e 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -892,6 +892,7 @@ cl-loop the overlays/intervals [of BUFFER] [from POS1] [to POS2] the frames/buffers the windows [of FRAME] + the matches of/for REGEXP [using (group GROUP [limit LIMIT])] Iteration clauses: repeat INTEGER while/until/always/never/thereis CONDITION @@ -1339,6 +1340,33 @@ cl--parse-loop-clause (push (list temp-idx `(1+ ,temp-idx)) loop-for-steps))) + ((memq word '(match matches)) + (let* ((_ (or (and (not (memq (car cl--loop-args) '(of for))) + (error "Expected `of'")))) + (regexp (cl--pop2 cl--loop-args)) + (group-limit + (and (eq (car cl--loop-args) 'using) + (consp (cadr cl--loop-args)) + (>= (length (cadr cl--loop-args)) 2) + (cadr (cl--pop2 cl--loop-args)))) + (group + (or (and group-limit + (cl-find 'group group-limit) + (nth (1+ (cl-position 'group group-limit)) group-limit)) + 0)) + (limit + (and group-limit + (cl-find 'limit group-limit) + (nth (1+ (cl-position 'limit group-limit)) group-limit))) + (count (make-symbol "--cl-count"))) + (push (list count 0) loop-for-bindings) + (push (list var nil) loop-for-bindings) + (push `(re-search-forward ,regexp nil t) cl--loop-body) + (push `(or (null ,limit) (and (natnump ,limit) (< ,count ,limit))) cl--loop-body) + (push (list count `(1+ ,count)) loop-for-sets) + (push (list var `(match-string-no-properties ,group)) + loop-for-sets))) + ((memq word hash-types) (or (memq (car cl--loop-args) '(in of)) (error "Expected `of'")) --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 26.0.50 (build 7, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-04-07 Repository revision: 67aeaa74af8504f950f653136d749c6dd03a60de