298 |
:type '(repeat (choice regexp function)) |
:type '(repeat (choice regexp function)) |
299 |
:group 'iswitchb) |
:group 'iswitchb) |
300 |
|
|
301 |
|
(defcustom iswitchb-max-to-show nil |
302 |
|
"*If non-nil, limit the number of names shown in the minibuffer. |
303 |
|
If this value is N, and N is greater than the number of matching |
304 |
|
buffers, the first N/2 and the last N/2 matching buffers are |
305 |
|
shown. This can greatly speed up iswitchb if you have a |
306 |
|
multitude of buffers open." |
307 |
|
:type '(choice (const :tag "Show all" nil) integer) |
308 |
|
:group 'iswitchb) |
309 |
|
|
310 |
|
(defcustom iswitchb-use-virtual-buffers nil |
311 |
|
"*If non-nil, refer to past buffers when none match. |
312 |
|
This feature relies upon the `recentf' package, which will be |
313 |
|
enabled if this variable is configured to a non-nil value." |
314 |
|
:type 'boolean |
315 |
|
:require 'recentf |
316 |
|
:set (function |
317 |
|
(lambda (sym value) |
318 |
|
(if value (recentf-mode 1)) |
319 |
|
(set sym value))) |
320 |
|
:group 'iswitchb) |
321 |
|
|
322 |
|
(defvar iswitchb-virtual-buffers nil) |
323 |
|
|
324 |
(defcustom iswitchb-cannot-complete-hook 'iswitchb-completion-help |
(defcustom iswitchb-cannot-complete-hook 'iswitchb-completion-help |
325 |
"*Hook run when `iswitchb-complete' can't complete any more. |
"*Hook run when `iswitchb-complete' can't complete any more. |
326 |
The most useful values are `iswitchb-completion-help', which pops up a |
The most useful values are `iswitchb-completion-help', which pops up a |
478 |
(substitute-key-definition 'display-buffer ; C-x 4 C-o |
(substitute-key-definition 'display-buffer ; C-x 4 C-o |
479 |
'iswitchb-display-buffer map global-map) |
'iswitchb-display-buffer map global-map) |
480 |
map) |
map) |
481 |
"Global keymap for `iswtichb-mode'.") |
"Global keymap for `iswitchb-mode'.") |
482 |
|
|
483 |
(defvar iswitchb-history nil |
(defvar iswitchb-history nil |
484 |
"History of buffers selected using `iswitchb-buffer'.") |
"History of buffers selected using `iswitchb-buffer'.") |
585 |
(iswitchb-possible-new-buffer buf))) |
(iswitchb-possible-new-buffer buf))) |
586 |
)))) |
)))) |
587 |
|
|
588 |
;;;###autoload |
(defun iswitchb-read-buffer (prompt &optional default require-match |
589 |
(defun iswitchb-read-buffer (prompt &optional default require-match) |
start matches-set) |
590 |
"Replacement for the built-in `read-buffer'. |
"Replacement for the built-in `read-buffer'. |
591 |
Return the name of a buffer selected. |
Return the name of a buffer selected. |
592 |
PROMPT is the prompt to give to the user. DEFAULT if given is the default |
PROMPT is the prompt to give to the user. |
593 |
buffer to be selected, which will go to the front of the list. |
DEFAULT if given is the default buffer to be selected, which will |
594 |
If REQUIRE-MATCH is non-nil, an existing-buffer must be selected." |
go to the front of the list. |
595 |
|
If REQUIRE-MATCH is non-nil, an existing-buffer must be selected. |
596 |
|
If START is a string, the selection process is started with that |
597 |
|
string. |
598 |
|
If MATCHES-SET is non-nil, the buflist is not updated before |
599 |
|
the selection process begins. Used by isearchb.el." |
600 |
(let |
(let |
601 |
( |
( |
602 |
buf-sel |
buf-sel |
609 |
|
|
610 |
(iswitchb-define-mode-map) |
(iswitchb-define-mode-map) |
611 |
(setq iswitchb-exit nil) |
(setq iswitchb-exit nil) |
|
(setq iswitchb-rescan t) |
|
|
(setq iswitchb-text "") |
|
612 |
(setq iswitchb-default |
(setq iswitchb-default |
613 |
(if (bufferp default) |
(if (bufferp default) |
614 |
(buffer-name default) |
(buffer-name default) |
615 |
default)) |
default)) |
616 |
(iswitchb-make-buflist iswitchb-default) |
(setq iswitchb-text (or start "")) |
617 |
(iswitchb-set-matches) |
(unless matches-set |
618 |
|
(setq iswitchb-rescan t) |
619 |
|
(iswitchb-make-buflist iswitchb-default) |
620 |
|
(iswitchb-set-matches)) |
621 |
(let |
(let |
622 |
((minibuffer-local-completion-map iswitchb-mode-map) |
((minibuffer-local-completion-map iswitchb-mode-map) |
623 |
;; Record the minibuffer depth that we expect to find once |
;; Record the minibuffer depth that we expect to find once |
626 |
(iswitchb-require-match require-match)) |
(iswitchb-require-match require-match)) |
627 |
;; prompt the user for the buffer name |
;; prompt the user for the buffer name |
628 |
(setq iswitchb-final-text (completing-read |
(setq iswitchb-final-text (completing-read |
629 |
prompt ;the prompt |
prompt ;the prompt |
630 |
'(("dummy" . 1)) ;table |
'(("dummy" . 1)) ;table |
631 |
nil ;predicate |
nil ;predicate |
632 |
nil ;require-match [handled elsewhere] |
nil ;require-match [handled elsewhere] |
633 |
nil ;initial-contents |
start ;initial-contents |
634 |
'iswitchb-history))) |
'iswitchb-history))) |
635 |
(if (and (not (eq iswitchb-exit 'usefirst)) |
(if (and (not (eq iswitchb-exit 'usefirst)) |
636 |
(get-buffer iswitchb-final-text)) |
(get-buffer iswitchb-final-text)) |
637 |
;; This happens for example if the buffer was chosen with the mouse. |
;; This happens for example if the buffer was chosen with the mouse. |
638 |
(setq iswitchb-matches (list iswitchb-final-text))) |
(setq iswitchb-matches (list iswitchb-final-text) |
639 |
|
iswitchb-virtual-buffers nil)) |
640 |
|
|
641 |
|
;; If no buffer matched, but a virtual buffer was selected, visit |
642 |
|
;; that file now and act as though that buffer had been selected. |
643 |
|
(if (and iswitchb-virtual-buffers |
644 |
|
(not (iswitchb-existing-buffer-p))) |
645 |
|
(let ((virt (car iswitchb-virtual-buffers))) |
646 |
|
(find-file-noselect (cdr virt)) |
647 |
|
(setq iswitchb-matches (list (car virt)) |
648 |
|
iswitchb-virtual-buffers nil))) |
649 |
|
|
650 |
;; Handling the require-match must be done in a better way. |
;; Handling the require-match must be done in a better way. |
651 |
(if (and require-match (not (iswitchb-existing-buffer-p))) |
(if (and require-match |
652 |
|
(not (iswitchb-existing-buffer-p))) |
653 |
(error "Must specify valid buffer")) |
(error "Must specify valid buffer")) |
654 |
|
|
655 |
(if (or |
(if (or (eq iswitchb-exit 'takeprompt) |
656 |
(eq iswitchb-exit 'takeprompt) |
(null iswitchb-matches)) |
|
(null iswitchb-matches)) |
|
657 |
(setq buf-sel iswitchb-final-text) |
(setq buf-sel iswitchb-final-text) |
658 |
;; else take head of list |
;; else take head of list |
659 |
(setq buf-sel (car iswitchb-matches))) |
(setq buf-sel (car iswitchb-matches))) |
660 |
|
|
661 |
;; Or possibly choose the default buffer |
;; Or possibly choose the default buffer |
662 |
(if (equal iswitchb-final-text "") |
(if (equal iswitchb-final-text "") |
663 |
(setq buf-sel |
(setq buf-sel (car iswitchb-matches))) |
|
(car iswitchb-matches))) |
|
664 |
|
|
665 |
buf-sel)) |
buf-sel)) |
666 |
|
|
761 |
(setq iswitchb-exit 'findfile) |
(setq iswitchb-exit 'findfile) |
762 |
(exit-minibuffer)) |
(exit-minibuffer)) |
763 |
|
|
764 |
|
(eval-when-compile |
765 |
|
(defvar recentf-list)) |
766 |
|
|
767 |
(defun iswitchb-next-match () |
(defun iswitchb-next-match () |
768 |
"Put first element of `iswitchb-matches' at the end of the list." |
"Put first element of `iswitchb-matches' at the end of the list." |
769 |
(interactive) |
(interactive) |
770 |
(let ((next (cadr iswitchb-matches))) |
(let ((next (cadr iswitchb-matches))) |
771 |
(setq iswitchb-buflist (iswitchb-chop iswitchb-buflist next)) |
(if (and (null next) iswitchb-virtual-buffers) |
772 |
|
(setq recentf-list |
773 |
|
(iswitchb-chop recentf-list |
774 |
|
(cdr (cadr iswitchb-virtual-buffers)))) |
775 |
|
(setq iswitchb-buflist (iswitchb-chop iswitchb-buflist next))) |
776 |
(setq iswitchb-rescan t))) |
(setq iswitchb-rescan t))) |
777 |
|
|
778 |
(defun iswitchb-prev-match () |
(defun iswitchb-prev-match () |
779 |
"Put last element of `iswitchb-matches' at the front of the list." |
"Put last element of `iswitchb-matches' at the front of the list." |
780 |
(interactive) |
(interactive) |
781 |
(let ((prev (car (last iswitchb-matches)))) |
(let ((prev (car (last iswitchb-matches)))) |
782 |
(setq iswitchb-buflist (iswitchb-chop iswitchb-buflist prev)) |
(if (and (null prev) iswitchb-virtual-buffers) |
783 |
|
(setq recentf-list |
784 |
|
(iswitchb-chop recentf-list |
785 |
|
(cdr (car (last iswitchb-virtual-buffers))))) |
786 |
|
(setq iswitchb-buflist (iswitchb-chop iswitchb-buflist prev))) |
787 |
(setq iswitchb-rescan t))) |
(setq iswitchb-rescan t))) |
788 |
|
|
789 |
(defun iswitchb-chop (list elem) |
(defun iswitchb-chop (list elem) |
875 |
(setq iswitchb-matches |
(setq iswitchb-matches |
876 |
(let* ((buflist iswitchb-buflist)) |
(let* ((buflist iswitchb-buflist)) |
877 |
(iswitchb-get-matched-buffers iswitchb-text iswitchb-regexp |
(iswitchb-get-matched-buffers iswitchb-text iswitchb-regexp |
878 |
buflist))))) |
buflist)) |
879 |
|
iswitchb-virtual-buffers nil))) |
880 |
|
|
881 |
(defun iswitchb-get-matched-buffers (regexp |
(defun iswitchb-get-matched-buffers (regexp |
882 |
&optional string-format buffer-list) |
&optional string-format buffer-list) |
1114 |
(get-buffer-window buffer 0) ; better than 'visible |
(get-buffer-window buffer 0) ; better than 'visible |
1115 |
))) |
))) |
1116 |
|
|
|
;;;###autoload |
|
1117 |
(defun iswitchb-default-keybindings () |
(defun iswitchb-default-keybindings () |
1118 |
"Set up default keybindings for `iswitchb-buffer'. |
"Set up default keybindings for `iswitchb-buffer'. |
1119 |
Call this function to override the normal bindings. This function also |
Call this function to override the normal bindings. This function also |
1127 |
(global-set-key "\C-x4\C-o" 'iswitchb-display-buffer) |
(global-set-key "\C-x4\C-o" 'iswitchb-display-buffer) |
1128 |
(global-set-key "\C-x5b" 'iswitchb-buffer-other-frame)) |
(global-set-key "\C-x5b" 'iswitchb-buffer-other-frame)) |
1129 |
|
|
|
;;;###autoload |
|
1130 |
(defun iswitchb-buffer () |
(defun iswitchb-buffer () |
1131 |
"Switch to another buffer. |
"Switch to another buffer. |
1132 |
|
|
1139 |
(setq iswitchb-method iswitchb-default-method) |
(setq iswitchb-method iswitchb-default-method) |
1140 |
(iswitchb)) |
(iswitchb)) |
1141 |
|
|
|
;;;###autoload |
|
1142 |
(defun iswitchb-buffer-other-window () |
(defun iswitchb-buffer-other-window () |
1143 |
"Switch to another buffer and show it in another window. |
"Switch to another buffer and show it in another window. |
1144 |
The buffer name is selected interactively by typing a substring. |
The buffer name is selected interactively by typing a substring. |
1147 |
(setq iswitchb-method 'otherwindow) |
(setq iswitchb-method 'otherwindow) |
1148 |
(iswitchb)) |
(iswitchb)) |
1149 |
|
|
|
;;;###autoload |
|
1150 |
(defun iswitchb-display-buffer () |
(defun iswitchb-display-buffer () |
1151 |
"Display a buffer in another window but don't select it. |
"Display a buffer in another window but don't select it. |
1152 |
The buffer name is selected interactively by typing a substring. |
The buffer name is selected interactively by typing a substring. |
1155 |
(setq iswitchb-method 'display) |
(setq iswitchb-method 'display) |
1156 |
(iswitchb)) |
(iswitchb)) |
1157 |
|
|
|
;;;###autoload |
|
1158 |
(defun iswitchb-buffer-other-frame () |
(defun iswitchb-buffer-other-frame () |
1159 |
"Switch to another buffer and show it in another frame. |
"Switch to another buffer and show it in another frame. |
1160 |
The buffer name is selected interactively by typing a substring. |
The buffer name is selected interactively by typing a substring. |
1230 |
contents |
contents |
1231 |
(not minibuffer-completion-confirm))))))) |
(not minibuffer-completion-confirm))))))) |
1232 |
|
|
1233 |
|
(eval-when-compile |
1234 |
|
(defvar most-len) |
1235 |
|
(defvar most-is-exact)) |
1236 |
|
|
1237 |
|
(defun iswitchb-output-completion (com) |
1238 |
|
(if (= (length com) most-len) |
1239 |
|
;; Most is one exact match, |
1240 |
|
;; note that and leave out |
1241 |
|
;; for later indication: |
1242 |
|
(ignore |
1243 |
|
(setq most-is-exact t)) |
1244 |
|
(substring com most-len))) |
1245 |
|
|
1246 |
(defun iswitchb-completions (name require-match) |
(defun iswitchb-completions (name require-match) |
1247 |
"Return the string that is displayed after the user's text. |
"Return the string that is displayed after the user's text. |
1248 |
Modified from `icomplete-completions'." |
Modified from `icomplete-completions'." |
1267 |
first) |
first) |
1268 |
(setq comps (cons first (cdr comps))))) |
(setq comps (cons first (cdr comps))))) |
1269 |
|
|
1270 |
|
;; If no buffers matched, and virtual buffers are being used, then |
1271 |
|
;; consult the list of past visited files, to see if we can find |
1272 |
|
;; the file which the user might thought was still open. |
1273 |
|
(when (and iswitchb-use-virtual-buffers (null comps) |
1274 |
|
recentf-list) |
1275 |
|
(setq iswitchb-virtual-buffers nil) |
1276 |
|
(let ((head recentf-list) name) |
1277 |
|
(while head |
1278 |
|
(if (and (setq name (file-name-nondirectory (car head))) |
1279 |
|
(string-match (if iswitchb-regexp |
1280 |
|
iswitchb-text |
1281 |
|
(regexp-quote iswitchb-text)) name) |
1282 |
|
(null (get-file-buffer (car head))) |
1283 |
|
(not (assoc name iswitchb-virtual-buffers)) |
1284 |
|
(not (iswitchb-ignore-buffername-p name)) |
1285 |
|
(file-exists-p (car head))) |
1286 |
|
(setq iswitchb-virtual-buffers |
1287 |
|
(cons (cons name (car head)) |
1288 |
|
iswitchb-virtual-buffers))) |
1289 |
|
(setq head (cdr head))) |
1290 |
|
(setq iswitchb-virtual-buffers (nreverse iswitchb-virtual-buffers) |
1291 |
|
comps (mapcar 'car iswitchb-virtual-buffers)) |
1292 |
|
(let ((comp comps)) |
1293 |
|
(while comp |
1294 |
|
(put-text-property 0 (length (car comp)) |
1295 |
|
'face 'font-lock-builtin-face |
1296 |
|
(car comp)) |
1297 |
|
(setq comp (cdr comp)))))) |
1298 |
|
|
1299 |
(cond ((null comps) (format " %sNo match%s" |
(cond ((null comps) (format " %sNo match%s" |
1300 |
open-bracket-determined |
open-bracket-determined |
1301 |
close-bracket-determined)) |
close-bracket-determined)) |
1311 |
"") |
"") |
1312 |
(if (not iswitchb-use-fonts) " [Matched]"))) |
(if (not iswitchb-use-fonts) " [Matched]"))) |
1313 |
(t ;multiple matches |
(t ;multiple matches |
1314 |
|
(if (and iswitchb-max-to-show |
1315 |
|
(> (length comps) iswitchb-max-to-show)) |
1316 |
|
(setq comps |
1317 |
|
(append |
1318 |
|
(let ((res nil) |
1319 |
|
(comp comps) |
1320 |
|
(end (/ iswitchb-max-to-show 2))) |
1321 |
|
(while (>= (setq end (1- end)) 0) |
1322 |
|
(setq res (cons (car comp) res) |
1323 |
|
comp (cdr comp))) |
1324 |
|
(nreverse res)) |
1325 |
|
(list "...") |
1326 |
|
(nthcdr (- (length comps) |
1327 |
|
(/ iswitchb-max-to-show 2)) comps)))) |
1328 |
(let* ( |
(let* ( |
1329 |
;;(most (try-completion name candidates predicate)) |
;;(most (try-completion name candidates predicate)) |
1330 |
(most nil) |
(most nil) |
1331 |
(most-len (length most)) |
(most-len (length most)) |
1332 |
most-is-exact |
most-is-exact |
1333 |
(alternatives |
(alternatives |
1334 |
(apply |
(mapconcat (if most 'iswitchb-output-completion |
1335 |
(function concat) |
'identity) comps ","))) |
|
(cdr (apply |
|
|
(function nconc) |
|
|
(mapcar '(lambda (com) |
|
|
(if (= (length com) most-len) |
|
|
;; Most is one exact match, |
|
|
;; note that and leave out |
|
|
;; for later indication: |
|
|
(progn |
|
|
(setq most-is-exact t) |
|
|
()) |
|
|
(list "," |
|
|
(substring com |
|
|
most-len)))) |
|
|
comps)))))) |
|
1336 |
|
|
1337 |
(concat |
(concat |
1338 |
|
|