1

I have this Elisp code that allows me to use ace-window to open a file in a selected window from Dired:

  (defun find-file-dired-ace-window ()
    "Use ace window to select a window for opening a file from dired."
    (interactive)
    (let ((file (dired-get-file-for-visit)))
      (if (> (length (aw-window-list)) 1)
          (aw-select "" (lambda (window)
                          (aw-switch-to-window window)
                          (find-file file)))
    (find-file-other-window file))))

This works well, however I find it annoying that the focus switches to the newly opened buffer. I would like the focus to stay in the Dired buffer.

I have thought to use save-window-excursion for this, however now the file does not get opened at all, so it is totally useless:

  (defun save-excursion-dired-ace-window ()
    "Use ace window to select a window for opening a file from dired."
    (interactive)
    (save-window-excursion
      (let ((file (dired-get-file-for-visit)))
        (if (> (length (aw-window-list)) 1)
            (aw-select "" (lambda (window)
                            (aw-switch-to-window window)
                            (find-file file)))
          (find-file-other-window file)))))

How can I can get the desired behavior?

1
0

Don't use find-file (or find-file-other-window).

Use find-file-noselect to obtain a buffer visiting the file. Then use display-buffer-pop-up-window to display it in another window.

There are other buffer-display functions you can use, if you want to show it in some existing window. C-h f display-buffer tells you about them.

Dunno what aw-switch-to-window does. If that selects the window then maybe you don't want to do that. But the overall point is to use display-buffer (or one of its sidekicks), not find-file (or one of its sidekicks). And use find-file-noselect to get you the file-visiting buffer to display.

(defun find-file-dired-ace-window ()
    "Use ace window to select a window for opening a file from dired."
    (interactive)
    (let* ((file (dired-get-file-for-visit))
           (buf  (find-file-noselect file)))
      (if (> (length (aw-window-list)) 1)
             (aw-select "" (lambda (window)
                             (aw-switch-to-window window)
                             (display-buffer buf)
                             buf))
       (display-buffer-pop-up-window buf nil)))
2
  • Unfortunately this does not work. Whenever I select a buffer with this command I get the error "Invalid buffer", and I get switched to the selected window without the new buffer being opened. Jun 10 at 21:43
  • I had a typo: file instead of buf was passed to display-buffer. And maybe your aw-select expects its function arg to return a buffer (like find-file does). Try what I have now. If that doesn't help, then at least see if the other branch works, i.e., when aw-window-list returns less than 2.
    – Drew
    Jun 11 at 0:27
0

This may be hacky but it works! I save the dired buffer at the beginning and then switch back to it right at the end.

 (defun find-file-dired-ace-window ()
    "Use ace window to select a window for opening a file from dired."
    (interactive)
    (let ((file (dired-get-file-for-visit))
          (dired-buf (current-buffer)))
      (if (> (length (aw-window-list)) 1)
          (progn
            (aw-select "" (lambda (window)
                            (aw-switch-to-window window)
                            (find-file file)))
            (let ((dired-window (get-buffer-window dired-buf)))
              (when dired-window
                (select-window dired-window))))
    (find-file-other-window file))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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