From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Michael Heerdegen Newsgroups: gmane.emacs.help Subject: Re: [el-search] How to search string excluding docstring? Date: Mon, 25 Dec 2017 15:56:14 +0100 Message-ID: <87608u501d.fsf@web.de> References: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1514213701 12712 195.159.176.226 (25 Dec 2017 14:55:01 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 25 Dec 2017 14:55:01 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: help-gnu-emacs@gnu.org To: Chunyang Xu Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Dec 25 15:54:57 2017 Return-path: Envelope-to: geh-help-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 1eTU9X-0002oH-UM for geh-help-gnu-emacs@m.gmane.org; Mon, 25 Dec 2017 15:54:56 +0100 Original-Received: from localhost ([::1]:50613 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eTUBV-0005i1-Kb for geh-help-gnu-emacs@m.gmane.org; Mon, 25 Dec 2017 09:56:57 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:38693) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eTUAy-0005hY-UQ for help-gnu-emacs@gnu.org; Mon, 25 Dec 2017 09:56:25 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eTUAu-0000tG-50 for help-gnu-emacs@gnu.org; Mon, 25 Dec 2017 09:56:25 -0500 Original-Received: from mout.web.de ([212.227.17.11]:63362) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eTUAt-0000ss-Qc for help-gnu-emacs@gnu.org; Mon, 25 Dec 2017 09:56:20 -0500 Original-Received: from drachen.dragon ([88.74.120.211]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MYO45-1eOtdG3Ss5-00V5zV; Mon, 25 Dec 2017 15:56:15 +0100 In-Reply-To: (Chunyang Xu's message of "Mon, 25 Dec 2017 18:27:24 +0800") X-Provags-ID: V03:K0:PQABzw1I8BmpAUBms0UcSlZJmB9x4MhRlMbIzClb480+GyeXSOO sTFJNbp0/G8nb48M6ASzYaymI36kLjcNUout2F8TkhZaDDl7KeJDpXZXmbzgaFExlD7QXc9 ASk0zWODp3fhLa339J6fmnZoNG9vXACN0Iz5a5nJEmf9z2tRopgIgdA1XMHWy8iwBr/0nL7 LeN7nwLp41W/nkzakeufQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:EtxLvjpe62k=:RQZmq4TbXFV/urLux1on7b +7eRXN50tAP8Et2DjI0NiQAWaLaH+Tjj1WklfP1ji9f3+pCm431Zs5w6FVYHa5Rd2LCVEp2Uq U19NKWyKoEvOKgacEzPJoKWVuxwmoVjiFoAX9tHkpLG8x7NhmMp3fsI+dwJEf+XQIuU3r0lfm L3G4HcVCBVdQLB1ttIgWLL43XpS61goW89LTc1im8WNqkMay3ul9nc1t3/9837SwqI7JqvJpt cghnWaa3EA+dGpcE9Snljl22oagzNb1XEofJuiOLcixwHONQrSjCX4IXAH4OLNziizPBzKhJ1 atLrMK3Z95xyky+RUedfC0jpnNvxgBBQ4b09JRml71mK5/xeyq2j0IJZ5bQlvP6+tpA4o5GdQ haXD9dvyr4XS9fElLtujBbSalEPp0WActZu8+mZRkm8NOxiqnLjO6Oq5leTcxMKFRe9nAOtOO ES+0JGRRrkkfRlfUoQJzEoYVo1Zqp7LlKVl4Aij0B5C4JFlgqy9NO5cloNGofYyy1FCYF9H9v K2/npxiX+lWCNlIm+fRDUo9YN0F92khuD2oQeR51MDFmQHVrptwfiuFxzv0JuFw2cq6uiVBOI 0qXsJab9ghmuwD54N5dnvTfNnXx3nYvVXCgkkXJGYMNuZRoFcEUc639oI8GHyAWVsl1eNJG19 q5yhCSKNog55lOwxQRfEU9+1Xvu3ALleoYTDM4HYRLv702o46G5UpAwixSP3qBXRzYu7/qgSm vFnD38hravjUPMKgjWHRcbY8KTARPpUyGA1SugHD7oKeyMkuhMZv9usVXUH7uQRVeDvmyHiy X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.11 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "help-gnu-emacs" Xref: news.gmane.org gmane.emacs.help:115450 Archived-At: Chunyang Xu writes: > Hi Michael Heerdegen and other Emacs users, > > For example, with the following contents in a buffer > > (defun foo () > "foo docstring" > (message "foo string")) > > (string "foo") matches both "foo docstring" and "foo string", I want a > way to exclude the docstring, by "docstring", I just mean the string > being checking should not be the fourth element in > > (defun _ _ docstring . _) > > I am thinking a pattern like > > (and (pred stringp) (guard (not (docstring-p))) (string "foo")) > > but I have no idea how to define 'docstring-p'. The general task is context-sensitive matching. You have no chance with the current version of el-search, because all patterns there are not context aware, as you have noticed. I want to add that, but because there are some pitfalls, I've not yet uploaded something like this. Here is what I currently have: #+begin_src emacs-lisp (defun el-search--try-find-parent-beg () ;; try to find beg of parent exp heuristically (unless (looking-at "^(") (let ((opoint (point))) (or (and (search-backward-regexp "[;\(\)\"]" (max (- (point) 300) (point-min))) (looking-at "\(") (and (or (eobp)) (not (= (char-before) ?\\))) (not (looking-back ";" (line-beginning-position)))) (progn (goto-char opoint) nil))))) (el-search-defpattern parent (pattern &optional n) "Matches when PATTERN matches the (Nth) parent of the current expression. N defaults to 1. Slow." (let ((parent-end (make-symbol "parent-end")) (counter (make-symbol "ctr"))) `(and (let ,counter (or ,n 1)) (let (,'\` ((,'\, ,pattern))) (save-excursion (condition-case nil (progn (while (>= (cl-decf ,counter) 0) (or (el-search--try-find-parent-beg) (cond ((eq (char-before) ?`) (backward-char 1)) ((eq (char-before) ?,) (backward-char 1)) ((and (eq (char-before (1- (point))) ?,) (eq (char-before) ?@)) (backward-char 2)) ((eq (char-before) ?') (backward-char 1)) ((and (eq (char-before (1- (point))) ?#) (eq (char-before) ?')) (backward-char 2)) (t (when-let* ((,parent-end (scan-lists (point) 1 1))) (goto-char ,parent-end) (backward-list)))))) (list (read (current-buffer)))) (scan-error nil))))))) #+end_src That should enable you to solve your task. Note it's experimental, and I only had a quick look again now - want to go hiking! One thing you can definitely _not_ do with this is to use it recursively - i.e. (parent (parent PATTERN)) won't work (that's why I added the optional N argument) - `parent' is only valid when applied to the current expression. Please tell me if it works for you. BTW, another not yet uploaded pattern for matching strings you may find useful is #+begin_src emacs-lisp (el-search-defpattern string-lines (pattern) "Match any string whose line number is matched by PATTERN. Examples: (string-lines 1) matches one-line strings. \(string-lines (pred (>= 5))\) matches strings consisting of not more than 5 lines." (let ((string (make-symbol "string"))) `(and (string) ,string (let ,pattern (with-temp-buffer (insert ,string) (count-lines (point-min) (point-max))))))) #+end_src I don't know if it's useful enough to upload it. Regards, Michael.