3

Almost always, I want to run find-grep like this:

ack --no-heading --no-color "SOMETHING" ~/myco/firmwaresrc

Where SOMETHING is the only variable. There are actually a surprising number of keypresses and bits of thinking required to get this to happen.

How would I go about 'canning' this, so that M-x fgf would run find-grep with that command and the current region in place of SOMETHING?

Actually I've worked out how to do this (see answer below). Can anyone tell me how to get emacs to ask for SOMETHING if there's no selected region?

John Lawrence Aspden
  • 17,124
  • 11
  • 67
  • 110

3 Answers3

7
(defun fgf (term)
  (interactive
   (list (if (use-region-p)
             (buffer-substring (region-beginning) (region-end))
           (read-string "grep-find: "))))
  (grep-find (concat "ack --no-heading --no-color \""
                     term  "\" ~/myco/firmwaresrc")))
huaiyuan
  • 26,129
  • 5
  • 57
  • 63
  • 2
    +1. It would be good to replace `term` with `(shell-quote-argument term)`, though, in case you ever search for a pattern with shell special characters in it. –  Feb 10 '12 at 17:36
  • In fact I have already run into this problem! Thank you for solving it. – John Lawrence Aspden Feb 10 '12 at 18:20
  • Possibly. That would escape regexp operators such as the Kleene star, though. – huaiyuan Feb 10 '12 at 18:54
  • 1
    Exactly, and they *need* to be escaped at the shell level if you don't want them mis-interpreted as glob characters instead. –  Feb 11 '12 at 02:57
1

You might also want to look at ack, full-ack or ack-and-a-half. The last is supposed to be the marriage of the two previous ones. They allow you to specify default arguments and such (although there's nothing wrong with learning elisp :-).

Ivan Andrus
  • 5,221
  • 24
  • 31
0

This works:

(defun fgf ()
  (interactive)
  (if (region-active-p)
      (let (start end term command)
        (setq start (region-beginning)
              end   (region-end)
              term (buffer-substring start end)
              command (concat "ack --no-heading --no-color \"" term  "\" ~/myco/firmwaresrc"))
    (grep-find command))))

So now I wonder if it's possible to get it to ask me for "SOMETHING" if there's no region selected. I'll change the question.

Tom
  • 7,515
  • 7
  • 38
  • 54
John Lawrence Aspden
  • 17,124
  • 11
  • 67
  • 110
  • 3
    You're correct to use `(let)` to generate local bindings, but it's not necessary to have a separate `(setq)` to assign values to those variables -- you can (and should) do that as part of the `let` call: `(let ((start (region-beginning)) (end (region-end)) ...) (grep-find command))` – phils Feb 10 '12 at 15:01
  • Dude, i tried that and it broke! I was assuming emacs-lisp funnies, but it must have been finger trouble. thanks. – John Lawrence Aspden Feb 10 '12 at 18:15