Search code examples
emacsdot-emacs

How to execute emacs grep-find link in the same window?


When I use grep-find it opens another window (area in the frame) with a list of results that I can select. When I select one it opens the target file in a different window than grep-find is in.

How can I get the target file to open in the same window as the grep results (replacing the grep results window with what I am actually looking for).

How can I keep grep-find from opening a separate window (have it so it opens in the current window). My goal is I look for something, I find it, I go to it, all within the same window. I would like to add this to my .emacs file.


Solution

  • It doesn't look like there is any way to configure the compile package to do what you're asking. And there's no easy way to use advice to tweak the behavior. I think you have to resort to editing the function which actually jumps to the error, which you can do with the following addition to your .emacs (tested in Emacs 23.1):

    (eval-after-load "compile"
    '(defun compilation-goto-locus (msg mk end-mk)
      "Jump to an error corresponding to MSG at MK.
    All arguments are markers.  If END-MK is non-nil, mark is set there
    and overlay is highlighted between MK and END-MK."
      ;; Show compilation buffer in other window, scrolled to this error.
      (let* ((from-compilation-buffer (eq (window-buffer (selected-window))
                      (marker-buffer msg)))
         ;; Use an existing window if it is in a visible frame.
         (pre-existing (get-buffer-window (marker-buffer msg) 0))
         (w (if (and from-compilation-buffer pre-existing)
            ;; Calling display-buffer here may end up (partly) hiding
            ;; the error location if the two buffers are in two
            ;; different frames.  So don't do it if it's not necessary.
            pre-existing
          (let ((display-buffer-reuse-frames t)
            (pop-up-windows t))
            ;; Pop up a window.
            (display-buffer (marker-buffer msg)))))
         (highlight-regexp (with-current-buffer (marker-buffer msg)
                 ;; also do this while we change buffer
                 (compilation-set-window w msg)
                 compilation-highlight-regexp)))
    ;; Ideally, the window-size should be passed to `display-buffer' (via
    ;; something like special-display-buffer) so it's only used when
    ;; creating a new window.
    (unless pre-existing (compilation-set-window-height w))
    
    (switch-to-buffer (marker-buffer mk))
    
        ;; was
    ;; (if from-compilation-buffer
    ;;     ;; If the compilation buffer window was selected,
    ;;     ;; keep the compilation buffer in this window;
    ;;     ;; display the source in another window.
    ;;     (let ((pop-up-windows t))
    ;;       (pop-to-buffer (marker-buffer mk) 'other-window))
    ;;   (if (window-dedicated-p (selected-window))
    ;;       (pop-to-buffer (marker-buffer mk))
    ;;     (switch-to-buffer (marker-buffer mk))))
    ;; If narrowing gets in the way of going to the right place, widen.
    (unless (eq (goto-char mk) (point))
      (widen)
      (goto-char mk))
    (if end-mk
        (push-mark end-mk t)
      (if mark-active (setq mark-active)))
    ;; If hideshow got in the way of
    ;; seeing the right place, open permanently.
    (dolist (ov (overlays-at (point)))
      (when (eq 'hs (overlay-get ov 'invisible))
        (delete-overlay ov)
        (goto-char mk)))
    
    (when highlight-regexp
      (if (timerp next-error-highlight-timer)
          (cancel-timer next-error-highlight-timer))
      (unless compilation-highlight-overlay
        (setq compilation-highlight-overlay
          (make-overlay (point-min) (point-min)))
        (overlay-put compilation-highlight-overlay 'face 'next-error))
      (with-current-buffer (marker-buffer mk)
        (save-excursion
          (if end-mk (goto-char end-mk) (end-of-line))
          (let ((end (point)))
        (if mk (goto-char mk) (beginning-of-line))
        (if (and (stringp highlight-regexp)
             (re-search-forward highlight-regexp end t))
            (progn
              (goto-char (match-beginning 0))
              (move-overlay compilation-highlight-overlay
                    (match-beginning 0) (match-end 0)
                    (current-buffer)))
          (move-overlay compilation-highlight-overlay
                (point) end (current-buffer)))
        (if (or (eq next-error-highlight t)
            (numberp next-error-highlight))
            ;; We want highlighting: delete overlay on next input.
            (add-hook 'pre-command-hook
                  'compilation-goto-locus-delete-o)
          ;; We don't want highlighting: delete overlay now.
          (delete-overlay compilation-highlight-overlay))
        ;; We want highlighting for a limited time:
        ;; set up a timer to delete it.
        (when (numberp next-error-highlight)
          (setq next-error-highlight-timer
            (run-at-time next-error-highlight nil
                     'compilation-goto-locus-delete-o)))))))
    (when (and (eq next-error-highlight 'fringe-arrow))
      ;; We want a fringe arrow (instead of highlighting).
      (setq next-error-overlay-arrow-position
        (copy-marker (line-beginning-position)))))))
    

    The eval-afer-load portion just ensures that you re-define it after Emacs defined it, so that your change takes hold.