10

Is there a way to automatically switch focus to any new windows?

For example, if I C-h f some-function, that creates a new window. But the focus remains where I was, so when I'm done reading and hit q, I just type a q in whatever buffer I was in previously.

Ideally, I'd like to always switch focus to a new window whenever one is created.

Ideas?

Alex
  • 1,028
  • 5
  • 20
  • How about `delete-other-windows` aka `C-x 1` or `delete-window` aka `C-x 0` -- https://www.gnu.org/software/emacs/manual/html_node/emacs/Change-Window.html There is a variable `help-window-select` for the `*Help*` buffer that controls whether you switch to it or not when it is displayed: http://emacs.stackexchange.com/a/3357/2287 Some, buffers like the `*Help*` buffer and the `*Backtrace*` buffer already have `q` set up to delete the window if it is selected. – lawlist Apr 22 '16 at 02:25
  • The author of each function that causes a particular window to be displayed has made a decision how that should work, and sometimes there are user options to alter that behavior. Most people aren't really interested in "taking the bull by the horns" by modifying the various functions to do what is desired -- in fact, I'm probably one of the only people in this forum who does that. Most people try to set up some rules in the `display-buffer-alist` using the things like the `buffer-name` to help control how and where windows are displayed. There is no hard set rule and there are exceptions. – lawlist Apr 22 '16 at 02:32
  • 1
    I recommend popwin or shackle for this. – InHarmsWay Apr 22 '16 at 03:09
  • 4
    For your example, `(setq help-window-select t)`. – xuchunyang Apr 22 '16 at 08:37

2 Answers2

4

Help windows

Add this to your init.el to automatically focus any help window you see. Then, you'll be able to quit it with Q.

(setq help-window-select t)  ; Switch to help buffers automatically

Alternatively, if you're using use-package, I recommend adding this to your init.el (or appending to an existing (use-package emacs ... declaration):

(use-package emacs
  :custom
  (help-window-select t "Switch to help buffers automatically"))

This does not change it for other buffers, such as the buffer that opens when you run pp-macroexpand-last-sexp, though.

Automatically switch focus to new windows when you make them

Add this block of code which I copied from the witchmacs repository:

(defun split-and-follow-horizontally ()
  (interactive)
  (split-window-below)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-x 2") 'split-and-follow-horizontally)

(defun split-and-follow-vertically ()
  (interactive)
  (split-window-right)
  (balance-windows)
  (other-window 1))
(global-set-key (kbd "C-x 3") 'split-and-follow-vertically)

Alternatively, if you're using use-package, I recommend not adding (global-set-key...) to your config and using

(use-package emacs
  :bind (:map ctl-x-map
  ("2" . split-and-follow-horizontally)
  ("3" . split-and-follow-vertically)))

You can also put the function definition into :config.

Changing the behavior globally

Add this to your init.el

(defadvice split-window (after split-window-after activate)
  (other-window 1))
  • What is advantage of use-package over config? – tejasvi88 Mar 20 '21 at 09:11
  • `(select-window (get-lru-window))` seems more reliable than `(other-window 1)` for correctly selecting the window that another command has just created or reused, rather than some other window that happens to be next per Emacs' ideas of window cycling. (Still a +1 for this answer despite that.) – mtraceur May 17 '23 at 01:57
2

Here is how to solve the problem. The problem you describe has two parts, really. One part is to change focus (like you describe), so the "q" is sent to the Help window. The second part is to get back to your original window.

I solved the issue by forcing the Help window to pop up over top of my current window, so that I can just type "q" to dispatch the help window and return to my original buffer. The method shown below can be extended to any of the usual whatever Apropos, Help, etc windows. Good luck.

(add-to-list 'display-buffer-alist '("*Apropos*" display-buffer-same-window)) (add-to-list 'display-buffer-alist '("*Help*" display-buffer-same-window))

Kevin
  • 1,308
  • 8
  • 20
  • While that does indeed work, how would you create the buffer in another window And then set focus using display-buffer-alist? – RichieHH Jan 31 '20 at 08:54
  • @RichieHH Replacing `display-buffer-same-window` with `display-buffer-pop-up-window` might work. I've not tested it, though. Have a look at `C-h f display-buffer` for more information. – Arch Stanton Jan 29 '21 at 23:30
  • @ArchStanton -pop-up-window doesn't work. – tejasvi88 Mar 20 '21 at 10:05