In vanilla Emacs, I have to do
C-x b and then manually type out the buffer name to switch. If I forget the name of the buffer, I have to hit
TAB to list possible completions. Is there anything I can do to make this process faster?
There is ido mode that should help.
put this in your init file, to activate ido mode by default:
C-x b will show you a list of candidates.
Put this in your init file, if you prefer the items being displayed vertically:
(setq ido-separator "\n")
Courtesy of ergoemacs
Let me also suggest this post talking about switch to previous/next buffer.
I've recently started using
C-x <left> and
C-x <right>. Those are both standard Emacs bindings—nothing to configure. Left takes you back to the previous buffer (initially the same as
C-x b RET) but doing it again takes you to the 3rd most recently visited buffer. If you're popping back and forth between 3 or 4 buffers a lot then I find it a lot easier than trying to remember buffer names.
Also I just discovered
C-x C-<left> and
C-x C-<right> are bound to the same functions so that you can just hold down the control key and alternate between x and the arrows to flip through buffers. Pretty nice!
You could use Helm.
In my setup, I have switched
C-x b for
M-l. This allied with
helm-buffers-list, makes the process pretty fast, at least for me.
Just to add tweaks that I use with already mentioned Ido:
(require 'ido) (require 'ido-hacks) (require 'flx-ido) (require 'ido-vertical-mode) (ido-mode 1) (flx-ido-mode 1) (ido-hacks-mode 1) (ido-everywhere 1) (ido-vertical-mode 1) (setq ido-enable-flex-matching t ido-use-filename-at-point 'guess ido-vertical-define-keys 'C-n-C-p-up-down-left-right))
I have combined it with
key-chord-mode and hit
so for quick jump:
(key-chord-define-global "so" 'ace-window)
All of the above mentioned packages are available via the package manager from Melpa.
As @kuanyui says in a comment,
previous-buffer are very quick, if you have only a few buffers to cycle among. (For more than a few, and for more buffer-choosing features, I use
However, by default,
previous-buffer are on a prefix key,
That means that they are not repeatable: you cannot just hit
C-x <right> <right> <right>.... You must instead either bind these commands to different, repeatable keys, or you must use
C-x <right> C-x <right> C-x <right>..., which is not very quick.
For repeatable versions of these commands, load library
misc-cmds.el and remap the vanilla, unrepeatable versions to the repeatable ones defined there:
(global-set-key [remap previous-buffer] 'previous-buffer-repeat) (global-set-key [remap next-buffer] 'next-buffer-repeat)
(Similarly, in the same library you will find a version of
undo that is repeatable even when on a prefix key:
BTW, you can make pretty much any command repeatable (even on a prefix key), by using function
misc-cmds.el). This is all that was needed to define the repeatable version of
(defun previous-buffer-repeat () "Switch to the previous buffer in the selected window. You can repeat this by hitting the last key again..." (interactive) (require 'repeat nil t) ; Library `repeat.el' is in Emacs 22.1 and later (repeat-command 'next-buffer))
Use helm-buffer-list or helm-mini for visually selecting buffer entry and fuzzy matching. It can do a lot of things outside of switching buffers. You should see the demo in the link.
Others have discussed packages that are useful to make life easier with regards to buffer/window/frame switching. (I personally use
helm which is phenomenal.) I want to discuss simpler changes that can make for a more enjoyable Emacs experience.
For me, the solution to my buffer/frame woes (because I think
C-x o is the worst) was not a package; it was simply:
other-window(cycling through windows)
other-frame(cycling through frames). I actually started using frames a lot more after adding this shortcut).
- mapping other easy single-keystroke key-bindings to simple, custom functions for manipulating buffers in the visible frame. Examples include: throwing a buffer to the other window (in a 2-window set-up), toggling between the current buffer and last buffer in a given window, burying the other buffer (this one is great for replacing the
helpwindow that pops up (when reading man pages, apropos, etc) with whatever window was previously visible).
I also thought I'd share a few thoughts on key-bindings which newbies might find helpful. (Sorry if this is the wrong place.) I don't have specific suggestions but, rather, a "philosophy" that lets me maintain an effective set of keybindings for myself.
Unfrequently used commands do not deserve easy key-bindings.
keyfreq.eland see what you really use a lot. I use a survival-of-the-fittest method to decide which commands are awarded the most valuable real-estate on my keyboard.
- Don't be afraid to get rid of the default Emacs keybindings, some of which are just absurd.
C-\is a great shortcut (for the reasons discussed in #2)...and it would be a crime to leave it mapped to its default command:
change-input-method. (Maybe some of you use it a lot, I certainly don't.)
The following factors determine the ease and speed of a keyboard shortcut (starting with the most important):
- Continuously pressing the modifier key (whatever it may be,
Meta, etc.). For example, it's way faster for me to hit
C-c C-l C-pthan it is to hit
C-x o. I personally find it very inconvenient to have to lift off the
Ctrlkey in between successive key-strokes of a given key sequence; it's so much easier just to keep mashing the modifier button (in this case,
Ctrl). (This specific example might be influenced by the fact that I've remapped my
Ctrlkey and my
- Alternation in your friend. It's way faster for me to hit
C-c C-l C-pthan it is to hit
C-p C-' C-;. (Give it a try and it should be obvious.) Generally speaking, it's a lot easier to use keystroke sequences that use alternating hands (or, at the least, alternating fingers on the same hand).
- Degree of departure from standard hand position. This doesn't apply to the hunt-and-peck enthusiasts out there. But for the rest of us, our most frequently used keyboard shortcuts should allow us to return to our standard touch-typing position quickly and easily.
- Continuously pressing the modifier key (whatever it may be,
Just a couple of thoughts that I thought might be helpful to newbies. I may add some more later.
bs.el to switch buffers quickly. Both modes
are included with Emacs.
windmove.el- switches to a window (a buffer that is currently displayed) in a specified direction, e.g. left, right, up, down.
bs.el- I use
bs-cycle-previousto switch to the next buffer that isn't currently shown in a window.
You can setup windmove with
will bind the appropriate commands to
Shift-Right Arrow, etc.
For setting up
bs.el, something like this will work:
(global-set-key [(f9)] 'bs-cycle-previous) (global-set-key [(f10)] 'bs-cycle-next)
The fastest way to switch buffers I'm aware of is with
ace-jump-buffer. One key stroke opens the buffer menu and then select the letter next to the buffer you want with
ace-jump-line-mode. This works best for the 26 or so most recent buffers. For switching to buffers farther back in your usage history,
ido-switch-buffer is always a good choice.
Widely speaking, there are 2 ways to switch buffers and most of the solutions will fall into one of these.
- Using the mini buffer
This is what
C-x b does by default. Ido gives you nice auto completion so that
you don't need to TAB TAB TAB so much. Projects like helm, projectile etc makes
it easier by giving you abilities to work with files in a project etc, and along
with ido, they can be pretty useful.
- An entire buffer with all items listed.
This is useful when you have so many buffers and you want a list of them all. You can go up and down the buffer, and press enter to visit a particular file. Ibuffer is pretty good for that.
I use both and this is how you can set it up.
(global-set-key (kbd "C-x C-b") 'ido-switch-buffer) (global-set-key (kbd "C-x b") 'ibuffer)`
Addition to ido, I have following setup.
In case of evil mode, use following key bindings to switch buffers
(define-key evil-normal-state-map (kbd "C-j") 'next-buffer) (define-key evil-normal-state-map (kbd "C-k") 'previous-buffer) (define-key evil-normal-state-map (kbd "C-S-h") 'evil-window-left) (define-key evil-normal-state-map (kbd "C-S-j") 'evil-window-down) (define-key evil-normal-state-map (kbd "C-S-k") 'evil-window-up) (define-key evil-normal-state-map (kbd "C-S-l") 'evil-window-right)
Set buffer name as title of window. This will help you when navigating with above keybindings
(setq frame-title-format "%b")
If you are using evil mode, you can try
evil-leader. Bind frequently used keys to leader. e.g You can bind
(global-evil-leader-mode) (evil-leader/set-leader ",") (evil-leader/set-key "b" 'switch-to-buffer)
Bind dired mode to
C-<f8>. Now when you want to open file in directory, press
C-<f8>, navigate to file name & press
RET. So dired buffer will be killed immediately.
(global-set-key (kbd "C-<f8>") (lambda () (interactive) (dired default-directory))) (put 'dired-find-alternate-file 'disabled nil)
recentfmode to navigate recent files.
One last important point is - use ergonomic mechanical keyboard. So you can press 'ctrl' key easily and quickly with wrist instead of hurting pinky.
Hope this might help someone.
As you can see from the other answers there are many ways to streamline this particular task. I personally use Lusty Emacs as my buffer switching apparatus as it handles fuzzy completion quite nicely. This minimises the number of key-strokes required to select the new buffer, for example I need only type oxr to switch to ox-reveal.el, or even just o the second time round as it does track history of switches as well.
If you want to just keep brushing through your buffers, add this to your init file:
(bind-key* "M-l" 'next-buffer) (bind-key* "M-k" 'previous-buffer)
You do need the bind-key package and you can change the key-bindings to your wish but I found these keybindings to be the most comfortable. Before adding this snippet, you do need to require bind-key by,
I using C-Tab and C-S-Tab like general applications.
(defun change-buffer-until-normal (change-fn) (let (current (buffer-name)) (funcall change-fn) (while (and (string-prefix-p "*" (buffer-name)) (not (eq current (buffer-name)))) (funcall change-fn)))) (defun my-next-buffer () (interactive) (change-buffer-until-normal 'next-buffer)) (defun my-prev-buffer () (interactive) (change-buffer-until-normal 'previous-buffer)) (global-set-key [C-tab] 'my-next-buffer) (global-set-key [C-S-iso-lefttab] 'my-prev-buffer)
This is not a very elegant solution (since it uses macros instead of functions) and it does not answer how to jump to any buffer quickly, but only how to jump to buffers used recently. But it works very well for me:
I have a series of macros using
ido-switch-buffer to jump to the previous buffer, the buffer before that, the buffer before that, etc. And I bound those macros to key bindings that I find convenient.
To jump to the last buffer:
(fset 'my-goto-previous-buffer [?\C-x ?b return])
To jump to the penultimate buffer:
(fset 'my-goto-previous-buffer [?\C-x ?b ?\C-n return])
To jump to the antepenultimate buffer:
(fset 'my-goto-previous-buffer [?\C-x ?b ?\C-n ?\C-n return])
Etc. (you can ad as many
?\C-n as you want to go as far back the history of visited buffers as you want).
There is a built-in function to jump to the previous buffer, but the advantage of using macros with
ido-switch-buffer is that you can customize the variable
ido-ignore-buffers to remove special buffers such as
*scratch* and any other unwanted buffer from the list. That way, the only buffers you jump to are the ones you are really interested in jumping to.
On my VM, C-x ALT-RIGHT / LEFT is too slow. I have to wait for C-x to register in the status bar before I can do anything else. plus its just too many keys. So i mapped C-TAB and C-M-TAB to next and prev buffer as that's what I do in most windows programs anyway. Its easy to do from within emacs:
M-x takes you to the status bar.
global-set-key which will prompt you for the key sequence you wish to bind (
C-TAB) and then for the command you wish to bind it to (
next-buffer). That's it!