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
  • 75,699
  • 9
  • 109
  • 225
Håkon Hægland
  • 3,608
  • 1
  • 20
  • 51
  • 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](http://tuhdo.github.io/static/part3/helm-occur.gif). – Tu Do Jan 11 '15 at 15:38
  • @TuDo Thanks! I will have a look at these options.. – Håkon Hægland Jan 11 '15 at 16:20
  • You may want to look at [my helm guide](http://tuhdo.github.io/helm-intro.html). – Tu Do Jan 11 '15 at 17:05
  • If you use [`icicle-occur`](http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview) (`C-c '`) to visit occurrences, then just use `C-g` to return to the original position. – Drew Jan 11 '15 at 18:09

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
  • 313
  • 2
  • 8
  • 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