From: mcook@fendahl.dev.cdx.mot.com (Michael Cook)
Subject: Re: anyone got a way to cycle through buffers with a keystroke?
Organization: Motorola Codex, Canton, Massachusetts
Date: Sun, 8 Nov 1992 00:57:51 GMT

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.

You've gotten quite a few follow-ups, so here's another with a slightly
different approach.  iswitch-to-buffer is an isearch-like version of
switch-to-buffer.  You need type only the first few characters of the buffer
name -- enough to uniquely identify the buffer.  Once you've typed enough, it
tells you by saying "[Matched]".  If there are multiple buffers whose name is
matched by what you've typed, and their names have a common part that you
haven't typed yet, that common part is shown in parens; if you hit TAB, it
pretends you typed that whole common part.  Press RET to finish.

I find that I use iswitch-to-buffer when I have a lot of buffers and I want to
switch to one that I haven't visited in quite a while.  I know that that
buffer will be quite a ways down the buffer list, so I don't want to have to
walk down a long list.

Michael.

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./iswitch.el`
then
echo "writing ./iswitch.el"
cat > ./iswitch.el << '\End\Of\Shar\'
(defun iswitch-to-buffer ()
  "An isearch-like version of switch-to-buffer."
  (interactive)
  (let ((buf (save-window-excursion
	       (catch 'iswitch-done
		 (let ((bufs (apply 'append
				    (mapcar '(lambda (buf)
					       (if (eq buf (current-buffer))
						   nil
						 (list (cons (buffer-name buf) buf))))
					    (buffer-list))))
		       (name '(""))
		       (completion-ignore-case t))
		   (while t
		     (if (or (>= unread-command-char 0)
			     (input-pending-p))
			 nil
		       (let ((comps (all-completions (car name) bufs)))
			 (message "Switch to buffer: %s%s"
				  (car name)
				  (cond ((null comps)
					 " [No matches]")
					((null (cdr comps)) ;one match
					 (concat
					  (and (> (length (car comps))
						  (length (car name)))
					       (concat "(" (substring (car comps) (length (car name))) ")"))
					  " [Matched]"))
					(t ;multiple matches
					 (let ((most (try-completion (car name) bufs)))
					   (if (<= (length most) (length (car name)))
					       ""
					     (concat "(" (substring most (length (car name))) ")"))))))))
		     (let ((char (read-char)))
		       (cond ((eq char ?\177)
			      (if (cdr name)
				  (setq name (cdr name))))
			     ((eq char ?\t)
			      (let ((most (try-completion (car name) bufs)))
				(if (> (length most) (length (car name)))
				    (setq name (cons most name))
				  (iswitch-show-completions (car name) bufs))))
			     ((eq char ??)
			      (iswitch-show-completions (car name) bufs))
			     ((or (eq char ?\C-m)
				  (eq char ?\C-j))
			      (let ((most (try-completion (car name) bufs)))
				(let ((buf (cond ((eq most t)
						  (get-buffer (car name)))
						 (most
						  (get-buffer most)))))
				  (if (not buf)
				      (let ((match (car (all-completions (car name) bufs))))
					(setq buf (and match (get-buffer match)))))
				  (and buf
				       (throw 'iswitch-done buf))
				  (beep))))
			     ((and (>= char ? )
				   (<= char ?~))
			      (setq name (cons (concat (car name)
						       (char-to-string char))
					       name)))
			     (t
			      (setq unread-command-char char)
			      (throw 'iswitch-done nil))))))))))
    (and buf
	 (switch-to-buffer buf))))

(defun iswitch-show-completions (name bufs)
  (let ((comps (all-completions name bufs)))
    (cond ((null comps)
	   (message "No matches.")
	   (sit-for 2))
	  (t
	   (with-output-to-temp-buffer "*Help*"
	     (display-completion-list comps))))))
\End\Of\Shar\
else
  echo "will not over write ./iswitch.el"
fi
if [ `wc -c ./iswitch.el | awk '{printf $1}'` -ne 2449 ]
then
echo `wc -c ./iswitch.el | awk '{print "Got " $1 ", Expected " 2449}'`
fi
echo "Finished archive 1 of 1"
exit