;; Installation:
;; To get the functions in this package bound to keys, do
;; (iswitchb-default-keybindings)
+;;
+;; If you want to use the features of iswitchb, but without rebinding
+;; the keys as above, then you need to add the following hook:
+;; (add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)
;; As you type in a substring, the list of buffers currently matching
;; the substring are displayed as you type. The list is ordered so
;; common to all of the matching buffers as you type.
;; This code is similar to a couple of other packages. Michael R Cook
-;; <mcook@cognex.com> wrote a similar buffer switching package, but
+;; <cook@sightpath.com> wrote a similar buffer switching package, but
;; 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.
;; See the doc string of iswitchb for full keybindings and features.
;; (describe-function 'iswitchb)
+;; 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
+;; buffers:
+;;
+;; 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
+;; ----------------------------------------------
+;; nil in | *info*
+;; t in | INBOX, *info*
+;; t IN | INBOX
+;; t In | [No match]
+
;;; Customisation
;; See the User Variables section below for easy ways to change the
(defmacro defgroup (&rest args)
nil)
(defmacro defcustom (var value doc &rest args)
- (` (defvar (, var) (, value) (, doc))))))
+ `(defvar ,var ,value ,doc))))
;;; User Variables
;;
:link '(emacs-library-link :tag "Lisp File" "iswitchb.el"))
(defcustom iswitchb-case case-fold-search
- "*Non-nil if searching of buffer names should ignore case."
+ "*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."
:type 'boolean
:group 'iswitchb)
:type 'boolean
:group 'iswitchb)
+(defcustom iswitchb-use-frame-buffer-list nil
+ "*Non-nil means use the currently selected frame's buffer list."
+ :type 'boolean
+ :group 'iswitchb)
+
(defcustom iswitchb-make-buflist-hook nil
"*Hook to run when list of matching buffers is created."
:type 'hook
;; found something to complete, so put it in the minibuffer.
(progn
(setq iswitchb-rescan nil)
- (delete-region (point-min) (point))
+ (delete-region (minibuffer-prompt-end) (point))
(insert res))
;; else nothing to complete
(iswitchb-completion-help)
(iswitchb-ignore-buffername-p b-name)
(memq b-name iswitchb-current-buffers)))
b-name)))
- (buffer-list)))))
+ (buffer-list (and iswitchb-use-frame-buffer-list
+ (selected-frame)))))))
(nconc iswitchb-temp-buflist iswitchb-current-buffers)
(run-hooks 'iswitchb-make-buflist-hook)
;; Should this be after the hooks, or should the hooks be the
"Return buffers matching REGEXP.
If STRING-FORMAT is nil, consider REGEXP as just a string.
BUFFER-LIST can be list of buffers or list of strings."
- (let* ((case-fold-search iswitchb-case)
+ (let* ((case-fold-search (iswitchb-case))
;; need reverse since we are building up list backwards
(list (reverse buffer-list))
(do-string (stringp (car list)))
(defun iswitchb-word-matching-substring (word)
"Return part of WORD before 1st match to `iswitchb-change-word-sub'.
If `iswitchb-change-word-sub' cannot be found in WORD, return nil."
- (let ((case-fold-search iswitchb-case))
+ (let ((case-fold-search (iswitchb-case)))
(let ((m (string-match iswitchb-change-word-sub word)))
(if m
(substring word m)
(setq alist (mapcar 'iswitchb-makealist res)) ;; could use an OBARRAY
;; try-completion returns t if there is an exact match.
- (let ((completion-ignore-case iswitchb-case))
+ (let ((completion-ignore-case (iswitchb-case)))
(try-completion subs alist))))
iswitchb-buflist)
:help-string "iswitchb "
:activate-callback
- '(lambda (x y z)
- (message "doesn't work yet, sorry!")))
+ (lambda (x y z)
+ (message "doesn't work yet, sorry!")))
;; else running Emacs
(display-completion-list (if iswitchb-matches
iswitchb-matches
adds a hook to the minibuffer."
(interactive)
(add-hook 'minibuffer-setup-hook 'iswitchb-minibuffer-setup)
- (global-set-key (read-kbd-macro "C-x b") 'iswitchb-buffer)
- (global-set-key (read-kbd-macro "C-x 4 b") 'iswitchb-buffer-other-window)
- (global-set-key (read-kbd-macro "C-x 4 C-o") 'iswitchb-display-buffer)
- (global-set-key (read-kbd-macro "C-x 5 b") 'iswitchb-buffer-other-frame))
+ (global-set-key "\C-xb" 'iswitchb-buffer)
+ (global-set-key "\C-x4b" 'iswitchb-buffer-other-window)
+ (global-set-key "\C-x4\C-o" 'iswitchb-display-buffer)
+ (global-set-key "\C-x5b" 'iswitchb-buffer-other-frame))
;;;###autoload
(defun iswitchb-buffer ()
Copied from `icomplete-exhibit' with two changes:
1. It prints a default buffer name when there is no text yet entered.
2. It calls my completion routine rather than the standard completion."
-
(if iswitchb-use-mycompletion
- (let ((contents (buffer-string))
+ (let ((contents (buffer-substring (minibuffer-prompt-end) (point-max)))
(buffer-undo-list t))
(save-excursion
(goto-char (point-max))
(iswitchb-set-common-completion)
;; Insert the match-status information:
- (insert-string
- (iswitchb-completions
- contents
- minibuffer-completion-table
- minibuffer-completion-predicate
- (not minibuffer-completion-confirm)))
- ))))
-
-(defun iswitchb-completions
- (name candidates predicate require-match)
+ (insert-string (iswitchb-completions
+ contents
+ minibuffer-completion-table
+ minibuffer-completion-predicate
+ (not minibuffer-completion-confirm)))))))
+
+(defun iswitchb-completions (name candidates predicate require-match)
"Return the string that is displayed after the user's text.
Modified from `icomplete-completions'."
(setq iswitchb-eoinput 1)))
(defun iswitchb-entryfn-p ()
- "Return non-nil if `this-command' shows we are using `iswitchb-buffer'."
- (or (boundp 'iswitchb-prepost-hooks)
- ;; I think the of this may be redundant, since the prepost hooks
- ;; will always be set in the iswitchb defuns.
- ;;(and (symbolp this-command) ; ignore lambda functions
- ;;(memq this-command
- ;; '(iswitchb-buffer
- ;; iswitchb-buffer-other-frame
- ;; iswitchb-display-buffer
- ;; iswitchb-buffer-other-window))))
- ))
+ "Return non-nil if we are using `iswitchb-buffer'."
+ ;; Testing if `iswitchb-prepost-hooks' is bound does not work when
+ ;; we're invoking a recursive mini-buffer from an Iswitchb buffer.
+ ;; In this case, `iswitchb-prepost-hooks' is bound in the second
+ ;; mini-buffer, although it's not an Iswitchb buffer.
+ (memq this-command
+ '(iswitchb-buffer iswitchb-buffer-other-frame
+ iswitchb-display-buffer
+ iswitchb-buffer-other-window)))
(defun iswitchb-summaries-to-end ()
"Move the summaries to the end of the list.
iswitchb-temp-buflist))))
(iswitchb-to-end summaries)))
+(defun iswitchb-case ()
+ "Return non-nil iff we should ignore case when matching.
+See the variable `iswitchb-case' for details."
+ (if iswitchb-case
+ (if iswitchb-xemacs
+ (isearch-no-upper-case-p iswitchb-text)
+ (isearch-no-upper-case-p iswitchb-text t))))
+
(provide 'iswitchb)
;;; iswitchb.el ends here