emacs list-buffers behavior - emacs

In GNU emacs, every time I hit Ctrl-x Ctrl-b to see all of my buffers, the window is split to show the buffer list, or if I have my window already split in 2 (for instance, I will have a shell running in the lower window), the buffer list appears in the other window.
My desired behavior is for the buffer list to appear in my active window so that I can select the buffer I want and continue to working in the same window, rather than having to Ctrl-x Ctrl-o to the other buffer, selecting the buffer (with enter) and editing that buffer in the other window... I've googled for it but it doesn't seem to be a common desire? I wonder if anyone has an elispy (or other) solution?

You might want to rebind C-x C-b to invoke buffer-menu rather than list-buffers:
(global-set-key "\C-x\C-b" 'buffer-menu)

Just customize the variable same-window-regexps. display-buffer will display any buffer whose name matches a regexp there in the currently-selected window.
(You will want to add "[*]Buffer List".)

not exactly a solution, but ido-mode provides a different and powerful way to interact with buffers. C-x b will then show a list of all the open buffers, and the one you select will open in the current window.

Strangely, there isn't an answer here about ibuffer.
I would recommend this as a standard change for the majority of Emacs users:
(global-set-key (kbd "C-x C-b") 'ibuffer)
ibuffer is a very advanced replacement for the default buffer listing, and not only features the exact behaviour requested, but provides a wealth of other functionality.
I listed a few ibuffer filtering and grouping basics in
Emacs: help me understand file/buffer management, but be sure to read the documentation for details.

Try to add
(ido-mode 1)
to your .emacs, and enjoy the result :)

If you like the original buffer list (as opposed to the 'buffer-menu solution proposed by others), you can use this:
(global-set-key (kbd "C-x C-b") 'my-list-buffers)
(defun my-list-buffers (&optional files-only)
"Display a list of names of existing buffers.
The list is displayed in a buffer named `*Buffer List*'.
Note that buffers with names starting with spaces are omitted.
Non-null optional arg FILES-ONLY means mention only file buffers.
For more information, see the function `buffer-menu'."
(interactive "P")
(switch-to-buffer (list-buffers-noselect files-only)))
Which is the same function as before, only in the current window.

I highly recommend bs.el from http://www.geekware.de/software/emacs/ Install it and:
(require 'bs)
(add-hook 'bs-mode-hook 'turn-on-font-lock)
(global-set-key "\C-x\C-b" 'bs-show)
It manages buffers and window configuration in the right way, so everything requires minimum number of keystrokes.

Not sure where I got this but:
;;; Faster buffer switching
(global-set-key [(C tab)] 'buffer-menu)
This makes Ctrl-Tab display all buffers in the current window. You can then navigate to a buffer and hit Enter to visit it.

Another not-what-you-asked-for solution: don't select the desired buffer with the mouse, rather finish typing its name (use tab-completion to reduce keystrokes and increase accuracy), then hit return. The buffer list will disappear, and the new file will be open in the previously active window.

Related

How can I get back the "natural" order in the Buffer List?

With C-x C-b the buffer list is displayed. First in it's natural order with most recently used buffers on top, and buried buffers at the bottom.
There, I can now sort the Buffer by name, size, mode and file. But once I click on such an option I cannot go back to the original ordering.
Also killing the buffer and recreating it does not change that order. (Using 25.2)
So how can I get that ordering back without restarting emacs?
There is another mode that's nowadays built-in to Emacs that can be used to display the buffer list: ibuffer-mode.
If you are not using it already, you can experiment with M-x ibuffer and find out its capabilities with C-h m. Note that in particular, it can sort the buffer list in various ways, one of which is by recency with s v, which is what the OP asked for; but note also that it has many other ways to sort that make it very flexible.
Once you are convinced that that's the way to go, you can redefine the C-x C-b keybinding in your init file with:
(global-set-key (kbd "C-x C-b") 'ibuffer)
I did that a long time ago and have never looked back. IMO, it should be the default: that may come to pass, but AFAIK that is still not the case.
Sorting order goes away as expected when I kill buffer named *Buffer List* and reopen using C-x C-b (Using emacs 27.1 & 28.1). From the EmacsWiki
Once sorted, there is no nice way to restore the default MRU sort. You
have to ‘kill-buffer’ the buffer menu buffer, and then re-open it.
(Sorting sets the variable ‘tabulated-list-sort-key’ in
tabulated-list.el. Its default is ‘nil’. No way to restore the nil
value is provided.)
May be worth adding a custom function which can disable the sort without closing the buffer.
(defun disable-buffer-sort()
(interactive)
(save-excursion
(set-buffer (get-buffer "*Buffer List*"))
(setq tabulated-list-sort-key 'nil)
(revert-buffer)
))
(disable-buffer-sort)
As #NickD mentioned in other answer ibuffer-mode is also a good alternative with more features.

How to switch between visible buffers in emacs?

If I am in split-screen viewing 2 different buffers on Emacs and the cursor is on the top buffer, what's a quick way to move the cursor to the bottom buffer?
Bonus question: if I know a command, is there an easy way to identify what key-combo it's bound to, if any?
To switch to other buffer use: C-x o.
Describe key: C-h k.
Here is a better solution when you open more than two windows(buffers) in one frame:
(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <left>") 'windmove-left)
(global-set-key (kbd "C-x <right>") 'windmove-right)
Now, you can use C-x UP/DOWN/LEFT/RIGHT to go to the above/nether/left/right buffer when you have three or more in one frame, they are more precise than 'other-window and you don't need to install any package.
You even CAN make it to cycle the buffers in the direction(vertically/horizontally) with one of the above shortkeys with configuration in .emacs/init.el file, but I don't recommend it(besides I don't remember it anymore, you can google it if you want).
Of course, you can use other shortkeys other than the ones I use in my .emacs.
You may also be interested in WindMove, which enables "directional" window navigation with <S-up>, <S-right> etc.
With respect to the bonus question, if you know the command (other-window), and you invoke it with M-x other-window, Emacs will show a brief message in the minibuffer stating: "You can run the command `other-window' with C-x n".
There is also M-x where-is which prompts for a command and gives you the current bindings that result in that command (if any).
There is a tutorial that's shipped with Emacs. It actually has the answer to your question (see the section MULTIPLE WINDOWS about 80% into the tutorial). The tutorial can be accessed via C-h t, or M-x help-with-tutorial. There's also a link to the tutorial on the initial splash screen of Emacs. Right below the link to the tutorial is a link to the on-line Emacs Guided Tour. The tutorial walks you through basic editing/movement commands, the guided tour is more of an introduction to what Emacs has to offer.
If you want to navigate among only buffers that are currently displayed, then you really want to navigate among the windows they are displayed in. This gives you a way to do that, using window/frame names that are the same as the buffers:
See Better window navigation in Emacs?

How do you list and manage hidden buffers?

When calling switch-to-buffer, in the minibuffer, when you press SPACE, you can see hidden buffers that you normally don't see, like *Minibuf-0* for example.
How could you list those hidden buffers into the list of buffers shown by list-buffers ? If it's not possible using list-buffers, how do you manage them ?
You can tweak the function to show all buffers, like so:
(defun list-all-buffers (&optional files-only)
"Display a list of names of existing buffers.
The list is displayed in a buffer named `*Buffer List*'.
Non-null optional arg FILES-ONLY means mention only file buffers.
For more information, see the function `buffer-menu'."
(interactive "P")
(display-buffer (list-buffers-noselect files-only (buffer-list))))
(define-key ctl-x-map "\C-b" 'list-all-buffers)
ElectricBufferList does it for me:
(global-set-key "\C-x\C-b" 'electric-buffer-list)
Shows all buffers.
I prefer bs-show to list-buffers and electric-buffer-list.
bs-show can be configured to display all buffers by changing the value of the variable bs--intern-show-never
I think though that because they begin with a space, they're not supposed to be easily visible to you. They're more like internal variables, and manipulating them may make things start misbehaving pretty quickly. Best to just ignore them for the most part.
In any buffer do...
(buffer-list) C-x C-e
The list will now be in *messages*
now leave those hidden buffers alone ;-)

Is there any way to get Ediff to not open its navigation interface in an external window?

Not being using Emacs all that long (v23, windows) and just discovered M-x ediff. Fantastic.
Although I'm not to keen on the fact it opens its help/navigation in a separate frame/window, meaning that if I lose focus to that window, the single key shortcuts don't work.
For example as soon as I press ? to expand the window, it shifts over top of my current window, so I have to pick up my mouse and move it to another screen. Then if I lose focus to that window and press p / n / j or any other key to work with the diff, it inserts it into my document. So i have to undo, grab mouse, focus to other window, and repeat.
Is there any way to configure these options to show in a split instead?
I didn't know how to do it but it is usually easy to learn with Emacs. First I asked about ediff customizations:
M-x customize-apropos
ediff
I saw there is something called Ediff Window Setup Function which takes the values Multi Frame, Single Frame, or Other Function. Mine was set to Multi Frame and changed it to Single Frame and saved it for future sessions. And Voila! as they say somewhere.
Simply:
(setq ediff-window-setup-function 'ediff-setup-windows-plain)
M-x describe-variable ediff-window-setup-function will enlighten you
further.
For reference my ediff customisation is fairly simple:
(if (locate-library "ediff")
(progn
(autoload 'ediff-files "ediff")
(autoload 'ediff-buffers "ediff")
(eval-after-load "ediff" '(progn
(message "doing ediff customisation")
(setq diff-switches "-u"
ediff-custom-diff-options "-U3"
ediff-split-window-function 'split-window-horizontally
ediff-window-setup-function 'ediff-setup-windows-plain)
(add-hook 'ediff-startup-hook 'ediff-toggle-wide-display)
(add-hook 'ediff-cleanup-hook 'ediff-toggle-wide-display)
(add-hook 'ediff-suspend-hook 'ediff-toggle-wide-display)))))
From chapter Window and Frame Configuration in Ediff User's Manual:
The following variable controls how
windows are set up:
ediff-window-setup-function
The multiframe setup is done by the ediff-setup-windows-multiframe
function, which is the default on
windowing displays. The plain setup,
one where all windows are always in
one frame, is done by
ediff-setup-windows-plain, which is
the default on a non-windowing display
(or in an xterm window). In fact,
under Emacs, you can switch freely
between these two setups by executing
the command ediff-toggle-multiframe
using the Minibuffer of the Menubar.
(custom-set-variables
...
'(ediff-window-setup-function (quote ediff-setup-windows-plain))
...)
Not that you would set the variable this way, but it allows you to know these things:
The variable you are interested in is ediff-window-setup-function
The value it needs to be set to is ediff-setup-windows-plain
You can configure the variable from customize: M-x customize-group RET ediff-window
Ediff Window Setup Function: Menu Single Frame
Note: you can avoid using the mouse to go back to the ediff control window by using M-x other-frame. Also found on C-x 5 o.
This no longer works in 2017 gnu emacs (24.5, 25.2, 2017) on windows
(setq ediff-window-setup-function 'ediff-setup-windows-plain) ; stopped working
Even
ediff-toggle-multiframe ; no longer has any effect now.
It works in emacs22.3 on windows, so I have use older emacs from 2008!

How do I close an automatically opened window in Emacs?

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))))