comparison lisp/iswitchb.el @ 31797:b9e108c1c1bf

Some doc fixes. (iswitchb-mode-map): Define completely initially. Inherit minibuffer-local-map. (iswitchb-completion-help) <!iswitchb-xemacs>: Use fundamental-mode. (iswitchb-global-map): New variable. (iswitchb-summaries-to-end): Amalgamate regexps. (iswitchb-mode): New. (iswitchb-mode-hook): New variable. (iswitchb) <defgroup>: Add URL link. Use group `completion', not `extensions'.
author Dave Love <fx@gnu.org>
date Wed, 20 Sep 2000 22:47:50 +0000
parents 876c0335dead
children 47476840057c
comparison
equal deleted inserted replaced
31796:72688e296f28 31797:b9e108c1c1bf
1 ;;; iswitchb.el --- switch between buffers using substrings 1 ;;; iswitchb.el --- switch between buffers using substrings
2 2
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
4 4
5 ;; Author: Stephen Eglen <stephen@anc.ed.ac.uk> 5 ;; Author: Stephen Eglen <stephen@anc.ed.ac.uk>
6 ;; Maintainer: Stephen Eglen <stephen@anc.ed.ac.uk> 6 ;; Maintainer: Stephen Eglen <stephen@anc.ed.ac.uk>
7 ;; Keywords: extensions convenience 7 ;; Keywords: completion convenience
8 ;; location: http://www.anc.ed.ac.uk/~stephen/emacs/ 8 ;; location: http://www.anc.ed.ac.uk/~stephen/emacs/
9 9
10 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
11 11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
25 ;; Boston, MA 02111-1307, USA. 25 ;; Boston, MA 02111-1307, USA.
26 26
27 ;;; Commentary: 27 ;;; Commentary:
28 28
29 ;; Installation: 29 ;; Installation:
30 ;; To get the functions in this package bound to keys, do 30 ;; To get the functions in this package bound to keys, use
31 ;; (iswitchb-default-keybindings) 31 ;; M-x iswitchb-mode or customize the option `iswitchb-mode'.
32 ;;
33 ;; If you want to use the features of iswitchb, but without rebinding
34 ;; the keys as above, then you need to add the following hook:
35 ;; (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)
36 32
37 ;; As you type in a substring, the list of buffers currently matching 33 ;; As you type in a substring, the list of buffers currently matching
38 ;; the substring are displayed as you type. The list is ordered so 34 ;; the substring is displayed as you type. The list is ordered so
39 ;; that the most recent buffers visited come at the start of the list. 35 ;; that the most recent buffers visited come at the start of the list.
40 ;; The buffer at the start of the list will be the one visited when 36 ;; The buffer at the start of the list will be the one visited when
41 ;; you press return. By typing more of the substring, the list is 37 ;; you press return. By typing more of the substring, the list is
42 ;; narrowed down so that gradually the buffer you want will be at the 38 ;; narrowed down so that gradually the buffer you want will be at the
43 ;; top of the list. Alternatively, you can use C-s an C-r to rotate 39 ;; top of the list. Alternatively, you can use C-s and C-r to rotate
44 ;; buffer names in the list until the one you want is at the top of 40 ;; buffer names in the list until the one you want is at the top of
45 ;; the list. Completion is also available so that you can see what is 41 ;; the list. Completion is also available so that you can see what is
46 ;; common to all of the matching buffers as you type. 42 ;; common to all of the matching buffers as you type.
47 43
48 ;; This code is similar to a couple of other packages. Michael R Cook 44 ;; This code is similar to a couple of other packages. Michael R Cook
49 ;; <cook@sightpath.com> wrote a similar buffer switching package, but 45 ;; <cook@sightpath.com> wrote a similar buffer switching package, but
50 ;; does exact matching rather than substring matching on buffer names. 46 ;; does exact matching rather than substring matching on buffer names.
51 ;; I also modified a couple of functions from icomplete.el to provide 47 ;; I also modified a couple of functions from icomplete.el to provide
52 ;; the completion feedback in the minibuffer. 48 ;; the completion feedback in the minibuffer.
53 49
54 ;;; Example 50 ;;; Example
55 51
56 ;;If I have two buffers called "123456" and "123", with "123456" the 52 ;;If I have two buffers called "123456" and "123", with "123456" the
57 ;;most recent, when I use iswitchb, I first of all get presented with 53 ;;most recent, when I use iswitchb, I first of all get presented with
58 ;;the list of all the buffers 54 ;;the list of all the buffers
59 ;; 55 ;;
60 ;; iswitch {123456,123} 56 ;; iswitch {123456,123}
61 ;; 57 ;;
62 ;; If I then press 2: 58 ;; If I then press 2:
63 ;; iswitch 2[3]{123456,123} 59 ;; iswitch 2[3]{123456,123}
64 ;; 60 ;;
65 ;; The list in {} are the matching buffers, most recent first (buffers 61 ;; The list in {} are the matching buffers, most recent first (buffers
67 ;; default). At any time I can select the item at the head of the 63 ;; default). At any time I can select the item at the head of the
68 ;; list by pressing RET. I can also bring the put the first element 64 ;; list by pressing RET. I can also bring the put the first element
69 ;; at the end of the list by pressing C-s, or put the last element at 65 ;; at the end of the list by pressing C-s, or put the last element at
70 ;; the head of the list by pressing C-r. The item in [] indicates 66 ;; the head of the list by pressing C-r. The item in [] indicates
71 ;; what can be added to my input by pressing TAB. In this case, I 67 ;; what can be added to my input by pressing TAB. In this case, I
72 ;; will get "3" added to my input. So, press TAB: 68 ;; will get "3" added to my input. So, press TAB:
73 ;; iswitch 23{123456,123} 69 ;; iswitch 23{123456,123}
74 ;; 70 ;;
75 ;; At this point, I still have two matching buffers. 71 ;; At this point, I still have two matching buffers.
76 ;; If I want the first buffer in the list, I simply press RET. If I 72 ;; If I want the first buffer in the list, I simply press RET. If I
77 ;; wanted the second in the list, I could press C-s to move it to the 73 ;; wanted the second in the list, I could press C-s to move it to the
112 ;; (describe-function 'iswitchb) 108 ;; (describe-function 'iswitchb)
113 109
114 ;; Case matching: The case of strings when matching can be ignored or 110 ;; Case matching: The case of strings when matching can be ignored or
115 ;; used depending on the value of iswitchb-case (default is the same 111 ;; used depending on the value of iswitchb-case (default is the same
116 ;; as case-fold-search, normally t). Imagine you have the following 112 ;; as case-fold-search, normally t). Imagine you have the following
117 ;; buffers: 113 ;; buffers:
118 ;; 114 ;;
119 ;; INBOX *info* *scratch* 115 ;; INBOX *info* *scratch*
120 ;; 116 ;;
121 ;; Then these will be the matching buffers, depending on how you type 117 ;; Then these will be the matching buffers, depending on how you type
122 ;; the two letters `in' and the value of iswitchb-case: 118 ;; the two letters `in' and the value of iswitchb-case:
123 ;; 119 ;;
124 ;; iswitchb-case user input | matching buffers 120 ;; iswitchb-case user input | matching buffers
125 ;; ---------------------------------------------- 121 ;; ----------------------------------------------
126 ;; nil in | *info* 122 ;; nil in | *info*
127 ;; t in | INBOX, *info* 123 ;; t in | INBOX, *info*
128 ;; t IN | INBOX 124 ;; t IN | INBOX
129 ;; t In | [No match] 125 ;; t In | [No match]
130 126
131 ;;; Customisation 127 ;;; Customisation
132 128
133 ;; See the User Variables section below for easy ways to change the 129 ;; See the User Variables section below for easy ways to change the
134 ;; functionality of the program. These are accessible using the 130 ;; functionality of the program. These are accessible using the
180 ;; for the normal buffer selection routine `read-buffer'. To use 176 ;; for the normal buffer selection routine `read-buffer'. To use
181 ;; iswitch for all buffer selections in Emacs, add: 177 ;; iswitch for all buffer selections in Emacs, add:
182 ;; (setq read-buffer-function 'iswitchb-read-buffer) 178 ;; (setq read-buffer-function 'iswitchb-read-buffer)
183 ;; (This variable should be present in Emacs 20.3+) 179 ;; (This variable should be present in Emacs 20.3+)
184 ;; XEmacs users can get the same behaviour by doing: 180 ;; XEmacs users can get the same behaviour by doing:
185 ;; (defalias 'read-buffer 'iswitchb-read-buffer) 181 ;; (defalias 'read-buffer 'iswitchb-read-buffer)
186 ;; since `read-buffer' is defined in lisp. 182 ;; since `read-buffer' is defined in lisp.
187 183
188 ;; Regexp matching 184 ;; Regexp matching
189 185
190 ;; There is limited provision for regexp matching within iswitchb, 186 ;; There is limited provision for regexp matching within iswitchb,
222 (if (and (featurep 'custom) (fboundp 'custom-declare-variable)) 218 (if (and (featurep 'custom) (fboundp 'custom-declare-variable))
223 nil ;; We've got what we needed 219 nil ;; We've got what we needed
224 ;; We have the old custom-library, hack around it! 220 ;; We have the old custom-library, hack around it!
225 (defmacro defgroup (&rest args) 221 (defmacro defgroup (&rest args)
226 nil) 222 nil)
227 (defmacro defcustom (var value doc &rest args) 223 (defmacro defcustom (var value doc &rest args)
228 `(defvar ,var ,value ,doc)))) 224 `(defvar ,var ,value ,doc))))
229 225
230 ;;; User Variables 226 ;;; User Variables
231 ;; 227 ;;
232 ;; These are some things you might want to change. 228 ;; These are some things you might want to change.
233 229
234 (defgroup iswitchb nil 230 (defgroup iswitchb nil
235 "Switch between buffers using substrings." 231 "Switch between buffers using substrings."
236 :group 'extensions
237 :group 'convenience 232 :group 'convenience
238 ;; These links are to be added in later versions of custom and 233 :group 'completion
239 ;; so are currently commented out.
240 :link '(emacs-commentary-link :tag "Commentary" "iswitchb.el") 234 :link '(emacs-commentary-link :tag "Commentary" "iswitchb.el")
235 :link '(url-link "http://www.anc.ed.ac.uk/~stephen/emacs/")
241 :link '(emacs-library-link :tag "Lisp File" "iswitchb.el")) 236 :link '(emacs-library-link :tag "Lisp File" "iswitchb.el"))
237
238 ;;;###autoload
239 (defcustom iswitchb-mode nil
240 "Toggle Iswitchb mode.
241 Setting this variable directly does not take effect;
242 use either \\[customize] or the function `iswitchb-mode'."
243 :set (lambda (symbol value)
244 (iswitchb-mode (or value 0)))
245 :initialize 'custom-initialize-default
246 :group 'iswitchb
247 :version "21.1"
248 :type 'boolean)
249
250 (defcustom iswitchb-mode-hook nil
251 "Hook run at the end of function `iswitchb-mode'."
252 :group 'iswitchb
253 :type 'hook)
242 254
243 (defcustom iswitchb-case case-fold-search 255 (defcustom iswitchb-case case-fold-search
244 "*Non-nil if searching of buffer names should ignore case. 256 "*Non-nil if searching of buffer names should ignore case.
245 If this is non-nil but the user input has any upper case letters, matching 257 If this is non-nil but the user input has any upper case letters, matching
246 is temporarily case sensitive." 258 is temporarily case sensitive."
276 `maybe-frame' If a buffer is visible in another frame, prompt to ask if you 288 `maybe-frame' If a buffer is visible in another frame, prompt to ask if you
277 you want to see the buffer in the same window of the current 289 you want to see the buffer in the same window of the current
278 frame or in the other frame. 290 frame or in the other frame.
279 `always-frame' If a buffer is visible in another frame, raise that 291 `always-frame' If a buffer is visible in another frame, raise that
280 frame. Otherwise, visit the buffer in the same window." 292 frame. Otherwise, visit the buffer in the same window."
281 :type '(choice (const samewindow) 293 :type '(choice (const samewindow)
282 (const otherwindow) 294 (const otherwindow)
283 (const display) 295 (const display)
284 (const otherframe) 296 (const otherframe)
285 (const maybe-frame) 297 (const maybe-frame)
286 (const always-frame)) 298 (const always-frame))
287 :group 'iswitchb) 299 :group 'iswitchb)
288 300
289 (defcustom iswitchb-regexp nil 301 (defcustom iswitchb-regexp nil
303 See also `iswitchb-newbuffer'." 315 See also `iswitchb-newbuffer'."
304 :type 'boolean 316 :type 'boolean
305 :group 'iswitchb) 317 :group 'iswitchb)
306 318
307 (defcustom iswitchb-define-mode-map-hook nil 319 (defcustom iswitchb-define-mode-map-hook nil
308 "*Hook to define keys in `iswitchb-mode-map' for extra keybindings." 320 "Hook to define keys in `iswitchb-mode-map' for extra keybindings."
309 :type 'hook 321 :type 'hook
310 :group 'iswitchb) 322 :group 'iswitchb)
311 323
312 (defcustom iswitchb-use-fonts t 324 (defcustom iswitchb-use-fonts t
313 "*Non-nil means use font-lock fonts for showing first match." 325 "*Non-nil means use font-lock fonts for showing first match."
318 "*Non-nil means use the currently selected frame's buffer list." 330 "*Non-nil means use the currently selected frame's buffer list."
319 :type 'boolean 331 :type 'boolean
320 :group 'iswitchb) 332 :group 'iswitchb)
321 333
322 (defcustom iswitchb-make-buflist-hook nil 334 (defcustom iswitchb-make-buflist-hook nil
323 "*Hook to run when list of matching buffers is created." 335 "Hook to run when list of matching buffers is created."
324 :type 'hook 336 :type 'hook
325 :group 'iswitchb) 337 :group 'iswitchb)
326 338
327 (defvar iswitchb-all-frames 'visible 339 (defvar iswitchb-all-frames 'visible
328 "*Argument to pass to `walk-windows' when finding visible buffers. 340 "*Argument to pass to `walk-windows' when finding visible buffers.
329 See documentation of `walk-windows' for useful values.") 341 See documentation of `walk-windows' for useful values.")
330 342
331 (defcustom iswitchb-minibuffer-setup-hook nil 343 (defcustom iswitchb-minibuffer-setup-hook nil
332 "*Iswitchb-specific customization of minibuffer setup. 344 "Iswitchb-specific customization of minibuffer setup.
333 345
334 This hook is run during minibuffer setup iff `iswitchb' will be active. 346 This hook is run during minibuffer setup iff `iswitchb' will be active.
335 It is intended for use in customizing iswitchb for interoperation 347 It is intended for use in customizing iswitchb for interoperation
336 with other packages. For instance: 348 with other packages."
337 349 ;;; For instance:
338 \(add-hook 'iswitchb-minibuffer-setup-hook 350
339 \(function 351 ;;; \(add-hook 'iswitchb-minibuffer-setup-hook
340 \(lambda () 352 ;;; \(function
341 \(make-local-variable 'resize-minibuffer-window-max-height) 353 ;;; \(lambda ()
342 \(setq resize-minibuffer-window-max-height 3)))) 354 ;;; \(make-local-variable 'resize-minibuffer-window-max-height)
343 355 ;;; \(setq resize-minibuffer-window-max-height 3))))
344 will constrain rsz-mini to a maximum minibuffer height of 3 lines when 356
345 iswitchb is running. Copied from `icomplete-minibuffer-setup-hook'." 357 ;;; will constrain rsz-mini to a maximum minibuffer height of 3 lines when
358 ;;; iswitchb is running. Copied from `icomplete-minibuffer-setup-hook'."
346 :type 'hook 359 :type 'hook
347 :group 'iswitchb) 360 :group 'iswitchb)
348 361
349 ;; Do we need the variable iswitchb-use-mycompletion? 362 ;; Do we need the variable iswitchb-use-mycompletion?
350 363
351 ;;; Internal Variables 364 ;;; Internal Variables
352 365
353 (defvar iswitchb-method nil 366 (defvar iswitchb-method nil
354 "Stores the method for viewing the selected buffer. 367 "Stores the method for viewing the selected buffer.
355 Its value is one of `samewindow', `otherwindow', `display', `otherframe', 368 Its value is one of `samewindow', `otherwindow', `display', `otherframe',
356 `maybe-frame' or `always-frame'. See `iswitchb-default-method' for 369 `maybe-frame' or `always-frame'. See `iswitchb-default-method' for
357 details of values.") 370 details of values.")
358 371
359 (defvar iswitchb-eoinput 1 372 (defvar iswitchb-eoinput 1
368 at the end of the list. Created by `iswitchb-make-buflist'.") 381 at the end of the list. Created by `iswitchb-make-buflist'.")
369 382
370 ;; todo -- is this necessary? 383 ;; todo -- is this necessary?
371 384
372 (defvar iswitchb-use-mycompletion nil 385 (defvar iswitchb-use-mycompletion nil
373 "Non-nil means use `iswitchb-buffer' completion feedback. 386 "Non-nil means use `iswitchb-buffer' completion feedback.
374 Should only be set to t by iswitchb functions, so that it doesn't 387 Should only be set to t by iswitchb functions, so that it doesn't
375 interfere with other minibuffer usage.") 388 interfere with other minibuffer usage.")
376 389
377 (defvar iswitchb-change-word-sub nil 390 (defvar iswitchb-change-word-sub nil
378 "Private variable used by `iswitchb-word-matching-substring'.") 391 "Private variable used by `iswitchb-word-matching-substring'.")
379 392
380 (defvar iswitchb-common-match-string nil 393 (defvar iswitchb-common-match-string nil
381 "Stores the string that is common to all matching buffers.") 394 "Stores the string that is common to all matching buffers.")
382 395
387 "Stores the users string as it is typed in.") 400 "Stores the users string as it is typed in.")
388 401
389 (defvar iswitchb-matches nil 402 (defvar iswitchb-matches nil
390 "List of buffers currently matching `iswitchb-text'.") 403 "List of buffers currently matching `iswitchb-text'.")
391 404
392 (defvar iswitchb-mode-map nil 405 (defvar iswitchb-mode-map
393 "Keymap for `iswitchb-buffer'.") 406 (let ((map (make-sparse-keymap)))
394 407 (set-keymap-parent map minibuffer-local-map)
395 (defvar iswitchb-history nil 408 (define-key map "?" 'iswitchb-completion-help)
409 (define-key map "\C-s" 'iswitchb-next-match)
410 (define-key map "\C-r" 'iswitchb-prev-match)
411 (define-key map "\t" 'iswitchb-complete)
412 (define-key map "\C-j" 'iswitchb-select-buffer-text)
413 (define-key map "\C-t" 'iswitchb-toggle-regexp)
414 (define-key map "\C-x\C-f" 'iswitchb-find-file)
415 (define-key map "\C-c" 'iswitchb-toggle-case)
416 (define-key map "\C-k" 'iswitchb-kill-buffer)
417 (define-key map "\C-m" 'iswitchb-exit-minibuffer)
418 map)
419 "Minibuffer keymap for `iswitchb-buffer'.")
420
421 (defvar iswitchb-global-map
422 (let ((map (make-sparse-keymap)))
423 (substitute-key-definition 'switch-to-buffer ; normally C-x b
424 'iswitchb-buffer map global-map)
425 (substitute-key-definition 'switch-to-buffer-other-window ; C-x 4 b
426 'iswitchb-buffer-other-window map global-map)
427 (substitute-key-definition 'switch-to-buffer-other-frame ; C-x 5 b
428 'iswitchb-buffer-other-frame map global-map)
429 (substitute-key-definition 'display-buffer ; C-x 4 C-o
430 'iswitchb-display-buffer map global-map)
431 map)
432 "Global keymap for `iswtichb-mode'.")
433
434 (defvar iswitchb-history nil
396 "History of buffers selected using `iswitchb-buffer'.") 435 "History of buffers selected using `iswitchb-buffer'.")
397 436
398 (defvar iswitchb-exit nil 437 (defvar iswitchb-exit nil
399 "Flag to monitor how `iswitchb-buffer' exits. 438 "Flag to monitor how `iswitchb-buffer' exits.
400 If equal to `takeprompt', we use the prompt as the buffer name to be 439 If equal to `takeprompt', we use the prompt as the buffer name to be
401 selected.") 440 selected.")
402 441
403 (defvar iswitchb-buffer-ignore-orig nil 442 (defvar iswitchb-buffer-ignore-orig nil
404 "Stores original value of `iswitchb-buffer-ignore'.") 443 "Stores original value of `iswitchb-buffer-ignore'.")
419 (defvar iswitchb-bufs-in-frame nil 458 (defvar iswitchb-bufs-in-frame nil
420 "List of the buffers visible in the current frame.") 459 "List of the buffers visible in the current frame.")
421 460
422 ;;; FUNCTIONS 461 ;;; FUNCTIONS
423 462
424 ;;; ISWITCHB KEYMAP 463 ;;; ISWITCHB KEYMAP
425 (defun iswitchb-define-mode-map () 464 (defun iswitchb-define-mode-map ()
426 "Set up the keymap for `iswitchb-buffer'." 465 "Set up the keymap for `iswitchb-buffer'.
466 This is obsolete. Use \\[iswitchb-mode] or customize the
467 variable `iswitchb-mode'."
427 (interactive) 468 (interactive)
428 (let (map) 469 (let (map)
429 ;; generated every time so that it can inherit new functions. 470 ;; generated every time so that it can inherit new functions.
430 ;;(or iswitchb-mode-map 471 ;;(or iswitchb-mode-map
431 472
459 \\[iswitchb-select-buffer-text] Select the current prompt as the buffer. 500 \\[iswitchb-select-buffer-text] Select the current prompt as the buffer.
460 If no buffer is found, prompt for a new one. 501 If no buffer is found, prompt for a new one.
461 502
462 \\[iswitchb-next-match] Put the first element at the end of the list. 503 \\[iswitchb-next-match] Put the first element at the end of the list.
463 \\[iswitchb-prev-match] Put the last element at the start of the list. 504 \\[iswitchb-prev-match] Put the last element at the start of the list.
464 \\[iswitchb-complete] Complete a common suffix to the current string that 505 \\[iswitchb-complete] Complete a common suffix to the current string that
465 matches all buffers. If there is only one match, select that buffer. 506 matches all buffers. If there is only one match, select that buffer.
466 If there is no common suffix, show a list of all matching buffers 507 If there is no common suffix, show a list of all matching buffers
467 in a separate window. 508 in a separate window.
468 \\[iswitchb-toggle-regexp] Toggle regexp searching. 509 \\[iswitchb-toggle-regexp] Toggle regexp searching.
469 \\[iswitchb-toggle-case] Toggle case-sensitive searching of buffer names. 510 \\[iswitchb-toggle-case] Toggle case-sensitive searching of buffer names.
470 \\[iswitchb-completion-help] Show list of matching buffers in separate window. 511 \\[iswitchb-completion-help] Show list of matching buffers in separate window.
471 \\[iswitchb-find-file] Exit iswitchb and drop into find-file. 512 \\[iswitchb-find-file] Exit iswitchb and drop into `find-file'.
472 \\[iswitchb-kill-buffer] Kill buffer at head of buffer list." 513 \\[iswitchb-kill-buffer] Kill buffer at head of buffer list."
473 ;;\\[iswitchb-toggle-ignore] Toggle ignoring certain buffers (see \ 514 ;;\\[iswitchb-toggle-ignore] Toggle ignoring certain buffers (see \
474 ;;`iswitchb-buffer-ignore') 515 ;;`iswitchb-buffer-ignore')
475 516
476 (let 517 (let
500 )))) 541 ))))
501 542
502 ;;;###autoload 543 ;;;###autoload
503 (defun iswitchb-read-buffer (prompt &optional default require-match) 544 (defun iswitchb-read-buffer (prompt &optional default require-match)
504 "Replacement for the built-in `read-buffer'. 545 "Replacement for the built-in `read-buffer'.
505 Return the name of a buffer selected. 546 Return the name of a buffer selected.
506 PROMPT is the prompt to give to the user. DEFAULT if given is the default 547 PROMPT is the prompt to give to the user. DEFAULT if given is the default
507 buffer to be selected, which will go to the front of the list. 548 buffer to be selected, which will go to the front of the list.
508 If REQUIRE-MATCH is non-nil, an existing-buffer must be selected." 549 If REQUIRE-MATCH is non-nil, an existing-buffer must be selected."
509 (let 550 (let
510 ( 551 (
524 (if (bufferp default) 565 (if (bufferp default)
525 (buffer-name default) 566 (buffer-name default)
526 default)) 567 default))
527 (iswitchb-make-buflist iswitchb-default) 568 (iswitchb-make-buflist iswitchb-default)
528 (iswitchb-set-matches) 569 (iswitchb-set-matches)
529 (let 570 (let
530 ((minibuffer-local-completion-map iswitchb-mode-map) 571 ((minibuffer-local-completion-map iswitchb-mode-map)
531 (iswitchb-prepost-hooks t) 572 (iswitchb-prepost-hooks t)
532 (iswitchb-require-match require-match)) 573 (iswitchb-require-match require-match))
533 ;; prompt the user for the buffer name 574 ;; prompt the user for the buffer name
534 (setq iswitchb-final-text (completing-read 575 (setq iswitchb-final-text (completing-read
535 prompt ;the prompt 576 prompt ;the prompt
536 '(("dummy".1)) ;table 577 '(("dummy".1)) ;table
537 nil ;predicate 578 nil ;predicate
538 nil ;require-match [handled elsewhere] 579 nil ;require-match [handled elsewhere]
539 nil ;initial-contents 580 nil ;initial-contents
540 'iswitchb-history))) 581 'iswitchb-history)))
541 ;; Handling the require-match must be done in a better way. 582 ;; Handling the require-match must be done in a better way.
542 (if (and require-match (not (iswitchb-existing-buffer-p))) 583 (if (and require-match (not (iswitchb-existing-buffer-p)))
543 (error "must specify valid buffer")) 584 (error "Must specify valid buffer"))
544 585
545 (if (or 586 (if (or
546 (eq iswitchb-exit 'takeprompt) 587 (eq iswitchb-exit 'takeprompt)
547 (null iswitchb-matches)) 588 (null iswitchb-matches))
548 (setq buf-sel iswitchb-final-text) 589 (setq buf-sel iswitchb-final-text)
549 ;; else take head of list 590 ;; else take head of list
550 (setq buf-sel (car iswitchb-matches))) 591 (setq buf-sel (car iswitchb-matches)))
551 592
552 ;; Or possibly choose the default buffer 593 ;; Or possibly choose the default buffer
553 (if (equal iswitchb-final-text "") 594 (if (equal iswitchb-final-text "")
554 (setq buf-sel 595 (setq buf-sel
555 (car iswitchb-matches))) 596 (car iswitchb-matches)))
556 597
557 buf-sel)) 598 buf-sel))
558 599
559 (defun iswitchb-existing-buffer-p () 600 (defun iswitchb-existing-buffer-p ()
603 ))))) 644 )))))
604 645
605 ;;; TOGGLE FUNCTIONS 646 ;;; TOGGLE FUNCTIONS
606 647
607 (defun iswitchb-toggle-case () 648 (defun iswitchb-toggle-case ()
608 "Toggle the value of `iswitchb-case'." 649 "Toggle the value of variable `iswitchb-case'."
609 (interactive) 650 (interactive)
610 (setq iswitchb-case (not iswitchb-case)) 651 (setq iswitchb-case (not iswitchb-case))
611 ;; ask for list to be regenerated. 652 ;; ask for list to be regenerated.
612 (setq iswitchb-rescan t)) 653 (setq iswitchb-rescan t))
613 654
644 (interactive) 685 (interactive)
645 (setq iswitchb-exit 'takeprompt) 686 (setq iswitchb-exit 'takeprompt)
646 (exit-minibuffer)) 687 (exit-minibuffer))
647 688
648 (defun iswitchb-find-file () 689 (defun iswitchb-find-file ()
649 "Drop into find-file from buffer switching." 690 "Drop into `find-file' from buffer switching."
650 (interactive) 691 (interactive)
651 (setq iswitchb-exit 'findfile) 692 (setq iswitchb-exit 'findfile)
652 (exit-minibuffer)) 693 (exit-minibuffer))
653 694
654 (defun iswitchb-next-match () 695 (defun iswitchb-next-match ()
655 "Put first element of `iswitchb-matches' at the end of the list." 696 "Put first element of `iswitchb-matches' at the end of the list."
656 (interactive) 697 (interactive)
657 (let ((next (cadr iswitchb-matches))) 698 (let ((next (cadr iswitchb-matches)))
658 (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist next)) 699 (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist next))
659 (setq iswitchb-rescan t))) 700 (setq iswitchb-rescan t)))
660 701
661 (defun iswitchb-prev-match () 702 (defun iswitchb-prev-match ()
662 "Put last element of `iswitchb-matches' at the front of the list." 703 "Put last element of `iswitchb-matches' at the front of the list."
663 (interactive) 704 (interactive)
664 (let ((prev (car (last iswitchb-matches)))) 705 (let ((prev (car (last iswitchb-matches))))
665 (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist prev)) 706 (setq iswitchb-buflist (iswitchb-chop iswitchb-buflist prev))
666 (setq iswitchb-rescan t))) 707 (setq iswitchb-rescan t)))
683 ;;; CREATE LIST OF ALL CURRENT BUFFERS 724 ;;; CREATE LIST OF ALL CURRENT BUFFERS
684 725
685 (defun iswitchb-make-buflist (default) 726 (defun iswitchb-make-buflist (default)
686 "Set `iswitchb-buflist' to the current list of buffers. 727 "Set `iswitchb-buflist' to the current list of buffers.
687 Currently visible buffers are put at the end of the list. 728 Currently visible buffers are put at the end of the list.
688 The hook `iswitchb-make-buflist-hook' is run after the list has been 729 The hook `iswitchb-make-buflist-hook' is run after the list has been
689 created to allow the user to further modify the order of the buffer names 730 created to allow the user to further modify the order of the buffer names
690 in this list. If DEFAULT is non-nil, and corresponds to an existing buffer, 731 in this list. If DEFAULT is non-nil, and corresponds to an existing buffer,
691 it is put to the start of the list." 732 it is put to the start of the list."
692 (setq iswitchb-buflist 733 (setq iswitchb-buflist
693 (let* ((iswitchb-current-buffers (iswitchb-get-buffers-in-frames)) 734 (let* ((iswitchb-current-buffers (iswitchb-get-buffers-in-frames))
694 (iswitchb-temp-buflist 735 (iswitchb-temp-buflist
695 (delq nil 736 (delq nil
696 (mapcar 737 (mapcar
697 (lambda (x) 738 (lambda (x)
698 (let ((b-name (buffer-name x))) 739 (let ((b-name (buffer-name x)))
699 (if (not 740 (if (not
700 (or 741 (or
701 (iswitchb-ignore-buffername-p b-name) 742 (iswitchb-ignore-buffername-p b-name)
702 (memq b-name iswitchb-current-buffers))) 743 (memq b-name iswitchb-current-buffers)))
703 b-name))) 744 b-name)))
704 (buffer-list (and iswitchb-use-frame-buffer-list 745 (buffer-list (and iswitchb-use-frame-buffer-list
705 (selected-frame))))))) 746 (selected-frame)))))))
707 (run-hooks 'iswitchb-make-buflist-hook) 748 (run-hooks 'iswitchb-make-buflist-hook)
708 ;; Should this be after the hooks, or should the hooks be the 749 ;; Should this be after the hooks, or should the hooks be the
709 ;; final thing to be run? 750 ;; final thing to be run?
710 (if default 751 (if default
711 (progn 752 (progn
712 (setq iswitchb-temp-buflist 753 (setq iswitchb-temp-buflist
713 (delete default iswitchb-temp-buflist)) 754 (delete default iswitchb-temp-buflist))
714 (setq iswitchb-temp-buflist 755 (setq iswitchb-temp-buflist
715 (cons default iswitchb-temp-buflist)))) 756 (cons default iswitchb-temp-buflist))))
716 iswitchb-temp-buflist))) 757 iswitchb-temp-buflist)))
717 758
718 (defun iswitchb-to-end (lst) 759 (defun iswitchb-to-end (lst)
719 "Move the elements from LST to the end of `iswitchb-temp-buflist'." 760 "Move the elements from LST to the end of `iswitchb-temp-buflist'."
720 (mapcar 761 (mapcar
721 (lambda (elem) 762 (lambda (elem)
722 (setq iswitchb-temp-buflist (delq elem iswitchb-temp-buflist))) 763 (setq iswitchb-temp-buflist (delq elem iswitchb-temp-buflist)))
723 lst) 764 lst)
724 (nconc iswitchb-temp-buflist lst)) 765 (nconc iswitchb-temp-buflist lst))
725 766
726 (defun iswitchb-get-buffers-in-frames (&optional current) 767 (defun iswitchb-get-buffers-in-frames (&optional current)
727 "Return the list of buffers that are visible in the current frame. 768 "Return the list of buffers that are visible in the current frame.
728 If optional argument `current' is given, restrict searching to the 769 If optional argument CURRENT is given, restrict searching to the
729 current frame, rather than all frames, regardless of value of 770 current frame, rather than all frames, regardless of value of
730 `iswitchb-all-frames'." 771 `iswitchb-all-frames'."
731 (let ((iswitchb-bufs-in-frame nil)) 772 (let ((iswitchb-bufs-in-frame nil))
732 (walk-windows 'iswitchb-get-bufname nil 773 (walk-windows 'iswitchb-get-bufname nil
733 (if current 774 (if current
734 nil 775 nil
735 iswitchb-all-frames)) 776 iswitchb-all-frames))
736 iswitchb-bufs-in-frame)) 777 iswitchb-bufs-in-frame))
737 778
738 (defun iswitchb-get-bufname (win) 779 (defun iswitchb-get-bufname (win)
841 "Return dotted pair (RES . 1)." 882 "Return dotted pair (RES . 1)."
842 (cons res 1)) 883 (cons res 1))
843 884
844 ;; from Wayne Mesard <wmesard@esd.sgi.com> 885 ;; from Wayne Mesard <wmesard@esd.sgi.com>
845 (defun iswitchb-rotate-list (lis) 886 (defun iswitchb-rotate-list (lis)
846 "Destructively removes the last element from LIS. 887 "Destructively remove the last element from LIS.
847 Return the modified list with the last element prepended to it." 888 Return the modified list with the last element prepended to it."
848 (if (<= (length lis) 1) 889 (if (<= (length lis) 1)
849 lis 890 lis
850 (let ((las lis) 891 (let ((las lis)
851 (prev lis)) 892 (prev lis))
857 898
858 (defun iswitchb-completion-help () 899 (defun iswitchb-completion-help ()
859 "Show possible completions in a *Buffer Completions* buffer." 900 "Show possible completions in a *Buffer Completions* buffer."
860 ;; we could allow this buffer to be used to select match, but I think 901 ;; we could allow this buffer to be used to select match, but I think
861 ;; choose-completion-string will need redefining, so it just inserts 902 ;; choose-completion-string will need redefining, so it just inserts
862 ;; choice with out any previous input. 903 ;; choice with out any previous input.
863 (interactive) 904 (interactive)
864 (setq iswitchb-rescan nil) 905 (setq iswitchb-rescan nil)
865 (let ((completion-setup-hook nil) ;disable fancy highlight/selection. 906 (let ((completion-setup-hook nil) ;disable fancy highlight/selection.
866 (buf (current-buffer)) 907 (buf (current-buffer))
867 (temp-buf "*Buffer Completions*") 908 (temp-buf "*Buffer Completions*")
877 (set-window-start win (point-min)) 918 (set-window-start win (point-min))
878 (scroll-other-window)) 919 (scroll-other-window))
879 (set-buffer buf)) 920 (set-buffer buf))
880 921
881 (with-output-to-temp-buffer temp-buf 922 (with-output-to-temp-buffer temp-buf
882 (if iswitchb-xemacs 923 (if iswitchb-xemacs
883 924
884 ;; XEmacs extents are put on by default, doesn't seem to be 925 ;; XEmacs extents are put on by default, doesn't seem to be
885 ;; any way of switching them off. 926 ;; any way of switching them off.
886 (display-completion-list (if iswitchb-matches 927 (display-completion-list (if iswitchb-matches
887 iswitchb-matches 928 iswitchb-matches
888 iswitchb-buflist) 929 iswitchb-buflist)
889 :help-string "iswitchb " 930 :help-string "iswitchb "
890 :activate-callback 931 :activate-callback
891 (lambda (x y z) 932 (lambda (x y z)
892 (message "doesn't work yet, sorry!"))) 933 (message "doesn't work yet, sorry!")))
893 ;; else running Emacs 934 ;; else running Emacs
935 (with-current-buffer standard-output
936 (fundamental-mode))
894 (display-completion-list (if iswitchb-matches 937 (display-completion-list (if iswitchb-matches
895 iswitchb-matches 938 iswitchb-matches
896 iswitchb-buflist)) 939 iswitchb-buflist))
897 ))))) 940 )))))
898 941
899 ;;; KILL CURRENT BUFFER 942 ;;; KILL CURRENT BUFFER
900 943
913 ;; Check if buffer exists. XEmacs gnuserv.el makes alias 956 ;; Check if buffer exists. XEmacs gnuserv.el makes alias
914 ;; for kill-buffer which does not return t if buffer is 957 ;; for kill-buffer which does not return t if buffer is
915 ;; killed, so we can't rely on kill-buffer return value. 958 ;; killed, so we can't rely on kill-buffer return value.
916 (if (get-buffer buf) 959 (if (get-buffer buf)
917 ;; buffer couldn't be killed. 960 ;; buffer couldn't be killed.
918 (setq iswitchb-rescan t) 961 (setq iswitchb-rescan t)
919 ;; else buffer was killed so remove name from list. 962 ;; else buffer was killed so remove name from list.
920 (setq iswitchb-buflist (delq buf iswitchb-buflist))))))) 963 (setq iswitchb-buflist (delq buf iswitchb-buflist)))))))
921 964
922 ;;; VISIT CHOSEN BUFFER 965 ;;; VISIT CHOSEN BUFFER
923 (defun iswitchb-visit-buffer (buffer) 966 (defun iswitchb-visit-buffer (buffer)
994 1037
995 ;;;###autoload 1038 ;;;###autoload
996 (defun iswitchb-default-keybindings () 1039 (defun iswitchb-default-keybindings ()
997 "Set up default keybindings for `iswitchb-buffer'. 1040 "Set up default keybindings for `iswitchb-buffer'.
998 Call this function to override the normal bindings. This function also 1041 Call this function to override the normal bindings. This function also
999 adds a hook to the minibuffer." 1042 adds a hook to the minibuffer.
1043
1044 Obsolescent. Use `iswitchb-mode'."
1000 (interactive) 1045 (interactive)
1001 (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup) 1046 (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)
1002 (global-set-key "\C-xb" 'iswitchb-buffer) 1047 (global-set-key "\C-xb" 'iswitchb-buffer)
1003 (global-set-key "\C-x4b" 'iswitchb-buffer-other-window) 1048 (global-set-key "\C-x4b" 'iswitchb-buffer-other-window)
1004 (global-set-key "\C-x4\C-o" 'iswitchb-display-buffer) 1049 (global-set-key "\C-x4\C-o" 'iswitchb-display-buffer)
1062 (iswitchb-exhibit) 1107 (iswitchb-exhibit)
1063 (goto-char (point-min))))) 1108 (goto-char (point-min)))))
1064 1109
1065 ;; add this hook for XEmacs only. 1110 ;; add this hook for XEmacs only.
1066 (if iswitchb-xemacs 1111 (if iswitchb-xemacs
1067 (add-hook 'iswitchb-minibuffer-setup-hook 1112 (add-hook 'iswitchb-minibuffer-setup-hook
1068 'iswitchb-init-XEmacs-trick)) 1113 'iswitchb-init-XEmacs-trick))
1069 1114
1070 ;;; XEmacs / backspace key 1115 ;;; XEmacs / backspace key
1071 ;; For some reason, if the backspace key is pressed in XEmacs, the 1116 ;; For some reason, if the backspace key is pressed in XEmacs, the
1072 ;; line gets confused, so I've added a simple key definition to make 1117 ;; line gets confused, so I've added a simple key definition to make
1073 ;; backspace act like the normal delete key. 1118 ;; backspace act like the normal delete key.
1074 1119
1075 (defun iswitchb-xemacs-backspacekey () 1120 (defun iswitchb-xemacs-backspacekey ()
1076 "Bind backspace to `backward-delete-char'." 1121 "Bind backspace to `backward-delete-char'."
1077 (define-key iswitchb-mode-map '[backspace] 'backward-delete-char) 1122 (define-key iswitchb-mode-map '[backspace] 'backward-delete-char)
1078 (define-key iswitchb-mode-map '[(meta backspace)] 'backward-kill-word)) 1123 (define-key iswitchb-mode-map '[(meta backspace)] 'backward-kill-word))
1079 1124
1080 (if iswitchb-xemacs 1125 (if iswitchb-xemacs
1081 (add-hook 'iswitchb-define-mode-map-hook 1126 (add-hook 'iswitchb-define-mode-map-hook
1082 'iswitchb-xemacs-backspacekey)) 1127 'iswitchb-xemacs-backspacekey))
1083 1128
1084 ;;; ICOMPLETE TYPE CODE 1129 ;;; ICOMPLETE TYPE CODE
1085 1130
1086 (defun iswitchb-exhibit () 1131 (defun iswitchb-exhibit ()
1129 (if (and iswitchb-use-fonts comps) 1174 (if (and iswitchb-use-fonts comps)
1130 (progn 1175 (progn
1131 (setq first (car comps)) 1176 (setq first (car comps))
1132 (setq first (format "%s" first)) 1177 (setq first (format "%s" first))
1133 (put-text-property 0 (length first) 'face 1178 (put-text-property 0 (length first) 'face
1134 (if (= (length comps) 1) 1179 (if (= (length comps) 1)
1135 'font-lock-comment-face 1180 'font-lock-comment-face
1136 'font-lock-function-name-face) 1181 'font-lock-function-name-face)
1137 first) 1182 first)
1138 (setq comps (cons first (cdr comps))))) 1183 (setq comps (cons first (cdr comps)))))
1139 1184
1140 (cond ((null comps) (format " %sNo match%s" 1185 (cond ((null comps) (format " %sNo match%s"
1141 open-bracket-determined 1186 open-bracket-determined
1142 close-bracket-determined)) 1187 close-bracket-determined))
1143 1188
1144 ((null (cdr comps)) ;one match 1189 ((null (cdr comps)) ;one match
1145 (concat (if (and (> (length (car comps)) 1190 (concat (if (and (> (length (car comps))
1146 (length name))) 1191 (length name)))
1147 (concat open-bracket-determined 1192 (concat open-bracket-determined
1148 ;; when there is one match, show the 1193 ;; when there is one match, show the
1149 ;; matching buffer name in full 1194 ;; matching buffer name in full
1150 (car comps) 1195 (car comps)
1151 close-bracket-determined) 1196 close-bracket-determined)
1152 "") 1197 "")
1153 (if (not iswitchb-use-fonts) " [Matched]"))) 1198 (if (not iswitchb-use-fonts) " [Matched]")))
1180 1225
1181 ;; put in common completion item -- what you get by 1226 ;; put in common completion item -- what you get by
1182 ;; pressing tab 1227 ;; pressing tab
1183 (if (> (length iswitchb-common-match-string) (length name)) 1228 (if (> (length iswitchb-common-match-string) (length name))
1184 (concat open-bracket-determined 1229 (concat open-bracket-determined
1185 (substring iswitchb-common-match-string 1230 (substring iswitchb-common-match-string
1186 (length name)) 1231 (length name))
1187 close-bracket-determined)) 1232 close-bracket-determined))
1188 ;; end of partial matches... 1233 ;; end of partial matches...
1189 1234
1190 ;; think this bit can be ignored. 1235 ;; think this bit can be ignored.
1258 (defun iswitchb-summaries-to-end () 1303 (defun iswitchb-summaries-to-end ()
1259 "Move the summaries to the end of the list. 1304 "Move the summaries to the end of the list.
1260 This is an example function which can be hooked on to 1305 This is an example function which can be hooked on to
1261 `iswitchb-make-buflist-hook'. Any buffer matching the regexps 1306 `iswitchb-make-buflist-hook'. Any buffer matching the regexps
1262 `Summary' or `output\*$'are put to the end of the list." 1307 `Summary' or `output\*$'are put to the end of the list."
1263 (let ((summaries (delq nil (mapcar 1308 (let ((summaries (delq nil
1264 (lambda (x) 1309 (mapcar
1265 (if (or 1310 (lambda (x)
1266 (string-match "Summary" x) 1311 (if (string-match "Summary\\|output\\*$" x)
1267 (string-match "output\\*$" x)) 1312 x))
1268 x)) 1313 iswitchb-temp-buflist))))
1269 iswitchb-temp-buflist))))
1270 (iswitchb-to-end summaries))) 1314 (iswitchb-to-end summaries)))
1271 1315
1272 (defun iswitchb-case () 1316 (defun iswitchb-case ()
1273 "Return non-nil iff we should ignore case when matching. 1317 "Return non-nil iff we should ignore case when matching.
1274 See the variable `iswitchb-case' for details." 1318 See the variable `iswitchb-case' for details."
1275 (if iswitchb-case 1319 (if iswitchb-case
1276 (if iswitchb-xemacs 1320 (if iswitchb-xemacs
1277 (isearch-no-upper-case-p iswitchb-text) 1321 (isearch-no-upper-case-p iswitchb-text)
1278 (isearch-no-upper-case-p iswitchb-text t)))) 1322 (isearch-no-upper-case-p iswitchb-text t))))
1279 1323
1324 ;;;###autoload
1325 (defun iswitchb-mode (&optional arg)
1326 "Toggle Iswitchb global minor mode.
1327 With arg, turn Iswitchb mode on if and only iff ARG is positive.
1328 This mode enables switching between buffers using substrings. See
1329 `iswitchb' for details."
1330 (interactive "P")
1331 (setq iswitchb-mode
1332 (if arg
1333 (> (prefix-numeric-value arg) 0)
1334 (not iswitchb-mode)))
1335 (if iswitchb-mode
1336 (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)
1337 (remove-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup))
1338 (run-hooks 'iswitchb-mode-hook)
1339 (if (interactive-p)
1340 (message "Iswitchb mode %sabled"
1341 (if iswitchb-mode "en" "dis"))))
1342
1343 (unless (assq 'iswitchb-mode minor-mode-map-alist)
1344 (push (cons 'iswitchb-mode iswitchb-global-map)
1345 minor-mode-map-alist))
1346
1280 (provide 'iswitchb) 1347 (provide 'iswitchb)
1281 1348
1282 ;;; iswitchb.el ends here 1349 ;;; iswitchb.el ends here