4

Is there a way to switch between buffers without having to go through the buffer-list, or writing the name of the buffer that I want to switch to? More specific I wonder if emacs can tab between buffers much like how it is working in notepad++

Drew
  • 29,895
  • 7
  • 74
  • 104
starcorn
  • 8,261
  • 23
  • 83
  • 124
  • 2
    This question is also asked (and answered differently) over on superuser: http://superuser.com/questions/208871/emacs-tab-between-buffers – jwernerny Nov 09 '10 at 13:50
  • 1
    I tried many, and stopped finally on a simple iflip package http://www.emacswiki.org/emacs-ja/iflipb With time though, you will find out that there is hardly a better switching than "C-x b" + ido-mode – VitoshKa Nov 09 '10 at 21:18

4 Answers4

4

Emacs 22.1 and higher supports the previous-buffer (C-x <left arrow>) and next-buffer (C-x <right arrow>) commands.

These two commands can be added to older Emacsen using this script.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
4

I've never ended up using C-x <right> or C-x <C-right> much, because I find them cumbersome to repeat if I want to cycle past more than one buffer, so I've just written a couple of functions to let you continue to switch to next/previous-buffer with <C-right> and <C-left> if the last command was also a next/previous-buffer command.

e.g. C-x <C-left> <C-left> <C-left> <C-right> <C-left> would take you back three buffers, forward one, and backward again.

I've made the assumption that <C-left> & <C-right> are usually bound to forward/backward-word, and am calling those explicitly as the fallback.

(defun my-forward-word-or-buffer-or-windows (&optional arg)
  "Enable <C-left> to call next-buffer if the last command was
next-buffer or previous-buffer, and winner-redo if the last
command was winner-undo or winner-redo."
  (interactive "p")
  (cond ((memq last-command (list 'next-buffer 'previous-buffer))
         (progn (next-buffer)
                (setq this-command 'next-buffer)))
        ((memq last-command (list 'winner-redo 'winner-undo))
         (progn (winner-redo)
                (setq this-command 'winner-redo)))
        (t ;else
         (progn (forward-word arg)
                (setq this-command 'forward-word)))))

(defun my-backward-word-or-buffer-or-windows (&optional arg)
  "Enable <C-left> to call previous-buffer if the last command
was next-buffer or previous-buffer, and winner-undo if the last
command was winner-undo or winner-redo."
  (interactive "p")
  (cond ((memq last-command (list 'next-buffer 'previous-buffer))
         (progn (previous-buffer)
                (setq this-command 'previous-buffer)))
        ((memq last-command (list 'winner-redo 'winner-undo))
         (progn (winner-undo)
                (setq this-command 'winner-undo)))
        (t ;else
         (progn (backward-word arg)
                (setq this-command 'backward-word)))))

(global-set-key (kbd "<C-left>") 'my-backward-word-or-buffer-or-windows)
(global-set-key (kbd "<C-right>") 'my-forward-word-or-buffer-or-windows)
phils
  • 71,335
  • 11
  • 153
  • 198
1

Although the following suggestion does use the buffer-list, Ivy (or Helm) and evil, I think it is a nice, nearly equivalent alternative to the common Ctrl-TAB way (incl. updating the buffer list) when using e.g. Spacemacs. Of course the commands can be adapted to your personal config (vanilla Emacs)

(evil-global-set-key 'motion (kbd "<C-tab>") 'ivy-switch-buffer)
(evil-global-set-key 'insert (kbd "<C-iso-lefttab>") 'ivy-switch-buffer)
(define-key ivy-mode-map (kbd "<C-tab>") 'ivy-next-line-and-call)
(define-key ivy-mode-map (kbd "<C-iso-lefttab>") 'ivy-previous-line-and-call)

or for the equivalent for Helm

(evil-global-set-key 'motion (kbd "<C-tab>") 'helm-buffers-list)
(evil-global-set-key 'motion (kbd "<C-iso-lefttab>") 'helm-buffers-list)
(define-key helm-map (kbd "<C-tab>") 'helm-follow-action-forward)
(define-key helm-map (kbd "<C-iso-lefttab>") 'helm-follow-action-backward)

The keystring for the last command means Ctrl-Shift-tab in my keyboard. You can find the one to use with C-h k C-S-tab.

Indeed you still need to press RET or C-l after releasing <C-tab>.

For evil users using Helm, a possibly even nicer alternative is to bind helm-buffers-list to C-j and C-k, then set helm-follow-mode-persistent to t, and in the helm-buffers-list buffer activate helm-follow-mode with C-c C-f. Now you can switch (and preview) buffers with C-j and C-k.

dalanicolai
  • 335
  • 2
  • 13
1

(I use Icicles for buffer switching, myself, but...)

If you want to repeat the previous command any number of times, just use C-x z z z z z z... In this case, e.g., C-x left C-x z z z...

If that's too cumbersome, bind (next|previous)-buffer to other, repeatable keys, as others have suggested.

But repeatable keys are in great demand. If you don't want to waste any, you can even put such commands on a prefix key, so that, e.g., you can do, e.g., C-x left left left... Here's a trick to do that (taken from the Bookmark+ code):


    (defun my-repeat-command (command)
      "Repeat COMMAND."
      (let ((repeat-message-function  'ignore))
        (setq last-repeatable-command  command)
        (repeat nil)))

    (defun my-next-whatever-repeat (arg)  ; `C-x right'
      "Jump to the Nth-next whatever.
    N defaults to 1, meaning the next whatever.
    Plain `C-u' means start over at the first whatever (and no repeat)."
      (interactive "P")
      (require 'repeat)
      (my-repeat-command 'next-whatever))

    (define-key ctl-x-map [right] 'my-next-whatever-repeat 
Drew
  • 29,895
  • 7
  • 74
  • 104