From: wally@Auspex.COM (Wally Bass)
Newsgroups: comp.emacs
Subject: Re: anyone got a way to cycle through buffers with a keystroke?
Keywords: buffers
Date: 7 Nov 92 01:46:39 GMT
Organization: Auspex Systems, Santa Clara

In article <EJH.92Nov4132905@khonshu.colorado.edu> ejh@khonshu.colorado.edu (Edward J. Hartnett) writes:
>
>Hi. I often have maybe 5 or 10 programs and other files open at once,
>and switch back and forth more or less randomly. It's very annoying
>that I have to tyep out the buffer name I want each time (even with
>tab completion). Does anyone out there have any elisp code that would
>allow me to cycle through the buffers with a keystroke? So I'd hit a
>key and the buffer would switch to the next one, then again and it
>would go to the next, etc. Then I could just pop pop pop on the key
>until the buffer I wanted came up.
>--
>Edward Hartnett			ejh@khonshu.colorado.edu

The following code cycles thru the ring of buffers with a
single key, but also does a little bit more. Suppose you bind
the function 'go-buffer-ring' to your 'foo' key, and 'buf-xcld-key'
to your 'bar' key. Then

  pressing 'bar' places (or removes) (toggles) the current buffer name
        in a list of names which will be excluded when cycling thru
        buffers with the 'foo' key. A message is also displayed which
        indicates the new state of the current buffer (e.g., 'included'
        or 'excluded')
  (prefix-key (i.e., C-u), 'bar') clears the exclude list
  repeatedly pressing 'foo' cycles thru buffers in the buffer list,
        but skips any buffers which are on the exclude list. It also
        displays a message indicating the complete file name or the
        directory name (for dired buffers) of the new buffer, or displays
        'none' if all buffers are currently excluded.
  repeatedly pressing (prefix-key, 'foo') cycles thru buffers,
        but ONLY displays buffers which ARE on the exclude list. It
        also displays pathnames or 'none' as appropriate.

Note that, when you alternately press ('foo') and (prefix-key,'foo'),
you will toggle between the 'first' file in each category (excluded
or included), but you will not advance thru either set. This mode
is also useful for toggling between exactly two files.

(This is inter-twined with other stuff in my .emacs file. I think/hope
I extracted a complete and coherent chunk.)

-------------------------------
(defvar buffer-exclude-list nil
  "list of buffers not to be included in go-buffer-ring")

(defun identify ()
  (cond
    ((eq major-mode 'dired-mode) (message "dir: %s" default-directory))
    (buffer-file-name (message "file: %s" buffer-file-name))
    (t (message "")) ) )

(defun chk-buf-xcld-lst (arg purge)
  "Checks if buffer is on exclude list. With non-nil 2nd arg, also removes
the buffer name from the list if found"
  (let ((lp buffer-exclude-list)
        (prev nil)
	(ans nil) )  
     (while (and lp (not ans))
       (if (equal arg (car lp))
	 (setq ans t)
         (setq prev lp)
	 (setq lp (cdr lp)) ) )
     (if (and purge ans)
       (if prev
         (setcdr prev (if lp (cdr lp) nil))
         (setq buffer-exclude-list (if lp (cdr lp) nil)) ) ) 
     ans ) )
       
(defun go-buffer-ring (arg)
  "Cycles around a ring of buffers"
  (interactive "P")
  (let ((list (buffer-list))
        (sw t)
	(msg "none")
	x xc )
    (while
      (and list
	(or
	  (equal (substring (buffer-name (car list)) 0 1) " ")
	  (prog1
	    sw
	    (setq x (chk-buf-xcld-lst (buffer-name (car list)) nil))
	    (if sw (setq xc x))
	    (setq sw nil)
            (setq x (if arg (not x) x))
	    (if (not x) (setq msg nil)) )
	  x ) )
      (setq list (cdr list)) )
    (cond
      (list
	(if (if (chk-buf-xcld-lst (buffer-name (car list)) nil) xc (not xc)) 
	  (bury-buffer (current-buffer)) )
	(switch-to-buffer (car list))
	(set-buffer (window-buffer (selected-window))) ) )
    (if msg (message msg) (identify)) ) )

(defun buf-xcld-key (arg)
  "Adds or removes a buffer from the buffer-ring exclude list.
With arg, clears the exclude list"
  (interactive "P")
  (let ((bufname nil)
	(msg "exclude list cleared") )
    (if arg (setq buffer-exclude-list nil)
      (setq msg "now excluded")
      (setq bufname (buffer-list))
      (while
	(and bufname (equal (substring (buffer-name (car bufname)) 0 1) " "))
	(setq bufname (cdr bufname)) )
      (setq bufname
	(if bufname (buffer-name (car bufname)) "") )
      (if (chk-buf-xcld-lst bufname t)
	(setq msg "now included")
	(setq buffer-exclude-list
	  (cons bufname buffer-exclude-list) ) ) )
    (message msg) ) )
---------------
Newsgroups: comp.emacs