Whenever I do apropos, describe-key, or some other help function in emacs, it displays the help in my other window. In order to get rid of it, I must change windows/buffers to go there, type "q", and then change back to my original working buffer.
Is there a way I can do this in code somehow? I know how to save-excursion, switch buffers, etc, but I don't know how to send the "q" to the minibuffer/emacs while I'm over in the other buffer. Thanks
The help-window-select variable might be exactly what you want.
If you set its value to true (setq help-window-select t) then the help window will automatically be selected when you open it via one of the help commands. You can then press q to quit out of it and go back to your original buffer. There are many other options so you should check those out too.
For the apropos window or any window that uses display-buffer you can use.
(add-to-list 'display-buffer-alist
'("*Apropos*" display-buffer-same-window))
display-buffer-same-window is one options of many; it opens the buffer in the current window. The other possible options can be seen by looking up the docs on the display-buffer function.
Here's my solution to this problem. I bind this command to C-c q:
(defvar my/help-window-names
'(
;; Ubiquitous help buffers
"*Help*"
"*Apropos*"
"*Messages*"
"*Completions*"
;; Other general buffers
"*Command History*"
"*Compile-Log*"
"*disabled command*")
"Names of buffers that `my/quit-help-windows' should quit.")
(defun my/quit-help-windows (&optional kill frame)
"Quit all windows with help-like buffers.
Call `quit-windows-on' for every buffer named in
`my/help-windows-name'. The optional parameters KILL and FRAME
are just as in `quit-windows-on', except FRAME defaults to t (so
that only windows on the selected frame are considered).
Note that a nil value for FRAME cannot be distinguished from an
omitted parameter and will be ignored; use some other value if
you want to quit windows on all frames."
(interactive)
(let ((frame (or frame t)))
(dolist (name my/help-window-names)
(ignore-errors
(quit-windows-on name kill frame)))))
I suggest putting (winner-mode 1) in your init file, and then using C-c<left> to call winner-undo (repeatedly, if necessary) to return to a previous window configuration.
Related
I have one frame, one window.
I use Cx 3, I now have two windows.
I use Cx Cb in order to see the list of buffers, however it opens it in another window but doesn't put the focus on it. It is even more annoying if I had opened a buffer on the 2nd window.
I would prefer to either open the buffer list in the window which currently has the focus, or temporarily change the focus to the buffer list.
First of all I want to start by saying that the ibuffer function does similary to what you want and does so in the current window, its definitely worth checking out.
Now onto your actual question. C-x C-b by default calls the function list-buffers. If you search for that command using C-h f it will show you the documentation, from there you can view the source code for the function by clicking on the underlined text that says buff-menu.el.
Now we can view the source of the list-buffers, the first function called is display-buffer. That sounds promising. We can now use C-h f once again to search for the display-buffer command. Reading though this documentation we see that the variable display-buffer-alist dictates how the display-buffer and in turn how list-buffers works. We can then see that by adding ("*Buffer List*" . display-buffer-same-window) to display-buffer-alist you will get the desired result.
All in all you simply need to put (add-to-list 'display-buffer-alist '("*Buffer List*" . display-buffer-same-window)) in your init file for your changes to take place.
Please just try one of these:
open the buffer list who currently has the focus:
(defun my:list-buffers (&optional arg)
(interactive "P")
(display-buffer (list-buffers-no-select arg) '(display-buffer-same-window)))
change the focus
(defun my:list-buffers2 (&optional arg)
(interactive "P")
(select-window (list-buffers arg)))
Often I have multiples windows carefully arranged within a frame.
However, certain command, say M-x man RET will grab one of the visible windows to display its own content. Sometimes this is annoying because the window that was taken away is one that I need to keep it visible.
e.g. I have 3 windows on screen, one useful source-code window and two useless windows. I want to keep the soure-code window visible while checking the man page. But very often Emacs just take away the code-window for the newly opened man page.
One way I can think of is to display the (chronological) open order of each window, so that I can focus point on n-th window and be confident that Emacs will grab (n+1)-th window for new content.
Is there a way to display such order, e.g. in the mode-line of each window?
Or is there another way for better control for displaying new window?
A little late to the party but as discussed in the comments, using dedicated windows is a good way to control where new content is displayed (+1 to #lawlist for bringing it up and to #phils for mentioning toggling!).
I'm pretty sure you'd be able to implement a command that toggles dedicatedness yourself at this point, but since I have the code for this handy I'll share it anyway:
(defun toggle-window-dedicated ()
"Control whether or not Emacs is allowed to display another
buffer in current window."
(interactive)
(message
(if (let (window (get-buffer-window (current-buffer)))
; set-window-dedicated-p returns FLAG that was passed as
; second argument, thus can be used as COND for if:
(set-window-dedicated-p window (not (window-dedicated-p window))))
"%s: Can't touch this!"
"%s is up for grabs.")
(current-buffer)))
(global-set-key (kbd "C-c d") 'toggle-window-dedicated)
Now, in a multi-window setup you can simply press C-c d in each window you would like to "protect".
I'll throw this example usage of display-buffer-alist into the mix, given that it was mentioned in the comments, and is indeed a general mechanism for controlling how and where buffers are displayed (even though, as Drew indicates, it is far from trivial).
Start with the help for the variable itself:
C-hv display-buffer-alist RET
From there you'll get to the help for display-buffer, and no doubt acquire some idea of the complexities involved :)
In any case, the following is an example of using a custom function to decide how to display buffers named *Buffer List*.
You can easily see that if you can write a function which can figure out how to display a buffer where you want it to, then you can use display-buffer-alist to make it happen.
(defun my-display-buffer-pop-up-same-width-window (buffer alist)
"A `display-buffer' ACTION forcing a vertical window split.
See `split-window-sensibly' and `display-buffer-pop-up-window'."
(let ((split-width-threshold nil)
(split-height-threshold 0))
(display-buffer-pop-up-window buffer alist)))
(add-to-list 'display-buffer-alist
'("\\*Buffer List\\*" my-display-buffer-pop-up-same-width-window))
A key quote regarding the ACTION functions is:
Each such FUNCTION should accept two arguments: the buffer to
display and an alist. Based on those arguments, it should
display the buffer and return the window.
I'd like for the C-x o command (next window) to include windows in other frames as well as windows in the current frame.
Does anyone know how to pull this off? Is there another command that I should be using? Is there some snippet of elisp magic that can do this with ease?
C-x o is other-window. To go to an other frame use C-x 5 o which is other-frame.
Not sure if this is what you mean, but if you want to just cycle through buffers in the buffer list, regardless of frame:
Ctrl x→
Ctrl x←
These are bound to (next-buffer) and (previous-buffer), respectively.
This can be a first approximation.
http://www.gnu.org/software/emacs/manual/html_node/elisp/Cyclic-Window-Ordering.html
http://www.gnu.org/software/emacs/manual/html_node/elisp/Frames.html
other-window has a parameter to control how it deals with frames.
(global-set-key (kbd "C-x o") (lambda ()
(interactive)
(other-window 1 t)
(let ((nframe (window-frame (selected-window))))
(select-frame-set-input-focus nframe)
(make-frame-visible nframe))))
You must press C-x 5 o C-h to see all functions about working with frames.
Some of these function is other-frame.
I use the version 2.0 of ace-jump-mode. It takes about two minutes to understand how it works and since version 2.0 it allows to "jump" to another frame. You can jump to any character from any buffer/frame/window that you can actually see on a screen in three or four keypresses. It's very hard to beat.
It's a gigantic time saver anyway so I'd recommend checking it out because it's really convenient.
http://www.emacswiki.org/emacs/AceJump
And the "Emacs Rocks! Episode 10: Jumping around" two minutes screencast showing it in action:
http://www.youtube.com/watch?v=UZkpmegySnc
From C-h f next-window:
(next-window &optional WINDOW MINIBUF ALL-FRAMES) ...
ALL-FRAMES nil or omitted means consider all windows on WINDOW's
frame, plus the minibuffer window if specified by the MINIBUF
argument. If the minibuffer counts, consider all windows on all
frames that share that minibuffer too. The following non-nil values
of ALL-FRAMES have special meanings:
t means consider all windows on all existing frames.
`visible' means consider all windows on all visible frames.
0 (the number zero) means consider all windows on all visible and iconified frames.
A frame means consider all windows on that frame only.
Anything else means consider all windows on WINDOW's frame and no
others.
Somewhat ironically, other-window supports this as well, as it uses next-window. Unfortunately, I don't know of a way to pass non-numeric arguments interactively, but a simple function should do the trick:
(defun my-other-window (count)
(interactive "p")
(other-window count t))
You say "Is there a way to cycle through windows regardless of what frame they're in? That's really what I'm looking for?"
Yes, there is, with Icicles.
What you request is what command icicle-select-window does when you use a prefix arg. If you want that behavior always, you can define your own command that does it without a prefix arg:
(defun my-select-window ()
"Select window by name. Windows of all visible frames are candidates."
(interactive)
(let ((current-prefix-arg 1)) (icicle-select-window)))
You are prompted for the window name. But if you just want to cycle, without narrowing the candidates by typing part of the name, then just use C-down to get the window you want.
(A window name is the name of its displayed buffer, but suffixed as
needed by [NUMBER], to make the name unique. For example, if you have
two windows showing buffer *Help*, one of the windows will be called
*Help*[2] for use with this command.)
When switching buffers with emacs ido mode enabled, a list of completions are displayed in the minibuffer. It appears there is a "feature" that buffers that are already open are put to the end of the list. I, however, often open the same buffer in multiple panes.
Is there a way to either turn this "feature" off, or alternatively do the opposite: have the buffers that are already open be at the front of the completion list?
The main point of ido mode is that you don't use arrows to navigate between buffers in the minibuffer. Instead you type the part of the buffer's name. In this case it doesn't matter where the buffer is in the list.
This is not possible unless you want to wade deep in ido's intestines.
As eGlyph already said: You're likely using ido wrongly (and there's also C-s for <right> and C-r for <left>; no need for arrow keys).
But you can define command for choosing among the already shown buffers (here only from the current frame, if you want all shown buffers you have to collect the windows first via `frame-list):
(defun choose-from-shown-buffers ()
(interactive)
(let ((buffers (mapcar (lambda (window)
(buffer-name (window-buffer window)))
(window-list))))
(pop-to-buffer (ido-completing-read "Buffer: " buffers))))
This is probably a very naive Emacs question - I'm new to it.
When I'm evaluating a lisp expression, if there's an error the debugger automatically comes up in another window. If I have *scratch* and *info* open (the former for trying out lisp and the latter for reading about it), then the debugger opens up in the window that *info* was in. At the moment, I have to switch to that window, then change it back to *info*, before returning to *scratch*. (The same thing happens if I do C-x C-b for a list of buffers.) I'm guessing there has to be a way to just close that window without this long sequence of commands. Can anyone enlighten me?
At least here on my emacs (22.3), when the debugger pops up, its window becomes the active one. There, pressing q just quits the debugger, if that's what you want. At that point, it also gets out of recursive editing.
From what I understand, you want to close the buffer in the other window without moving your cursor from the current window.
I don't any existing function does that, so I rolled my own.
(defun other-window-kill-buffer ()
"Kill the buffer in the other window"
(interactive)
;; Window selection is used because point goes to a different window
;; if more than 2 windows are present
(let ((win-curr (selected-window))
(win-other (next-window)))
(select-window win-other)
(kill-this-buffer)
(select-window win-curr)))
You can bind it to something like "C-x K" or some other somewhat difficult-to-press key so you won't press it by mistake.
(global-set-key (kbd "C-x K") 'other-window-kill-buffer)
I use this a LOT! (for Help buffers, Compilation buffers, Grep buffers, and just plain old buffers I want to close now, without moving the point)
I'm usually using the delete-other-windows command. C-x 1.
It's so regullar, that I rebinded to F4.
Official docs: https://www.gnu.org/software/emacs/manual/html_node/emacs/Change-Window.html#Change-Window
HTH
Using winner mode, you can use the keybinding C-C left arrow to return to the previous window configuration. Of course, this doesn't actually kill the new buffer, but it does hide it.
I think you're looking for C-x 4 C-o, which displays a buffer in the "other" window without switching to it.
As mentioned above, in the case of the backtrace buffer you probably want to exit from it with q, to get out of the recursive edit.
Try to use popwin-mode. It is really good about closing windows automatically.
I want to describe how mechanism work|
You open undo-tree-visualize than you find your correct branch, after that when you change your active window which has cursor via switch-window undo-tree related buffer will close other window automatically.
One possible solution is to use a window management package. Store your "preferred" window arrangement, and after the debugger/buffer window pops up and you're done with it, revert to your preferred arrangement.
There are a bunch of packages to choose from, see: switching window configurations on the wiki.
Additionally, you might want to figure out the actions you commonly do that trigger the extra (unwanted) window popping up, and use that to trigger saving your window configuration just before the window pops up.
If you want to roll your own (it's pretty easy), you can just save off the window configuration, and restore it like so:
(setq the-window-configuration-i-want (current-window-configuration))
(global-set-key (kbd "<f7>")
(lambda () (interactive)
(set-window-configuration the-window-configuration-i-want)))
The trick is figuring out where to put the setting of the-window-configuration-i-want.
Thanks go to #spk for a nice function. I merely modified it to also close the window too and bound it to the already nice set of window control functions found in evil-windows (via "C-w"):
(use-package evil
:bind (:map evil-window-map ("O" . delete-most-recent-window))
:preface
(defun delete-most-recent-window ()
"Kill the buffer in the most recent window."
(interactive)
;; Window selection is used because point goes to a different window
;; if more than 2 windows are present
(let ((win-curr (selected-window))
(win-other (next-window)))
(select-window win-other)
(kill-this-buffer)
(delete-window) ; <-- Added this
(select-window win-curr))))