iswitchb.el 50.8 KB
Newer Older
Richard M. Stallman's avatar
Richard M. Stallman committed
1
;;; iswitchb.el --- switch between buffers using substrings
Richard M. Stallman's avatar
Richard M. Stallman committed
2

3 4
;; Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004,
;;   2005 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
5

6 7
;; Author: Stephen Eglen <stephen@gnu.org>
;; Maintainer: Stephen Eglen <stephen@gnu.org>
Dave Love's avatar
Dave Love committed
8
;; Keywords: completion convenience
9
;; location: http://www.anc.ed.ac.uk/~stephen/emacs/
Richard M. Stallman's avatar
Richard M. Stallman committed
10

Richard M. Stallman's avatar
Richard M. Stallman committed
11 12 13
;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
Richard M. Stallman's avatar
Richard M. Stallman committed
14 15 16 17
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

Richard M. Stallman's avatar
Richard M. Stallman committed
18
;; GNU Emacs is distributed in the hope that it will be useful,
Richard M. Stallman's avatar
Richard M. Stallman committed
19 20 21 22 23 24
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
25 26
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
27

28
;;; Commentary:
Richard M. Stallman's avatar
Richard M. Stallman committed
29

30
;; Installation:
Dave Love's avatar
Dave Love committed
31 32
;; To get the functions in this package bound to keys, use
;; M-x iswitchb-mode or customize the option `iswitchb-mode'.
33 34
;; Alternatively, add the following line to your .emacs:
;; (iswitchb-mode 1)
Richard M. Stallman's avatar
Richard M. Stallman committed
35 36

;; As you type in a substring, the list of buffers currently matching
Dave Love's avatar
Dave Love committed
37
;; the substring is displayed as you type.  The list is ordered so
Richard M. Stallman's avatar
Richard M. Stallman committed
38 39 40 41
;; that the most recent buffers visited come at the start of the list.
;; The buffer at the start of the list will be the one visited when
;; you press return.  By typing more of the substring, the list is
;; narrowed down so that gradually the buffer you want will be at the
Dave Love's avatar
Dave Love committed
42
;; top of the list.  Alternatively, you can use C-s and C-r to rotate
Richard M. Stallman's avatar
Richard M. Stallman committed
43 44 45 46 47
;; buffer names in the list until the one you want is at the top of
;; the list.  Completion is also available so that you can see what is
;; common to all of the matching buffers as you type.

;; This code is similar to a couple of other packages.  Michael R Cook
48
;; <cook@sightpath.com> wrote a similar buffer switching package, but
Richard M. Stallman's avatar
Richard M. Stallman committed
49 50 51 52
;; does exact matching rather than substring matching on buffer names.
;; I also modified a couple of functions from icomplete.el to provide
;; the completion feedback in the minibuffer.

Dave Love's avatar
Dave Love committed
53
;;; Example
Richard M. Stallman's avatar
Richard M. Stallman committed
54

55 56 57
;; If I have two buffers called "123456" and "123", with "123456" the
;; most recent, when I use iswitchb, I first of all get presented with
;; the list of all the buffers
Richard M. Stallman's avatar
Richard M. Stallman committed
58
;;
Dave Love's avatar
Dave Love committed
59
;;       iswitch  {123456,123}
Richard M. Stallman's avatar
Richard M. Stallman committed
60 61 62 63 64 65 66
;;
;; If I then press 2:
;;       iswitch 2[3]{123456,123}
;;
;; The list in {} are the matching buffers, most recent first (buffers
;; visible in the current frame are put at the end of the list by
;; default).  At any time I can select the item at the head of the
67 68 69 70 71
;; list by pressing RET.  I can also put the first element at the end
;; of the list by pressing C-s, or put the last element at the head of
;; the list by pressing C-r.  The item in [] indicates what can be
;; added to my input by pressing TAB.  In this case, I will get "3"
;; added to my input.  So, press TAB:
Richard M. Stallman's avatar
Richard M. Stallman committed
72 73 74 75 76 77 78
;;	 iswitch 23{123456,123}
;;
;; At this point, I still have two matching buffers.
;; If I want the first buffer in the list, I simply press RET.  If I
;; wanted the second in the list, I could press C-s to move it to the
;; top of the list and then RET to select it.
;;
79
;; However, if I type 4, I only have one match left:
Richard M. Stallman's avatar
Richard M. Stallman committed
80 81
;;       iswitch 234[123456] [Matched]
;;
82 83 84
;; Since there is only one matching buffer left, it is given in [] and we
;; see the text [Matched] afterwards.  I can now press TAB or RET to go
;; to that buffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
85 86 87 88 89 90 91 92 93
;;
;; If however, I now type "a":
;;       iswitch 234a [No match]
;; There are no matching buffers.  If I press RET or TAB, I can be
;; prompted to create a new buffer called "234a".
;;
;; Of course, where this function comes in really useful is when you
;; can specify the buffer using only a few keystrokes.  In the above
;; example, the quickest way to get to the "123456" buffer would be
94
;; just to type 4 and then RET (assuming there isn't any newer buffer
Richard M. Stallman's avatar
Richard M. Stallman committed
95 96 97 98
;; with 4 in its name).

;; To see a full list of all matching buffers in a separate buffer,
;; hit ? or press TAB when there are no further completions to the
99 100
;; substring.  Repeated TAB presses will scroll you through this
;; separate buffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
101

102 103 104 105 106 107 108
;; The buffer at the head of the list can be killed by pressing C-k.
;; If the buffer needs saving, you will be queried before the buffer
;; is killed.

;; If you find that the file you are after is not in a buffer, you can
;; press C-x C-f to immediately drop into find-file.

109 110
;; See the doc string of iswitchb for full keybindings and features.
;; (describe-function 'iswitchb)
Richard M. Stallman's avatar
Richard M. Stallman committed
111

112 113 114
;; Case matching: The case of strings when matching can be ignored or
;; used depending on the value of iswitchb-case (default is the same
;; as case-fold-search, normally t).  Imagine you have the following
Dave Love's avatar
Dave Love committed
115
;; buffers:
116 117 118 119 120 121 122 123
;;
;; INBOX *info* *scratch*
;;
;; Then these will be the matching buffers, depending on how you type
;; the two letters `in' and the value of iswitchb-case:
;;
;; iswitchb-case   user input  | matching buffers
;; ----------------------------------------------
Dave Love's avatar
Dave Love committed
124 125 126 127
;; nil             in          | *info*
;; t               in          | INBOX, *info*
;; t               IN          | INBOX
;; t               In          | [No match]
128

Richard M. Stallman's avatar
Richard M. Stallman committed
129 130 131
;;; Customisation

;; See the User Variables section below for easy ways to change the
132 133
;; functionality of the program.  These are accessible using the
;; custom package.
134
;; To modify the keybindings, use something like:
Richard M. Stallman's avatar
Richard M. Stallman committed
135
;;
136
;;(add-hook 'iswitchb-mode-hook 'iswitchb-my-keys)
Richard M. Stallman's avatar
Richard M. Stallman committed
137
;;(defun iswitchb-my-keys ()
138
;;  "Add my keybindings for iswitchb."
139
;;  (define-key iswitchb-mode-map " " 'iswitchb-next-match))
Richard M. Stallman's avatar
Richard M. Stallman committed
140
;;
Stephen Eglen's avatar
Stephen Eglen committed
141
;; Seeing all the matching buffers
142
;;
Richard M. Stallman's avatar
Richard M. Stallman committed
143
;; If you have many matching buffers, they may not all fit onto one
144 145 146 147
;; line of the minibuffer.  In Emacs 21, the variable
;; `resize-mini-windows' controls how many lines of the minibuffer can
;; be seen.  For older versions of emacs, you can use
;; `resize-minibuffer-mode'.  You can also limit iswitchb so that it
Richard M. Stallman's avatar
Richard M. Stallman committed
148 149 150
;; only shows a certain number of lines -- see the documentation for
;; `iswitchb-minibuffer-setup-hook'.

Stephen Eglen's avatar
Stephen Eglen committed
151
;; Changing the list of buffers
Richard M. Stallman's avatar
Richard M. Stallman committed
152 153 154 155 156 157 158 159 160 161 162

;; By default, the list of current buffers is most recent first,
;; oldest last, with the exception that the buffers visible in the
;; current frame are put at the end of the list.  A hook exists to
;; allow other functions to order the list.  For example, if you add:
;;
;; (add-hook 'iswitchb-make-buflist-hook 'iswitchb-summaries-to-end)
;;
;; then all buffers matching "Summary" are moved to the end of the
;; list.  (I find this handy for keeping the INBOX Summary and so on
;; out of the way.)  It also moves buffers matching "output\*$" to the
David Kastrup's avatar
David Kastrup committed
163
;; end of the list (these are created by AUCTeX when compiling.)
Richard M. Stallman's avatar
Richard M. Stallman committed
164 165 166 167 168
;; Other functions could be made available which alter the list of
;; matching buffers (either deleting or rearranging elements.)

;; Font-Lock

Eli Zaretskii's avatar
Eli Zaretskii committed
169 170 171 172
;; font-lock is used to highlight the first matching buffer.  To
;; switch this off, set (setq iswitchb-use-faces nil).  Colouring of
;; the matching buffer name was suggested by Carsten Dominik
;; (dominik@strw.leidenuniv.nl)
Richard M. Stallman's avatar
Richard M. Stallman committed
173

Stephen Eglen's avatar
Stephen Eglen committed
174
;; Replacement for read-buffer
Richard M. Stallman's avatar
Richard M. Stallman committed
175

176 177
;; iswitchb-read-buffer has been written to be a drop in replacement
;; for the normal buffer selection routine `read-buffer'.  To use
178
;; iswitch for all buffer selections in Emacs, add:
179
;; (setq read-buffer-function 'iswitchb-read-buffer)
180
;; (This variable was introduced in Emacs 20.3.)
181
;; XEmacs users can get the same behaviour by doing:
Dave Love's avatar
Dave Love committed
182
;; (defalias 'read-buffer 'iswitchb-read-buffer)
183
;; since `read-buffer' is defined in lisp.
184

185 186
;; Using iswitchb for other completion tasks.

187
;; Kin Cho (kin@neoscale.com) sent the following suggestion to use
188
;; iswitchb for other completion tasks.
189 190 191 192 193 194 195 196 197 198 199 200 201 202
;;
;; (defun my-icompleting-read (prompt choices)
;;   "Use iswitch as a completing-read replacement to choose from
;; choices.  PROMPT is a string to prompt with.  CHOICES is a list of
;; strings to choose from."
;;   (let ((iswitchb-make-buflist-hook
;;          (lambda ()
;;            (setq iswitchb-temp-buflist choices))))
;;     (iswitchb-read-buffer prompt)))
;;
;; example:
;; (my-icompleting-read "Which fruit? " '
;; 		     ("apple" "pineapple" "pear" "bananas" "oranges") )

203 204 205 206 207 208 209 210 211 212 213
;; Kin Cho also suggested the following defun.  Once you have a subset of
;; matching buffers matching your current prompt, you can then press
;; e.g. C-o to restrict matching to those buffers and clearing the prompt:
;; (defun iswitchb-exclude-nonmatching()
;;    "Make iswitchb work on only the currently matching names."
;;    (interactive)
;;    (setq iswitchb-buflist iswitchb-matches)
;;    (setq iswitchb-rescan t)
;;    (delete-minibuffer-contents))
;;
;; (add-hook 'iswitchb-define-mode-map-hook
214 215
;; 	  '(lambda () (define-key
;; 			iswitchb-mode-map "\C-o"
216 217
;; 			'iswitchb-exclude-nonmatching)))

218 219 220 221 222 223 224 225 226 227 228 229 230
;; Other lisp packages extend iswitchb behaviour to other tasks.  See
;; ido.el (by Kim Storm) and mcomplete.el (Yuji Minejima).

;; Window managers: Switching frames/focus follows mouse; Sawfish.

;; If you switch to a buffer that is visible in another frame,
;; iswitchb can switch focus to that frame.  If your window manager
;; uses "click to focus" policy for window selection, you should also
;; set focus-follows-mouse to nil.

;; iswitch functionality has also been implemented for switching
;; between windows in the Sawfish window manager.

Stephen Eglen's avatar
Stephen Eglen committed
231 232
;; Regexp matching

Eli Zaretskii's avatar
Eli Zaretskii committed
233 234 235 236
;; There is provision for regexp matching within iswitchb, enabled
;; through `iswitchb-regexp'.  This allows you to type `c$' for
;; example and see all buffer names ending in `c'.  No completion
;; mechanism is currently offered when regexp searching.
Stephen Eglen's avatar
Stephen Eglen committed
237

238
;;; TODO
239

Richard M. Stallman's avatar
Richard M. Stallman committed
240 241 242 243 244 245 246 247
;;; Acknowledgements

;; Thanks to Jari Aalto <jari.aalto@poboxes.com> for help with the
;; first version of this package, iswitch-buffer.  Thanks also to many
;; others for testing earlier versions.

;;; Code:

248
;; CL needed for cadr and last
249 250 251
(if (not (and (fboundp 'cadr)
	      (fboundp 'last)))
    (require 'cl))
252

Eli Zaretskii's avatar
Eli Zaretskii committed
253 254
(require 'font-lock)

255 256 257 258 259 260 261 262 263 264 265
;; Set up the custom library.
;; taken from http://www.dina.kvl.dk/~abraham/custom/
(eval-and-compile
  (condition-case ()
      (require 'custom)
    (error nil))
  (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
      nil ;; We've got what we needed
    ;; We have the old custom-library, hack around it!
    (defmacro defgroup (&rest args)
      nil)
Dave Love's avatar
Dave Love committed
266
    (defmacro defcustom (var value doc &rest args)
Gerd Moellmann's avatar
Gerd Moellmann committed
267
      `(defvar ,var ,value ,doc))))
268

Richard M. Stallman's avatar
Richard M. Stallman committed
269 270 271 272
;;; User Variables
;;
;; These are some things you might want to change.

273
(defgroup iswitchb nil
274
  "Switch between buffers using substrings."
Dan Nicolaescu's avatar
Dan Nicolaescu committed
275
  :group 'convenience
Dave Love's avatar
Dave Love committed
276
  :group 'completion
277
  :link '(emacs-commentary-link :tag "Commentary" "iswitchb.el")
Dave Love's avatar
Dave Love committed
278
  :link '(url-link "http://www.anc.ed.ac.uk/~stephen/emacs/")
279
  :link '(emacs-library-link :tag "Lisp File" "iswitchb.el"))
280 281

(defcustom iswitchb-case case-fold-search
282 283 284
  "*Non-nil if searching of buffer names should ignore case.
If this is non-nil but the user input has any upper case letters, matching
is temporarily case sensitive."
285 286
  :type 'boolean
  :group 'iswitchb)
Richard M. Stallman's avatar
Richard M. Stallman committed
287

288
(defcustom iswitchb-buffer-ignore
Richard M. Stallman's avatar
Richard M. Stallman committed
289
  '("^ ")
Richard M. Stallman's avatar
Richard M. Stallman committed
290 291 292
  "*List of regexps or functions matching buffer names to ignore.
For example, traditional behavior is not to list buffers whose names begin
with a space, for which the regexp is `^ '.  See the source file for
293
example functions that filter buffernames."
294
  :type '(repeat (choice regexp function))
295
  :group 'iswitchb)
296
(put 'iswitchb-buffer-ignore 'risky-local-variable t)
297

298 299
(defcustom iswitchb-max-to-show nil
  "*If non-nil, limit the number of names shown in the minibuffer.
300 301 302 303
If this value is N, and N is greater than the number of matching
buffers, the first N/2 and the last N/2 matching buffers are
shown.  This can greatly speed up iswitchb if you have a
multitude of buffers open."
Stephen Eglen's avatar
Stephen Eglen committed
304
  :type '(choice (const :tag "Show all" nil) integer)
305 306
  :group 'iswitchb)

307 308 309 310 311 312 313 314
(defcustom iswitchb-use-virtual-buffers nil
  "*If non-nil, refer to past buffers when none match.
This feature relies upon the `recentf' package, which will be
enabled if this variable is configured to a non-nil value."
  :type 'boolean
  :require 'recentf
  :set (function
	(lambda (sym value)
315
	  (if value (recentf-mode 1))
316 317 318 319 320
	  (set sym value)))
  :group 'iswitchb)

(defvar iswitchb-virtual-buffers nil)

321 322 323 324 325 326 327 328
(defcustom iswitchb-cannot-complete-hook 'iswitchb-completion-help
  "*Hook run when `iswitchb-complete' can't complete any more.
The most useful values are `iswitchb-completion-help', which pops up a
window with completion alternatives, or `iswitchb-next-match' or
`iswitchb-prev-match', which cycle the buffer list."
  :type 'hook
  :group 'iswitchb)

Richard M. Stallman's avatar
Richard M. Stallman committed
329
;;; Examples for setting the value of iswitchb-buffer-ignore
Stephen Eglen's avatar
Stephen Eglen committed
330
;(defun iswitchb-ignore-c-mode (name)
Richard M. Stallman's avatar
Richard M. Stallman committed
331 332 333 334 335
;  "Ignore all c mode buffers -- example function for iswitchb."
;  (save-excursion
;    (set-buffer name)
;    (string-match "^C$" mode-name)))

Stephen Eglen's avatar
Stephen Eglen committed
336
;(setq iswitchb-buffer-ignore '("^ " iswitchb-ignore-c-mode))
Richard M. Stallman's avatar
Richard M. Stallman committed
337 338
;(setq iswitchb-buffer-ignore '("^ " "\\.c$" "\\.h$"))

339
(defcustom iswitchb-default-method  'always-frame
Richard M. Stallman's avatar
Richard M. Stallman committed
340
    "*How to switch to new buffer when using `iswitchb-buffer'.
Richard M. Stallman's avatar
Richard M. Stallman committed
341 342 343
Possible values:
`samewindow'	Show new buffer in same window
`otherwindow'	Show new buffer in another window (same frame)
344
`display'	Display buffer in another window without switching to it
Richard M. Stallman's avatar
Richard M. Stallman committed
345 346 347 348
`otherframe'	Show new buffer in another frame
`maybe-frame'	If a buffer is visible in another frame, prompt to ask if you
		you want to see the buffer in the same window of the current
  		frame or in the other frame.
349
`always-frame'  If a buffer is visible in another frame, raise that
350
		frame.  Otherwise, visit the buffer in the same window."
Dave Love's avatar
Dave Love committed
351
    :type '(choice (const samewindow)
352 353
		   (const otherwindow)
		   (const display)
Dave Love's avatar
Dave Love committed
354
		   (const otherframe)
355 356
		   (const maybe-frame)
		   (const always-frame))
357
    :group 'iswitchb)
Richard M. Stallman's avatar
Richard M. Stallman committed
358

359
(defcustom iswitchb-regexp nil
Richard M. Stallman's avatar
Richard M. Stallman committed
360
  "*Non-nil means that `iswitchb' will do regexp matching.
Stephen Eglen's avatar
Stephen Eglen committed
361
Value can be toggled within `iswitchb' using `iswitchb-toggle-regexp'."
362 363 364 365
  :type 'boolean
  :group 'iswitchb)

(defcustom iswitchb-newbuffer t
Richard M. Stallman's avatar
Richard M. Stallman committed
366
  "*Non-nil means create new buffer if no buffer matches substring.
367 368 369
See also `iswitchb-prompt-newbuffer'."
  :type 'boolean
  :group 'iswitchb)
Richard M. Stallman's avatar
Richard M. Stallman committed
370

371
(defcustom iswitchb-prompt-newbuffer t
Richard M. Stallman's avatar
Richard M. Stallman committed
372
  "*Non-nil means prompt user to confirm before creating new buffer.
373 374 375 376
See also `iswitchb-newbuffer'."
  :type 'boolean
  :group 'iswitchb)

Eli Zaretskii's avatar
Eli Zaretskii committed
377
(defcustom iswitchb-use-faces t
Stephen Eglen's avatar
Stephen Eglen committed
378
  "*Non-nil means use font-lock fonts for showing first match."
379 380
  :type 'boolean
  :group 'iswitchb)
Eli Zaretskii's avatar
Eli Zaretskii committed
381
(define-obsolete-variable-alias 'iswitchb-use-fonts 'iswitchb-use-faces "22.1")
Richard M. Stallman's avatar
Richard M. Stallman committed
382

383 384 385 386 387
(defcustom iswitchb-use-frame-buffer-list nil
  "*Non-nil means use the currently selected frame's buffer list."
  :type 'boolean
  :group 'iswitchb)

388
(defcustom iswitchb-make-buflist-hook  nil
Dave Love's avatar
Dave Love committed
389
  "Hook to run when list of matching buffers is created."
390 391 392
  :type 'hook
  :group 'iswitchb)

Richard M. Stallman's avatar
Richard M. Stallman committed
393 394 395 396
(defvar iswitchb-all-frames 'visible
  "*Argument to pass to `walk-windows' when finding visible buffers.
See documentation of `walk-windows' for useful values.")

Stephen Eglen's avatar
Stephen Eglen committed
397
(defcustom iswitchb-minibuffer-setup-hook nil
Dave Love's avatar
Dave Love committed
398
  "Iswitchb-specific customization of minibuffer setup.
Richard M. Stallman's avatar
Richard M. Stallman committed
399

Richard M. Stallman's avatar
Richard M. Stallman committed
400
This hook is run during minibuffer setup iff `iswitchb' will be active.
401 402 403 404 405
For instance:
\(add-hook 'iswitchb-minibuffer-setup-hook
	  '\(lambda () (set (make-local-variable 'max-mini-window-height) 3)))
will constrain the minibuffer to a maximum height of 3 lines when
iswitchb is running."
Stephen Eglen's avatar
Stephen Eglen committed
406 407 408
  :type 'hook
  :group 'iswitchb)

409
(defface iswitchb-single-match
Eli Zaretskii's avatar
Eli Zaretskii committed
410 411 412 413 414 415
  '((t
     (:inherit font-lock-comment-face)))
  "Iswitchb face for single matching buffer name."
  :version "22.1"
  :group 'iswitchb)

416
(defface iswitchb-current-match
Eli Zaretskii's avatar
Eli Zaretskii committed
417 418 419 420 421 422
  '((t
     (:inherit font-lock-function-name-face)))
  "Iswitchb face for current matching buffer name."
  :version "22.1"
  :group 'iswitchb)

423
(defface iswitchb-virtual-matches
Eli Zaretskii's avatar
Eli Zaretskii committed
424 425 426 427 428 429 430
  '((t
     (:inherit font-lock-builtin-face)))
  "Iswitchb face for matching virtual buffer names.
See also `iswitchb-use-virtual-buffers'."
  :version "22.1"
  :group 'iswitchb)

431
(defface iswitchb-invalid-regexp
Eli Zaretskii's avatar
Eli Zaretskii committed
432 433 434 435 436 437
  '((t
     (:inherit font-lock-warning-face)))
  "Iswitchb face for indicating invalid regexp. "
  :version "22.1"
  :group 'iswitchb)

Stephen Eglen's avatar
Stephen Eglen committed
438 439 440 441 442
;; Do we need the variable iswitchb-use-mycompletion?

;;; Internal Variables

(defvar iswitchb-method nil
Dave Love's avatar
Dave Love committed
443
  "Stores the method for viewing the selected buffer.
Stephen Eglen's avatar
Stephen Eglen committed
444 445 446
Its value is one of `samewindow', `otherwindow', `display', `otherframe',
`maybe-frame' or `always-frame'.  See `iswitchb-default-method' for
details of values.")
Richard M. Stallman's avatar
Richard M. Stallman committed
447 448 449

(defvar iswitchb-eoinput 1
  "Point where minibuffer input ends and completion info begins.
Richard M. Stallman's avatar
Richard M. Stallman committed
450
Copied from `icomplete-eoinput'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
451 452 453 454 455 456 457 458 459 460 461
(make-variable-buffer-local 'iswitchb-eoinput)

(defvar iswitchb-buflist nil
  "Stores the current list of buffers that will be searched through.
The list is ordered, so that the most recent buffers come first,
although by default, the buffers visible in the current frame are put
at the end of the list.  Created by `iswitchb-make-buflist'.")

;; todo -- is this necessary?

(defvar iswitchb-use-mycompletion nil
Dave Love's avatar
Dave Love committed
462
  "Non-nil means use `iswitchb-buffer' completion feedback.
Richard M. Stallman's avatar
Richard M. Stallman committed
463 464
Should only be set to t by iswitchb functions, so that it doesn't
interfere with other minibuffer usage.")
Richard M. Stallman's avatar
Richard M. Stallman committed
465

Dave Love's avatar
Dave Love committed
466
(defvar iswitchb-change-word-sub nil
Richard M. Stallman's avatar
Richard M. Stallman committed
467 468 469 470 471 472 473 474 475 476 477 478
  "Private variable used by `iswitchb-word-matching-substring'.")

(defvar iswitchb-common-match-string  nil
  "Stores the string that is common to all matching buffers.")

(defvar iswitchb-rescan nil
  "Non-nil means we need to regenerate the list of matching buffers.")

(defvar iswitchb-text nil
  "Stores the users string as it is typed in.")

(defvar iswitchb-matches nil
479
  "List of buffers currently matching `iswitchb-text'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
480

Dave Love's avatar
Dave Love committed
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
(defvar iswitchb-mode-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map minibuffer-local-map)
    (define-key map "?" 'iswitchb-completion-help)
    (define-key map "\C-s" 'iswitchb-next-match)
    (define-key map "\C-r" 'iswitchb-prev-match)
    (define-key map "\t" 'iswitchb-complete)
    (define-key map "\C-j" 'iswitchb-select-buffer-text)
    (define-key map "\C-t" 'iswitchb-toggle-regexp)
    (define-key map "\C-x\C-f" 'iswitchb-find-file)
    (define-key map "\C-c" 'iswitchb-toggle-case)
    (define-key map "\C-k" 'iswitchb-kill-buffer)
    (define-key map "\C-m" 'iswitchb-exit-minibuffer)
    map)
  "Minibuffer keymap for `iswitchb-buffer'.")

(defvar iswitchb-global-map
  (let ((map (make-sparse-keymap)))
    (substitute-key-definition 'switch-to-buffer ; normally C-x b
			       'iswitchb-buffer map global-map)
    (substitute-key-definition 'switch-to-buffer-other-window ; C-x 4 b
			       'iswitchb-buffer-other-window map global-map)
    (substitute-key-definition 'switch-to-buffer-other-frame ; C-x 5 b
			       'iswitchb-buffer-other-frame map global-map)
    (substitute-key-definition 'display-buffer ; C-x 4 C-o
			       'iswitchb-display-buffer map global-map)
    map)
508
  "Global keymap for `iswitchb-mode'.")
Dave Love's avatar
Dave Love committed
509 510

(defvar iswitchb-history nil
Richard M. Stallman's avatar
Richard M. Stallman committed
511
  "History of buffers selected using `iswitchb-buffer'.")
Richard M. Stallman's avatar
Richard M. Stallman committed
512

Dave Love's avatar
Dave Love committed
513 514
(defvar iswitchb-exit nil
  "Flag to monitor how `iswitchb-buffer' exits.
Richard M. Stallman's avatar
Richard M. Stallman committed
515 516
If equal to `takeprompt', we use the prompt as the buffer name to be
selected.")
Richard M. Stallman's avatar
Richard M. Stallman committed
517 518 519 520

(defvar iswitchb-buffer-ignore-orig nil
  "Stores original value of `iswitchb-buffer-ignore'.")

Stephen Eglen's avatar
Stephen Eglen committed
521 522
(defvar iswitchb-default nil
  "Default buffer for iswitchb.")
Richard M. Stallman's avatar
Richard M. Stallman committed
523

524 525 526 527 528 529 530 531 532 533
;; The following variables are needed to keep the byte compiler quiet.
(defvar iswitchb-require-match nil
  "Non-nil if matching buffer must be selected.")

(defvar iswitchb-temp-buflist nil
  "Stores a temporary version of the buffer list being created.")

(defvar iswitchb-bufs-in-frame nil
  "List of the buffers visible in the current frame.")

534 535 536
(defvar iswitchb-minibuf-depth nil
  "Value we expect to be returned by `minibuffer-depth' in the minibuffer.")

Eli Zaretskii's avatar
Eli Zaretskii committed
537 538 539 540 541
(defvar iswitchb-common-match-inserted nil
  "Non-nil if we have just inserted a common match in the minibuffer.")

(defvar iswitchb-invalid-regexp)

Richard M. Stallman's avatar
Richard M. Stallman committed
542 543
;;; FUNCTIONS

Dave Love's avatar
Dave Love committed
544
;;; ISWITCHB KEYMAP
Richard M. Stallman's avatar
Richard M. Stallman committed
545
(defun iswitchb-define-mode-map ()
Dave Love's avatar
Dave Love committed
546 547 548
  "Set up the keymap for `iswitchb-buffer'.
This is obsolete.  Use \\[iswitchb-mode] or customize the
variable `iswitchb-mode'."
Richard M. Stallman's avatar
Richard M. Stallman committed
549 550
  (interactive)
  (let (map)
551
    ;; generated every time so that it can inherit new functions.
Richard M. Stallman's avatar
Richard M. Stallman committed
552 553 554 555 556 557 558 559 560
    ;;(or iswitchb-mode-map

    (setq map (copy-keymap minibuffer-local-map))
    (define-key map "?" 'iswitchb-completion-help)
    (define-key map "\C-s" 'iswitchb-next-match)
    (define-key map "\C-r" 'iswitchb-prev-match)
    (define-key map "\t" 'iswitchb-complete)
    (define-key map "\C-j" 'iswitchb-select-buffer-text)
    (define-key map "\C-t" 'iswitchb-toggle-regexp)
561
    (define-key map "\C-x\C-f" 'iswitchb-find-file)
562
    (define-key map "\C-a" 'iswitchb-toggle-ignore)
Richard M. Stallman's avatar
Richard M. Stallman committed
563
    (define-key map "\C-c" 'iswitchb-toggle-case)
564
    (define-key map "\C-k" 'iswitchb-kill-buffer)
565
    (define-key map "\C-m" 'iswitchb-exit-minibuffer)
Richard M. Stallman's avatar
Richard M. Stallman committed
566
    (setq iswitchb-mode-map map)
567
    (run-hooks 'iswitchb-define-mode-map-hook)))
568

Richard M. Stallman's avatar
Richard M. Stallman committed
569 570 571 572 573 574 575 576 577 578
;;; MAIN FUNCTION
(defun iswitchb ()
  "Switch to buffer matching a substring.
As you type in a string, all of the buffers matching the string are
displayed.  When you have found the buffer you want, it can then be
selected.  As you type, most keys have their normal keybindings,
except for the following:
\\<iswitchb-mode-map>

RET Select the buffer at the front of the list of matches.  If the
Richard M. Stallman's avatar
Richard M. Stallman committed
579
list is empty, possibly prompt to create new buffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
580 581 582 583 584 585

\\[iswitchb-select-buffer-text] Select the current prompt as the buffer.
If no buffer is found, prompt for a new one.

\\[iswitchb-next-match] Put the first element at the end of the list.
\\[iswitchb-prev-match] Put the last element at the start of the list.
Dave Love's avatar
Dave Love committed
586
\\[iswitchb-complete] Complete a common suffix to the current string that
Richard M. Stallman's avatar
Richard M. Stallman committed
587 588 589
matches all buffers.  If there is only one match, select that buffer.
If there is no common suffix, show a list of all matching buffers
in a separate window.
590
\\[iswitchb-toggle-regexp] Toggle regexp searching.
Richard M. Stallman's avatar
Richard M. Stallman committed
591
\\[iswitchb-toggle-case] Toggle case-sensitive searching of buffer names.
592
\\[iswitchb-completion-help] Show list of matching buffers in separate window.
Dave Love's avatar
Dave Love committed
593
\\[iswitchb-find-file] Exit iswitchb and drop into `find-file'.
594
\\[iswitchb-kill-buffer] Kill buffer at head of buffer list."
Richard M. Stallman's avatar
Richard M. Stallman committed
595 596
  ;;\\[iswitchb-toggle-ignore] Toggle ignoring certain buffers (see \
  ;;`iswitchb-buffer-ignore')
597

598
  (let* ((prompt "iswitch ")
Eli Zaretskii's avatar
Eli Zaretskii committed
599
         iswitchb-invalid-regexp
600
	 (buf (iswitchb-read-buffer prompt)))
601 602 603 604 605 606 607

    ;;(message "chosen text %s" iswitchb-final-text)
    ;; Choose the buffer name: either the text typed in, or the head
    ;; of the list of matches

    (cond ( (eq iswitchb-exit 'findfile)
	    (call-interactively 'find-file))
Eli Zaretskii's avatar
Eli Zaretskii committed
608 609
          (iswitchb-invalid-regexp
           (message "Won't make invalid regexp named buffer"))
610 611
	  (t
	   ;; View the buffer
612
	   ;;(message "go to buf %s" buf)
613 614 615 616 617 618 619
	   ;; Check buf is non-nil.
	   (if buf
	       (if (get-buffer buf)
		   ;; buffer exists, so view it and then exit
		   (iswitchb-visit-buffer buf)
		 ;; else buffer doesn't exist
		 (iswitchb-possible-new-buffer buf)))
620
	   ))))
621

622 623
(defun iswitchb-read-buffer (prompt &optional default require-match
				    start matches-set)
624
  "Replacement for the built-in `read-buffer'.
Dave Love's avatar
Dave Love committed
625
Return the name of a buffer selected.
626 627 628 629 630 631 632 633
PROMPT is the prompt to give to the user.
DEFAULT if given is the default buffer to be selected, which will
go to the front of the list.
If REQUIRE-MATCH is non-nil, an existing-buffer must be selected.
If START is a string, the selection process is started with that
string.
If MATCHES-SET is non-nil, the buflist is not updated before
the selection process begins.  Used by isearchb.el."
Richard M. Stallman's avatar
Richard M. Stallman committed
634 635 636 637 638
  (let
      (
       buf-sel
       iswitchb-final-text
       (icomplete-mode nil) ;; prevent icomplete starting up
Eli Zaretskii's avatar
Eli Zaretskii committed
639
       )
640

Richard M. Stallman's avatar
Richard M. Stallman committed
641 642
    (iswitchb-define-mode-map)
    (setq iswitchb-exit nil)
Stephen Eglen's avatar
Stephen Eglen committed
643 644 645 646
    (setq iswitchb-default
	  (if (bufferp default)
	      (buffer-name default)
	    default))
647 648 649 650 651
    (setq iswitchb-text (or start ""))
    (unless matches-set
      (setq iswitchb-rescan t)
      (iswitchb-make-buflist iswitchb-default)
      (iswitchb-set-matches))
Dave Love's avatar
Dave Love committed
652
    (let
653
	((minibuffer-local-completion-map iswitchb-mode-map)
654 655 656
	 ;; Record the minibuffer depth that we expect to find once
	 ;; the minibuffer is set up and iswitchb-entryfn-p is called.
	 (iswitchb-minibuf-depth (1+ (minibuffer-depth)))
657
	 (iswitchb-require-match require-match))
658
      ;; prompt the user for the buffer name
Dave Love's avatar
Dave Love committed
659
      (setq iswitchb-final-text (completing-read
660
				 prompt		  ;the prompt
Dave Love's avatar
Dave Love committed
661
				 '(("dummy" . 1)) ;table
662 663 664
				 nil		  ;predicate
				 nil ;require-match [handled elsewhere]
				 start	;initial-contents
665
				 'iswitchb-history)))
666 667
    (if (and (not (eq iswitchb-exit 'usefirst))
	     (get-buffer iswitchb-final-text))
668
	;; This happens for example if the buffer was chosen with the mouse.
669 670 671 672 673 674 675 676 677 678 679
	(setq iswitchb-matches (list iswitchb-final-text)
	      iswitchb-virtual-buffers nil))

    ;; If no buffer matched, but a virtual buffer was selected, visit
    ;; that file now and act as though that buffer had been selected.
    (if (and iswitchb-virtual-buffers
	     (not (iswitchb-existing-buffer-p)))
	(let ((virt (car iswitchb-virtual-buffers)))
	  (find-file-noselect (cdr virt))
	  (setq iswitchb-matches (list (car virt))
		iswitchb-virtual-buffers nil)))
680

681
    ;; Handling the require-match must be done in a better way.
682 683
    (if (and require-match
	     (not (iswitchb-existing-buffer-p)))
Dave Love's avatar
Dave Love committed
684
	(error "Must specify valid buffer"))
685

686 687
    (if (or (eq iswitchb-exit 'takeprompt)
	    (null iswitchb-matches))
688 689 690
	(setq buf-sel iswitchb-final-text)
      ;; else take head of list
      (setq buf-sel (car iswitchb-matches)))
691

692
    ;; Or possibly choose the default buffer
Dave Love's avatar
Dave Love committed
693
    (if  (equal iswitchb-final-text "")
694
	(setq buf-sel (car iswitchb-matches)))
695

696
    buf-sel))
697

698 699 700
(defun iswitchb-existing-buffer-p ()
  "Return non-nil if there is a matching buffer."
  (not (null iswitchb-matches)))
Richard M. Stallman's avatar
Richard M. Stallman committed
701 702 703 704

;;; COMPLETION CODE

(defun iswitchb-set-common-completion  ()
Richard M. Stallman's avatar
Richard M. Stallman committed
705 706
  "Find common completion of `iswitchb-text' in `iswitchb-matches'.
The result is stored in `iswitchb-common-match-string'."
Richard M. Stallman's avatar
Richard M. Stallman committed
707 708 709 710

  (let* (val)
    (setq  iswitchb-common-match-string nil)
    (if (and iswitchb-matches
Stephen Eglen's avatar
Stephen Eglen committed
711
	     (not iswitchb-regexp) ;; testing
Richard M. Stallman's avatar
Richard M. Stallman committed
712 713 714 715 716
             (stringp iswitchb-text)
             (> (length iswitchb-text) 0))
        (if (setq val (iswitchb-find-common-substring
                       iswitchb-matches iswitchb-text))
            (setq iswitchb-common-match-string val)))
717
    val))
Richard M. Stallman's avatar
Richard M. Stallman committed
718 719 720 721 722 723

(defun iswitchb-complete ()
  "Try and complete the current pattern amongst the buffer names."
  (interactive)
  (let (res)
    (cond ((not  iswitchb-matches)
724
	   (run-hooks 'iswitchb-cannot-complete-hook))
Eli Zaretskii's avatar
Eli Zaretskii committed
725 726 727
          (iswitchb-invalid-regexp
           ;; Do nothing
           )
728
	  ((= 1 (length iswitchb-matches))
Richard M. Stallman's avatar
Richard M. Stallman committed
729 730
	   ;; only one choice, so select it.
	   (exit-minibuffer))
731

Richard M. Stallman's avatar
Richard M. Stallman committed
732 733
	  (t
	   ;; else there could be some completions
Stephen Eglen's avatar
Stephen Eglen committed
734
	   (setq res iswitchb-common-match-string)
Richard M. Stallman's avatar
Richard M. Stallman committed
735
	   (if (and (not (memq res '(t nil)))
736
		    (not (equal res iswitchb-text)))
737
	       ;; found something to complete, so put it in the minibuffer.
Richard M. Stallman's avatar
Richard M. Stallman committed
738
	       (progn
Eli Zaretskii's avatar
Eli Zaretskii committed
739 740
		 (setq iswitchb-rescan nil
                       iswitchb-common-match-inserted t)
741
		 (delete-region (minibuffer-prompt-end) (point))
Richard M. Stallman's avatar
Richard M. Stallman committed
742 743
		 (insert  res))
	     ;; else nothing to complete
744
	     (run-hooks 'iswitchb-cannot-complete-hook)
745
	     )))))
Richard M. Stallman's avatar
Richard M. Stallman committed
746 747 748 749

;;; TOGGLE FUNCTIONS

(defun iswitchb-toggle-case ()
Dave Love's avatar
Dave Love committed
750
  "Toggle the value of variable `iswitchb-case'."
Richard M. Stallman's avatar
Richard M. Stallman committed
751 752 753
  (interactive)
  (setq iswitchb-case (not iswitchb-case))
  ;; ask for list to be regenerated.
754
  (setq iswitchb-rescan t))
Richard M. Stallman's avatar
Richard M. Stallman committed
755 756 757 758 759 760

(defun iswitchb-toggle-regexp ()
  "Toggle the value of `iswitchb-regexp'."
  (interactive)
  (setq iswitchb-regexp (not iswitchb-regexp))
  ;; ask for list to be regenerated.
761
  (setq iswitchb-rescan t))
Richard M. Stallman's avatar
Richard M. Stallman committed
762 763 764 765 766 767 768

(defun iswitchb-toggle-ignore ()
  "Toggle ignoring buffers specified with `iswitchb-buffer-ignore'."
  (interactive)
  (if iswitchb-buffer-ignore
      (progn
        (setq iswitchb-buffer-ignore-orig iswitchb-buffer-ignore)
769
        (setq iswitchb-buffer-ignore nil))
Richard M. Stallman's avatar
Richard M. Stallman committed
770
    ;; else
771
    (setq iswitchb-buffer-ignore iswitchb-buffer-ignore-orig))
Stephen Eglen's avatar
Stephen Eglen committed
772
  (iswitchb-make-buflist iswitchb-default)
Richard M. Stallman's avatar
Richard M. Stallman committed
773
  ;; ask for list to be regenerated.
774
  (setq iswitchb-rescan t))
Richard M. Stallman's avatar
Richard M. Stallman committed
775

776 777 778 779 780
(defun iswitchb-exit-minibuffer ()
  "Exit minibuffer, but make sure we have a match if one is needed."
  (interactive)
  (if (or (not iswitchb-require-match)
	   (iswitchb-existing-buffer-p))
781 782 783
      (progn
	(setq iswitchb-exit 'usefirst)
	(throw 'exit nil))))
Richard M. Stallman's avatar
Richard M. Stallman committed
784 785

(defun iswitchb-select-buffer-text ()
Richard M. Stallman's avatar
Richard M. Stallman committed
786 787
  "Select the buffer named by the prompt.
If no buffer exactly matching the prompt exists, maybe create a new one."
Richard M. Stallman's avatar
Richard M. Stallman committed
788 789 790 791
  (interactive)
  (setq iswitchb-exit 'takeprompt)
  (exit-minibuffer))

792
(defun iswitchb-find-file ()
Dave Love's avatar
Dave Love committed
793
  "Drop into `find-file' from buffer switching."
794 795 796 797
  (interactive)
  (setq iswitchb-exit 'findfile)
  (exit-minibuffer))

798 799 800
(eval-when-compile
  (defvar recentf-list))

Dave Love's avatar
Dave Love committed
801
(defun iswitchb-next-match ()
Richard M. Stallman's avatar
Richard M. Stallman committed
802 803
  "Put first element of `iswitchb-matches' at the end of the list."
  (interactive)
804
  (let ((next  (cadr iswitchb-matches)))
805 806 807 808 809
    (if (and (null next) iswitchb-virtual-buffers)
	(setq recentf-list
	      (iswitchb-chop recentf-list
			     (cdr (cadr iswitchb-virtual-buffers))))
      (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist next)))
810
    (setq iswitchb-rescan t)))
Richard M. Stallman's avatar
Richard M. Stallman committed
811

Dave Love's avatar
Dave Love committed
812
(defun iswitchb-prev-match ()
Richard M. Stallman's avatar
Richard M. Stallman committed
813 814
  "Put last element of `iswitchb-matches' at the front of the list."
  (interactive)
815
  (let ((prev  (car (last iswitchb-matches))))
816 817 818 819 820
    (if (and (null prev) iswitchb-virtual-buffers)
	(setq recentf-list
	      (iswitchb-chop recentf-list
			     (cdr (car (last iswitchb-virtual-buffers)))))
      (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist prev)))
821
    (setq iswitchb-rescan t)))
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836

(defun iswitchb-chop (list elem)
  "Remove all elements before ELEM and put them at the end of LIST."
  (let ((ret nil)
	(next nil)
	(sofar nil))
    (while (not ret)
      (setq next (car list))
      (if (equal next elem)
	  (setq ret (append list (nreverse sofar)))
	;; else
	(progn
	  (setq list (cdr list))
	  (setq sofar (cons next sofar)))))
    ret))
Richard M. Stallman's avatar
Richard M. Stallman committed
837 838 839

;;; CREATE LIST OF ALL CURRENT BUFFERS

840
(defun iswitchb-make-buflist (default)
Richard M. Stallman's avatar
Richard M. Stallman committed
841
  "Set `iswitchb-buflist' to the current list of buffers.
842
Currently visible buffers are put at the end of the list.
Dave Love's avatar
Dave Love committed
843
The hook `iswitchb-make-buflist-hook' is run after the list has been
844
created to allow the user to further modify the order of the buffer names
845 846
in this list.  If DEFAULT is non-nil, and corresponds to an existing buffer,
it is put to the start of the list."
Dave Love's avatar
Dave Love committed
847
  (setq iswitchb-buflist
848
	(let* ((iswitchb-current-buffers (iswitchb-get-buffers-in-frames))
849 850 851 852 853 854 855 856 857 858 859 860 861 862
	       (iswitchb-temp-buflist
		(delq nil
		      (mapcar
		       (lambda (x)
			 (let ((b-name (buffer-name x)))
			   (if (not
				(or
				 (iswitchb-ignore-buffername-p b-name)
				 (memq b-name iswitchb-current-buffers)))
			       b-name)))
		       (buffer-list (and iswitchb-use-frame-buffer-list
					 (selected-frame)))))))
	  (setq iswitchb-temp-buflist
		(nconc iswitchb-temp-buflist iswitchb-current-buffers))
Richard M. Stallman's avatar
Richard M. Stallman committed
863
	  (run-hooks 'iswitchb-make-buflist-hook)
864
	 ;; Should this be after the hooks, or should the hooks be the
865 866 867
	  ;; final thing to be run?
	  (if default
	      (progn
Dave Love's avatar
Dave Love committed
868
		(setq iswitchb-temp-buflist
869
		      (delete default iswitchb-temp-buflist))
Dave Love's avatar
Dave Love committed
870
		(setq iswitchb-temp-buflist
871 872
		      (cons default iswitchb-temp-buflist))))
	  iswitchb-temp-buflist)))
Richard M. Stallman's avatar
Richard M. Stallman committed
873

874
(defun iswitchb-to-end (lst)
875
  "Move the elements from LST to the end of `iswitchb-temp-buflist'."
876 877
  (dolist (elem lst)
    (setq iswitchb-temp-buflist (delq elem iswitchb-temp-buflist)))
878
  (setq iswitchb-temp-buflist (nconc iswitchb-temp-buflist lst)))
Richard M. Stallman's avatar
Richard M. Stallman committed
879 880 881

(defun iswitchb-get-buffers-in-frames (&optional current)
  "Return the list of buffers that are visible in the current frame.
Dave Love's avatar
Dave Love committed
882
If optional argument CURRENT is given, restrict searching to the
Richard M. Stallman's avatar
Richard M. Stallman committed
883 884 885 886
current frame, rather than all frames, regardless of value of
`iswitchb-all-frames'."
  (let ((iswitchb-bufs-in-frame nil))
    (walk-windows 'iswitchb-get-bufname nil
Dave Love's avatar
Dave Love committed
887
		  (if current
Richard M. Stallman's avatar
Richard M. Stallman committed
888 889 890 891 892 893
		      nil
		    iswitchb-all-frames))
    iswitchb-bufs-in-frame))

(defun iswitchb-get-bufname (win)
  "Used by `iswitchb-get-buffers-in-frames' to walk through all windows."
894 895 896 897 898 899 900
  (let ((buf (buffer-name (window-buffer win))))
	(if (not (member buf iswitchb-bufs-in-frame))
	    ;; Only add buf if it is not already in list.
	    ;; This prevents same buf in two different windows being
	    ;; put into the list twice.
	    (setq iswitchb-bufs-in-frame
		  (cons buf iswitchb-bufs-in-frame)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
901 902 903 904 905 906 907

;;; FIND MATCHING BUFFERS

(defun iswitchb-set-matches ()
  "Set `iswitchb-matches' to the list of buffers matching prompt."
  (if iswitchb-rescan
      (setq iswitchb-matches
908
	    (let* ((buflist iswitchb-buflist))
909
	      (iswitchb-get-matched-buffers iswitchb-text iswitchb-regexp
910 911
					    buflist))
	    iswitchb-virtual-buffers nil)))
912 913 914

(defun iswitchb-get-matched-buffers (regexp
				     &optional string-format buffer-list)
Stephen Eglen's avatar
Stephen Eglen committed
915 916
  "Return buffers matching REGEXP.
If STRING-FORMAT is nil, consider REGEXP as just a string.
Richard M. Stallman's avatar
Richard M. Stallman committed
917
BUFFER-LIST can be list of buffers or list of strings."
918 919 920
  (let* ((case-fold-search (iswitchb-case))
         name ret)
    (if (null string-format) (setq regexp (regexp-quote regexp)))
Eli Zaretskii's avatar
Eli Zaretskii committed
921
    (setq iswitchb-invalid-regexp nil)
922 923 924 925 926 927 928 929 930
    (condition-case error
        (dolist (x buffer-list (nreverse ret))
          (setq name (if (stringp x) x (buffer-name x)))
          (when (and (string-match regexp name)
                     (not (iswitchb-ignore-buffername-p name)))
            (push name ret)))
      (invalid-regexp
       (setq iswitchb-invalid-regexp t)
       (cdr error)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
931 932 933 934 935 936

(defun iswitchb-ignore-buffername-p (bufname)
  "Return t if the buffer BUFNAME should be ignored."
  (let ((data       (match-data))
        (re-list    iswitchb-buffer-ignore)
        ignorep
937
        nextstr)
Richard M. Stallman's avatar
Richard M. Stallman committed
938 939 940 941 942 943 944 945
    (while re-list
      (setq nextstr (car re-list))
      (cond
       ((stringp nextstr)
        (if (string-match nextstr bufname)
            (progn
              (setq ignorep t)
              (setq re-list nil))))
946
       ((functionp nextstr)
Richard M. Stallman's avatar
Richard M. Stallman committed
947 948 949
        (if (funcall nextstr bufname)
            (progn
              (setq ignorep t)
950
              (setq re-list nil)))))
Richard M. Stallman's avatar
Richard M. Stallman committed
951
      (setq re-list (cdr re-list)))
952
    (set-match-data data)
Richard M. Stallman's avatar
Richard M. Stallman committed
953 954

    ;; return the result
955
    ignorep))
Richard M. Stallman's avatar
Richard M. Stallman committed
956 957 958 959

(defun iswitchb-word-matching-substring (word)
  "Return part of WORD before 1st match to `iswitc