3

I often have grep (technically rgrep) in a buffer/window and another buffer/window with a "compilation" of my active project in it. I would like to bind two different keys (e.g. f2 and f3) to next-error and next-grep-hit and have them be independent. Is there a package that does that?

2

Doing all the preparation to be able to do that is going to be more work than it is worth: you have to write special functions to use the buffer(s) of interest and then bind them to keys.

I think it would be simpler to rename-uniquely the various grep/compile/etc buffers you create (so you would have *grep*<2>, *grep*<3> etc buffers, one for each different grep command you did). Then switching to the appropriate *grep* buffer and doing C-x ` would use that buffer. In fact, that's what the doc of next-error says:

To specify use of a particular buffer for error messages, type C-x ` in that buffer. You can also use the command ‘next-error-select-buffer’ to select the buffer to use for the subsequent invocation of ‘next-error’.

The next-error-select-buffer method works, but unfortunately the simple "switch to the appropriate grep buffer and do next-error" does not. I believe that is a bug in next-error-find-buffer: it prefers to use the last-used grep buffer, rather than using the current buffer. It needs to do things in the other order: use the current buffer if that buffer is usable for next-error, and fall back to the last-used buffer if not. You can probably implement that behavior by setting the variable next-error-find-buffer-function to a modified function that does things in the "right" order, but the contradiction between the doc and the implementation needs to be addressed.

I'm going to suggest the following patch as a fix, but for the time being if you want things to work that way, you will have to patch the source code in simple.el. Here's the patch:

diff --git a/lisp/simple.el b/lisp/simple.el
index f8050091d5..8796b612cc 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -298,15 +298,15 @@ next-error-find-buffer
    (funcall next-error-find-buffer-function avoid-current
                                             extra-test-inclusive
                                             extra-test-exclusive)
-   ;; 2. If next-error-last-buffer is an acceptable buffer, use that.
+   ;; 2. If the current buffer is acceptable, choose it.
+   (if (next-error-buffer-p (current-buffer) avoid-current
+               extra-test-inclusive extra-test-exclusive)
+       (current-buffer))
+   ;; 3. If next-error-last-buffer is an acceptable buffer, use that.
    (if (and next-error-last-buffer
             (next-error-buffer-p next-error-last-buffer avoid-current
                                  extra-test-inclusive extra-test-exclusive))
        next-error-last-buffer)
-   ;; 3. If the current buffer is acceptable, choose it.
-   (if (next-error-buffer-p (current-buffer) avoid-current
-               extra-test-inclusive extra-test-exclusive)
-       (current-buffer))
    ;; 4. Look for any acceptable buffer.
    (let ((buffers (buffer-list)))
      (while (and buffers

With that, the workflow is as follows:

  • M-x grep, switch to the *grep* buffer and M-x rename-uniquely (bound to C-x x u).
  • Repeat for a different search.
  • You now have two buffers *grep*<2> and *grep*<3>.
  • Switch to the <2> buffer and do C-x ` - that will take you to the next hit for the search associated with that buffer.
  • Switch to the <3> buffer and do C-x ` - that will take you to the next hit associated with that buffer.

If you switch to some unrelated buffer, you will continue using the last grep buffer you used (the <3> buffer in the above scenario), until you switch again.

EDIT: Here's the bug report - stay tuned.

2
  • Ok, if there isn't, I'll go write the functions. I was just hoping that someone already had done so. I have the buffers already named uniquely, but I don't want to switch to the buffer, as I generally have between 6 and 12 buffers on my screen at a time (several of them laid out in specific places on the 3x2 (or 3x4) grid so that they are in known locations for my eyes to glance at them. (The left column is for 2 shells. The middle is for the compilation buffer. The right column is for files, and grep if visible is at the top of it.) – intel_chris Mar 10 at 21:41
  • OK - sorry I could't come up with a satisfactory solution. If you come up with a good solution, I'd encourage you to provide an answer to your question. – NickD Mar 10 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.