* [el-search] How to search string excluding docstring? @ 2017-12-25 10:27 Chunyang Xu 2017-12-25 10:40 ` Jean-Christophe Helary ` (3 more replies) 0 siblings, 4 replies; 28+ messages in thread From: Chunyang Xu @ 2017-12-25 10:27 UTC (permalink / raw) To: help-gnu-emacs; +Cc: michael_heerdegen 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'. Any tips? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 10:27 [el-search] How to search string excluding docstring? Chunyang Xu @ 2017-12-25 10:40 ` Jean-Christophe Helary 2017-12-25 12:00 ` Skip Montanaro ` (2 subsequent siblings) 3 siblings, 0 replies; 28+ messages in thread From: Jean-Christophe Helary @ 2017-12-25 10:40 UTC (permalink / raw) To: Chunyang Xu; +Cc: michael_heerdegen, help-gnu-emacs > On Dec 25, 2017, at 19:27, Chunyang Xu <mail@xuchunyang.me> wrote: > > (defun foo () > "foo docstring" > (message "foo string")) > > (and (pred stringp) (guard (not (docstring-p))) (string "foo")) > > but I have no idea how to define 'docstring-p'. > > Any tips? The definition of a docstring is that it is located right below the defun. Sorry I can't help much more than that... Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 10:27 [el-search] How to search string excluding docstring? Chunyang Xu 2017-12-25 10:40 ` Jean-Christophe Helary @ 2017-12-25 12:00 ` Skip Montanaro 2017-12-25 18:04 ` Michael Heerdegen 2017-12-25 14:56 ` Michael Heerdegen [not found] ` <mailman.6340.1514213787.27995.help-gnu-emacs@gnu.org> 3 siblings, 1 reply; 28+ messages in thread From: Skip Montanaro @ 2017-12-25 12:00 UTC (permalink / raw) To: Chunyang Xu; +Cc: michael_heerdegen, Help GNU Emacs While you consider a solution, it might be worthwhile to think about generalizing beyond ELisp. Python, for example, uses the same structural placement of docstrings for modules, classes, functions, and methods. Skip ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 12:00 ` Skip Montanaro @ 2017-12-25 18:04 ` Michael Heerdegen 0 siblings, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2017-12-25 18:04 UTC (permalink / raw) To: Skip Montanaro; +Cc: Help GNU Emacs, Chunyang Xu Skip Montanaro <skip.montanaro@gmail.com> writes: > While you consider a solution, it might be worthwhile to think about > generalizing beyond ELisp. Python, for example, uses the same > structural placement of docstrings for modules, classes, functions, > and methods. If there was a tool to produce abstract syntax trees efficiently, preferably with positions, it would be possible to extend el-search to the supported languages. Semantic had something like that, but AFAICT it has been obsoleted. Regards, Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 10:27 [el-search] How to search string excluding docstring? Chunyang Xu 2017-12-25 10:40 ` Jean-Christophe Helary 2017-12-25 12:00 ` Skip Montanaro @ 2017-12-25 14:56 ` Michael Heerdegen 2017-12-25 16:58 ` Chunyang Xu [not found] ` <mailman.6340.1514213787.27995.help-gnu-emacs@gnu.org> 3 siblings, 1 reply; 28+ messages in thread From: Michael Heerdegen @ 2017-12-25 14:56 UTC (permalink / raw) To: Chunyang Xu; +Cc: help-gnu-emacs Chunyang Xu <mail@xuchunyang.me> 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. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 14:56 ` Michael Heerdegen @ 2017-12-25 16:58 ` Chunyang Xu 2017-12-25 17:51 ` Michael Heerdegen 0 siblings, 1 reply; 28+ messages in thread From: Chunyang Xu @ 2017-12-25 16:58 UTC (permalink / raw) To: Michael Heerdegen; +Cc: help-gnu-emacs Michael Heerdegen writes: > Chunyang Xu <mail@xuchunyang.me> 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. It does work for me, via (and (string "foo") (not (parent `(defun . ,_)))) I also realize another way, which is not general at all but seeming working. To check if the current string is docstring (save-excursion (backward-up-list) (pcase (read (current-buffer)) (`(defun ,_ ,_ ,(and (pred stringp) docstring) . ,_) (string= docstring string)))) then to search docstring (and (string) string (guard ...)) It has a bug, for example, when search the following, it matches both the first and the second "foo" (the second is not wanted) (defun hello () "foo" "foo" (message "foo")) But it can be ignored because the second "foo" is useless so we don't write code like this. So my current approach of searching string excluding docstring is (defun el-search--docstring-p (string) (save-excursion (backward-up-list) (pcase (read (current-buffer)) (`(defun ,_ ,_ ,(and (pred stringp) docstring) . ,_) (string= docstring string))))) (and (string "foo") s (guard (not (el-search--docstring-p s)))) I plan to support defvar/defcustom etc later. > 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. Thanks. I don't have such a need yet but it shows me a simple example of using 'el-search-defpattern'. > > Regards, > > Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 16:58 ` Chunyang Xu @ 2017-12-25 17:51 ` Michael Heerdegen 0 siblings, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2017-12-25 17:51 UTC (permalink / raw) To: Chunyang Xu; +Cc: help-gnu-emacs Chunyang Xu <mail@xuchunyang.me> writes: > I also realize another way, which is not general at all but seeming > working. To check if the current string is docstring > > (save-excursion > (backward-up-list) > (pcase (read (current-buffer)) > (`(defun ,_ ,_ ,(and (pred stringp) docstring) . ,_) > (string= docstring string)))) > > then to search docstring > > (and (string) string (guard ...)) > > It has a bug, for example, when search the following, it matches both > the first and the second "foo" (the second is not wanted) > > (defun hello () > "foo" > "foo" > (message "foo")) Yes, that's one of the pitfalls you can run into. One could try to find out at which list position the current expression is - I've not really needed something like this, however. > So my current approach of searching string excluding docstring is > > (defun el-search--docstring-p (string) > (save-excursion > (backward-up-list) > (pcase (read (current-buffer)) > (`(defun ,_ ,_ ,(and (pred stringp) docstring) . ,_) > (string= docstring string))))) > > (and (string "foo") s (guard (not (el-search--docstring-p s)))) Yes, that should work fine (unless you have any top-level strings, but that is never the case for code buffers). You could simplify it a bit by using (pred (string= string)) in the pattern. Regards, Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6340.1514213787.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6340.1514213787.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 15:50 ` Emanuel Berg 2017-12-25 16:59 ` Michael Heerdegen [not found] ` <mailman.6351.1514221174.27995.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 15:50 UTC (permalink / raw) To: help-gnu-emacs Michael Heerdegen wrote: > 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. Tell us again why one can't just use grep to search Elisp? :) -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 15:50 ` Emanuel Berg @ 2017-12-25 16:59 ` Michael Heerdegen [not found] ` <mailman.6351.1514221174.27995.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2017-12-25 16:59 UTC (permalink / raw) To: help-gnu-emacs Emanuel Berg <moasen@zoho.com> writes: > Tell us again why one can't just use grep to search Elisp? :) There are tasks where grep isn't enough, like "find all uses of cl stuff where I have forgotten the cl- prefix", "find all definitions that have no docstring", "find all function "foo" calls that make use the third optional arg", etc. It can also do list-level query-replace. Some examples: "I've changed my function "bar" so that the second and third argument are now transposed. Let's adopt every use of it and transpose the expressions at the second and third argument position." Or "automatically transform any nested if's into an equivalent `cond'", or "find any `if' expressions that have no `else' and make them a "when", and such stuff. Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6351.1514221174.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6351.1514221174.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 18:04 ` Emanuel Berg 0 siblings, 0 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 18:04 UTC (permalink / raw) To: help-gnu-emacs Michael Heerdegen wrote: >> Tell us again why one can't just use grep to >> search Elisp? :) > > There are tasks where grep isn't enough, like > "find all uses of cl stuff where I have > forgotten the cl- prefix", "find all > definitions that have no docstring", "find > all function "foo" calls that make use the > third optional arg", etc. > > It can also do list-level query-replace. > Some examples: "I've changed my function > "bar" so that the second and third argument > are now transposed. Let's adopt every use of > it and transpose the expressions at the > second and third argument position." Or > "automatically transform any nested if's into > an equivalent `cond'", or "find any `if' > expressions that have no `else' and make them > a "when", and such stuff. Your software can do that? Impressive! Still, I'd do that manually. But that's just me. OTOH I have written tons of Elisp "for the sake of Elisp". So I enjoy that. Looking at it from a spaceship tho one might consider it a case of built-up creativity/frustration. There aren't any real challanges left [1] so people write code for the sake or writing code, with the purpose of writing even more code later. It gives pleasure and is interesting but I, who almost exclusively did just that, know there is even more pleasure to do stuff that has a less recursive application surface... Like it is more interesting to write very advanced Elisp. But to build a ramp so people can get their bikes up onto a deck without bumping up a stairways. Building the ramp might be trivial in comparison but nonetheless every time you see or use it it'll make you feel happy. So it is complicated. [1] Of course there are real challenges left! They are just harder to find. It is an open question if all fiddling makes you more perceptive of seeing them, *or* if it makes you less so as you get stuck in all the fiddling details. Some random thoughts on a general level, not to be taken as an assault on anyone's project or style in particular... pink elephants and lemonade dear Jessie hears the laughter running thru the love parade -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6328.1514197667.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] <mailman.6328.1514197667.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 12:00 ` Emanuel Berg 2017-12-25 13:57 ` Chunyang Xu [not found] ` <mailman.6334.1514210258.27995.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 12:00 UTC (permalink / raw) To: help-gnu-emacs Chunyang Xu wrote: > but I have no idea how to define > 'docstring-p'. Docstrings are in `font-lock-doc-face' so Emacs already knows how to determine that. Find out how that is done, and then invoke or reuse that code from your function. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 12:00 ` Emanuel Berg @ 2017-12-25 13:57 ` Chunyang Xu 2017-12-25 14:34 ` Michael Heerdegen [not found] ` <mailman.6334.1514210258.27995.help-gnu-emacs@gnu.org> 1 sibling, 1 reply; 28+ messages in thread From: Chunyang Xu @ 2017-12-25 13:57 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs Emanuel Berg writes: > Chunyang Xu wrote: > >> but I have no idea how to define >> 'docstring-p'. > > Docstrings are in `font-lock-doc-face' so Emacs > already knows how to determine that. Find out > how that is done, and then invoke or reuse that > code from your function. It almost solves my problem via: (and (pred stringp) (guard (not (eq 'font-lock-doc-face (get-char-property (point) 'face)))) (string "foo")) but it doesn't work for files which is not already opened, I guess it is because font-lock-mode is only active when I open the file. For example, M-x el-search-directory RET (and (pred stringp) (guard (not (eq 'font-lock-doc-face (get-char-property (point) 'face)))) (string "^GNU Emacs")) RET M-x el-search-occur RET also matches process-event-p's docstring (from levents.el.gz): (defun process-event-p (obj) "True if the argument is a process-output event object. GNU Emacs 19 does not currently generate process-output events." (eq (car-safe obj) 'process)) and after I open levents.el.gz and try the 'M-x el-search-directory' with the exact same argument again, the match disappears. Besides I am still interested in using "pattern match" to solve the issue. I think it is possible though I don't know how yet. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 13:57 ` Chunyang Xu @ 2017-12-25 14:34 ` Michael Heerdegen 0 siblings, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2017-12-25 14:34 UTC (permalink / raw) To: Chunyang Xu; +Cc: help-gnu-emacs, Emanuel Berg Chunyang Xu <mail@xuchunyang.me> writes: > (and (pred stringp) > (guard (not (eq 'font-lock-doc-face (get-char-property (point) 'face)))) > (string "foo")) > > but it doesn't work for files which is not already opened, I guess it is > because font-lock-mode is only active when I open the file. Exactly. It's intentional, because applying the major mode and fontifying is by a factor n slower than el-searching with most patterns. Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6334.1514210258.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6334.1514210258.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 14:08 ` Emanuel Berg 2017-12-25 17:55 ` tomas [not found] ` <mailman.6358.1514224565.27995.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 14:08 UTC (permalink / raw) To: help-gnu-emacs Chunyang Xu wrote: > It almost solves my problem via: > > (and (pred stringp) > (guard (not (eq 'font-lock-doc-face (get-char-property (point) 'face)))) > (string "foo")) > > but it doesn't work for files which is not > already opened, I guess it is because > font-lock-mode is only active when I open the > file. Font lock is run by the idle timer. So if you are productive enough and do things all the time, you won't get it :) If the file isn't opened, it is just a bunch of data. Font lock isn't encoded in the files, thanks heaven. You will have to make a loop that opens all files... perhaps it'll be a challenge to have font loke come to life each time tho? > Besides I am still interested in using > "pattern match" to solve the issue. I think > it is possible though I don't know how yet. Pattern match, like they have for arguments in Erlang and SML? There are Lisp modules for that. Still, I'd start with finding out how font lock does it... -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 14:08 ` Emanuel Berg @ 2017-12-25 17:55 ` tomas [not found] ` <mailman.6358.1514224565.27995.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 28+ messages in thread From: tomas @ 2017-12-25 17:55 UTC (permalink / raw) To: help-gnu-emacs -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Mon, Dec 25, 2017 at 03:08:31PM +0100, Emanuel Berg wrote: [...] > Pattern match, like they have for arguments in > Erlang and SML? Pattern match like pcase, I guess. Cheers - -- t -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlpBO6MACgkQBcgs9XrR2ka9IwCeJ+d1Qqm1K3IvNAjSV1qXVNtx C5gAn1Kui6Qi90CNWpHOjkXNGwznjfAF =oZm0 -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6358.1514224565.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6358.1514224565.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 18:11 ` Emanuel Berg 2017-12-25 19:14 ` tomas [not found] ` <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org> 0 siblings, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 18:11 UTC (permalink / raw) To: help-gnu-emacs t wrote: >> Pattern match, like they have for arguments >> in Erlang and SML? > > Pattern match like pcase, I guess. Isn't that the same? AFAIK there isn't any native pattern matching i Lisp, but one can do it with macros... I don't like it personally because it makes writing code neurotic keeping track of all those cases, rather than just examine what the value is and act accordingly... Whenever I use `pcase' it isn't really pattern matching in my eyes, i.e. in the Erlang/SML sense, more like a way of doing case with strings. I guess it could be used in other ways as well. Even tho technically it is the same thing. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 18:11 ` Emanuel Berg @ 2017-12-25 19:14 ` tomas [not found] ` <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 28+ messages in thread From: tomas @ 2017-12-25 19:14 UTC (permalink / raw) To: help-gnu-emacs -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Mon, Dec 25, 2017 at 07:11:19PM +0100, Emanuel Berg wrote: > t wrote: > > >> Pattern match, like they have for arguments > >> in Erlang and SML? > > > > Pattern match like pcase, I guess. > > Isn't that the same? No. Regexps are built to match regular languages. Pcase is built to match S-expressions, which are beyond regular. Well-nested parentheses are more than a regular language. Start with the Chomsky hierarchy[1], and delve as deep as you like :-) > AFAIK there isn't any > native pattern matching i Lisp, but one can do > it with macros... whatever you understand by "native pattern matching". > I don't like it personally because it makes > writing code neurotic keeping track of all > those cases, rather than just examine what the > value is and act accordingly... It's not a psychological question, but rather a mathematical one: there are things you can't do with regexps. > Whenever I use `pcase' it isn't really pattern > matching in my eyes, i.e. in the Erlang/SML > sense, more like a way of doing case with > strings. There lies your error: you are matching S-expressions, not strings. The "case" part isn't the exciting one :-) > I guess it could be used in other ways > as well. Even tho technically it is the > same thing. Hmmm. Cheers [1] https://en.wikipedia.org/wiki/Chomsky_hierarchy - -- tomás -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlpBTgwACgkQBcgs9XrR2kbuAwCdGeCGed8FArdnqKkpQ2sLLnym SUsAn2Kd5MuqW6LzPW6ZZP0RzXQNlEoA =F3k5 -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 19:36 ` Emanuel Berg 2017-12-25 21:20 ` tomas [not found] ` <mailman.6371.1514236843.27995.help-gnu-emacs@gnu.org> 2017-12-25 19:39 ` Emanuel Berg 1 sibling, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 19:36 UTC (permalink / raw) To: help-gnu-emacs t wrote: >>>> Pattern match, like they have for >>>> arguments in Erlang and SML? >>> >>> Pattern match like pcase, I guess. >> >> Isn't that the same? > > No. Regexps are built to match regular > languages. Pcase is built to match > S-expressions, which are beyond regular. > Well-nested parentheses are more than > a regular language. Regexps, you mean that is what they use to implement pattern match in Erlang and SML?! Or why did you bring it up? I lost all my Erlang and SML (literally) but I found some Haskell, the most neurotic of all languages, which rely the most on pattern matching virtually all the time - here is what I mean: data Prop = DoNotCare | Pp Char instance Eq Prop where DoNotCare == DoNotCare = True Pp a == Pp b = a == b _ == _ = False a /= b = not (a == b) Is this really what you mean? Surly that isn't implemented as mere regexps?! From: http://user.it.uu.se/~embe8573/candelim/ce.hs -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 19:36 ` Emanuel Berg @ 2017-12-25 21:20 ` tomas [not found] ` <mailman.6371.1514236843.27995.help-gnu-emacs@gnu.org> 1 sibling, 0 replies; 28+ messages in thread From: tomas @ 2017-12-25 21:20 UTC (permalink / raw) To: help-gnu-emacs -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Mon, Dec 25, 2017 at 08:36:41PM +0100, Emanuel Berg wrote: > t wrote: > > >>>> Pattern match, like they have for > >>>> arguments in Erlang and SML? > >>> > >>> Pattern match like pcase, I guess. [...] > I lost all my Erlang and SML (literally) but > I found some Haskell, the most neurotic of all > languages, which rely the most on pattern > matching virtually all the time - here is what [...] > Is this really what you mean? Surly that isn't > implemented as mere regexps?! I'd be very surprised if it were. Regards - -- t -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlpBa6MACgkQBcgs9XrR2ka/kgCfXr+GmyO5FrZhhUWkEmVveFL9 ff4AnRiVSFq7GPuBSiAbQSpm4yd3yBWU =4ZPe -----END PGP SIGNATURE----- ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6371.1514236843.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6371.1514236843.27995.help-gnu-emacs@gnu.org> @ 2017-12-25 21:56 ` Emanuel Berg 2017-12-26 2:44 ` Emanuel Berg 2017-12-26 13:34 ` Emanuel Berg 0 siblings, 2 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 21:56 UTC (permalink / raw) To: help-gnu-emacs t wrote: >> Is this really what you mean? Surly that >> isn't implemented as mere regexps?! > > I'd be very surprised if it were. So why did you bring it up to begin with? -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 21:56 ` Emanuel Berg @ 2017-12-26 2:44 ` Emanuel Berg 2017-12-26 13:34 ` Emanuel Berg 1 sibling, 0 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-26 2:44 UTC (permalink / raw) To: help-gnu-emacs First check if it is a string at all, then (lisp-font-lock-syntactic-face-function (syntax-ppss)) If you don't want to use font lock, try reuse code from that function. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-25 21:56 ` Emanuel Berg 2017-12-26 2:44 ` Emanuel Berg @ 2017-12-26 13:34 ` Emanuel Berg 2017-12-26 13:48 ` Jean-Christophe Helary ` (3 more replies) 1 sibling, 4 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-26 13:34 UTC (permalink / raw) To: help-gnu-emacs YT wrote: >>> Is this really what you mean? Surly that >>> isn't implemented as mere regexps?! >> >> I'd be very surprised if it were. > > So why did you bring it up to begin with? OK, so now I understand how regexps entered this discussion! "You can't use grep with regexps", because it isn't a Lisp parser so it can't answer the kind of questions that require you to crunch it down token by token!" And that's true! Regexps are sometimes underestimated. Because they cannot do everything, it doesn't mean they cannot do a lot, still. But it will never be a perfect fallout and the result may also be confusing as semantically the same Lisp, and the same regexp, can still yield different results. So you can use grep to search your Elisp, but not to query your Elisp and expect 100% consistent/correct/complete answers. If this is the goal, even to use font lock, which probably itself uses some half baked method to find out, to use font lock would be a clever hack at best. The reason you can still use grep or font lock or any other such method is that in the world of editing code, these are just tools to do things. An imperfect tool can still help you do things. And a perfect tool, which is 100 times more advanced than the imperfect tool, will not be 100 times more helpful to you. If we then switch worlds from the practical/editing to the abstract/theoretical, to parse the code, or eval it like Lisp does, this is already capable of telling if something is a docstring or not. Just do C-h f forward-char RET ! However here there is a collision between the two worlds. Because where is point? Over which element to begin with, when the query is executed? If one knows that, one could simply get the defun as a list (which it already is) and ask, "is the 4th element a string?". If it is, and if point's at it in the buffer, then yes it is a docstring. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-26 13:34 ` Emanuel Berg @ 2017-12-26 13:48 ` Jean-Christophe Helary [not found] ` <mailman.6381.1514296097.27995.help-gnu-emacs@gnu.org> ` (2 subsequent siblings) 3 siblings, 0 replies; 28+ messages in thread From: Jean-Christophe Helary @ 2017-12-26 13:48 UTC (permalink / raw) To: Help Gnu Emacs mailing list > On Dec 26, 2017, at 22:34, Emanuel Berg <moasen@zoho.com> wrote: > > If one knows that, one could > simply get the defun as a list (which it > already is) and ask, "is the 4th element > a string?". Ok, so we're back to my suggestion. docstring-p can be defined as the string coming after the defun statement. Jean-Christophe Helary ----------------------------------------------- @brandelune http://mac4translators.blogspot.com ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6381.1514296097.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6381.1514296097.27995.help-gnu-emacs@gnu.org> @ 2017-12-26 15:19 ` Emanuel Berg 0 siblings, 0 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-26 15:19 UTC (permalink / raw) To: help-gnu-emacs Jean-Christophe Helary wrote: > Ok, so we're back to my suggestion. > docstring-p can be defined as the string > coming after the defun statement. Technically, `defun' is a macro. Talking broadly, this (do-something-with me and you) is a function or a form. But yes :) -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-26 13:34 ` Emanuel Berg 2017-12-26 13:48 ` Jean-Christophe Helary [not found] ` <mailman.6381.1514296097.27995.help-gnu-emacs@gnu.org> @ 2017-12-27 5:38 ` Chunyang Xu 2017-12-27 13:58 ` Michael Heerdegen [not found] ` <mailman.6406.1514353148.27995.help-gnu-emacs@gnu.org> 3 siblings, 1 reply; 28+ messages in thread From: Chunyang Xu @ 2017-12-27 5:38 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs Emanuel Berg writes: > However here there is a collision between the > two worlds. Because where is point? > Over which element to begin with, when the > query is executed? If one knows that, one could > simply get the defun as a list (which it > already is) and ask, "is the 4th element > a string?". If it is, and if point's at it in > the buffer, then yes it is a docstring. I think point is at the beginning of the string, the following assumes this to work. I compare point with the point of docstring (if any) to see if it is a docstring. #+begin_src emacs-lisp ;; FIXME: Update this list every time el-search starts. How? (defvar el-search--symbols-with-doc-string (let (symbols) (mapatoms (lambda (sym) (and (fboundp sym) (get sym 'doc-string-elt) (push sym symbols)))) symbols) "A list of symbols which support doc-string.") (defun el-search--doc-string-p () "Return t if point is at docstring." (pcase (save-excursion (backward-up-list) (read (current-buffer))) (`(,(and symbol (guard (memq symbol el-search--symbols-with-doc-string))) ,_ . ,_) (let ((op (point))) (save-excursion (backward-up-list) (forward-char) (ignore-errors (forward-sexp (1+ (get symbol 'doc-string-elt))) (backward-sexp) (= op (point)))))))) (el-search-defpattern doc-string (&rest regexps) "Match any documentation string that is matched by all REGEXPS." `(and (string ,@regexps) (guard (el-search--doc-string-p)))) (el-search-defpattern s (&rest regexps) "Match any string (excluding doc string) that is matched by all REGEXPS" `(and (string ,@regexps) (guard (not (el-search--doc-string-p))))) #+end_src ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? 2017-12-27 5:38 ` Chunyang Xu @ 2017-12-27 13:58 ` Michael Heerdegen 0 siblings, 0 replies; 28+ messages in thread From: Michael Heerdegen @ 2017-12-27 13:58 UTC (permalink / raw) To: Chunyang Xu; +Cc: help-gnu-emacs, Emanuel Berg Chunyang Xu <mail@xuchunyang.me> writes: > ;; FIXME: Update this list every time el-search starts. How? For efficiency reasons I use in el-search a primitive type of caches that know when they need to refresh themselves. In this situation, this would look like #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (defun el-search--documented-function-p (name) (gethash name (el-search--get-documented-function-table))) (let ((helper (el-search-with-short-term-memory (lambda (_load-history) (message "Recomputing table of documented functions...") (let ((table (make-hash-table))) (mapatoms (lambda (sym) (and (fboundp sym) (get sym 'doc-string-elt) (puthash sym t table)))) table))))) (defun el-search--get-documented-function-table () (funcall helper load-history))) #+end_src The cache is a hash-table (faster lookup) that refreshes when queried and `load-history' changed. This is not optimal when you evaluate definitions by hand, of course. I could provide a `el-search-last-search-start-time' for that purpose, or a `el-search-start-hook' - though, I don't really want hooks to be used to implement pattern matching. FWIW, if you happen to want this (hack!), with a similar technique you can let el-search load searched buffers or files by side effect: #+begin_src emacs-lisp (el-search-defpattern load () "Match anything, load current buffer or file as side effect. Any buffer or file is loaded at most once. This is useful only in rare cases. Use with caution!!!" (declare (heuristic-matcher #'el-search--load-matcher)) (let ((load-matcher (el-search--load-matcher))) `(guard (funcall ',load-matcher (current-buffer) nil)))) (defun el-search--load-matcher () (let ((test (el-search-with-short-term-memory (lambda (file-name-or-buffer) (when-let ((file (if (bufferp file-name-or-buffer) (buffer-file-name file-name-or-buffer) file-name-or-buffer))) (with-demoted-errors "Error: %S" (load file))))))) (lambda (file-name-or-buffer _) (funcall test file-name-or-buffer)))) #+end_src HTH, Michael. ^ permalink raw reply [flat|nested] 28+ messages in thread
[parent not found: <mailman.6406.1514353148.27995.help-gnu-emacs@gnu.org>]
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6406.1514353148.27995.help-gnu-emacs@gnu.org> @ 2017-12-27 6:58 ` Emanuel Berg 0 siblings, 0 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-27 6:58 UTC (permalink / raw) To: help-gnu-emacs Chunyang Xu wrote: > I think point is at the beginning of the > string, the following assumes this to work. Perhaps that can be improved easily. First, check if point is at a string. If it is, search backwards to the initial string delimiter (and make sure it isn't quoted). Then, check if that string is in a docstring position. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [el-search] How to search string excluding docstring? [not found] ` <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org> 2017-12-25 19:36 ` Emanuel Berg @ 2017-12-25 19:39 ` Emanuel Berg 1 sibling, 0 replies; 28+ messages in thread From: Emanuel Berg @ 2017-12-25 19:39 UTC (permalink / raw) To: help-gnu-emacs t wrote: > Start with the Chomsky hierarchy, and delve > as deep as you like :-) I had that on Automata Theory which I completed 2010-01-13. That was only 7y 11m 12d (total 2903d) ago which is why I remember it so well. -- underground experts united http://user.it.uu.se/~embe8573 ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2017-12-27 13:58 UTC | newest] Thread overview: 28+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-12-25 10:27 [el-search] How to search string excluding docstring? Chunyang Xu 2017-12-25 10:40 ` Jean-Christophe Helary 2017-12-25 12:00 ` Skip Montanaro 2017-12-25 18:04 ` Michael Heerdegen 2017-12-25 14:56 ` Michael Heerdegen 2017-12-25 16:58 ` Chunyang Xu 2017-12-25 17:51 ` Michael Heerdegen [not found] ` <mailman.6340.1514213787.27995.help-gnu-emacs@gnu.org> 2017-12-25 15:50 ` Emanuel Berg 2017-12-25 16:59 ` Michael Heerdegen [not found] ` <mailman.6351.1514221174.27995.help-gnu-emacs@gnu.org> 2017-12-25 18:04 ` Emanuel Berg [not found] <mailman.6328.1514197667.27995.help-gnu-emacs@gnu.org> 2017-12-25 12:00 ` Emanuel Berg 2017-12-25 13:57 ` Chunyang Xu 2017-12-25 14:34 ` Michael Heerdegen [not found] ` <mailman.6334.1514210258.27995.help-gnu-emacs@gnu.org> 2017-12-25 14:08 ` Emanuel Berg 2017-12-25 17:55 ` tomas [not found] ` <mailman.6358.1514224565.27995.help-gnu-emacs@gnu.org> 2017-12-25 18:11 ` Emanuel Berg 2017-12-25 19:14 ` tomas [not found] ` <mailman.6366.1514229270.27995.help-gnu-emacs@gnu.org> 2017-12-25 19:36 ` Emanuel Berg 2017-12-25 21:20 ` tomas [not found] ` <mailman.6371.1514236843.27995.help-gnu-emacs@gnu.org> 2017-12-25 21:56 ` Emanuel Berg 2017-12-26 2:44 ` Emanuel Berg 2017-12-26 13:34 ` Emanuel Berg 2017-12-26 13:48 ` Jean-Christophe Helary [not found] ` <mailman.6381.1514296097.27995.help-gnu-emacs@gnu.org> 2017-12-26 15:19 ` Emanuel Berg 2017-12-27 5:38 ` Chunyang Xu 2017-12-27 13:58 ` Michael Heerdegen [not found] ` <mailman.6406.1514353148.27995.help-gnu-emacs@gnu.org> 2017-12-27 6:58 ` Emanuel Berg 2017-12-25 19:39 ` Emanuel Berg
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).