2

As an example, let's say I want to search for the word test. When I type M-x occur RET test RET, the current frame is split into two windows, with the current buffer on top and the *Occur* buffer on bottom. If I click a line in the *Occur* buffer point is moved to the matching line in the top buffer. All this is fine..

But if I want to return to the original position in the top buffer, it is more difficult. First, there is no shortcut in the *Occur* buffer to return to that original position in the searched buffer. I could of course as a workaround type C-x r b before I clicked the line in the *Occur* buffer such that I got a bookmark. But I think this is not an ideal solution.

So the question is: Is it possible to add the original buffer position in the searched buffer as a single line in the *Occur* buffer (for example, the topmost line) such that I can easily return to my starting point after visiting (that is: moving to) some matches from the *Occur* buffer?

4
  • 2
    You can save the current buffer position with a register using C-x r SPC and later jump back with C-x r j. If you use Helm, you can use helm-occur that allows you to visit match by pressing TAB on the match for previewing. Then you can either jump to that match using RET or cancel with C-g to return to original location. Here is a demo.
    – Tu Do
    Jan 11, 2015 at 15:38
  • @TuDo Thanks! I will have a look at these options.. Jan 11, 2015 at 16:20
  • You may want to look at my helm guide.
    – Tu Do
    Jan 11, 2015 at 17:05
  • If you use icicle-occur (C-c ') to visit occurrences, then just use C-g to return to the original position.
    – Drew
    Jan 11, 2015 at 18:09

1 Answer 1

1

This code advises the occur function to prefix the result buffer with a link to the place of the point before running occur.

(require 'button)

(defun my-goto-start-marker (b)
  "Get the marker from the button B and go to it."
  (let ((marker (button-get b 'my-start-marker)))
    (pop-to-buffer (marker-buffer marker))
    (goto-char (marker-position marker))))


(defun my-occur-advice (orig &rest args)
  ;; keep starting pos
  (let ((start-marker (point-marker)))
    ;; call old regular `occur'
    (apply orig args)

    ;; prefix the occur buffer with a button/link if its not already there
    (with-current-buffer (get-buffer "*Occur*")
      (when (save-excursion
              (goto-char (point-min))
              (looking-at (rx bol (+ digit) " match")))

        (let ((buffer-read-only nil))
          (save-excursion
            (goto-char (point-min))
            (insert-button ">START POS<"
                           'action 'my-goto-start-marker ;; function to call on click/RET
                           'my-start-marker start-marker ;; store the marker as text property of the button
                           'face '(:underline t)
                           'follow-link t)
            (insert "\n")))))))

(advice-add 'occur :around 'my-occur-advice)
5
  • Thanks! This looks great.. but I get error Debugger entered--Lisp error: (void-function advice-add) (advice-add (quote occur) :around (quote my-occur-advice)) I am using Emacs 24.3.. maybe advice-add is only available in Emacs 24.4? Jan 11, 2015 at 19:20
  • Hi knarf, I installed Emacs 24.4, now it works better.. but when I click the link >START POS< nothing happens.. Jan 12, 2015 at 6:57
  • I think I found the problem, I had to add a 'follow-link t property to the button. Now it works perfectly :) Thank you very much! Jan 12, 2015 at 7:33
  • 1
    ok, i updated the answer
    – knarf
    Jan 12, 2015 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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