开发者

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

When I use grep-find it opens another window (area in t开发者_如何学JAVAhe 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.


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.


You can add a binding (e.g. Alt-m) and do the following

(define-key grep-mode-map "\M-m" (lambda() 
                                   (interactive) 
                                   (compile-goto-error)
                                   (delete-other-windows)
                                   (kill-buffer "*grep*")))

I didn't find a way to replace the standard "Enter" / Mouse-click binding with a custom function


There is an another approach:

(defun eab/compile-goto-error ()
  (interactive)
  (let ((cwc (current-window-configuration)))
    (funcall
     `(lambda ()
        (defun eab/compile-goto-error-internal ()
          (let ((cb (current-buffer))
                (p (point)))
            (set-window-configuration ,cwc)
            (switch-to-buffer cb)
            (goto-char p ))))))
  (compile-goto-error)
  (run-with-timer 0.01 nil 'eab/compile-goto-error-internal))


I had the same question, and found this answer over at emacs.stackexchange https://emacs.stackexchange.com/a/33908/20000

(defun my-compile-goto-error-same-window ()
  (interactive)
  (let ((display-buffer-overriding-action
         '((display-buffer-reuse-window
            display-buffer-same-window)
           (inhibit-same-window . nil))))
    (call-interactively #'compile-goto-error)))

(defun my-compilation-mode-hook ()
  (local-set-key (kbd "o") #'my-compile-goto-error-same-window))

(add-hook 'compilation-mode-hook #'my-compilation-mode-hook)

Pressing o in the *grep* buffer will open the location and file in the same frame.

I found this an elegant solution without deleting frames or too much lisp code and just hooking into compilation-mode-hook.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜