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?

Drew
  • 77,472
  • 10
  • 114
  • 243
Håkon Hægland
  • 3,648
  • 1
  • 22
  • 51

1 Answers1

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)
knarf
  • 323
  • 2
  • 9
  • 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? – Håkon Hægland Jan 11 '15 at 19:20
  • https://www.gnu.org/software/emacs/manual/html_node/elisp/Porting-old-advices.html#Porting-old-advices – Håkon Hægland Jan 11 '15 at 19:27
  • Hi knarf, I installed Emacs 24.4, now it works better.. but when I click the link >START POS< nothing happens.. – Håkon Hægland Jan 12 '15 at 06: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! – Håkon Hægland Jan 12 '15 at 07:33
  • 1
    ok, i updated the answer – knarf Jan 12 '15 at 12:55