iflipb lets you flip between recently visited buffers in a way that resembles what Alt-(Shift-)TAB does in Microsoft Windows and other graphical window managers. iflipb treats the buffer list as a stack, and (by design) it doesn’t wrap around. This means that when you have flipped to the last buffer and continue, you don’t get to the first buffer again. This is a good thing. (If you disagree and want wrap-around, set iflipb-wrap-around to non-nil.)
iflipb provides two commands: iflipb-next-buffer and iflipb-previous-buffer.
iflipb-next-buffer behaves like Alt-TAB: it switches to the previously used buffer, just like C-x b RET (or C-M-l in XEmacs). However, another consecutive call to iflipb-next-buffer switches to the next buffer in the buffer list, and so on. When such a consecutive call is made, the skipped-over buffer is not regarded as visited.
While flipping, the names of the most recent buffers are displayed in the minibuffer, and the currently visited buffer is surrounded by square brackets and marked with a bold face.
A key thing to notice here is that iflipb displays the buffer contents after each step forward/backwards (in addition to displaying the buffer names), unlike for instance the buffer switching model of ido-mode where only the buffer names are displayed.
iflipb-previous-buffer behaves like Alt-Shift-TAB: it walks backwards in the buffer list.
Here is an illustration of what happens in a couple of different scenarios:
| Scenario 1 | Minibuffer display | Actual buffer list |
| Original | A B C D E | |
| Forward flip | A [B] C D E | B A C D E |
| Forward flip | A B [C] D E | C A B D E |
| Forward flip | A B C [D] E | D A B C E |
| Scenario 2 | Minibuffer display | Actual buffer list |
| Original | A B C D E | |
| Forward flip | A [B] C D E | B A C D E |
| Forward flip | A B [C] D E | C A B D E |
| Backward flip | A [B] C D E | B A C D E |
| Scenario 3 | Minibuffer display | Actual buffer list |
| Original | A B C D E | |
| Forward flip | A [B] C D E | B A C D E |
| Forward flip | A B [C] D E | C A B D E |
| [Edit buffer C] | C A B D E | |
| Forward flip | C [A] B D E | A C B D E |
iflipb by default ignores buffers whose names start with an asterix or space. You can give a prefix argument to iflipb-next-buffer to make it flip between more buffers. See the documentation of the variables iflipb-ignore-buffers and iflipb-always-ignore-buffers for how to change this.
Direct link to iflipb.el: https://github.com/jrosdahl/iflipb/raw/master/iflipb.el
Source code repository: https://github.com/jrosdahl/iflipb
To load iflipb, store iflipb.el in your Emacs load path and put
(require 'iflipb)
in your .emacs or equivalent.
This file does not install any key bindings for the two commands. I personally use M-h and M-H (i.e., M-S-h) since I don’t use the standard binding of M-h (mark-paragraph) and M-h is quick and easy to press. To install iflipb with M-h and M-H as keyboard bindings, put something like this in your .emacs:
(global-set-key (kbd "M-h") 'iflipb-next-buffer) (global-set-key (kbd "M-H") 'iflipb-previous-buffer)
Another alternative is to use C-tab and C-S-tab:
(global-set-key (kbd "<C-tab>") 'iflipb-next-buffer) (global-set-key (if (featurep 'xemacs) (kbd "<C-iso-left-tab>") (kbd "<C-S-iso-lefttab>")) 'iflipb-previous-buffer)
Or perhaps use functions keys like F9 and F10:
(global-set-key (kbd "<f10>") 'iflipb-next-buffer) (global-set-key (kbd "<f9>") 'iflipb-previous-buffer)
iflipb was inspired by cycle-buffer.el. cycle-buffer.el has some more features, but doesn’t quite behave like I want, so I wrote my own simple replacement.
Have fun!
Joel Rosdahl <joel@rosdahl.net>
After several days of using other buffer switching packages, I’ve settled down on yours. Thanks. neat implementation. Sometimes it would be more convenient if buffer switching action is stopped by timer(without inputing any command instead). For example, after pressing C-TAB, I’m frequently looking a buffer contents for a while… and then want to go back by just pressing another C-TAB. Your original implementation need another command’s to predicate whether last action is relevant to iflipb’ing or not.
Heres’ my customization for iflipb but please be noted that I’m not that good at elisp.
(when (my-try-require 'iflipb) ;; wrap is better?! trying.. (setq iflipb-wrap-around t) ;; auto off function iflipb'ing (setq my-iflipb-auto-off-timeout-sec 1) (setq my-iflipb-auto-off-timer-canceler-internal nil) (setq my-iflipb-ing-internal nil) (defun my-iflipb-auto-off () (message nil) (setq my-iflipb-auto-off-timer-canceler-internal nil my-iflipb-ing-internal nil) ) (defun my-iflipb-next-buffer (arg) (interactive "P") (iflipb-next-buffer arg) (if my-iflipb-auto-off-timer-canceler-internal (cancel-timer my-iflipb-auto-off-timer-canceler-internal)) (run-with-idle-timer my-iflipb-auto-off-timeout-sec 0 'my-iflipb-auto-off) (setq my-iflipb-ing-internal t) ) (defun my-iflipb-previous-buffer () (interactive) (iflipb-previous-buffer) (if my-iflipb-auto-off-timer-canceler-internal (cancel-timer my-iflipb-auto-off-timer-canceler-internal)) (run-with-idle-timer my-iflipb-auto-off-timeout-sec 0 'my-iflipb-auto-off) (setq my-iflipb-ing-internal t) ) (global-set-key (kbd "<C-tab>") 'my-iflipb-next-buffer) (global-set-key (kbd "<C-S-tab>") 'my-iflipb-previous-buffer) (defun iflipb-first-iflipb-buffer-switch-command () "Determines whether this is the first invocation of iflipb-next-buffer or iflipb-previous-buffer this round." (not (and (or (eq last-command 'my-iflipb-next-buffer) (eq last-command 'my-iflipb-previous-buffer)) my-iflipb-ing-internal))) )