* [mange@freemail.hu: grep-tree doesn't shell-quote-argument] @ 2006-04-18 12:57 Richard Stallman 2006-04-18 14:02 ` Kim F. Storm 0 siblings, 1 reply; 67+ messages in thread From: Richard Stallman @ 2006-04-18 12:57 UTC (permalink / raw) Cc: Magnus Henoch Since M-x grep does not do this, I am not sure it is desirable to make M-x grep-tree incompatible with it. But I don't use grep-tree. What do others think? ------- Start of forwarded message ------- Mail-Followup-To: emacs-pretest-bug@gnu.org To: emacs-pretest-bug@gnu.org From: Magnus Henoch <mange@freemail.hu> Date: Mon, 17 Apr 2006 23:17:14 +0200 Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Mail-Copies-To: never Jabber-Id: legoscia@jabber.cd.chalmers.se Subject: grep-tree doesn't shell-quote-argument X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=failed version=3.0.4 - --=-=-= grep-tree doesn't quote its regexp argument to protect it from the shell. This makes it harder to use * and ? in regexps. I propose this patch: 2006-04-17 Magnus Henoch <mange@freemail.hu> * progmodes/grep.el (grep-tree): Call shell-quote-argument on regexp. - --=-=-= Content-Type: text/x-patch Content-Disposition: inline *** orig/lisp/progmodes/grep.el - --- mod/lisp/progmodes/grep.el *************** *** 631,637 **** (setq files (cdr mf))))) (let ((command-args (grep-expand-command-macros grep-tree-command ! (setq grep-tree-last-regexp regexp) (and files (concat "-name '" files "'")) (if subdirs (if (stringp subdirs) - --- 632,638 ---- (setq files (cdr mf))))) (let ((command-args (grep-expand-command-macros grep-tree-command ! (shell-quote-argument (setq grep-tree-last-regexp regexp)) (and files (concat "-name '" files "'")) (if subdirs (if (stringp subdirs) - --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ emacs-pretest-bug mailing list emacs-pretest-bug@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug - --=-=-=-- ------- End of forwarded message ------- ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 12:57 [mange@freemail.hu: grep-tree doesn't shell-quote-argument] Richard Stallman @ 2006-04-18 14:02 ` Kim F. Storm 2006-04-18 14:44 ` Eli Zaretskii 0 siblings, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-18 14:02 UTC (permalink / raw) Cc: Magnus Henoch, emacs-devel Richard Stallman <rms@gnu.org> writes: > Since M-x grep does not do this, I am not sure it is desirable > to make M-x grep-tree incompatible with it. But I don't use > grep-tree. What do others think? M-x grep prompts for the entire command line, so the user can easily add the necessary quoting of the regexp. M-x grep-tree prompts individually for the regexp, files, and directory, so I think it makes good sense to quote the regexp automatically. It would make sense to rewrite the following line to use shell-quote-argument as well: > (and files (concat "-name '" files "'")) i.e. (and files (concat "-name " (shell-quote-argument files))) > > From: Magnus Henoch <mange@freemail.hu> > Subject: grep-tree doesn't shell-quote-argument > To: emacs-pretest-bug@gnu.org > Date: Mon, 17 Apr 2006 23:17:14 +0200 > Mail-Followup-To: emacs-pretest-bug@gnu.org > Mail-Copies-To: never > > - --=-=-= > > grep-tree doesn't quote its regexp argument to protect it from the > shell. This makes it harder to use * and ? in regexps. I propose > this patch: > > 2006-04-17 Magnus Henoch <mange@freemail.hu> > > * progmodes/grep.el (grep-tree): Call shell-quote-argument on > regexp. > > > - --=-=-= > Content-Type: text/x-patch > Content-Disposition: inline > > *** orig/lisp/progmodes/grep.el > - --- mod/lisp/progmodes/grep.el > *************** > *** 631,637 **** > (setq files (cdr mf))))) > (let ((command-args (grep-expand-command-macros > grep-tree-command > ! (setq grep-tree-last-regexp regexp) > (and files (concat "-name '" files "'")) > (if subdirs > (if (stringp subdirs) > - --- 632,638 ---- > (setq files (cdr mf))))) > (let ((command-args (grep-expand-command-macros > grep-tree-command > ! (shell-quote-argument (setq grep-tree-last-regexp regexp)) > (and files (concat "-name '" files "'")) > (if subdirs > (if (stringp subdirs) > > - --=-=-= > Content-Type: text/plain; charset="us-ascii" > MIME-Version: 1.0 > Content-Transfer-Encoding: 7bit > Content-Disposition: inline > > _______________________________________________ > emacs-pretest-bug mailing list > emacs-pretest-bug@gnu.org > http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug > > - --=-=-=-- > ---------- > -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 14:02 ` Kim F. Storm @ 2006-04-18 14:44 ` Eli Zaretskii 2006-04-18 15:11 ` Eric Hanchrow ` (2 more replies) 0 siblings, 3 replies; 67+ messages in thread From: Eli Zaretskii @ 2006-04-18 14:44 UTC (permalink / raw) Cc: mange, emacs-devel > From: storm@cua.dk (Kim F. Storm) > Date: Tue, 18 Apr 2006 16:02:44 +0200 > Cc: Magnus Henoch <mange@freemail.hu>, emacs-devel@gnu.org > > Richard Stallman <rms@gnu.org> writes: > > > Since M-x grep does not do this, I am not sure it is desirable > > to make M-x grep-tree incompatible with it. But I don't use > > grep-tree. What do others think? > > M-x grep prompts for the entire command line, so the user can easily > add the necessary quoting of the regexp. How easily is that is not very important in this case, IMO. What is important is that "M-x grep" prompts for _a_shell_command_, and the user should type there a command that she would type at a shell's prompt. Which means the _user_ is responsible for any quoting that's required, especially since "M-x grep" has no real understanding of the command's semantics; it is just reading a string that it will pass to Grep. > M-x grep-tree prompts individually for the regexp, files, and directory, > so I think it makes good sense to quote the regexp automatically. In this case, grep-tree does know what is the semantics of each part of the command, since it prompts for them individually. So I agree. Btw, isn't it confusing that we have no less than 3 different commands (find-grep-dired, grep-find, and grep-tree) to do the same job? ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 14:44 ` Eli Zaretskii @ 2006-04-18 15:11 ` Eric Hanchrow 2006-04-18 15:18 ` Lennart Borgman 2006-04-18 15:27 ` Romain Francoise 2006-04-19 4:17 ` Richard Stallman 2 siblings, 1 reply; 67+ messages in thread From: Eric Hanchrow @ 2006-04-18 15:11 UTC (permalink / raw) >>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes: Eli> Btw, isn't it confusing that we have no less than 3 different Eli> commands (find-grep-dired, grep-find, and grep-tree) to do Eli> the same job? Yes. I've been using Emacs for 20 years, more or less, and only knew about grep-find until just now :-| -- "People think that throwing multiple exclamation points into a business letter will make their point forcefully," Ms. Andrews said. "I tell them they're allowed two exclamation points in their whole life." -- New York Times ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 15:11 ` Eric Hanchrow @ 2006-04-18 15:18 ` Lennart Borgman 2006-04-19 8:59 ` Kim F. Storm 0 siblings, 1 reply; 67+ messages in thread From: Lennart Borgman @ 2006-04-18 15:18 UTC (permalink / raw) Cc: emacs-devel Eric Hanchrow wrote: >>>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes: >>>>>> > > Eli> Btw, isn't it confusing that we have no less than 3 different > Eli> commands (find-grep-dired, grep-find, and grep-tree) to do > Eli> the same job? > > Yes. I've been using Emacs for 20 years, more or less, and only knew > about grep-find until just now :-| > Too me it seems like merging them into one command could possibly save a lot of time for many people. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 15:18 ` Lennart Borgman @ 2006-04-19 8:59 ` Kim F. Storm 2006-04-19 9:15 ` Romain Francoise 2006-04-19 9:16 ` Eli Zaretskii 0 siblings, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-19 8:59 UTC (permalink / raw) Cc: Eric Hanchrow, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Btw, isn't it confusing that we have no less than 3 different > commands (find-grep-dired, grep-find, and grep-tree) to do > the same job? Why? They do it differently and each serves a different audience. Eric Hanchrow wrote: > Yes. I've been using Emacs for 20 years, more or less, and only knew > about grep-find until just now :-| So what? Lennart Borgman <lennart.borgman.073@student.lu.se> writes: > Too me it seems like merging them into one command could possibly save > a lot of time for many people. Huh? Have you actually looked at them and what they do? Command Input Output ---------------------------------------------------------------------- grep Shell Command List of matching lines grep ... grep-find Shell Command List of matching lines find ... | grep ... (recurses directories) grep-tree Regexp, Files, Dir List of matching lines (recurses directorires) find-grep-dired Dir, Regexp List of matching FILES (recurses directorires) So grep and grep-find are similar in the sense that they both prompts the user for a SHELL COMMAND -- which is flexible but low-level (IMO). Like grep-find, grep-tree recurses directories listing matching lines, but the interface it completely different, as grep-tree prompts individually for regexp, files, and starting directory (with normal directory name completion). It also remembers your previous choice for each parameter, so you can quickly repeat a previous search starting in a different directory. IMO, grep-tree is much more user friendly than grep and grep-find (I use grep-tree all the time), while others obviously prefer the power of grep and grep-find. find-grep-dired is completely different in the sense that it doesn't list the matches, but rather presents a dired buffer which lists the files which matches the regexp. So they all serve a different purpose, and I don't see any way to merge them ...or how doing so can "save a lot of time for many people". -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 8:59 ` Kim F. Storm @ 2006-04-19 9:15 ` Romain Francoise 2006-04-19 9:16 ` Eli Zaretskii 1 sibling, 0 replies; 67+ messages in thread From: Romain Francoise @ 2006-04-19 9:15 UTC (permalink / raw) Cc: Eric Hanchrow, Lennart Borgman, emacs-devel storm@cua.dk (Kim F. Storm) writes: > So they all serve a different purpose, and I don't see any way to > merge them ...or how doing so can "save a lot of time for many > people". Neither do I. -- Romain Francoise <romain@orebokech.com> | The sea! the sea! the open it's a miracle -- http://orebokech.com/ | sea! The blue, the fresh, the | ever free! --Bryan W. Procter ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 8:59 ` Kim F. Storm 2006-04-19 9:15 ` Romain Francoise @ 2006-04-19 9:16 ` Eli Zaretskii 2006-04-19 11:41 ` Kim F. Storm 1 sibling, 1 reply; 67+ messages in thread From: Eli Zaretskii @ 2006-04-19 9:16 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, emacs-devel > From: storm@cua.dk (Kim F. Storm) > Date: Wed, 19 Apr 2006 10:59:44 +0200 > Cc: Eric Hanchrow <offby1@blarg.net>, emacs-devel@gnu.org > > > Eli Zaretskii <eliz@gnu.org> writes: > > Btw, isn't it confusing that we have no less than 3 different > > commands (find-grep-dired, grep-find, and grep-tree) to do > > the same job? > > Why? Because it is hard to remember which one does what, unless you use them every day. I only use them once in several months, and I always have to read the documentation to remember which one I need for the particular job at hand. > Have you actually looked at them and what they do? Well, I have, and I trust that Lennart did as well. > Like grep-find, grep-tree recurses directories listing matching lines, > but the interface it completely different, as grep-tree prompts > individually for regexp, files, and starting directory (with normal > directory name completion). It also remembers your previous choice > for each parameter, so you can quickly repeat a previous search > starting in a different directory. Don't you see how these are equivalent? > IMO, grep-tree is much more user > friendly than grep and grep-find (I use grep-tree all the time), > while others obviously prefer the power of grep and grep-find. Then making one a variant of the other should save us from having to remember another command name. > find-grep-dired is completely different in the sense that it > doesn't list the matches, but rather presents a dired buffer > which lists the files which matches the regexp. It's not ``completely different'', because in most situations the user wants to visit the matching files. The only real reason to prefer find-grep-dired to the others is when you want to invoke Dired commands on the matching files. > I don't see any way to merge them The normal Emacs way: use the prefix argument. > ...or how doing so can "save a lot of time for many people". For me, that time is wasted on reading the doc strings of the commands. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 9:16 ` Eli Zaretskii @ 2006-04-19 11:41 ` Kim F. Storm 2006-04-19 12:23 ` David Kastrup 2006-04-19 12:49 ` Stefan Monnier 0 siblings, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-19 11:41 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> IMO, grep-tree is much more user >> friendly than grep and grep-find (I use grep-tree all the time), >> while others obviously prefer the power of grep and grep-find. > > Then making one a variant of the other should save us from having to > remember another command name. > > The normal Emacs way: use the prefix argument. So what you suggest is that the current grep-tree should replace grep-find/find-grep as the default interface, and the current grep-find functionality should be selected if a prefix arg is specified. That would be ok with me, and I will make the changes if people agree. This should be done before the release as grep-tree is new in 22.x, and there are several defcustoms which should be renamed as part of this rework. > >> find-grep-dired is completely different in the sense that it >> doesn't list the matches, but rather presents a dired buffer >> which lists the files which matches the regexp. > > It's not ``completely different'', because in most situations the user > wants to visit the matching files. The only real reason to prefer > find-grep-dired to the others is when you want to invoke Dired > commands on the matching files. YMMV, but to me that's "completely different". So I still don't see how to merge find-grep-dired into grep-find. (a negative arg perhaps? wouldn't the be too obscure?) I suggest we leave that one alone! -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 11:41 ` Kim F. Storm @ 2006-04-19 12:23 ` David Kastrup 2006-04-19 12:51 ` Kim F. Storm ` (2 more replies) 2006-04-19 12:49 ` Stefan Monnier 1 sibling, 3 replies; 67+ messages in thread From: David Kastrup @ 2006-04-19 12:23 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel storm@cua.dk (Kim F. Storm) writes: > Eli Zaretskii <eliz@gnu.org> writes: > >>> IMO, grep-tree is much more user >>> friendly than grep and grep-find (I use grep-tree all the time), >>> while others obviously prefer the power of grep and grep-find. >> >> Then making one a variant of the other should save us from having to >> remember another command name. >> >> The normal Emacs way: use the prefix argument. > > So what you suggest is that the current grep-tree should replace > grep-find/find-grep as the default interface, and the current > grep-find functionality should be selected if a prefix arg is > specified. This is somewhat radical and might surprise people. And it might be a good idea if previous non-interactive calls kept their API (which basically means clever use of &optional or similar). How about making a configurable "grep-find-prompt" option that is a list or string with possible elements "p" and "c". The old default would be "c" (prompting with command), the new default "p" (prompting for parts), and an interactive argument would temporarily give "pc", where the parts are queried first, and then the finished command is offered again with point at a convenient location for adding `find' conditions. Something like that. That way, people can easily reconfigure the old behavior if they want to. And use C-u M-x grep-find RET for being able to post-edit the command, and maybe C-u C-u M-x grep-find RET for getting the inverse than the default behavior. > That would be ok with me, and I will make the changes if people > agree. > > This should be done before the release as grep-tree is new in 22.x, > and there are several defcustoms which should be renamed as part of > this rework. Likely. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 12:23 ` David Kastrup @ 2006-04-19 12:51 ` Kim F. Storm 2006-04-19 13:09 ` David Kastrup 2006-04-19 13:14 ` Stefan Monnier 2006-04-19 21:13 ` Richard Stallman 2 siblings, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-19 12:51 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel David Kastrup <dak@gnu.org> writes: >> So what you suggest is that the current grep-tree should replace >> grep-find/find-grep as the default interface, and the current >> grep-find functionality should be selected if a prefix arg is >> specified. > > This is somewhat radical and might surprise people. True, but that's how things evolve :-) I imagine to implement it with grep-find being just a front-end to two other commands grep-find-command and grep-find-template (corresponding to the old grep-find and grep-tree). So an easy way for a user to get the desired behaviour would be to defalias grep-find to either of these if the default doesn't suit him. > And it might be a > good idea if previous non-interactive calls kept their API (which > basically means clever use of &optional or similar). Yes, that would be easy (1 arg => command line, 3 args => grep-tree API) But currently there are no non-interactive calls to grep-find, find-grep or grep-tree in CVS emacs. And I doubt there are any at all, as there really isn't any logic in calling the existing grep-find non-interactively -- as there is no simple way to build the necessary command line (and running grep would do just as well). For non-interactive use, it seems like the grep-tree API would be much easier to use as the caller would not have to think about the low-level command line. > > How about making a configurable "grep-find-prompt" option that ... > ... And use C-u M-x grep-find RET for being > able to post-edit the command, and maybe C-u C-u M-x grep-find RET for > getting the inverse than the default behavior. So we merge two commands into one (because people cannot remember which is which), and then we add a new cryptic customize option to configure what it should do by default, and a couple of prefix args to tweak things even further. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 12:51 ` Kim F. Storm @ 2006-04-19 13:09 ` David Kastrup 2006-04-19 21:13 ` Richard Stallman 0 siblings, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-19 13:09 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel storm@cua.dk (Kim F. Storm) writes: > David Kastrup <dak@gnu.org> writes: > >>> So what you suggest is that the current grep-tree should replace >>> grep-find/find-grep as the default interface, and the current >>> grep-find functionality should be selected if a prefix arg is >>> specified. >> >> This is somewhat radical and might surprise people. > > True, but that's how things evolve :-) Sure, but we generally need two things for evolution: a) a recipe to put into NEWS and antinews how to get back the old behavior (there are always people shouting for that on any change). b) sort of a migration path so that those people can actually be made to swallow the new way piece by piece. > I imagine to implement it with grep-find being just a front-end to > two other commands grep-find-command and grep-find-template > (corresponding to the old grep-find and grep-tree). So an easy way > for a user to get the desired behaviour would be to defalias > grep-find to either of these if the default doesn't suit him. Customize by alias? Not really the most desirable thing in my book. >> How about making a configurable "grep-find-prompt" option that ... >> ... And use C-u M-x grep-find RET for being >> able to post-edit the command, and maybe C-u C-u M-x grep-find RET for >> getting the inverse than the default behavior. > > So we merge two commands into one (because people cannot remember > which is which), and then we add a new cryptic customize option to > configure what it should do by default, and a couple of prefix args to > tweak things even further. You make it sound like it would be a bad idea... Drop the "couple": just let grep-find prompt for everything when given a prefix argument. But I think a customization option for the default, namely whether to prompt for parts or the command, would be more reasonable than an _alias_ for selecting the default behavior. We don't usually customize by alias. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:09 ` David Kastrup @ 2006-04-19 21:13 ` Richard Stallman 0 siblings, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-19 21:13 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, eliz, emacs-devel, storm Sure, but we generally need two things for evolution: a) a recipe to put into NEWS and antinews how to get back the old behavior (there are always people shouting for that on any change). b) sort of a migration path so that those people can actually be made to swallow the new way piece by piece. We do not, in general, insist on this much. All we do in NEWS and Antinews is document the change. We do not usually bother with "migration paths", not even for incompatible changes. This would not be an incompatible change from Emacs 21. It need not be mentioned in Antinews, but should be in NEWS. (I see that grep-tree is not in NEWS.) ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 12:23 ` David Kastrup 2006-04-19 12:51 ` Kim F. Storm @ 2006-04-19 13:14 ` Stefan Monnier 2006-04-19 13:28 ` David Kastrup 2006-04-19 18:10 ` Bill Wohler 2006-04-19 21:13 ` Richard Stallman 2 siblings, 2 replies; 67+ messages in thread From: Stefan Monnier @ 2006-04-19 13:14 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel, Kim F. Storm >> So what you suggest is that the current grep-tree should replace >> grep-find/find-grep as the default interface, and the current >> grep-find functionality should be selected if a prefix arg is >> specified. > This is somewhat radical and might surprise people. Surprise is not bad. Confusing the user would be bad and making her do something she didn't intend to do would be even worse, but I don't think either of them applies here: the prompt should be sufficiently different that she should immediately realize what's going on. I think that what Kim suggests (rename grep-find to grep-find-command, grep-tree to grep-find-template, and introduce a new grep-find which calls either of the two depending on nilness of current-arg-prefix) is the way to go. Much better than introducing a complex configuration and prefix-arg protocol to choose what to do when. Stefan ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:14 ` Stefan Monnier @ 2006-04-19 13:28 ` David Kastrup 2006-04-19 13:58 ` Stefan Monnier 2006-04-19 14:52 ` Kim F. Storm 2006-04-19 18:10 ` Bill Wohler 1 sibling, 2 replies; 67+ messages in thread From: David Kastrup @ 2006-04-19 13:28 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel, Kim F. Storm Stefan Monnier <monnier@iro.umontreal.ca> writes: > I think that what Kim suggests (rename grep-find to > grep-find-command, grep-tree to grep-find-template, and introduce a > new grep-find which calls either of the two depending on nilness of > current-arg-prefix) is the way to go. Much better than introducing > a complex configuration and prefix-arg protocol to choose what to do > when. Strike the complexity. Use of a prefix arg to make it possible to post-edit the command is, IMO, a good idea. Quite often one wants to start a command that is almost, but not quite, like the default recipe. Kim's suggestion to use an alias for configuration between two separate commands is not customize-friendly. And it offers no reasonable way to actually get both: prompting for the parts, and a final opportunity for editing the resulting command before sending it off. I think the latter is important enough to offer this with a prefix argument, and this can't be easily accomplished if there is no unified command that can actually prompt for the parts as well as the finished command. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:28 ` David Kastrup @ 2006-04-19 13:58 ` Stefan Monnier 2006-04-19 14:09 ` David Kastrup 2006-04-19 14:52 ` Kim F. Storm 1 sibling, 1 reply; 67+ messages in thread From: Stefan Monnier @ 2006-04-19 13:58 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel, Kim F. Storm > And it offers no reasonable way to actually get both: prompting for the > parts, and a final opportunity for editing the resulting command before > sending it off. Shell command completion support would go a long way towards making the difference irrelevant. Also it ocurred to me that grep-tree should put the resulting command onto grep-find's history. > I think the latter is important enough to offer this with a prefix > argument, It's not currently possible, and it's the first time I hear a request for it, so it doesn't seem particularly important. Stefan ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:58 ` Stefan Monnier @ 2006-04-19 14:09 ` David Kastrup 2006-04-19 14:58 ` Kim F. Storm 0 siblings, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-19 14:09 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel, Kim F. Storm Stefan Monnier <monnier@iro.umontreal.ca> writes: >> And it offers no reasonable way to actually get both: prompting for the >> parts, and a final opportunity for editing the resulting command before >> sending it off. > > Shell command completion support would go a long way towards > making the difference irrelevant. > > Also it ocurred to me that grep-tree should put the resulting command onto > grep-find's history. > >> I think the latter is important enough to offer this with a prefix >> argument, > > It's not currently possible, and it's the first time I hear a > request for it, so it doesn't seem particularly important. Of _course_ this is the first request you hear for it because the changes that would make it convenient have not even been made. grep-find _currently_ offers to edit the command and nobody complained about that. So I don't see how this sanctifies to take away that possibility without an easy way of accessing it in case of need, short of redefining an alias. For what it's worth, AUCTeX's command dispatcher will understand a prefix-command as a request to edit the command that is going to be sent to the shell, and this functionality has been added because it was requested. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 14:09 ` David Kastrup @ 2006-04-19 14:58 ` Kim F. Storm 2006-04-19 15:10 ` David Kastrup 2006-04-19 16:59 ` Kevin Rodgers 0 siblings, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-19 14:58 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, Stefan Monnier, emacs-devel David Kastrup <dak@gnu.org> writes: > grep-find _currently_ offers to edit the command and nobody complained > about that. See the existance of grep-tree as a complaint :-) > So I don't see how this sanctifies to take away that > possibility without an easy way of accessing it in case of need, short > of redefining an alias. What's difficult about the C-u prefix ?? > For what it's worth, AUCTeX's command dispatcher will understand a > prefix-command as a request to edit the command that is going to be > sent to the shell, and this functionality has been added because it > was requested. To follow that logic, every command which eventually causes a command to be sent to a shell should undeerstand a C-u prefix to mean "edit command string before sending it to the shell" ? -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 14:58 ` Kim F. Storm @ 2006-04-19 15:10 ` David Kastrup 2006-04-19 16:59 ` Kevin Rodgers 1 sibling, 0 replies; 67+ messages in thread From: David Kastrup @ 2006-04-19 15:10 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, Stefan Monnier, emacs-devel storm@cua.dk (Kim F. Storm) writes: > David Kastrup <dak@gnu.org> writes: > >> grep-find _currently_ offers to edit the command and nobody complained >> about that. > > See the existance of grep-tree as a complaint :-) Hardly, since it deals with the problem of being able to enter the required information in an easy way, not with a user requirement never to be able to edit the command before it gets sent off. >> So I don't see how this sanctifies to take away that possibility >> without an easy way of accessing it in case of need, short of >> redefining an alias. > > What's difficult about the C-u prefix ?? If this stops grep-find from prompting for the arguments, it does not give you a starting place for editing. And if it does not inhibit the prompting, uh, we have my proposal, so you'd hardly find me objecting to it... >> For what it's worth, AUCTeX's command dispatcher will understand a >> prefix-command as a request to edit the command that is going to be >> sent to the shell, and this functionality has been added because it >> was requested. > > To follow that logic, every command which eventually causes a > command to be sent to a shell should undeerstand a C-u prefix to > mean "edit command string before sending it to the shell" ? Not necessarily. It could come in handy in a few cases. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 14:58 ` Kim F. Storm 2006-04-19 15:10 ` David Kastrup @ 2006-04-19 16:59 ` Kevin Rodgers 2006-04-19 17:08 ` David Kastrup 1 sibling, 1 reply; 67+ messages in thread From: Kevin Rodgers @ 2006-04-19 16:59 UTC (permalink / raw) Kim F. Storm wrote: > David Kastrup <dak@gnu.org> writes: >>For what it's worth, AUCTeX's command dispatcher will understand a >>prefix-command as a request to edit the command that is going to be >>sent to the shell, and this functionality has been added because it >>was requested. > > To follow that logic, every command which eventually causes a command > to be sent to a shell should undeerstand a C-u prefix to mean "edit > command string before sending it to the shell" ? That logic can't be followed that far, because M-! and M-| already interpret C-u specially. -- Kevin Rodgers ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 16:59 ` Kevin Rodgers @ 2006-04-19 17:08 ` David Kastrup 0 siblings, 0 replies; 67+ messages in thread From: David Kastrup @ 2006-04-19 17:08 UTC (permalink / raw) Cc: emacs-devel Kevin Rodgers <ihs_4664@yahoo.com> writes: > Kim F. Storm wrote: >> David Kastrup <dak@gnu.org> writes: >>>For what it's worth, AUCTeX's command dispatcher will understand a >>>prefix-command as a request to edit the command that is going to be >>>sent to the shell, and this functionality has been added because it >>>was requested. >> To follow that logic, every command which eventually causes a >> command >> to be sent to a shell should undeerstand a C-u prefix to mean "edit >> command string before sending it to the shell" ? > > That logic can't be followed that far, because M-! and M-| already > interpret C-u specially. Well, it would be spectacularly pointless to let M-! and M-| offer the command for editing again, anyway. This would be useful as a convention mostly for commands which are set up by Emacs, not by the user, and which have their own _special_ output buffer (not something like *Shell Command* but rather something like *grep*) so that it would not make sense to insert the output into the current buffer. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:28 ` David Kastrup 2006-04-19 13:58 ` Stefan Monnier @ 2006-04-19 14:52 ` Kim F. Storm 2006-04-19 15:03 ` David Kastrup 1 sibling, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-19 14:52 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, Stefan Monnier, emacs-devel David Kastrup <dak@gnu.org> writes: > Strike the complexity. Use of a prefix arg to make it possible to > post-edit the command is, IMO, a good idea. It is a _nice_ idea, but I'm not sure it is a _good_ idea. Using the prefix arg for this purpose takes away the simple way to select the "old behaviour" shortcut (which Eli suggested as the way to go). One thing we could (should?) do is to enter the final command from non-C-u usage into the grep-find-history, so it would be easily accessible (for tweaking) on a subsequent use of C-u M-x grep-find in case the first run didn't give the desired results. > Quite often one wants to > start a command that is almost, but not quite, like the default > recipe. So tweak the grep-find-command-template instead... -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 14:52 ` Kim F. Storm @ 2006-04-19 15:03 ` David Kastrup 0 siblings, 0 replies; 67+ messages in thread From: David Kastrup @ 2006-04-19 15:03 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, Stefan Monnier, emacs-devel storm@cua.dk (Kim F. Storm) writes: > David Kastrup <dak@gnu.org> writes: > >> Strike the complexity. Use of a prefix arg to make it possible to >> post-edit the command is, IMO, a good idea. > > It is a _nice_ idea, but I'm not sure it is a _good_ idea. > > Using the prefix arg for this purpose takes away the simple way to > select the "old behaviour" shortcut (which Eli suggested as the way > to go). Well, you'd have to press RET a few more times then: filling in empty arguments will more or less land you with the old behavior. > One thing we could (should?) do is to enter the final command from > non-C-u usage into the grep-find-history, so it would be easily > accessible (for tweaking) on a subsequent use of C-u M-x grep-find > in case the first run didn't give the desired results. But if you _know_ in advance that the first run is not going to give you the desired results, having to start it nevertheless for the sake of being able to edit it afterwards seems pretty backward. I think the idea of entering the final command into the history is dandy in itself, but having to execute the command as a precursor of being allowed to edit it... Well... >> Quite often one wants to start a command that is almost, but not >> quite, like the default recipe. > > So tweak the grep-find-command-template instead... I don't find that having to redefine an Elisp command for a one-shot application is the most convenient user interface. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 13:14 ` Stefan Monnier 2006-04-19 13:28 ` David Kastrup @ 2006-04-19 18:10 ` Bill Wohler 2006-04-19 18:15 ` Drew Adams 2006-04-19 18:23 ` David Kastrup 1 sibling, 2 replies; 67+ messages in thread From: Bill Wohler @ 2006-04-19 18:10 UTC (permalink / raw) Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> So what you suggest is that the current grep-tree should replace >>> grep-find/find-grep as the default interface, and the current >>> grep-find functionality should be selected if a prefix arg is >>> specified. > >> This is somewhat radical and might surprise people. > > Surprise is not bad. If you're producing a horror film, perhaps. But not in a UI. ;-) I agree with Eli--there are way too many grep commands (and that was before I just learned about grep-tree). find-grep is redundant with grep's -r and --include options. grep-tree is redundant with find-grep. We only need two: grep (which shows you the grep hits) and grep-dired (which lists the matched files in dired). The default UIs for both should be simple (like grep-tree), but should allow editing of the command with the prefix argument. Another thought: it would be nice if the -i option were passed to grep if case-fold-search is t. -- Bill Wohler <wohler@newt.com> http://www.newt.com/wohler/ GnuPG ID:610BD9AD Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian! If you're passed on the right, you're in the wrong lane. ^ permalink raw reply [flat|nested] 67+ messages in thread
* RE: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 18:10 ` Bill Wohler @ 2006-04-19 18:15 ` Drew Adams 2006-04-19 18:23 ` David Kastrup 1 sibling, 0 replies; 67+ messages in thread From: Drew Adams @ 2006-04-19 18:15 UTC (permalink / raw) Another thought: it would be nice if the -i option were passed to grep if case-fold-search is t. case-fold-search where? the buffer where you run grep? That sounds like a bad idea to me. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 18:10 ` Bill Wohler 2006-04-19 18:15 ` Drew Adams @ 2006-04-19 18:23 ` David Kastrup 2006-04-19 18:34 ` Bill Wohler 1 sibling, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-19 18:23 UTC (permalink / raw) Cc: emacs-devel Bill Wohler <wohler@newt.com> writes: > Stefan Monnier <monnier@iro.umontreal.ca> writes: > >>>> So what you suggest is that the current grep-tree should replace >>>> grep-find/find-grep as the default interface, and the current >>>> grep-find functionality should be selected if a prefix arg is >>>> specified. >> >>> This is somewhat radical and might surprise people. >> >> Surprise is not bad. > > If you're producing a horror film, perhaps. But not in a UI. ;-) > > I agree with Eli--there are way too many grep commands (and that was > before I just learned about grep-tree). Yes. > find-grep is redundant with grep's -r and --include > options. No. Only the most primitive calls of find-grep can be catered for by "grep's" -r and --include options, and many greps don't even have those options. > grep-tree is redundant with find-grep. Which is why we are discussing how to merge them... > We only need two: grep (which shows you the grep hits) and > grep-dired (which lists the matched files in dired). Disagree. Find can't be obliterated for all usage cases, but using it for something like *.[ch] would certainly be inconvenient. > The default UIs for both should be simple (like grep-tree), but > should allow editing of the command with the prefix argument. > Another thought: it would be nice if the -i option were passed to grep > if case-fold-search is t. The setting of case-fold-search rarely is fine-tuned to the current editing need, so I doubt that passing it on to grep would feel natural to people. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 18:23 ` David Kastrup @ 2006-04-19 18:34 ` Bill Wohler 0 siblings, 0 replies; 67+ messages in thread From: Bill Wohler @ 2006-04-19 18:34 UTC (permalink / raw) Cc: emacs-devel David Kastrup <dak@gnu.org> wrote: > Bill Wohler <wohler@newt.com> writes: > > > We only need two: grep (which shows you the grep hits) and > > grep-dired (which lists the matched files in dired). > > Disagree. Find can't be obliterated for all usage cases, but using it > for something like *.[ch] would certainly be inconvenient. I'm taking the 50,000 foot view. The use of find is an implementation detail of these two major use cases. Generally speaking, a user either wants to see grep hits, or file names. So only offer two functions. All of the other grep commands should be non-interactive implementations. (These should be post-release changes, by the way. Incorporating grep-tree into find-grep is an excellent pre-release goal.) -- Bill Wohler <wohler@newt.com> http://www.newt.com/wohler/ GnuPG ID:610BD9AD Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian! If you're passed on the right, you're in the wrong lane. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 12:23 ` David Kastrup 2006-04-19 12:51 ` Kim F. Storm 2006-04-19 13:14 ` Stefan Monnier @ 2006-04-19 21:13 ` Richard Stallman 2 siblings, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-19 21:13 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, eliz, emacs-devel, storm How about making a configurable "grep-find-prompt" option that is a list or string with possible elements "p" and "c". No, that is too much complexity! Since grep-tree is new, we need not even consider the issue of "incompatible changes" in it. And the proposed change would be a compatible extension to grep-find. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 11:41 ` Kim F. Storm 2006-04-19 12:23 ` David Kastrup @ 2006-04-19 12:49 ` Stefan Monnier 1 sibling, 0 replies; 67+ messages in thread From: Stefan Monnier @ 2006-04-19 12:49 UTC (permalink / raw) Cc: offby1, lennart.borgman.073, Eli Zaretskii, emacs-devel > So I still don't see how to merge find-grep-dired into grep-find. Agreed. I think it'd be good to merge grep-find and grep-tree into grep-find (aka find-grep), and I think all that's left for find-grep-dired is to make an alias grep-find-dired for it. Stefan ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 14:44 ` Eli Zaretskii 2006-04-18 15:11 ` Eric Hanchrow @ 2006-04-18 15:27 ` Romain Francoise 2006-04-19 4:17 ` Richard Stallman 2 siblings, 0 replies; 67+ messages in thread From: Romain Francoise @ 2006-04-18 15:27 UTC (permalink / raw) Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Btw, isn't it confusing that we have no less than 3 different commands > (find-grep-dired, grep-find, and grep-tree) to do the same job? Er, `find-grep-dired' does the same "job" (it runs grep on files), but it doesn't do the same thing as the two others, and is used in different contexts. -- Romain Francoise <romain@orebokech.com> | The sea! the sea! the open it's a miracle -- http://orebokech.com/ | sea! The blue, the fresh, the | ever free! --Bryan W. Procter ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-18 14:44 ` Eli Zaretskii 2006-04-18 15:11 ` Eric Hanchrow 2006-04-18 15:27 ` Romain Francoise @ 2006-04-19 4:17 ` Richard Stallman 2006-04-19 8:57 ` Eli Zaretskii 2 siblings, 1 reply; 67+ messages in thread From: Richard Stallman @ 2006-04-19 4:17 UTC (permalink / raw) Cc: mange, emacs-devel, storm Btw, isn't it confusing that we have no less than 3 different commands (find-grep-dired, grep-find, and grep-tree) to do the same job? I never use any of them. How do they differ? ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 4:17 ` Richard Stallman @ 2006-04-19 8:57 ` Eli Zaretskii 2006-04-19 21:12 ` Richard Stallman 0 siblings, 1 reply; 67+ messages in thread From: Eli Zaretskii @ 2006-04-19 8:57 UTC (permalink / raw) Cc: mange, emacs-devel, storm > From: Richard Stallman <rms@gnu.org> > CC: storm@cua.dk, mange@freemail.hu, emacs-devel@gnu.org > Date: Wed, 19 Apr 2006 00:17:23 -0400 > > Btw, isn't it confusing that we have no less than 3 different commands > (find-grep-dired, grep-find, and grep-tree) to do the same job? > > I never use any of them. How do they differ? The first one displays a Dired buffer with all the matching files, the other two display the normal Grep hits, but differ in how they accept arguments: grep-find wants the full Find command line, while grep-tree asks only for its variable parts and keeps the rest hidden from the user. I think at least grep-tree and grep-find could be a single command: e.g., it would behave like grep-tree by default, but with a prefix argument will show the full command (so that power users could tailor it), like grep-find does. It's also possible to make find-grep-dired a variant of the same single command, if we want only one UI instead of 3. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 8:57 ` Eli Zaretskii @ 2006-04-19 21:12 ` Richard Stallman 2006-04-20 9:53 ` Eli Zaretskii 2006-04-21 8:27 ` Kim F. Storm 0 siblings, 2 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-19 21:12 UTC (permalink / raw) Cc: mange, emacs-devel, storm I think at least grep-tree and grep-find could be a single command: e.g., it would behave like grep-tree by default, but with a prefix argument will show the full command (so that power users could tailor it), like grep-find does. That sounds plausible. Can you make a precise proposal for the interface? It's also possible to make find-grep-dired a variant of the same single command, if we want only one UI instead of 3. I think this should remain a separate command, so let's not change it. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 21:12 ` Richard Stallman @ 2006-04-20 9:53 ` Eli Zaretskii 2006-04-21 8:27 ` Kim F. Storm 1 sibling, 0 replies; 67+ messages in thread From: Eli Zaretskii @ 2006-04-20 9:53 UTC (permalink / raw) Cc: mange, emacs-devel, storm > From: Richard Stallman <rms@gnu.org> > CC: storm@cua.dk, mange@freemail.hu, emacs-devel@gnu.org > Date: Wed, 19 Apr 2006 17:12:50 -0400 > > I think at least grep-tree and grep-find could be a single command: > e.g., it would behave like grep-tree by default, but with a prefix > argument will show the full command (so that power users could tailor > it), like grep-find does. > > That sounds plausible. Can you make a precise proposal > for the interface? There are already several proposals on the table, as you'll see from the ensuing discussion. I don't have anything useful to add to what others suggested. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-19 21:12 ` Richard Stallman 2006-04-20 9:53 ` Eli Zaretskii @ 2006-04-21 8:27 ` Kim F. Storm 2006-04-21 14:47 ` Magnus Henoch 2006-04-22 12:03 ` Richard Stallman 1 sibling, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-21 8:27 UTC (permalink / raw) Cc: mange, rms Richard Stallman <rms@gnu.org> writes: > I think at least grep-tree and grep-find could be a single command: > e.g., it would behave like grep-tree by default, but with a prefix > argument will show the full command (so that power users could tailor > it), like grep-find does. > > That sounds plausible. Can you make a precise proposal > for the interface? Below is a patch which merges grep-tree into grep-find, with the new grep-tree interface as the default API, while a C-u prefix requests using the old grep-find interface. If called non-interactively with one arg, it behaves like the old grep-find (interpreting the arg as a shell command). In the process, the grep-tree part of the code has been cleaned up, all the related defcustoms have been suitable renamed, and proper histories for the new-style arguments have been added. There is a new defcustom grep-find-prompt-style to permanently select the old-style prompting. One question: Why are grep-history and grep-find-history autoloaded? *** grep.el 16 Mar 2006 09:41:13 +0100 1.51 --- grep.el 20 Apr 2006 13:59:23 +0200 *************** *** 130,137 **** (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-tree-command nil ! "The default find command for \\[grep-tree]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: --- 130,137 ---- (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-find-template nil ! "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: *************** *** 145,170 **** :version "22.1" :group 'grep) ! (defcustom grep-tree-files-aliases '( ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") - ("m" . "[Mm]akefile*") ("asm" . "*.[sS]") ! ("all" . "*") ! ("el" . "*.el") ) ! "*Alist of aliases for the FILES argument to `grep-tree'." :type 'alist :group 'grep) ! (defcustom grep-tree-ignore-case t ! "*If non-nil, `grep-tree' ignores case in matches." :type 'boolean :group 'grep) ! (defcustom grep-tree-ignore-CVS-directories t ! "*If non-nil, `grep-tree' does no recurse into CVS directories." :type 'boolean :group 'grep) --- 145,180 ---- :version "22.1" :group 'grep) ! (defcustom grep-find-prompt-style nil ! "*Prompt style used by `grep-find'. ! Nil means to prompt for regexp, files, and directory. ! Value `shell' means to prompt for shell command instead. ! Value `post' means to post-edit the final shell command." ! :type '(choice (const :tag "Standard" nil) ! (const :tag "Shell Command" shell) ! (const :tag "Post-edit Command" post)) ! :version "22.1" ! :group 'grep) ! ! (defcustom grep-find-files-aliases '( ! ("el" . "*.el") ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") ("asm" . "*.[sS]") ! ("m" . "[Mm]akefile*") ) ! "*Alist of aliases for the FILES argument to `grep-find'." :type 'alist :group 'grep) ! (defcustom grep-find-ignore-case t ! "*If non-nil, `grep-find' ignores case in matches." :type 'boolean :group 'grep) ! (defcustom grep-find-ignore-CVS-directories t ! "*If non-nil, `grep-find' does no recurse into CVS directories." :type 'boolean :group 'grep) *************** *** 318,323 **** --- 328,337 ---- "Additional things to highlight in grep output. This gets tacked on the end of the generated expressions.") + ;; grep-find regexp and files history + (defvar grep-find-regexp-history nil) + (defvar grep-find-files-history '("ch" "el")) + ;;;###autoload (defvar grep-program ;; Currently zgrep has trouble. It runs egrep instead of grep, *************** *** 433,440 **** (t (cons (format "%s . -type f -exec %s {} %s \\;" find-program grep-command null-device) (+ 22 (length grep-command))))))) ! (unless grep-tree-command ! (setq grep-tree-command (let* ((glen (length grep-program)) (gcmd (concat grep-program " <C>" (substring grep-command glen)))) (cond ((eq grep-find-use-xargs 'gnu) --- 447,454 ---- (t (cons (format "%s . -type f -exec %s {} %s \\;" find-program grep-command null-device) (+ 22 (length grep-command))))))) ! (unless grep-find-template ! (setq grep-find-template (let* ((glen (length grep-program)) (gcmd (concat grep-program " <C>" (substring grep-command glen)))) (cond ((eq grep-find-use-xargs 'gnu) *************** *** 488,501 **** (replace-match tag-default t t grep-default 1)))) ;;;###autoload ! (defun grep (command-args &optional highlight-regexp) "Run grep, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its COMMAND-ARGS, so you can easily repeat a grep command. A prefix argument says to default the argument based upon the current --- 502,515 ---- (replace-match tag-default t t grep-default 1)))) ;;;###autoload ! (defun grep (command &optional highlight-regexp) "Run grep, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its COMMAND, so you can easily repeat a grep command. A prefix argument says to default the argument based upon the current *************** *** 520,527 **** ;; Setting process-setup-function makes exit-message-function work ;; even when async processes aren't supported. (compilation-start (if (and grep-use-null-device null-device) ! (concat command-args " " null-device) ! command-args) 'grep-mode nil highlight-regexp)) ;;;###autoload --- 534,541 ---- ;; Setting process-setup-function makes exit-message-function work ;; even when async processes aren't supported. (compilation-start (if (and grep-use-null-device null-device) ! (concat command " " null-device) ! command) 'grep-mode nil highlight-regexp)) ;;;###autoload *************** *** 536,571 **** 'grep-process-setup) (set (make-local-variable 'compilation-disable-input) t)) ! ;;;###autoload ! (defun grep-find (command-args) ! "Run grep via find, with user-specified args COMMAND-ARGS. ! Collect output in a buffer. ! While find runs asynchronously, you can use the \\[next-error] command ! to find the text that grep hits refer to. ! ! This command uses a special history list for its arguments, so you can ! easily repeat a find command." ! (interactive ! (progn ! (unless (and grep-command ! (or (not grep-use-null-device) (eq grep-use-null-device t))) ! (grep-compute-defaults)) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history)) ! ;; No default was set ! (read-string ! "compile.el: No `grep-find-command' command available. Press RET.") ! (list nil)))) ! (when (and grep-find-command command-args) ! (let ((null-device nil)) ; see grep ! (grep command-args)))) ! ! ;;;###autoload ! (defalias 'find-grep 'grep-find) ! ! (defun grep-expand-command-macros (command &optional regexp files dir excl case-fold) "Patch grep COMMAND replacing <D>, etc." (setq command (replace-regexp-in-string "<D>" --- 550,556 ---- 'grep-process-setup) (set (make-local-variable 'compilation-disable-input) t)) ! (defun grep-expand-template (command &optional regexp files dir excl case-fold) "Patch grep COMMAND replacing <D>, etc." (setq command (replace-regexp-in-string "<D>" *************** *** 584,649 **** (or regexp "") command t t)) command) - (defvar grep-tree-last-regexp "") - (defvar grep-tree-last-files (car (car grep-tree-files-aliases))) - ;;;###autoload ! (defun grep-tree (regexp files dir &optional subdirs) ! "Grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. Interactively, prompt separately for each search parameter. - With prefix arg, reuse previous REGEXP. The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-tree-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily repeat a find command. ! ! When used non-interactively, optional arg SUBDIRS limits the search to ! those sub directories of DIR." (interactive ! (let* ((regexp ! (if current-prefix-arg ! grep-tree-last-regexp ! (let* ((default (current-word)) ! (spec (read-string ! (concat "Search for" ! (if (and default (> (length default) 0)) ! (format " (default %s): " default) ": "))))) ! (if (equal spec "") default spec)))) ! (files ! (read-string (concat "Search for \"" regexp "\" in files (default " grep-tree-last-files "): "))) ! (dir ! (read-directory-name "Base directory: " nil default-directory t))) ! (list regexp files dir))) ! (unless grep-tree-command ! (grep-compute-defaults)) ! (unless (and (stringp files) (> (length files) 0)) ! (setq files grep-tree-last-files)) ! (when files ! (setq grep-tree-last-files files) ! (let ((mf (assoc files grep-tree-files-aliases))) ! (if mf ! (setq files (cdr mf))))) ! (let ((command-args (grep-expand-command-macros ! grep-tree-command ! (setq grep-tree-last-regexp regexp) ! (and files (concat "-name '" files "'")) ! (if subdirs ! (if (stringp subdirs) ! subdirs ! (mapconcat 'identity subdirs " ")) ! nil) ;; we change default-directory to dir ! (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ") ! grep-tree-ignore-case)) ! (default-directory (file-name-as-directory (expand-file-name dir))) ! (null-device nil)) ; see grep ! (grep command-args regexp))) (provide 'grep) --- 569,680 ---- (or regexp "") command t t)) command) ;;;###autoload ! (defun grep-find (regexp &optional files dir api) ! "Recusively grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. Interactively, prompt separately for each search parameter. The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-find-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. + With \\[universal-argument] prefix, prompt for shell command instead. + With two \\[universal-argument] prefixes, prompt for search parameters, + and allow user to edit the final shell command before it is submitted. + Note that setting `grep-find-prompt-style' overrides any prefix arg. + While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily modify or repeat a find command." (interactive ! (progn ! (unless (and grep-command grep-find-command grep-find-template ! (or (not grep-use-null-device) (eq grep-use-null-device t))) ! (grep-compute-defaults)) ! (cond ! ((or (eq grep-find-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history) ! nil nil current-prefix-arg) ! ! ;; No default was set ! (read-string ! "grep.el: No `grep-find-command' available. Press RET.") ! (list nil nil nil nil))) ! ((not grep-find-template) ! (read-string ! "grep.el: No `grep-find-template' available. Press RET.") ! (list nil nil nil nil)) ! (t ! (let* ((default-regexp ! (or (funcall (or find-tag-default-function ! (get major-mode 'find-tag-default-function) ! 'find-tag-default)) ! "")) ! (regexp (read-string ! (concat "Search for" ! (if (and default-regexp ! (> (length default-regexp) 0)) ! (format " (default %s): " default-regexp) ": ")) ! nil 'grep-find-regexp-history default-regexp)) ! (default-files ! (or (and (stringp (buffer-file-name)) ! (let ((fn (file-name-nondirectory (buffer-file-name))) ! (aliases grep-find-files-aliases) ! alias) ! (while aliases ! (setq alias (car aliases) ! aliases (cdr aliases)) ! (if (string-match (wildcard-to-regexp (cdr alias)) fn) ! (setq aliases nil) ! (setq alias nil))) ! (cdr alias))) ! (car grep-find-files-history))) ! (files (read-string ! (concat "Search for \"" regexp ! "\" in files (default " default-files ! "): ") ! nil 'grep-find-files-history default-files)) ! (dir ! (read-directory-name "Base directory: " nil default-directory t))) ! (list regexp files dir current-prefix-arg)))))) ! (when regexp ! (if (or (null files) ;; backwards compatible non-interactive call ! (eq grep-find-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (let ((null-device nil) ! (command regexp)) ! (grep command)) ! (when files ! (let ((mf (assoc files grep-find-files-aliases))) ! (if mf ! (setq files (cdr mf))))) ! (let ((command (grep-expand-template ! grep-find-template ! (shell-quote-argument regexp) ! (and files (concat "-name " ! (shell-quote-argument files))) ! nil ;; we change default-directory to dir ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") ! grep-find-ignore-case)) ! (default-directory (file-name-as-directory (expand-file-name dir))) ! (null-device nil)) ; see grep ! (when command ! (if (or (eq grep-find-prompt-style 'post) ! (equal current-prefix-arg '(16))) ! (setq command ! (read-from-minibuffer "Confirm: " ! command nil nil 'grep-find-history)) ! (push command grep-find-history)) ! (grep command regexp)))))) + ;;;###autoload + (defalias 'find-grep 'grep-find) (provide 'grep) -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 8:27 ` Kim F. Storm @ 2006-04-21 14:47 ` Magnus Henoch 2006-04-21 17:22 ` Stefan Monnier 2006-04-22 12:03 ` Richard Stallman 1 sibling, 1 reply; 67+ messages in thread From: Magnus Henoch @ 2006-04-21 14:47 UTC (permalink / raw) storm@cua.dk (Kim F. Storm) writes: > ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") I think this should ignore ".svn", "{arch}", and "_darcs" as well. Magnus ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 14:47 ` Magnus Henoch @ 2006-04-21 17:22 ` Stefan Monnier 2006-04-21 20:04 ` Kim F. Storm 0 siblings, 1 reply; 67+ messages in thread From: Stefan Monnier @ 2006-04-21 17:22 UTC (permalink / raw) >> ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") > I think this should ignore ".svn", "{arch}", and "_darcs" as well. And .hg .. and probably a bunch more. Stefan ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 17:22 ` Stefan Monnier @ 2006-04-21 20:04 ` Kim F. Storm 2006-04-21 20:40 ` Stefan Monnier 0 siblings, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-21 20:04 UTC (permalink / raw) Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >>> ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") > >> I think this should ignore ".svn", "{arch}", and "_darcs" as well. > > And .hg > .. and probably a bunch more. The problem with CVS is that while editing a file foo.c, there may be related file named CVS/Base/foo.c. We certainly don't want grep-find to look into that file. Does these other systems have files named like the original files in their respective sub-directories? -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 20:04 ` Kim F. Storm @ 2006-04-21 20:40 ` Stefan Monnier 2006-04-21 21:35 ` Kim F. Storm 0 siblings, 1 reply; 67+ messages in thread From: Stefan Monnier @ 2006-04-21 20:40 UTC (permalink / raw) Cc: emacs-devel >>>> ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") >> >>> I think this should ignore ".svn", "{arch}", and "_darcs" as well. >> >> And .hg >> .. and probably a bunch more. > The problem with CVS is that while editing a file foo.c, there may be > related file named CVS/Base/foo.c. We certainly don't want grep-find to > look into that file. That's one problem. Another is that those admin-dirs can be large (with many files), so the time to traverse them can be non-negligible. > Does these other systems have files named like the original files in > their respective sub-directories? IIRC, .svn may have similarly named files, as does .hg (.hg's files would be things like "foo.c.d" and "foo.c.i" rather than "foo.c"), while {arch} typically contains a large number of small files and may also contain "foo.c" depending on how you configured tla. Stefan ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 20:40 ` Stefan Monnier @ 2006-04-21 21:35 ` Kim F. Storm 0 siblings, 0 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-21 21:35 UTC (permalink / raw) Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >>>>> ! (and grep-find-ignore-CVS-directories "-path '*/CVS' -prune -o ") >>> >>>> I think this should ignore ".svn", "{arch}", and "_darcs" as well. >>> >>> And .hg >>> .. and probably a bunch more. > >> The problem with CVS is that while editing a file foo.c, there may be >> related file named CVS/Base/foo.c. We certainly don't want grep-find to >> look into that file. > > That's one problem. Another is that those admin-dirs can be large (with > many files), so the time to traverse them can be non-negligible. So the right thing would be to have a list of subdirectories to ignore. However, doing that will give some pretty long argument lists to find | grep. That's ok, unless you want to post-edit the command line (C-u C-u M-x grep-find). -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-21 8:27 ` Kim F. Storm 2006-04-21 14:47 ` Magnus Henoch @ 2006-04-22 12:03 ` Richard Stallman 2006-04-22 12:41 ` David Kastrup 2006-04-22 23:02 ` Kim F. Storm 1 sibling, 2 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-22 12:03 UTC (permalink / raw) Cc: mange, emacs-devel Below is a patch which merges grep-tree into grep-find, with the new grep-tree interface as the default API, while a C-u prefix requests using the old grep-find interface. That makes it an incompatible change. grep-find has existed since years ago; grep-tree is new. We could avoid that incompatible change by making grep-find with C-u implement the grep-tree behavior. Is there some specific reason you propose the incompatible way? ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-22 12:03 ` Richard Stallman @ 2006-04-22 12:41 ` David Kastrup 2006-04-23 16:06 ` Bill Wohler 2006-04-23 16:19 ` Bill Wohler 2006-04-22 23:02 ` Kim F. Storm 1 sibling, 2 replies; 67+ messages in thread From: David Kastrup @ 2006-04-22 12:41 UTC (permalink / raw) Cc: mange, emacs-devel, Kim F. Storm Richard Stallman <rms@gnu.org> writes: > Below is a patch which merges grep-tree into grep-find, with > the new grep-tree interface as the default API, while a C-u > prefix requests using the old grep-find interface. > > That makes it an incompatible change. Yes, intendedly so. > grep-find has existed since years ago; grep-tree is new. > > We could avoid that incompatible change by making grep-find > with C-u implement the grep-tree behavior. > > Is there some specific reason you propose the incompatible way? It's the more beginner-friendly version. The old variant is the "specialist" version which you'd use if you need full control. Using C-u to demand the easier variant seems like a backward way of using a prefix argument. The price is an incompatibility in the default user interface to previous versions. Personally, I consider it an improvement. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-22 12:41 ` David Kastrup @ 2006-04-23 16:06 ` Bill Wohler 2006-04-23 16:19 ` Bill Wohler 1 sibling, 0 replies; 67+ messages in thread From: Bill Wohler @ 2006-04-23 16:06 UTC (permalink / raw) David Kastrup <dak@gnu.org> writes: > Richard Stallman <rms@gnu.org> writes: > >> Below is a patch which merges grep-tree into grep-find, with >> the new grep-tree interface as the default API, while a C-u >> prefix requests using the old grep-find interface. >> >> That makes it an incompatible change. > > Yes, intendedly so. > >> grep-find has existed since years ago; grep-tree is new. >> >> We could avoid that incompatible change by making grep-find >> with C-u implement the grep-tree behavior. >> >> Is there some specific reason you propose the incompatible way? > > It's the more beginner-friendly version. The old variant is the > "specialist" version which you'd use if you need full control. Using > C-u to demand the easier variant seems like a backward way of using a > prefix argument. The price is an incompatibility in the default user > interface to previous versions. Personally, I consider it an > improvement. I agree completely. Since we're bumping the major version number of improvements, there isn't a reason not to allow improvements such as this. -- Bill Wohler <wohler@newt.com> http://www.newt.com/wohler/ GnuPG ID:610BD9AD Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian! If you're passed on the right, you're in the wrong lane. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-22 12:41 ` David Kastrup 2006-04-23 16:06 ` Bill Wohler @ 2006-04-23 16:19 ` Bill Wohler 1 sibling, 0 replies; 67+ messages in thread From: Bill Wohler @ 2006-04-23 16:19 UTC (permalink / raw) [Reposting, without editing errors. :-(] David Kastrup <dak@gnu.org> writes: > Richard Stallman <rms@gnu.org> writes: > >> Below is a patch which merges grep-tree into grep-find, with >> the new grep-tree interface as the default API, while a C-u >> prefix requests using the old grep-find interface. >> >> That makes it an incompatible change. > > Yes, intendedly so. > >> grep-find has existed since years ago; grep-tree is new. >> >> We could avoid that incompatible change by making grep-find >> with C-u implement the grep-tree behavior. >> >> Is there some specific reason you propose the incompatible way? > > It's the more beginner-friendly version. The old variant is the > "specialist" version which you'd use if you need full control. Using > C-u to demand the easier variant seems like a backward way of using a > prefix argument. The price is an incompatibility in the default user > interface to previous versions. Personally, I consider it an > improvement. I agree completely. Since we're bumping the major version number, there isn't a reason not to allow improvements such as this. -- Bill Wohler <wohler@newt.com> http://www.newt.com/wohler/ GnuPG ID:610BD9AD Maintainer of comp.mail.mh FAQ and MH-E. Vote Libertarian! If you're passed on the right, you're in the wrong lane. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-22 12:03 ` Richard Stallman 2006-04-22 12:41 ` David Kastrup @ 2006-04-22 23:02 ` Kim F. Storm 2006-04-23 21:58 ` Richard Stallman 1 sibling, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-22 23:02 UTC (permalink / raw) Cc: mange, emacs-devel Richard Stallman <rms@gnu.org> writes: > Below is a patch which merges grep-tree into grep-find, with > the new grep-tree interface as the default API, while a C-u > prefix requests using the old grep-find interface. > > That makes it an incompatible change. grep-find has existed since > years ago; grep-tree is new. > > We could avoid that incompatible change by making grep-find > with C-u implement the grep-tree behavior. The old grep-find interface is "a hack" (a way to start a compile-like command which runs find | grep. > > Is there some specific reason you propose the incompatible way? IMO, the grep-tree API is better (higher-level, non-technical) than the old interface (low-level, technical, requires knowledge in shell command syntax). Techinical users which prefers the old interface can just customize grep-find-prompt-style. But I really think that even technical users will prefer the new interface. It's much simpler to use, doing the same job in most cases -- and it automatically skips CVS subdirectories (and other VC-related directories when I get around to adding them) which makes good sense. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-22 23:02 ` Kim F. Storm @ 2006-04-23 21:58 ` Richard Stallman 2006-04-23 22:06 ` David Kastrup ` (2 more replies) 0 siblings, 3 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-23 21:58 UTC (permalink / raw) Cc: mange, emacs-devel The old grep-find interface is "a hack" (a way to start a compile-like command which runs find | grep. But it is quite like M-x grep, and that makes for consistency. I think that nearly everyone who uses grep-find will have used M-x grep first, and will therefore find grep-find quite natural. It could be the case that we could make both grep and grep-find easier for beginners to use, in a consistent way. But let's wait till after the release for that change. For now, I would suggest we consider making the new feature grep-tree more convenient in a way that isn't incompatible for old features such as grep-find. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-23 21:58 ` Richard Stallman @ 2006-04-23 22:06 ` David Kastrup 2006-04-24 11:51 ` Richard Stallman 2006-04-24 11:05 ` Kim F. Storm 2006-04-25 9:06 ` Kim F. Storm 2 siblings, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-23 22:06 UTC (permalink / raw) Cc: mange, emacs-devel, Kim F. Storm Richard Stallman <rms@gnu.org> writes: > The old grep-find interface is "a hack" (a way to > start a compile-like command which runs find | grep. > > But it is quite like M-x grep, and that makes for consistency. I > think that nearly everyone who uses grep-find will have used M-x > grep first, and will therefore find grep-find quite natural. > > It could be the case that we could make both grep and grep-find > easier for beginners to use, in a consistent way. But let's wait > till after the release for that change. > > For now, I would suggest we consider making the new feature > grep-tree more convenient in a way that isn't incompatible for old > features such as grep-find. The problem that was being addressed is that we already have to many similar features. The patch was intended to obliterate "grep-tree" as a separate feature. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-23 22:06 ` David Kastrup @ 2006-04-24 11:51 ` Richard Stallman 2006-04-24 12:04 ` David Kastrup 2006-04-24 12:10 ` Kim F. Storm 0 siblings, 2 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-24 11:51 UTC (permalink / raw) Cc: mange, emacs-devel, storm > For now, I would suggest we consider making the new feature > grep-tree more convenient in a way that isn't incompatible for old > features such as grep-find. The problem that was being addressed is that we already have to many similar features. The patch was intended to obliterate "grep-tree" as a separate feature. Yes, it could be C-u M-x grep-find. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:51 ` Richard Stallman @ 2006-04-24 12:04 ` David Kastrup 2006-04-25 16:46 ` Richard Stallman 2006-04-24 12:10 ` Kim F. Storm 1 sibling, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-24 12:04 UTC (permalink / raw) Cc: mange, emacs-devel, storm Richard Stallman <rms@gnu.org> writes: > > For now, I would suggest we consider making the new feature > > grep-tree more convenient in a way that isn't incompatible for old > > features such as grep-find. > > The problem that was being addressed is that we already have to many > similar features. The patch was intended to obliterate "grep-tree" as > a separate feature. > > Yes, it could be C-u M-x grep-find. Having to use the prefix-argument for getting the interactive user-friendly version and getting the complex expert version by default is backwards-compatible but backwards. In this case I'd consider it prudent to sacrifice the compatibility in the user interface (Kim made sure that we _have_ compatibility for non-interactive use). -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 12:04 ` David Kastrup @ 2006-04-25 16:46 ` Richard Stallman 0 siblings, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-25 16:46 UTC (permalink / raw) Cc: mange, emacs-devel, storm Having to use the prefix-argument for getting the interactive user-friendly version and getting the complex expert version by default is backwards-compatible but backwards. I am not convinced which interface is generally better, so I cannot accept that argument. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:51 ` Richard Stallman 2006-04-24 12:04 ` David Kastrup @ 2006-04-24 12:10 ` Kim F. Storm 2006-04-24 22:46 ` Kim F. Storm 2006-04-25 16:47 ` Richard Stallman 1 sibling, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-24 12:10 UTC (permalink / raw) Cc: mange, emacs-devel Richard Stallman <rms@gnu.org> writes: > > For now, I would suggest we consider making the new feature > > grep-tree more convenient in a way that isn't incompatible for old > > features such as grep-find. > > The problem that was being addressed is that we already have to many > similar features. The patch was intended to obliterate "grep-tree" as > a separate feature. > > Yes, it could be C-u M-x grep-find. How is that convenient? Here is a patch which make the improvement for both M-x grep and M-x grep-find. If people really object to making this the default for 22.x, we could make set grep-prompt-style to 'shell by default. *** grep.el 16 Mar 2006 09:41:13 +0100 1.51 --- grep.el 24 Apr 2006 14:06:30 +0200 *************** *** 108,113 **** --- 108,126 ---- (const :tag "Not Set" nil)) :group 'grep) + (defcustom grep-command-template nil + "The default find command for \\[grep-find]. + The default value of this variable is set up by `grep-compute-defaults'; + call that function before using this variable in your program. + The following place holders should be present in the string: + <C> - place to put -i if case insensitive grep. + <F> - file names and wildcards to search. + <R> - the regular expression searched for." + :type '(choice string + (const :tag "Not Set" nil)) + :version "22.1" + :group 'grep) + (defcustom grep-use-null-device 'auto-detect "If t, append the value of `null-device' to `grep' commands. This is done to ensure that the output of grep includes the filename of *************** *** 130,137 **** (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-tree-command nil ! "The default find command for \\[grep-tree]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: --- 143,150 ---- (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-find-command-template nil ! "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: *************** *** 145,171 **** :version "22.1" :group 'grep) ! (defcustom grep-tree-files-aliases '( ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") - ("m" . "[Mm]akefile*") ("asm" . "*.[sS]") ! ("all" . "*") ! ("el" . "*.el") ) ! "*Alist of aliases for the FILES argument to `grep-tree'." :type 'alist :group 'grep) ! (defcustom grep-tree-ignore-case t ! "*If non-nil, `grep-tree' ignores case in matches." :type 'boolean :group 'grep) ! (defcustom grep-tree-ignore-CVS-directories t ! "*If non-nil, `grep-tree' does no recurse into CVS directories." ! :type 'boolean :group 'grep) (defcustom grep-error-screen-columns nil --- 158,194 ---- :version "22.1" :group 'grep) ! (defcustom grep-prompt-style nil ! "*Prompt style used by `grep' and `grep-find'. ! Nil means to prompt for regexp, files, and directory. ! Value `shell' means to prompt for shell command instead. ! Value `post' means to post-edit the final shell command." ! :type '(choice (const :tag "Standard" nil) ! (const :tag "Shell Command" shell) ! (const :tag "Post-edit Command" post)) ! :version "22.1" ! :group 'grep) ! ! (defcustom grep-files-aliases '( ! ("el" . "*.el") ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") ("asm" . "*.[sS]") ! ("m" . "[Mm]akefile*") ) ! "*Alist of aliases for the FILES argument to `grep' and `grep-find'." :type 'alist :group 'grep) ! (defcustom grep-ignore-case t ! "*If non-nil, `grep' and `grep-find' ignores case in matches." :type 'boolean :group 'grep) ! (defcustom grep-find-ignored-directories '("CVS" ".hg" "{arch}") ! "*List of names of sub-directories which `grep-find' shall not recurse into." ! :type '(repeat string) :group 'grep) (defcustom grep-error-screen-columns nil *************** *** 208,213 **** --- 231,238 ---- '("Compile..." . compile)) (define-key map [menu-bar grep compilation-grep] '("Another grep..." . grep)) + (define-key map [menu-bar grep-find compilation-grep-find] + '("Recursive grep..." . grep-find)) (define-key map [menu-bar grep compilation-recompile] '("Repeat grep" . recompile)) (define-key map [menu-bar grep compilation-separator2] *************** *** 353,358 **** --- 378,388 ---- ;;;###autoload (defvar grep-find-history nil) + ;; History of grep and grep-find regexp and files args. + (defvar grep-regexp-history nil) + (defvar grep-files-history '("ch" "el")) + + ;;;###autoload (defun grep-process-setup () "Setup compilation variables and buffer for `grep'. *************** *** 412,417 **** --- 442,457 ---- 1) (format "%s %s -e " grep-program required-options) (format "%s %s " grep-program required-options))))) + (unless grep-command-template + (setq grep-command-template + (let ((required-options (if grep-use-null-device "-n" "-nH"))) + (if (equal (condition-case nil ; in case "grep" isn't in exec-path + (call-process grep-program nil nil nil + "-e" "foo" null-device) + (error nil)) + 1) + (format "%s <C> %s -e <R> <F>" grep-program required-options) + (format "%s <C> %s <R> <F>" grep-program required-options))))) (unless grep-find-use-xargs (setq grep-find-use-xargs (if (and *************** *** 433,440 **** (t (cons (format "%s . -type f -exec %s {} %s \\;" find-program grep-command null-device) (+ 22 (length grep-command))))))) ! (unless grep-tree-command ! (setq grep-tree-command (let* ((glen (length grep-program)) (gcmd (concat grep-program " <C>" (substring grep-command glen)))) (cond ((eq grep-find-use-xargs 'gnu) --- 473,480 ---- (t (cons (format "%s . -type f -exec %s {} %s \\;" find-program grep-command null-device) (+ 22 (length grep-command))))))) ! (unless grep-find-command-template ! (setq grep-find-command-template (let* ((glen (length grep-program)) (gcmd (concat grep-program " <C>" (substring grep-command glen)))) (cond ((eq grep-find-use-xargs 'gnu) *************** *** 487,528 **** (file-name-extension buffer-file-name)))) (replace-match tag-default t t grep-default 1)))) ;;;###autoload ! (defun grep (command-args &optional highlight-regexp) ! "Run grep, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its COMMAND-ARGS, so you can ! easily repeat a grep command. ! ! A prefix argument says to default the argument based upon the current ! tag the cursor is over, substituting it into the last grep command ! in the grep command history (or into `grep-command' ! if that history list is empty). ! ! If specified, optional second arg HIGHLIGHT-REGEXP is the regexp to ! temporarily highlight in visited source lines." (interactive (progn ! (unless (and grep-command (or (not grep-use-null-device) (eq grep-use-null-device t))) (grep-compute-defaults)) ! (let ((default (grep-default-command))) ! (list (read-from-minibuffer "Run grep (like this): " ! (if current-prefix-arg ! default grep-command) ! nil nil 'grep-history ! (if current-prefix-arg nil default)))))) ! ! ;; Setting process-setup-function makes exit-message-function work ! ;; even when async processes aren't supported. ! (compilation-start (if (and grep-use-null-device null-device) ! (concat command-args " " null-device) ! command-args) ! 'grep-mode nil highlight-regexp)) ;;;###autoload (define-compilation-mode grep-mode "Grep" --- 527,656 ---- (file-name-extension buffer-file-name)))) (replace-match tag-default t t grep-default 1)))) + (defun grep-expand-template (template &optional regexp case-fold files dir excl) + "Patch grep COMMAND string replacing <C>, <D>, <F>, <R>, and <X>." + (let ((command template)) + (setq command + (replace-regexp-in-string "<F>" + (or files "") command t t)) + (setq command + (replace-regexp-in-string "<C>" + (if case-fold "-i" "") command t t)) + (setq command + (replace-regexp-in-string "<R>" + (shell-quote-argument (or regexp "")) + command t t)) + (setq command + (replace-regexp-in-string "<D>" + (or dir ".") command t t)) + (setq command + (replace-regexp-in-string "<X>" + (or excl "") command t t)) + command)) + + ;;;###autoload ! (defun grep (regexp &optional files api) ! "Run grep, searching for REGEXP in FILES in current directory. ! Collect output in a buffer. ! Interactively, prompt separately for each search parameter. ! The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-files-aliases', e.g. ! entering `ch' is equivalent to `*.[ch]'. ! ! With \\[universal-argument] prefix, prompt for shell command instead. ! With two \\[universal-argument] prefixes, prompt for search parameters, ! and allow user to edit the final shell command before it is submitted. ! Note that setting `grep-prompt-style' overrides any prefix arg. ! While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its COMMAND, so you can ! easily repeat a grep command." (interactive (progn ! (unless (and grep-command grep-command-template (or (not grep-use-null-device) (eq grep-use-null-device t))) (grep-compute-defaults)) ! (cond ! ((or (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (if grep-command ! (list (read-from-minibuffer "Run grep (like this): " ! grep-command nil nil ! 'grep-history) ! nil current-prefix-arg) ! ! ;; No default was set ! (read-string ! "grep.el: No `grep-command' available. Press RET.") ! (list nil nil nil))) ! ((not grep-command-template) ! (read-string ! "grep.el: No `grep-command-template' available. Press RET.") ! (list nil nil nil)) ! (t ! (let* ((default-regexp ! (or (funcall (or find-tag-default-function ! (get major-mode 'find-tag-default-function) ! 'find-tag-default)) ! "")) ! (regexp (read-string ! (concat "Search for" ! (if (and default-regexp ! (> (length default-regexp) 0)) ! (format " (default %s): " default-regexp) ": ")) ! nil 'grep-regexp-history default-regexp)) ! (default-files ! (or (and (stringp (buffer-file-name)) ! (let ((fn (file-name-nondirectory (buffer-file-name))) ! (aliases grep-files-aliases) ! alias) ! (while aliases ! (setq alias (car aliases) ! aliases (cdr aliases)) ! (if (string-match (wildcard-to-regexp (cdr alias)) fn) ! (setq aliases nil) ! (setq alias nil))) ! (cdr alias))) ! (car grep-files-history))) ! (files (read-string ! (concat "Search for \"" regexp ! "\" in files (default " default-files ! "): ") ! nil 'grep-files-history default-files))) ! (list regexp files current-prefix-arg)))))) ! (when regexp ! (let (command) ! (if (or (null files) ;; backwards compatible non-interactive call ! (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (setq command regexp) ! (when files ! (let ((mf (assoc files grep-files-aliases))) ! (if mf ! (setq files (cdr mf))))) ! (setq command (grep-expand-template ! grep-command-template ! regexp ! grep-ignore-case ! files)) ! (when command ! (if (or (eq grep-prompt-style 'post) ! (equal current-prefix-arg '(16))) ! (setq command ! (read-from-minibuffer "Confirm: " ! command nil nil 'grep-find-history)) ! (push command grep-history)))) ! (when command ! ;; Setting process-setup-function makes exit-message-function work ! ;; even when async processes aren't supported. ! (compilation-start (if (and grep-use-null-device null-device) ! (concat command " " null-device) ! command) 'grep-mode))))) ;;;###autoload (define-compilation-mode grep-mode "Grep" *************** *** 537,650 **** (set (make-local-variable 'compilation-disable-input) t)) ;;;###autoload ! (defun grep-find (command-args) ! "Run grep via find, with user-specified args COMMAND-ARGS. Collect output in a buffer. While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily repeat a find command." (interactive (progn ! (unless (and grep-command (or (not grep-use-null-device) (eq grep-use-null-device t))) (grep-compute-defaults)) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history)) ! ;; No default was set (read-string ! "compile.el: No `grep-find-command' command available. Press RET.") ! (list nil)))) ! (when (and grep-find-command command-args) ! (let ((null-device nil)) ; see grep ! (grep command-args)))) ;;;###autoload (defalias 'find-grep 'grep-find) - (defun grep-expand-command-macros (command &optional regexp files dir excl case-fold) - "Patch grep COMMAND replacing <D>, etc." - (setq command - (replace-regexp-in-string "<D>" - (or dir ".") command t t)) - (setq command - (replace-regexp-in-string "<X>" - (or excl "") command t t)) - (setq command - (replace-regexp-in-string "<F>" - (or files "") command t t)) - (setq command - (replace-regexp-in-string "<C>" - (if case-fold "-i" "") command t t)) - (setq command - (replace-regexp-in-string "<R>" - (or regexp "") command t t)) - command) - - (defvar grep-tree-last-regexp "") - (defvar grep-tree-last-files (car (car grep-tree-files-aliases))) - - ;;;###autoload - (defun grep-tree (regexp files dir &optional subdirs) - "Grep for REGEXP in FILES in directory tree rooted at DIR. - Collect output in a buffer. - Interactively, prompt separately for each search parameter. - With prefix arg, reuse previous REGEXP. - The search is limited to file names matching shell pattern FILES. - FILES may use abbreviations defined in `grep-tree-files-aliases', e.g. - entering `ch' is equivalent to `*.[ch]'. - - While find runs asynchronously, you can use the \\[next-error] command - to find the text that grep hits refer to. - - This command uses a special history list for its arguments, so you can - easily repeat a find command. - - When used non-interactively, optional arg SUBDIRS limits the search to - those sub directories of DIR." - (interactive - (let* ((regexp - (if current-prefix-arg - grep-tree-last-regexp - (let* ((default (current-word)) - (spec (read-string - (concat "Search for" - (if (and default (> (length default) 0)) - (format " (default %s): " default) ": "))))) - (if (equal spec "") default spec)))) - (files - (read-string (concat "Search for \"" regexp "\" in files (default " grep-tree-last-files "): "))) - (dir - (read-directory-name "Base directory: " nil default-directory t))) - (list regexp files dir))) - (unless grep-tree-command - (grep-compute-defaults)) - (unless (and (stringp files) (> (length files) 0)) - (setq files grep-tree-last-files)) - (when files - (setq grep-tree-last-files files) - (let ((mf (assoc files grep-tree-files-aliases))) - (if mf - (setq files (cdr mf))))) - (let ((command-args (grep-expand-command-macros - grep-tree-command - (setq grep-tree-last-regexp regexp) - (and files (concat "-name '" files "'")) - (if subdirs - (if (stringp subdirs) - subdirs - (mapconcat 'identity subdirs " ")) - nil) ;; we change default-directory to dir - (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ") - grep-tree-ignore-case)) - (default-directory (file-name-as-directory (expand-file-name dir))) - (null-device nil)) ; see grep - (grep command-args regexp))) - - (provide 'grep) ;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d --- 665,780 ---- (set (make-local-variable 'compilation-disable-input) t)) ;;;###autoload ! (defun grep-find (regexp &optional files dir api) ! "Recusively grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. + Interactively, prompt separately for each search parameter. + The search is limited to file names matching shell pattern FILES. + FILES may use abbreviations defined in `grep-files-aliases', e.g. + entering `ch' is equivalent to `*.[ch]'. + + With \\[universal-argument] prefix, prompt for shell command instead. + With two \\[universal-argument] prefixes, prompt for search parameters, + and allow user to edit the final shell command before it is submitted. + Note that setting `grep-prompt-style' overrides any prefix arg. + While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily modify or repeat a find command." (interactive (progn ! (unless (and grep-command grep-find-command grep-find-command-template (or (not grep-use-null-device) (eq grep-use-null-device t))) (grep-compute-defaults)) ! (cond ! ((or (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history) ! nil nil current-prefix-arg) ! ! ;; No default was set ! (read-string ! "grep.el: No `grep-find-command' available. Press RET.") ! (list nil nil nil nil))) ! ((not grep-find-command-template) (read-string ! "grep.el: No `grep-find-command-template' available. Press RET.") ! (list nil nil nil nil)) ! (t ! (let* ((default-regexp ! (or (funcall (or find-tag-default-function ! (get major-mode 'find-tag-default-function) ! 'find-tag-default)) ! "")) ! (regexp (read-string ! (concat "Search for" ! (if (and default-regexp ! (> (length default-regexp) 0)) ! (format " (default %s): " default-regexp) ": ")) ! nil 'grep-regexp-history default-regexp)) ! (default-files ! (or (and (stringp (buffer-file-name)) ! (let ((fn (file-name-nondirectory (buffer-file-name))) ! (aliases grep-files-aliases) ! alias) ! (while aliases ! (setq alias (car aliases) ! aliases (cdr aliases)) ! (if (string-match (wildcard-to-regexp (cdr alias)) fn) ! (setq aliases nil) ! (setq alias nil))) ! (cdr alias))) ! (car grep-files-history))) ! (files (read-string ! (concat "Search for \"" regexp ! "\" in files (default " default-files ! "): ") ! nil 'grep-files-history default-files)) ! (dir ! (read-directory-name "Base directory: " nil default-directory t))) ! (list regexp files dir current-prefix-arg)))))) ! (when regexp ! (if (or (null files) ;; backwards compatible non-interactive call ! (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! ;; REGEXP is command line ! (compilation-start regexp 'grep-mode) ! (when files ! (let ((mf (assoc files grep-files-aliases))) ! (if mf ! (setq files (cdr mf))))) ! (let ((command (grep-expand-template ! grep-find-command-template ! regexp ! grep-ignore-case ! (and files (concat "-name " ! (shell-quote-argument files))) ! nil ;; we change default-directory to dir ! (and grep-find-ignored-directories ! (concat "\\( -path '*/" ! (mapconcat #'identity ! grep-find-ignored-directories ! "' -o -path '*/") ! "' \\) -prune -o ")))) ! (default-directory (file-name-as-directory (expand-file-name dir))) ! (null-device nil)) ; see grep ! (when command ! (if (or (eq grep-prompt-style 'post) ! (equal current-prefix-arg '(16))) ! (setq command ! (read-from-minibuffer "Confirm: " ! command nil nil 'grep-find-history)) ! (push command grep-find-history)) ! (compilation-start command 'grep-mode)))))) ;;;###autoload (defalias 'find-grep 'grep-find) (provide 'grep) ;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 12:10 ` Kim F. Storm @ 2006-04-24 22:46 ` Kim F. Storm 2006-04-25 16:47 ` Richard Stallman 1 sibling, 0 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-24 22:46 UTC (permalink / raw) Cc: mange, emacs-devel storm@cua.dk (Kim F. Storm) writes: > Richard Stallman <rms@gnu.org> writes: > >> > For now, I would suggest we consider making the new feature >> > grep-tree more convenient in a way that isn't incompatible for old >> > features such as grep-find. >> >> The problem that was being addressed is that we already have to many >> similar features. The patch was intended to obliterate "grep-tree" as >> a separate feature. >> >> Yes, it could be C-u M-x grep-find. > > How is that convenient? > > Here is a patch which make the improvement for both M-x grep and M-x grep-find. I worked some more on cleaning this up, consolidate some duplicate code, and removed the grep-ignore-case defcustom (and just obey case-fold-search, unless there are upper-case letters in the regexp [like isearch].) I still have a very strong belief that we MUST fix this issue before the release. Note that major parts of this patch still need to be applied to fix problems and short-comings in the current grep-tree implementation, and more of it must be applied to integrate grep-tree into grep-find [in some form or another]. So I still think it would be better to make the whole [incompatible, but much improved user interface] change now, so we don't end up in a significant mess trying to revert/fix even more incompatibilities after the release. *** grep.el 16 Mar 2006 09:41:13 +0100 1.51 --- grep.el 25 Apr 2006 00:30:13 +0200 *************** *** 108,113 **** --- 108,126 ---- (const :tag "Not Set" nil)) :group 'grep) + (defcustom grep-command-template nil + "The default find command for \\[grep-find]. + The default value of this variable is set up by `grep-compute-defaults'; + call that function before using this variable in your program. + The following place holders should be present in the string: + <C> - place to put -i if case insensitive grep. + <F> - file names and wildcards to search. + <R> - the regular expression searched for." + :type '(choice string + (const :tag "Not Set" nil)) + :version "22.1" + :group 'grep) + (defcustom grep-use-null-device 'auto-detect "If t, append the value of `null-device' to `grep' commands. This is done to ensure that the output of grep includes the filename of *************** *** 130,137 **** (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-tree-command nil ! "The default find command for \\[grep-tree]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: --- 143,150 ---- (const :tag "Not Set" nil)) :group 'grep) ! (defcustom grep-find-command-template nil ! "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: *************** *** 145,171 **** :version "22.1" :group 'grep) ! (defcustom grep-tree-files-aliases '( ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") - ("m" . "[Mm]akefile*") ("asm" . "*.[sS]") ! ("all" . "*") ! ("el" . "*.el") ) ! "*Alist of aliases for the FILES argument to `grep-tree'." :type 'alist :group 'grep) ! (defcustom grep-tree-ignore-case t ! "*If non-nil, `grep-tree' ignores case in matches." ! :type 'boolean ! :group 'grep) ! ! (defcustom grep-tree-ignore-CVS-directories t ! "*If non-nil, `grep-tree' does no recurse into CVS directories." ! :type 'boolean :group 'grep) (defcustom grep-error-screen-columns nil --- 158,189 ---- :version "22.1" :group 'grep) ! (defcustom grep-prompt-style nil ! "*Prompt style used by `grep' and `grep-find'. ! Nil means to prompt for regexp, files, and directory. ! Value `shell' means to prompt for shell command instead. ! Value `post' means to post-edit the final shell command." ! :type '(choice (const :tag "Standard" nil) ! (const :tag "Shell Command" shell) ! (const :tag "Post-edit Command" post)) ! :version "22.1" ! :group 'grep) ! ! (defcustom grep-files-aliases '( ! ("el" . "*.el") ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") ("asm" . "*.[sS]") ! ("m" . "[Mm]akefile*") ) ! "*Alist of aliases for the FILES argument to `grep' and `grep-find'." :type 'alist :group 'grep) ! (defcustom grep-find-ignored-directories '("CVS" ".hg" "{arch}") ! "*List of names of sub-directories which `grep-find' shall not recurse into." ! :type '(repeat string) :group 'grep) (defcustom grep-error-screen-columns nil *************** *** 208,213 **** --- 226,233 ---- '("Compile..." . compile)) (define-key map [menu-bar grep compilation-grep] '("Another grep..." . grep)) + (define-key map [menu-bar grep compilation-grep-find] + '("Recursive grep..." . grep-find)) (define-key map [menu-bar grep compilation-recompile] '("Repeat grep" . recompile)) (define-key map [menu-bar grep compilation-separator2] *************** *** 353,358 **** --- 373,383 ---- ;;;###autoload (defvar grep-find-history nil) + ;; History of grep and grep-find regexp and files args. + (defvar grep-regexp-history nil) + (defvar grep-files-history '("ch" "el")) + + ;;;###autoload (defun grep-process-setup () "Setup compilation variables and buffer for `grep'. *************** *** 402,461 **** (looking-at (concat (regexp-quote hello-file) ":[0-9]+:English"))))))))) ! (unless grep-command ! (setq grep-command ! (let ((required-options (if grep-use-null-device "-n" "-nH"))) ! (if (equal (condition-case nil ; in case "grep" isn't in exec-path ! (call-process grep-program nil nil nil ! "-e" "foo" null-device) ! (error nil)) ! 1) ! (format "%s %s -e " grep-program required-options) ! (format "%s %s " grep-program required-options))))) ! (unless grep-find-use-xargs ! (setq grep-find-use-xargs ! (if (and ! (equal (call-process "find" nil nil nil ! null-device "-print0") ! 0) ! (equal (call-process "xargs" nil nil nil ! "-0" "-e" "echo") ! 0)) ! 'gnu))) ! (unless grep-find-command ! (setq grep-find-command ! (cond ((eq grep-find-use-xargs 'gnu) ! (format "%s . -type f -print0 | xargs -0 -e %s" ! find-program grep-command)) ! (grep-find-use-xargs ! (format "%s . -type f -print | xargs %s" ! find-program grep-command)) ! (t (cons (format "%s . -type f -exec %s {} %s \\;" ! find-program grep-command null-device) ! (+ 22 (length grep-command))))))) ! (unless grep-tree-command ! (setq grep-tree-command ! (let* ((glen (length grep-program)) ! (gcmd (concat grep-program " <C>" (substring grep-command glen)))) ! (cond ((eq grep-find-use-xargs 'gnu) ! (format "%s <D> <X> -type f <F> -print0 | xargs -0 -e %s <R>" ! find-program gcmd)) ! (grep-find-use-xargs ! (format "%s <D> <X> -type f <F> -print | xargs %s <R>" ! find-program gcmd)) ! (t (format "%s <D> <X> -type f <F> -exec %s <R> {} %s \\;" ! find-program gcmd null-device)))))) ! (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t)) ! (setq grep-highlight-matches ! (with-temp-buffer ! (and (equal (condition-case nil ! (call-process grep-program nil t nil "--help") ! (error nil)) ! 0) ! (progn ! (goto-char (point-min)) ! (search-forward "--color" nil t)) ! t))))) (defun grep-default-command () (let ((tag-default --- 427,491 ---- (looking-at (concat (regexp-quote hello-file) ":[0-9]+:English"))))))))) ! (unless (and grep-command grep-command-template ! grep-find-command grep-find-command-template) ! (let ((required-options ! (concat (if grep-use-null-device "-n" "-nH") ! (if (equal (condition-case nil ; in case "grep" isn't in exec-path ! (call-process grep-program nil nil nil ! "-e" "foo" null-device) ! (error nil)) ! 1) " -e" "")))) ! (unless grep-command ! (setq grep-command ! (format "%s %s " grep-program required-options))) ! (unless grep-command-template ! (setq grep-command-template ! (format "%s <C> %s <R> <F>" grep-program required-options))) ! (unless grep-find-use-xargs ! (setq grep-find-use-xargs ! (if (and ! (equal (call-process "find" nil nil nil ! null-device "-print0") ! 0) ! (equal (call-process "xargs" nil nil nil ! "-0" "-e" "echo") ! 0)) ! 'gnu))) ! (unless grep-find-command ! (setq grep-find-command ! (cond ((eq grep-find-use-xargs 'gnu) ! (format "%s . -type f -print0 | xargs -0 -e %s" ! find-program grep-command)) ! (grep-find-use-xargs ! (format "%s . -type f -print | xargs %s" ! find-program grep-command)) ! (t (cons (format "%s . -type f -exec %s {} %s \\;" ! find-program grep-command null-device) ! (+ 22 (length grep-command))))))) ! (unless grep-find-command-template ! (setq grep-find-command-template ! (let ((gcmd (format "%s <C> %s <R>" ! grep-program required-options))) ! (cond ((eq grep-find-use-xargs 'gnu) ! (format "%s <D> <X> -type f <F> -print0 | xargs -0 -e %s" ! find-program gcmd)) ! (grep-find-use-xargs ! (format "%s <D> <X> -type f <F> -print | xargs %s" ! find-program gcmd)) ! (t (format "%s <D> <X> -type f <F> -exec %s {} %s \\;" ! find-program gcmd null-device)))))) ! (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t)) ! (setq grep-highlight-matches ! (with-temp-buffer ! (and (equal (condition-case nil ! (call-process grep-program nil t nil "--help") ! (error nil)) ! 0) ! (progn ! (goto-char (point-min)) ! (search-forward "--color" nil t)) ! t))))))) (defun grep-default-command () (let ((tag-default *************** *** 487,528 **** (file-name-extension buffer-file-name)))) (replace-match tag-default t t grep-default 1)))) ;;;###autoload ! (defun grep (command-args &optional highlight-regexp) ! "Run grep, with user-specified args, and collect output in a buffer. While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its COMMAND-ARGS, so you can ! easily repeat a grep command. ! ! A prefix argument says to default the argument based upon the current ! tag the cursor is over, substituting it into the last grep command ! in the grep command history (or into `grep-command' ! if that history list is empty). ! ! If specified, optional second arg HIGHLIGHT-REGEXP is the regexp to ! temporarily highlight in visited source lines." (interactive (progn ! (unless (and grep-command ! (or (not grep-use-null-device) (eq grep-use-null-device t))) ! (grep-compute-defaults)) ! (let ((default (grep-default-command))) ! (list (read-from-minibuffer "Run grep (like this): " ! (if current-prefix-arg ! default grep-command) ! nil nil 'grep-history ! (if current-prefix-arg nil default)))))) ! ! ;; Setting process-setup-function makes exit-message-function work ! ;; even when async processes aren't supported. ! (compilation-start (if (and grep-use-null-device null-device) ! (concat command-args " " null-device) ! command-args) ! 'grep-mode nil highlight-regexp)) ;;;###autoload (define-compilation-mode grep-mode "Grep" --- 517,659 ---- (file-name-extension buffer-file-name)))) (replace-match tag-default t t grep-default 1)))) + (defun grep-expand-template (template &optional regexp files dir excl) + "Patch grep COMMAND string replacing <C>, <D>, <F>, <R>, and <X>." + (let ((command template) + (case-fold case-fold-search) + (case-fold-search nil)) + (if (string-match "<C>" command) + (setq command + (replace-match (if (and case-fold + (isearch-no-upper-case-p regexp t)) + "-i" "") + t t command))) + (if (string-match "<D>" command) + (setq command + (replace-match (or dir ".") + t t command))) + (if (string-match "<F>" command) + (setq command + (replace-match (or files "") + t t command))) + (if (string-match "<N>" command) + (setq command + (replace-match (if (and grep-use-null-device null-device) + null-device "") + t t command))) + (if (string-match "<R>" command) + (setq command + (replace-match (shell-quote-argument (or regexp "")) + t t command))) + (if (string-match "<X>" command) + (setq command + (replace-match (or excl "") + t t command))) + command)) + + (defun grep-read-regexp () + "Read regexp arg for interactive grep." + (let ((default + (or (funcall (or find-tag-default-function + (get major-mode 'find-tag-default-function) + 'find-tag-default)) + ""))) + (read-string + (concat "Search for" + (if (and default (> (length default) 0)) + (format " (default %s): " default) ": ")) + nil 'grep-regexp-history default))) + + (defun grep-read-files (regexp) + "Read files arg for interactive grep." + (let* ((default + (or (and (stringp (buffer-file-name)) + (let ((fn (file-name-nondirectory (buffer-file-name))) + (aliases grep-files-aliases) + alias) + (while aliases + (setq alias (car aliases) + aliases (cdr aliases)) + (if (string-match (wildcard-to-regexp (cdr alias)) fn) + (setq aliases nil) + (setq alias nil))) + (cdr alias))) + (car grep-files-history))) + (files (read-string + (concat "Search for \"" regexp + "\" in files (default " default "): ") + nil 'grep-files-history default))) + (and files + (or (cdr (assoc files grep-files-aliases)) + files)))) + ;;;###autoload ! (defun grep (regexp &optional files api) ! "Run grep, searching for REGEXP in FILES in current directory. ! Collect output in a buffer. ! Interactively, prompt separately for each search parameter. ! The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-files-aliases', e.g. ! entering `ch' is equivalent to `*.[ch]'. ! ! With \\[universal-argument] prefix, prompt for shell command instead. ! With two \\[universal-argument] prefixes, prompt for search parameters, ! and allow user to edit the final shell command before it is submitted. ! Note that setting `grep-prompt-style' overrides any prefix arg. ! While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. ! This command uses a special history list for its arguments, so you can ! easily repeat a grep command." (interactive (progn ! (grep-compute-defaults) ! (cond ! ((or (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (if grep-command ! (list (read-from-minibuffer "Run grep (like this): " ! grep-command nil nil ! 'grep-history) ! nil current-prefix-arg) ! ;; No default was set ! (read-string ! "grep.el: No `grep-command' available. Press RET.") ! (list nil nil nil))) ! ((not grep-command-template) ! (read-string ! "grep.el: No `grep-command-template' available. Press RET.") ! (list nil nil nil)) ! (t ! (let* ((regexp (grep-read-regexp)) ! (files (grep-read-files regexp))) ! (list regexp files current-prefix-arg)))))) ! (when regexp ! (let (command) ! (if (or (null files) ;; backwards compatible non-interactive call ! (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (setq command regexp) ! (setq command (grep-expand-template ! grep-command-template ! regexp ! files)) ! (when command ! (if (or (eq grep-prompt-style 'post) ! (equal current-prefix-arg '(16))) ! (setq command ! (read-from-minibuffer "Confirm: " ! command nil nil 'grep-find-history)) ! (push command grep-history)))) ! (when command ! ;; Setting process-setup-function makes exit-message-function work ! ;; even when async processes aren't supported. ! (compilation-start (if (and grep-use-null-device null-device) ! (concat command " " null-device) ! command) 'grep-mode))))) ;;;###autoload (define-compilation-mode grep-mode "Grep" *************** *** 537,649 **** (set (make-local-variable 'compilation-disable-input) t)) ;;;###autoload ! (defun grep-find (command-args) ! "Run grep via find, with user-specified args COMMAND-ARGS. ! Collect output in a buffer. ! While find runs asynchronously, you can use the \\[next-error] command ! to find the text that grep hits refer to. ! ! This command uses a special history list for its arguments, so you can ! easily repeat a find command." ! (interactive ! (progn ! (unless (and grep-command ! (or (not grep-use-null-device) (eq grep-use-null-device t))) ! (grep-compute-defaults)) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history)) ! ;; No default was set ! (read-string ! "compile.el: No `grep-find-command' command available. Press RET.") ! (list nil)))) ! (when (and grep-find-command command-args) ! (let ((null-device nil)) ; see grep ! (grep command-args)))) ! ! ;;;###autoload ! (defalias 'find-grep 'grep-find) ! ! (defun grep-expand-command-macros (command &optional regexp files dir excl case-fold) ! "Patch grep COMMAND replacing <D>, etc." ! (setq command ! (replace-regexp-in-string "<D>" ! (or dir ".") command t t)) ! (setq command ! (replace-regexp-in-string "<X>" ! (or excl "") command t t)) ! (setq command ! (replace-regexp-in-string "<F>" ! (or files "") command t t)) ! (setq command ! (replace-regexp-in-string "<C>" ! (if case-fold "-i" "") command t t)) ! (setq command ! (replace-regexp-in-string "<R>" ! (or regexp "") command t t)) ! command) ! ! (defvar grep-tree-last-regexp "") ! (defvar grep-tree-last-files (car (car grep-tree-files-aliases))) ! ! ;;;###autoload ! (defun grep-tree (regexp files dir &optional subdirs) ! "Grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. Interactively, prompt separately for each search parameter. - With prefix arg, reuse previous REGEXP. The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-tree-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily repeat a find command. ! ! When used non-interactively, optional arg SUBDIRS limits the search to ! those sub directories of DIR." (interactive ! (let* ((regexp ! (if current-prefix-arg ! grep-tree-last-regexp ! (let* ((default (current-word)) ! (spec (read-string ! (concat "Search for" ! (if (and default (> (length default) 0)) ! (format " (default %s): " default) ": "))))) ! (if (equal spec "") default spec)))) ! (files ! (read-string (concat "Search for \"" regexp "\" in files (default " grep-tree-last-files "): "))) ! (dir ! (read-directory-name "Base directory: " nil default-directory t))) ! (list regexp files dir))) ! (unless grep-tree-command ! (grep-compute-defaults)) ! (unless (and (stringp files) (> (length files) 0)) ! (setq files grep-tree-last-files)) ! (when files ! (setq grep-tree-last-files files) ! (let ((mf (assoc files grep-tree-files-aliases))) ! (if mf ! (setq files (cdr mf))))) ! (let ((command-args (grep-expand-command-macros ! grep-tree-command ! (setq grep-tree-last-regexp regexp) ! (and files (concat "-name '" files "'")) ! (if subdirs ! (if (stringp subdirs) ! subdirs ! (mapconcat 'identity subdirs " ")) ! nil) ;; we change default-directory to dir ! (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ") ! grep-tree-ignore-case)) ! (default-directory (file-name-as-directory (expand-file-name dir))) ! (null-device nil)) ; see grep ! (grep command-args regexp))) (provide 'grep) --- 668,747 ---- (set (make-local-variable 'compilation-disable-input) t)) ;;;###autoload ! (defun grep-find (regexp &optional files dir api) ! "Recusively grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. Interactively, prompt separately for each search parameter. The search is limited to file names matching shell pattern FILES. ! FILES may use abbreviations defined in `grep-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. + With \\[universal-argument] prefix, prompt for shell command instead. + With two \\[universal-argument] prefixes, prompt for search parameters, + and allow user to edit the final shell command before it is submitted. + Note that setting `grep-prompt-style' overrides any prefix arg. + While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can ! easily modify or repeat a find command." (interactive ! (progn ! (grep-compute-defaults) ! (cond ! ((or (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! (if grep-find-command ! (list (read-from-minibuffer "Run find (like this): " ! grep-find-command nil nil ! 'grep-find-history) ! nil nil current-prefix-arg) ! ! ;; No default was set ! (read-string ! "grep.el: No `grep-find-command' available. Press RET.") ! (list nil nil nil nil))) ! ((not grep-find-command-template) ! (read-string ! "grep.el: No `grep-find-command-template' available. Press RET.") ! (list nil nil nil nil)) ! (t ! (let* ((regexp (grep-read-regexp)) ! (files (grep-read-files regexp)) ! (dir (read-directory-name "Base directory: " ! nil default-directory t))) ! (list regexp files dir current-prefix-arg)))))) ! (when regexp ! (if (or (null files) ;; backwards compatible non-interactive call ! (eq grep-prompt-style 'shell) ! (equal current-prefix-arg '(4))) ! ;; REGEXP is command line ! (compilation-start regexp 'grep-mode) ! (let ((command (grep-expand-template ! grep-find-command-template ! regexp ! (and files (concat "-name " ! (shell-quote-argument files))) ! nil ;; we change default-directory to dir ! (and grep-find-ignored-directories ! (concat "\\( -path '*/" ! (mapconcat #'identity ! grep-find-ignored-directories ! "' -o -path '*/") ! "' \\) -prune -o ")))) ! (default-directory (file-name-as-directory (expand-file-name dir)))) ! (when command ! (if (or (eq grep-prompt-style 'post) ! (equal current-prefix-arg '(16))) ! (setq command ! (read-from-minibuffer "Confirm: " ! command nil nil 'grep-find-history)) ! (push command grep-find-history)) ! (compilation-start command 'grep-mode)))))) + ;;;###autoload + (defalias 'find-grep 'grep-find) (provide 'grep) -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 12:10 ` Kim F. Storm 2006-04-24 22:46 ` Kim F. Storm @ 2006-04-25 16:47 ` Richard Stallman 1 sibling, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-25 16:47 UTC (permalink / raw) Cc: mange, emacs-devel Here is a patch which make the improvement for both M-x grep and M-x grep-find. Now is not the time for changes in commands such as M-x grep. We can consider this after the release. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-23 21:58 ` Richard Stallman 2006-04-23 22:06 ` David Kastrup @ 2006-04-24 11:05 ` Kim F. Storm 2006-04-24 11:11 ` Miles Bader 2006-04-24 17:52 ` Richard Stallman 2006-04-25 9:06 ` Kim F. Storm 2 siblings, 2 replies; 67+ messages in thread From: Kim F. Storm @ 2006-04-24 11:05 UTC (permalink / raw) Cc: mange, emacs-devel Richard Stallman <rms@gnu.org> writes: > The old grep-find interface is "a hack" (a way to > start a compile-like command which runs find | grep. > > But it is quite like M-x grep, and that makes for consistency. I > think that nearly everyone who uses grep-find will have used M-x grep > first, and will therefore find grep-find quite natural. Unless they also find grep quite un-natural (and unfriendly)! I do! In practice, I almost never use M-x grep, as I usually want to search in subdirectores too, and grep doesn't do that. And I find the old grep-find interface way too slow. So I use M-x grep-tree 99% of the time -- and really dislike M-x grep when I use it. > It could be the case that we could make both grep and grep-find easier > for beginners to use, in a consistent way. Yes, IMO the right approach would be to change M-x grep too to be like (the new) M-x grep-find, i.e. prompt for REGEXP + FILES, and then run grep with the proper args. A user can still use C-u M-x grep to enter the "expert mode" with the old-style shell command. And setting grep-prompt-style to 'shell will get the old behaviour of both M-x grep and M-x grep-find. Now, that would ensure consistency, and give both M-x grep and M-x grep-find a much more user friendly interface. > But let's wait till after > the release for that change. > I know we are close to starting the pretest, but since grep-tree is new, we should definitely fix this issue before the release. After the release, people will start using and customize it, so when we later clean things up, we would remove grep-tree and rename various defcustoms; that would be incompatible too! So it's now or never... > For now, I would suggest we consider making the new feature grep-tree > more convenient in a way that isn't incompatible for old features > such as grep-find. M-x grep-tree was convenient already -- but it was suggested to merge it into grep-find ... which need to make "incompatible" changes to grep-find to remain convenient. The code for grep-find is almost complete anyway -- and I can easily modify M-x grep to comply. -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:05 ` Kim F. Storm @ 2006-04-24 11:11 ` Miles Bader 2006-04-24 11:24 ` David Kastrup 2006-04-24 17:52 ` Richard Stallman 1 sibling, 1 reply; 67+ messages in thread From: Miles Bader @ 2006-04-24 11:11 UTC (permalink / raw) Cc: mange, rms, emacs-devel storm@cua.dk (Kim F. Storm) writes: > In practice, I almost never use M-x grep, as I usually want to search > in subdirectores too, and grep doesn't do that. Actually GNU grep can search in subdirectories -- use "grep -r". -Miles -- "1971 pickup truck; will trade for guns" ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:11 ` Miles Bader @ 2006-04-24 11:24 ` David Kastrup 2006-04-24 11:31 ` Miles Bader 0 siblings, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-24 11:24 UTC (permalink / raw) Cc: emacs-devel Miles Bader <miles.bader@necel.com> writes: > storm@cua.dk (Kim F. Storm) writes: >> In practice, I almost never use M-x grep, as I usually want to >> search in subdirectores too, and grep doesn't do that. > > Actually GNU grep can search in subdirectories -- use "grep -r". If the "most obscure excuse for Emacs not being helpful" contest is now officially open, I could try to come up with some entries of my own. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:24 ` David Kastrup @ 2006-04-24 11:31 ` Miles Bader 2006-04-24 11:43 ` David Kastrup 0 siblings, 1 reply; 67+ messages in thread From: Miles Bader @ 2006-04-24 11:31 UTC (permalink / raw) Cc: emacs-devel David Kastrup <dak@gnu.org> writes: >>> In practice, I almost never use M-x grep, as I usually want to >>> search in subdirectores too, and grep doesn't do that. >> >> Actually GNU grep can search in subdirectories -- use "grep -r". > > If the "most obscure excuse for Emacs not being helpful" contest is > now officially open, I could try to come up with some entries of my > own. Eh? I just thought Kim might like to know... -Miles -- Yo mama's so fat when she gets on an elevator it HAS to go down. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:31 ` Miles Bader @ 2006-04-24 11:43 ` David Kastrup 2006-04-24 11:52 ` Miles Bader 0 siblings, 1 reply; 67+ messages in thread From: David Kastrup @ 2006-04-24 11:43 UTC (permalink / raw) Cc: emacs-devel Miles Bader <miles.bader@necel.com> writes: > David Kastrup <dak@gnu.org> writes: >>>> In practice, I almost never use M-x grep, as I usually want to >>>> search in subdirectores too, and grep doesn't do that. >>> >>> Actually GNU grep can search in subdirectories -- use "grep -r". >> >> If the "most obscure excuse for Emacs not being helpful" contest is >> now officially open, I could try to come up with some entries of my >> own. > > Eh? I just thought Kim might like to know... Well, if you post this publicly to the Emacs developer list as a retort to Kim, it appears like you want to argue that searches in subdirectories need not be accommodated by Emacs. Assuming you are on-topic on emacs-devel: Emacs is not just used with GNU grep, and GNU grep having an accidental option available that does part of the job (it does not exclude version control directories) if you use a command line the hard way is, well... -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:43 ` David Kastrup @ 2006-04-24 11:52 ` Miles Bader 0 siblings, 0 replies; 67+ messages in thread From: Miles Bader @ 2006-04-24 11:52 UTC (permalink / raw) Cc: emacs-devel David Kastrup <dak@gnu.org> writes: > Well, if you post this publicly to the Emacs developer list as a > retort to Kim, it appears like you want to argue that searches in > subdirectories need not be accommodated by Emacs. I was not making such an argument. It's good to know the about "grep -r" because it's a very useful option. -Miles -- .Numeric stability is probably not all that important when you're guessing. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 11:05 ` Kim F. Storm 2006-04-24 11:11 ` Miles Bader @ 2006-04-24 17:52 ` Richard Stallman 2006-04-24 18:16 ` David Kastrup 1 sibling, 1 reply; 67+ messages in thread From: Richard Stallman @ 2006-04-24 17:52 UTC (permalink / raw) Cc: mange, emacs-devel We can consider changes like this after the release. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 17:52 ` Richard Stallman @ 2006-04-24 18:16 ` David Kastrup 2006-04-24 20:38 ` Chong Yidong 2006-04-25 16:48 ` Richard Stallman 0 siblings, 2 replies; 67+ messages in thread From: David Kastrup @ 2006-04-24 18:16 UTC (permalink / raw) Cc: mange, emacs-devel, Kim F. Storm Richard Stallman <rms@gnu.org> writes: > We can consider changes like this after the release. Not really, since it does not make sense to introduce a separate grep-tree in a single release, only to fold it into grep-find afterwards. It is exactly _now_ that we have to consider this change, since it is too late after the release: by then we will _have_ introduced new functionality under a new name. Whether or not we finally agree on the change (and pretty much everybody except you appears to consider it an improvement), we can sensibly _consider_ it only _before_ the release. Because otherwise the release will _introduce_ grep-tree for the first time. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 18:16 ` David Kastrup @ 2006-04-24 20:38 ` Chong Yidong 2006-04-25 16:48 ` Richard Stallman 1 sibling, 0 replies; 67+ messages in thread From: Chong Yidong @ 2006-04-24 20:38 UTC (permalink / raw) Cc: mange, rms, Kim F. Storm, emacs-devel David Kastrup <dak@gnu.org> writes: >> We can consider changes like this after the release. > > Not really, since it does not make sense to introduce a separate > grep-tree in a single release, only to fold it into grep-find > afterwards. > > Whether or not we finally agree on the change (and pretty much > everybody except you appears to consider it an improvement), we can > sensibly _consider_ it only _before_ the release. Because otherwise > the release will _introduce_ grep-tree for the first time. I, for one, would prefer to defer the grep-tree changes until after the release. We can always extend grep-tree and, if it proves to be much better, make grep-find obsolete --- *later*. That's the whole point of a release process (notwithstanding the fact that it hasn't exactly been followed very well). ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-24 18:16 ` David Kastrup 2006-04-24 20:38 ` Chong Yidong @ 2006-04-25 16:48 ` Richard Stallman 2006-04-26 8:27 ` Kim F. Storm 1 sibling, 1 reply; 67+ messages in thread From: Richard Stallman @ 2006-04-25 16:48 UTC (permalink / raw) Cc: mange, emacs-devel, storm If, after the release, we can contemplate an incompatible change to M-x grep-find, and even M-x grep, chopping down grep-tree will be nothing. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-25 16:48 ` Richard Stallman @ 2006-04-26 8:27 ` Kim F. Storm 2006-04-27 4:36 ` Richard Stallman 0 siblings, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-26 8:27 UTC (permalink / raw) Cc: mange, emacs-devel Richard Stallman <rms@gnu.org> writes: > If, after the release, we can contemplate an incompatible change to > M-x grep-find, and even M-x grep, chopping down grep-tree will be > nothing. Ok, so we keep grep-tree in 22.x (with necessary fixes and cleanups), and make no attempt to merge grep-tree and grep-find (IMO, there is no need to do that if/when we are going to rework the interface in 23.x). -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-26 8:27 ` Kim F. Storm @ 2006-04-27 4:36 ` Richard Stallman 0 siblings, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-27 4:36 UTC (permalink / raw) Cc: mange, emacs-devel Ok, so we keep grep-tree in 22.x (with necessary fixes and cleanups), and make no attempt to merge grep-tree and grep-find (IMO, there is no need to do that if/when we are going to rework the interface in 23.x). I guess that is ok. And it means less change now. ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-23 21:58 ` Richard Stallman 2006-04-23 22:06 ` David Kastrup 2006-04-24 11:05 ` Kim F. Storm @ 2006-04-25 9:06 ` Kim F. Storm 2006-04-29 3:50 ` Richard Stallman 2 siblings, 1 reply; 67+ messages in thread From: Kim F. Storm @ 2006-04-25 9:06 UTC (permalink / raw) Cc: mange, emacs-devel I took another round of cleaning up the grep.el module, fixing a number of minor defects (not related to the issue of the new API). Repeating myself (do I hear an echo?) many of the changes I've made to grep.el should still be included in the release even if we decide not to change the interactive api of grep and grep-find. This time, I have included the entire grep.el below, as it turns out that the file is 702 lines long, and a diff is also 702 lines long. Please remember that the issue that started this was that users complained about having two versions of "grep-find", and a request to merge the "grep-tree" and "grep-find" APIs. Then it became clear that changing grep-find to have the "easy" API by default meant that we should change grep in a similar way for consistency. With the changes below, I have accomodated those requests. IMO, it is a very good shape now, so if people would try it out for a few days before making a final decision on the subject of a new API, I would appreciate it -- after all, it is easier for me to just install this (the IMHO "RIGHT" version), rather than having to backport the necessary changes into grep-tree in the current CVS version. ;;; grep.el --- run Grep as inferior of Emacs, parse match messages ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, ;; 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ;; Author: Roland McGrath <roland@gnu.org> ;; Maintainer: FSF ;; Keywords: tools, processes ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; This package provides the grep facilities documented in the Emacs ;; user's manual. ;;; Code: (require 'compile) (defgroup grep nil "Run grep as inferior of Emacs, parse error messages." :group 'tools :group 'processes) ;;;###autoload (defcustom grep-window-height nil "*Number of lines in a grep window. If nil, use `compilation-window-height'." :type '(choice (const :tag "Default" nil) integer) :version "22.1" :group 'grep) (defcustom grep-highlight-matches 'auto-detect "If t, use special markers to highlight grep matches. Some grep programs are able to surround matches with special markers in grep output. Such markers can be used to highlight matches in grep mode. This option sets the environment variable GREP_COLOR to specify markers for highlighting and GREP_OPTIONS to add the --color option in front of any explicit grep options before starting the grep. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program." :type '(choice (const :tag "Do not highlight matches with grep markers" nil) (const :tag "Highlight matches with grep markers" t) (other :tag "Not Set" auto-detect)) :version "22.1" :group 'grep) (defcustom grep-scroll-output nil "*Non-nil to scroll the *grep* buffer window as output appears. Setting it causes the grep commands to put point at the end of their output window so that the end of the output is always visible rather than the begining." :type 'boolean :version "22.1" :group 'grep) ;;;###autoload (defcustom grep-command nil "The default grep command for \\[grep]. If the grep program used supports an option to always include file names in its output (such as the `-H' option to GNU grep), it's a good idea to include it when specifying `grep-command'. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program." :type '(choice string (const :tag "Not Set" nil)) :group 'grep) (defcustom grep-command-template nil "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: <C> - place to put -i if case insensitive grep. <F> - file names and wildcards to search. <R> - the regular expression searched for." :type '(choice string (const :tag "Not Set" nil)) :version "22.1" :group 'grep) (defcustom grep-use-null-device 'auto-detect "If t, append the value of `null-device' to `grep' commands. This is done to ensure that the output of grep includes the filename of any match in the case where only a single file is searched, and is not necessary if the grep program used supports the `-H' option. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program." :type '(choice (const :tag "Do Not Append Null Device" nil) (const :tag "Append Null Device" t) (other :tag "Not Set" auto-detect)) :group 'grep) ;;;###autoload (defcustom grep-find-command nil "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program." :type '(choice string (const :tag "Not Set" nil)) :group 'grep) (defcustom grep-find-command-template nil "The default find command for \\[grep-find]. The default value of this variable is set up by `grep-compute-defaults'; call that function before using this variable in your program. The following place holders should be present in the string: <D> - base directory for find <X> - find options to restrict or expand the directory list <F> - find options to limit the files matched <C> - place to put -i if case insensitive grep <R> - the regular expression searched for." :type '(choice string (const :tag "Not Set" nil)) :version "22.1" :group 'grep) (defcustom grep-prompt-style nil "*Prompt style used by `grep' and `grep-find'. Nil means to prompt for regexp, files, and directory. Value `shell' means to prompt for shell command instead. Value `post' means to post-edit the final shell command." :type '(choice (const :tag "Standard" nil) (const :tag "Shell Command" shell) (const :tag "Post-edit Command" post)) :version "22.1" :group 'grep) (defcustom grep-files-aliases '( ("el" . "*.el") ("ch" . "*.[ch]") ("c" . "*.c") ("h" . "*.h") ("asm" . "*.[sS]") ("m" . "[Mm]akefile*") ("l" . "[Cc]hange[Ll]og*") ) "*Alist of aliases for the FILES argument to `grep' and `grep-find'." :type 'alist :group 'grep) (defcustom grep-find-ignored-directories '("CVS" ".hg" "{arch}") "*List of names of sub-directories which `grep-find' shall not recurse into." :type '(repeat string) :group 'grep) (defcustom grep-error-screen-columns nil "*If non-nil, column numbers in grep hits are screen columns. See `compilation-error-screen-columns'" :type '(choice (const :tag "Default" nil) integer) :version "22.1" :group 'grep) ;;;###autoload (defcustom grep-setup-hook nil "List of hook functions run by `grep-process-setup' (see `run-hooks')." :type 'hook :group 'grep) (defvar grep-mode-map (let ((map (cons 'keymap compilation-minor-mode-map))) (define-key map " " 'scroll-up) (define-key map "\^?" 'scroll-down) (define-key map "\C-c\C-f" 'next-error-follow-minor-mode) (define-key map "\r" 'compile-goto-error) ;; ? (define-key map "n" 'next-error-no-select) (define-key map "p" 'previous-error-no-select) (define-key map "{" 'compilation-previous-file) (define-key map "}" 'compilation-next-file) (define-key map "\t" 'compilation-next-error) (define-key map [backtab] 'compilation-previous-error) ;; Set up the menu-bar (define-key map [menu-bar grep] (cons "Grep" (make-sparse-keymap "Grep"))) (define-key map [menu-bar grep compilation-kill-compilation] '("Kill Grep" . kill-compilation)) (define-key map [menu-bar grep compilation-separator2] '("----" . nil)) (define-key map [menu-bar grep compilation-compile] '("Compile..." . compile)) (define-key map [menu-bar grep compilation-grep] '("Another grep..." . grep)) (define-key map [menu-bar grep compilation-grep-find] '("Recursive grep..." . grep-find)) (define-key map [menu-bar grep compilation-recompile] '("Repeat grep" . recompile)) (define-key map [menu-bar grep compilation-separator2] '("----" . nil)) (define-key map [menu-bar grep compilation-first-error] '("First Match" . first-error)) (define-key map [menu-bar grep compilation-previous-error] '("Previous Match" . previous-error)) (define-key map [menu-bar grep compilation-next-error] '("Next Match" . next-error)) map) "Keymap for grep buffers. `compilation-minor-mode-map' is a cdr of this.") (defalias 'kill-grep 'kill-compilation) ;;;; TODO --- refine this!! ;;; (defcustom grep-use-compilation-buffer t ;;; "When non-nil, grep specific commands update `compilation-last-buffer'. ;;; This means that standard compile commands like \\[next-error] and \\[compile-goto-error] ;;; can be used to navigate between grep matches (the default). ;;; Otherwise, the grep specific commands like \\[grep-next-match] must ;;; be used to navigate between grep matches." ;;; :type 'boolean ;;; :group 'grep) ;; override compilation-last-buffer (defvar grep-last-buffer nil "The most recent grep buffer. A grep buffer becomes most recent when its process is started or when it is used with \\[grep-next-match]. Notice that using \\[next-error] or \\[compile-goto-error] modifies `complation-last-buffer' rather than `grep-last-buffer'.") ;;;###autoload (defvar grep-regexp-alist '(("^\\(.+?\\)\\(:[ \t]*\\)\\([0-9]+\\)\\2" 1 3) ;; Rule to match column numbers is commented out since no known grep ;; produces them ;; ("^\\(.+?\\)\\(:[ \t]*\\)\\([0-9]+\\)\\2\\(?:\\([0-9]+\\)\\(?:-\\([0-9]+\\)\\)?\\2\\)?" ;; 1 3 (4 . 5)) ("^\\(\\(.+?\\):\\([0-9]+\\):\\).*?\ \\(\033\\[01;31m\\(?:\033\\[K\\)?\\)\\(.*?\\)\\(\033\\[[0-9]*m\\)" 2 3 ;; Calculate column positions (beg . end) of first grep match on a line ((lambda () (setq compilation-error-screen-columns nil) (- (match-beginning 4) (match-end 1))) . (lambda () (- (match-end 5) (match-end 1) (- (match-end 4) (match-beginning 4))))) nil 1) ("^Binary file \\(.+\\) matches$" 1 nil nil 0 1)) "Regexp used to match grep hits. See `compilation-error-regexp-alist'.") (defvar grep-error "grep hit" "Message to print when no matches are found.") ;; Reverse the colors because grep hits are not errors (though we jump there ;; with `next-error'), and unreadable files can't be gone to. (defvar grep-hit-face compilation-info-face "Face name to use for grep hits.") (defvar grep-error-face 'compilation-error "Face name to use for grep error messages.") (defvar grep-match-face 'match "Face name to use for grep matches.") (defvar grep-context-face 'shadow "Face name to use for grep context lines.") (defvar grep-mode-font-lock-keywords '(;; Command output lines. ("^\\([A-Za-z_0-9/\.+-]+\\)[ \t]*:" 1 font-lock-function-name-face) (": \\(.+\\): \\(?:Permission denied\\|No such \\(?:file or directory\\|device or address\\)\\)$" 1 grep-error-face) ;; remove match from grep-regexp-alist before fontifying ("^Grep started.*" (0 '(face nil message nil help-echo nil mouse-face nil) t)) ("^Grep finished \\(?:(\\(matches found\\))\\|with \\(no matches found\\)\\).*" (0 '(face nil message nil help-echo nil mouse-face nil) t) (1 compilation-info-face nil t) (2 compilation-warning-face nil t)) ("^Grep \\(exited abnormally\\|interrupt\\|killed\\|terminated\\)\\(?:.*with code \\([0-9]+\\)\\)?.*" (0 '(face nil message nil help-echo nil mouse-face nil) t) (1 grep-error-face) (2 grep-error-face nil t)) ("^.+?-[0-9]+-.*\n" (0 grep-context-face)) ;; Highlight grep matches and delete markers ("\\(\033\\[01;31m\\)\\(.*?\\)\\(\033\\[[0-9]*m\\)" ;; Refontification does not work after the markers have been ;; deleted. So we use the font-lock-face property here as Font ;; Lock does not clear that. (2 (list 'face nil 'font-lock-face grep-match-face)) ((lambda (bound)) (progn ;; Delete markers with `replace-match' because it updates ;; the match-data, whereas `delete-region' would render it obsolete. (replace-match "" t t nil 3) (replace-match "" t t nil 1)))) ("\\(\033\\[[0-9;]*[mK]\\)" ;; Delete all remaining escape sequences ((lambda (bound)) (replace-match "" t t nil 1)))) "Additional things to highlight in grep output. This gets tacked on the end of the generated expressions.") ;;;###autoload (defvar grep-program ;; Currently zgrep has trouble. It runs egrep instead of grep, ;; and it doesn't pass along long options right. "grep" ;; (if (equal (condition-case nil ; in case "zgrep" isn't in exec-path ;; (call-process "zgrep" nil nil nil ;; "foo" null-device) ;; (error nil)) ;; 1) ;; "zgrep" ;; "grep") "The default grep program for `grep-command' and `grep-find-command'. This variable's value takes effect when `grep-compute-defaults' is called.") ;;;###autoload (defvar find-program "find" "The default find program for `grep-find-command'. This variable's value takes effect when `grep-compute-defaults' is called.") ;;;###autoload (defvar grep-find-use-xargs nil "Whether \\[grep-find] uses the `xargs' utility by default. If nil, it uses `find -exec'; if `gnu', it uses `find -print0' and `xargs -0'; if not nil and not `gnu', it uses `find -print' and `xargs'. This variable's value takes effect when `grep-compute-defaults' is called.") ;; History of grep commands. ;;;###autoload (defvar grep-history nil) ;;;###autoload (defvar grep-find-history nil) ;; History of grep and grep-find regexp and files args. (defvar grep-regexp-history nil) (defvar grep-files-history '("ch" "el")) ;;;###autoload (defun grep-process-setup () "Setup compilation variables and buffer for `grep'. Set up `compilation-exit-message-function' and run `grep-setup-hook'." (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t)) (grep-compute-defaults)) (when (eq grep-highlight-matches t) ;; Modify `process-environment' locally bound in `compilation-start' (setenv "GREP_OPTIONS" (concat (getenv "GREP_OPTIONS") " --color=always")) ;; for GNU grep 2.5.1 (setenv "GREP_COLOR" "01;31") ;; for GNU grep 2.5.1-cvs (setenv "GREP_COLORS" "mt=01;31:fn=:ln=:bn=:se=:ml=:cx=:ne")) (set (make-local-variable 'compilation-exit-message-function) (lambda (status code msg) (if (eq status 'exit) (cond ((zerop code) '("finished (matches found)\n" . "matched")) ((= code 1) '("finished with no matches found\n" . "no match")) (t (cons msg code))) (cons msg code)))) (run-hooks 'grep-setup-hook)) ;;;###autoload (defun grep-compute-defaults () (unless (or (not grep-use-null-device) (eq grep-use-null-device t)) (setq grep-use-null-device (with-temp-buffer (let ((hello-file (expand-file-name "HELLO" data-directory))) (not (and (equal (condition-case nil (if grep-command ;; `grep-command' is already set, so ;; use that for testing. (call-process-shell-command grep-command nil t nil "^English" hello-file) ;; otherwise use `grep-program' (call-process grep-program nil t nil "-nH" "^English" hello-file)) (error nil)) 0) (progn (goto-char (point-min)) (looking-at (concat (regexp-quote hello-file) ":[0-9]+:English"))))))))) (unless (and grep-command grep-command-template grep-find-command grep-find-command-template) (let ((required-options (concat (if grep-use-null-device "-n" "-nH") (if (equal (condition-case nil ; in case "grep" isn't in exec-path (call-process grep-program nil nil nil "-e" "foo" null-device) (error nil)) 1) " -e" "")))) (unless grep-command (setq grep-command (format "%s %s " grep-program required-options))) (unless grep-command-template (setq grep-command-template (format "%s <C> %s <R> <F>" grep-program required-options))) (unless grep-find-use-xargs (setq grep-find-use-xargs (if (and (equal (call-process "find" nil nil nil null-device "-print0") 0) (equal (call-process "xargs" nil nil nil "-0" "-e" "echo") 0)) 'gnu))) (unless grep-find-command (setq grep-find-command (cond ((eq grep-find-use-xargs 'gnu) (format "%s . -type f -print0 | xargs -0 -e %s" find-program grep-command)) (grep-find-use-xargs (format "%s . -type f -print | xargs %s" find-program grep-command)) (t (cons (format "%s . -type f -exec %s {} %s \\;" find-program grep-command null-device) (+ 22 (length grep-command))))))) (unless grep-find-command-template (setq grep-find-command-template (let ((gcmd (format "%s <C> %s <R>" grep-program required-options))) (cond ((eq grep-find-use-xargs 'gnu) (format "%s <D> <X> -type f <F> -print0 | xargs -0 -e %s" find-program gcmd)) (grep-find-use-xargs (format "%s <D> <X> -type f <F> -print | xargs %s" find-program gcmd)) (t (format "%s <D> <X> -type f <F> -exec %s {} %s \\;" find-program gcmd null-device)))))) (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t)) (setq grep-highlight-matches (with-temp-buffer (and (equal (condition-case nil (call-process grep-program nil t nil "--help") (error nil)) 0) (progn (goto-char (point-min)) (search-forward "--color" nil t)) t))))))) (defun grep-expand-template (template &optional regexp files dir excl) "Patch grep COMMAND string replacing <C>, <D>, <F>, <R>, and <X>." (let ((command template) (case-fold case-fold-search) (case-fold-search nil)) (if (string-match "<C>" command) (setq command (replace-match (if (and case-fold (isearch-no-upper-case-p regexp t)) "-i" "") t t command))) (if (string-match "<D>" command) (setq command (replace-match (or dir ".") t t command))) (if (string-match "<F>" command) (setq command (replace-match (or files "") t t command))) (if (string-match "<N>" command) (setq command (replace-match (if (and grep-use-null-device null-device) null-device "") t t command))) (if (string-match "<X>" command) (setq command (replace-match (or excl "") t t command))) (if (string-match "<R>" command) (setq command (replace-match (shell-quote-argument (or regexp "")) t t command))) command)) (defun grep-read-regexp () "Read regexp arg for interactive grep." (let ((default (or (funcall (or find-tag-default-function (get major-mode 'find-tag-default-function) 'find-tag-default)) ""))) (read-string (concat "Search for" (if (and default (> (length default) 0)) (format " (default %s): " default) ": ")) nil 'grep-regexp-history default))) (defun grep-read-files (regexp) "Read files arg for interactive grep." (let* ((default (or (and (stringp (buffer-file-name)) (let ((fn (file-name-nondirectory (buffer-file-name))) (aliases grep-files-aliases) alias) (while aliases (setq alias (car aliases) aliases (cdr aliases)) (if (string-match (wildcard-to-regexp (cdr alias)) fn) (setq aliases nil) (setq alias nil))) (cdr alias))) (car grep-files-history))) (files (read-string (concat "Search for \"" regexp "\" in files (default " default "): ") nil 'grep-files-history default))) (and files (or (cdr (assoc files grep-files-aliases)) files)))) ;;;###autoload (defun grep (regexp &optional files) "Run grep, searching for REGEXP in FILES in current directory. Collect output in a buffer. Interactively, prompt separately for each search parameter. The search is limited to file names matching shell pattern FILES. FILES may use abbreviations defined in `grep-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. With \\[universal-argument] prefix, prompt for shell command instead. With two \\[universal-argument] prefixes, prompt for search parameters, and allow user to edit the final shell command before it is submitted. Note that setting `grep-prompt-style' overrides any prefix arg. While grep runs asynchronously, you can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error] in the grep \ output buffer, to go to the lines where grep found matches. This command uses a special history list for its arguments, so you can easily repeat a grep command." (interactive (progn (grep-compute-defaults) (cond ((or (eq grep-prompt-style 'shell) (equal current-prefix-arg '(4))) (if grep-command (list (read-from-minibuffer "Run grep (like this): " grep-command nil nil 'grep-history) nil) ;; No default was set (read-string "grep.el: No `grep-command' available. Press RET.") (list nil nil))) ((not grep-command-template) (read-string "grep.el: No `grep-command-template' available. Press RET.") (list nil nil)) (t (let* ((regexp (grep-read-regexp)) (files (grep-read-files regexp))) (list regexp files)))))) (when regexp (let (command) (if (or (null files) ;; C-u or backwards compatible non-interactive call (eq grep-prompt-style 'shell)) (setq command regexp) (setq command (grep-expand-template grep-command-template regexp files)) (when command (if (or (eq grep-prompt-style 'post) (equal current-prefix-arg '(16))) (setq command (read-from-minibuffer "Confirm: " command nil nil 'grep-find-history)) (push command grep-history)))) (when command ;; Setting process-setup-function makes exit-message-function work ;; even when async processes aren't supported. (compilation-start (if (and grep-use-null-device null-device) (concat command " " null-device) command) 'grep-mode))))) ;;;###autoload (define-compilation-mode grep-mode "Grep" "Sets `grep-last-buffer' and `compilation-window-height'." (setq grep-last-buffer (current-buffer)) (set (make-local-variable 'compilation-error-face) grep-hit-face) (set (make-local-variable 'compilation-error-regexp-alist) grep-regexp-alist) (set (make-local-variable 'compilation-process-setup-function) 'grep-process-setup) (set (make-local-variable 'compilation-disable-input) t)) ;;;###autoload (defun grep-find (regexp &optional files dir api) "Recusively grep for REGEXP in FILES in directory tree rooted at DIR. Collect output in a buffer. Interactively, prompt separately for each search parameter. The search is limited to file names matching shell pattern FILES. FILES may use abbreviations defined in `grep-files-aliases', e.g. entering `ch' is equivalent to `*.[ch]'. With \\[universal-argument] prefix, prompt for shell command instead. With two \\[universal-argument] prefixes, prompt for search parameters, and allow user to edit the final shell command before it is submitted. Note that setting `grep-prompt-style' overrides any prefix arg. While find runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to. This command uses a special history list for its arguments, so you can easily modify or repeat a find command." (interactive (progn (grep-compute-defaults) (cond ((or (eq grep-prompt-style 'shell) (equal current-prefix-arg '(4))) (if grep-find-command (list (read-from-minibuffer "Run find (like this): " grep-find-command nil nil 'grep-find-history) nil nil) ;; No default was set (read-string "grep.el: No `grep-find-command' available. Press RET.") (list nil nil nil))) ((not grep-find-command-template) (read-string "grep.el: No `grep-find-command-template' available. Press RET.") (list nil nil nil)) (t (let* ((regexp (grep-read-regexp)) (files (grep-read-files regexp)) (dir (read-directory-name "Base directory: " nil default-directory t))) (list regexp files dir)))))) (when regexp (if (or (null files) ;; C-u or backwards compatible non-interactive call (eq grep-prompt-style 'shell)) ;; REGEXP is command line (compilation-start regexp 'grep-mode) (let ((command (grep-expand-template grep-find-command-template regexp (and files (concat "-name " (shell-quote-argument files))) nil ;; we change default-directory to dir (and grep-find-ignored-directories (concat "\\( -path '*/" (mapconcat #'identity grep-find-ignored-directories "' -o -path '*/") "' \\) -prune -o ")))) (default-directory (file-name-as-directory (expand-file-name dir)))) (when command (if (or (eq grep-prompt-style 'post) (equal current-prefix-arg '(16))) (setq command (read-from-minibuffer "Confirm: " command nil nil 'grep-find-history)) (push command grep-find-history)) (compilation-start command 'grep-mode)))))) ;;;###autoload (defalias 'find-grep 'grep-find) (provide 'grep) ;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d ;;; grep.el ends here -- Kim F. Storm <storm@cua.dk> http://www.cua.dk ^ permalink raw reply [flat|nested] 67+ messages in thread
* Re: [mange@freemail.hu: grep-tree doesn't shell-quote-argument] 2006-04-25 9:06 ` Kim F. Storm @ 2006-04-29 3:50 ` Richard Stallman 0 siblings, 0 replies; 67+ messages in thread From: Richard Stallman @ 2006-04-29 3:50 UTC (permalink / raw) Cc: mange, emacs-devel Repeating myself (do I hear an echo?) many of the changes I've made to grep.el should still be included in the release even if we decide not to change the interactive api of grep and grep-find. Could you please propose those changes, one by one? ^ permalink raw reply [flat|nested] 67+ messages in thread
end of thread, other threads:[~2006-04-29 3:50 UTC | newest] Thread overview: 67+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-04-18 12:57 [mange@freemail.hu: grep-tree doesn't shell-quote-argument] Richard Stallman 2006-04-18 14:02 ` Kim F. Storm 2006-04-18 14:44 ` Eli Zaretskii 2006-04-18 15:11 ` Eric Hanchrow 2006-04-18 15:18 ` Lennart Borgman 2006-04-19 8:59 ` Kim F. Storm 2006-04-19 9:15 ` Romain Francoise 2006-04-19 9:16 ` Eli Zaretskii 2006-04-19 11:41 ` Kim F. Storm 2006-04-19 12:23 ` David Kastrup 2006-04-19 12:51 ` Kim F. Storm 2006-04-19 13:09 ` David Kastrup 2006-04-19 21:13 ` Richard Stallman 2006-04-19 13:14 ` Stefan Monnier 2006-04-19 13:28 ` David Kastrup 2006-04-19 13:58 ` Stefan Monnier 2006-04-19 14:09 ` David Kastrup 2006-04-19 14:58 ` Kim F. Storm 2006-04-19 15:10 ` David Kastrup 2006-04-19 16:59 ` Kevin Rodgers 2006-04-19 17:08 ` David Kastrup 2006-04-19 14:52 ` Kim F. Storm 2006-04-19 15:03 ` David Kastrup 2006-04-19 18:10 ` Bill Wohler 2006-04-19 18:15 ` Drew Adams 2006-04-19 18:23 ` David Kastrup 2006-04-19 18:34 ` Bill Wohler 2006-04-19 21:13 ` Richard Stallman 2006-04-19 12:49 ` Stefan Monnier 2006-04-18 15:27 ` Romain Francoise 2006-04-19 4:17 ` Richard Stallman 2006-04-19 8:57 ` Eli Zaretskii 2006-04-19 21:12 ` Richard Stallman 2006-04-20 9:53 ` Eli Zaretskii 2006-04-21 8:27 ` Kim F. Storm 2006-04-21 14:47 ` Magnus Henoch 2006-04-21 17:22 ` Stefan Monnier 2006-04-21 20:04 ` Kim F. Storm 2006-04-21 20:40 ` Stefan Monnier 2006-04-21 21:35 ` Kim F. Storm 2006-04-22 12:03 ` Richard Stallman 2006-04-22 12:41 ` David Kastrup 2006-04-23 16:06 ` Bill Wohler 2006-04-23 16:19 ` Bill Wohler 2006-04-22 23:02 ` Kim F. Storm 2006-04-23 21:58 ` Richard Stallman 2006-04-23 22:06 ` David Kastrup 2006-04-24 11:51 ` Richard Stallman 2006-04-24 12:04 ` David Kastrup 2006-04-25 16:46 ` Richard Stallman 2006-04-24 12:10 ` Kim F. Storm 2006-04-24 22:46 ` Kim F. Storm 2006-04-25 16:47 ` Richard Stallman 2006-04-24 11:05 ` Kim F. Storm 2006-04-24 11:11 ` Miles Bader 2006-04-24 11:24 ` David Kastrup 2006-04-24 11:31 ` Miles Bader 2006-04-24 11:43 ` David Kastrup 2006-04-24 11:52 ` Miles Bader 2006-04-24 17:52 ` Richard Stallman 2006-04-24 18:16 ` David Kastrup 2006-04-24 20:38 ` Chong Yidong 2006-04-25 16:48 ` Richard Stallman 2006-04-26 8:27 ` Kim F. Storm 2006-04-27 4:36 ` Richard Stallman 2006-04-25 9:06 ` Kim F. Storm 2006-04-29 3:50 ` Richard Stallman
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.