emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Patch for "virtual buffers" in iswitchb


From: John Wiegley
Subject: Patch for "virtual buffers" in iswitchb
Date: Sun, 18 Apr 2004 04:13:37 -0700
User-agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3.50 (darwin)

Haven't signed my general papers yet, and would like some review on
this anyway:

The following patch adds a feature to iswitchb (off by default) that I
call "virtual buffers".  Basically, when a buffer visiting a file is
killed, iswitchb remembers the name and location of that file.  If the
user then types a search string and fails to match a living buffer,
iswitchb will consult the list of remembered ones, and allow the user
to match against those names.  Fontification is changed to reflect
that these are "virtual" matches.  If a virtual buffer is selected,
the buffer is resurrected by visiting the last known path associated
with that buffer name.

The motivation for this patch is that many of the files I open using
C-x C-f are being reopened.  Combined with a module like session.el,
virtual buffers allow my work environment to become more predictive.

John

Index: iswitchb.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/iswitchb.el,v
retrieving revision 1.48
diff -w -U3 -r1.48 iswitchb.el
--- iswitchb.el 18 Apr 2004 10:31:29 -0000      1.48
+++ iswitchb.el 18 Apr 2004 11:08:53 -0000
@@ -305,6 +305,20 @@
   :type 'integer
   :group 'iswitchb)
 
+(defcustom iswitchb-use-virtual-buffers nil
+  "*If non-nil, refer to past buffers when none match."
+  :type 'boolean
+  :set (function
+       (lambda (sym value)
+         (if value
+             (add-hook 'kill-buffer-hook 'iswitchb-remember-file)
+           (remove-hook 'kill-buffer-hook 'iswitchb-remember-file))
+         (set sym value)))
+  :group 'iswitchb)
+
+(defvar iswitchb-virtual-buffer-alist nil)
+(defvar iswitchb-virtual-buffers nil)
+
 (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
@@ -613,7 +627,17 @@
     (if (and (not (eq iswitchb-exit 'usefirst))
             (get-buffer iswitchb-final-text))
        ;; This happens for example if the buffer was chosen with the mouse.
-       (setq iswitchb-matches (list iswitchb-final-text)))
+       (setq iswitchb-matches (list iswitchb-final-text)
+             iswitchb-virtual-buffers nil))
+
+    (if (and iswitchb-use-virtual-buffers
+            (not (iswitchb-existing-buffer-p))
+            iswitchb-virtual-buffers)
+       (let ((virt (assoc (car iswitchb-virtual-buffers)
+                          iswitchb-virtual-buffer-alist)))
+         (find-file-noselect (cdr virt))
+         (setq iswitchb-matches (list (car virt))
+               iswitchb-virtual-buffers nil)))
 
     ;; Handling the require-match must be done in a better way.
     (if (and require-match (not (iswitchb-existing-buffer-p)))
@@ -833,7 +857,8 @@
       (setq iswitchb-matches
            (let* ((buflist iswitchb-buflist))
              (iswitchb-get-matched-buffers iswitchb-text iswitchb-regexp
-                                           buflist)))))
+                                           buflist))
+           iswitchb-virtual-buffers nil)))
 
 (defun iswitchb-get-matched-buffers (regexp
                                     &optional string-format buffer-list)
@@ -1192,6 +1217,25 @@
                   contents
                   (not minibuffer-completion-confirm)))))))
 
+(defun iswitchb-remember-file ()
+  (if (and buffer-file-name
+          (file-exists-p buffer-file-name))
+      (let* ((name (file-name-nondirectory buffer-file-name))
+            (virt (assoc name iswitchb-virtual-buffer-alist)))
+       (if virt
+           (setcdr virt buffer-file-name)
+         (setq iswitchb-virtual-buffer-alist
+               (cons (cons name buffer-file-name)
+                     iswitchb-virtual-buffer-alist))))))
+
+(defun iswitchb-virtual-buffer-predicate (entry)
+  (let ((name (car entry)))
+    (and (or (and iswitchb-regexp (string-match iswitchb-text name))
+            (and (null iswitchb-regexp)
+                 (string-match (regexp-quote iswitchb-text) name)))
+        (not (iswitchb-ignore-buffername-p name))
+        (file-exists-p (cdr entry)))))
+
 (defun iswitchb-output-completion (com)
   (if (= (length com) most-len)
       ;; Most is one exact match,
@@ -1225,6 +1273,23 @@
                             first)
          (setq comps  (cons first (cdr comps)))))
 
+    ;; If no buffers matched, and virtual buffers are being used, then
+    ;; consult the list of past visited files, to see if we can find
+    ;; the file which the user might thought was still open.
+    (if (and iswitchb-use-virtual-buffers (null comps)
+            iswitchb-virtual-buffer-alist)
+       (progn
+         (setq iswitchb-virtual-buffers
+               (all-completions "" iswitchb-virtual-buffer-alist
+                                'iswitchb-virtual-buffer-predicate)
+               comps iswitchb-virtual-buffers)
+         (let ((comp comps))
+           (while comp
+             (put-text-property 0 (length (car comp))
+                                'face 'font-lock-builtin-face
+                                (car comp))
+             (setq comp (cdr comp))))))
+
     (cond ((null comps) (format " %sNo match%s"
                                open-bracket-determined
                                close-bracket-determined))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]