[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: address@hidden: grep-tree doesn't shell-quote-argument]
From: |
Kim F. Storm |
Subject: |
Re: address@hidden: grep-tree doesn't shell-quote-argument] |
Date: |
Fri, 21 Apr 2006 10:27:12 +0200 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) |
Richard Stallman <address@hidden> 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 <address@hidden> http://www.cua.dk
- RE: address@hidden: grep-tree doesn't shell-quote-argument], (continued)
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Richard Stallman, 2006/04/19
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Stefan Monnier, 2006/04/19
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Romain Francoise, 2006/04/18
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Richard Stallman, 2006/04/19
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Eli Zaretskii, 2006/04/19
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Richard Stallman, 2006/04/19
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Eli Zaretskii, 2006/04/20
- Re: address@hidden: grep-tree doesn't shell-quote-argument],
Kim F. Storm <=
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Magnus Henoch, 2006/04/21
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Stefan Monnier, 2006/04/21
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Kim F. Storm, 2006/04/21
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Stefan Monnier, 2006/04/21
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Kim F. Storm, 2006/04/21
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Richard Stallman, 2006/04/22
- Re: address@hidden: grep-tree doesn't shell-quote-argument], David Kastrup, 2006/04/22
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Bill Wohler, 2006/04/23
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Bill Wohler, 2006/04/23
- Re: address@hidden: grep-tree doesn't shell-quote-argument], Kim F. Storm, 2006/04/22