Mercurial > emacs
diff lisp/filecache.el @ 18388:7e14277c51f3
Initial revision
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 22 Jun 1997 20:08:32 +0000 |
parents | |
children | 7eb29ad824eb |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/filecache.el Sun Jun 22 20:08:32 1997 +0000 @@ -0,0 +1,666 @@ +;;; filecache.el --- Find files using a pre-loaded cache +;; +;; Author: Peter Breton +;; Created: Sun Nov 10 1996 +;; Version: $Id: filecache.el,v 1.13 1997/02/07 22:27:51 pbreton Exp $ +;; Keywords: +;; Time-stamp: <97/02/07 17:26:54 peter> +;; +;; Copyright (C) Peter Breton Thu Dec 12 1996 +;; +;; This is free software; you can redistribute it and/or modify +;; 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. +;; +;; filecache.el is distributed in the hope that it will be useful, +;; 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 Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; +;; LCD Archive Entry: +;; filecache.el|Peter Breton|pbreton@i-kinetics.com| +;; Find files using a pre-loaded cache| +;; Thu Dec 12 1996|1.0|~/misc/filecache.el.gz| +;; +;; Purpose: +;; +;; Find files using a pre-loaded cache +;; +;;; Commentary: +;; +;; The file-cache package is an attempt to make it easy to locate files +;; by name, without having to remember exactly where they are located. +;; This is very handy when working with source trees. You can also add +;; frequently used files to the cache to create a hotlist effect. +;; The cache can be used with any interactive command which takes a +;; filename as an argument. +;; +;; It is worth noting that this package works best when most of the files +;; in the cache have unique names, or (if they have the same name) exist in +;; only a few directories. The worst case is many files all with +;; the same name and in different directories, for example a big source tree +;; with a Makefile in each directory. In such a case, you should probably +;; use an alternate strategy to find the files. +;; +;; ADDING FILES TO THE CACHE: +;; +;; Use the following functions to add items to the file cache: +;; +;; * `file-cache-add-file': Adds a single file to the cache +;; +;; * `file-cache-add-file-list': Adds a list of files to the cache +;; +;; The following functions use the regular expressions in +;; `file-cache-delete-regexps' to eliminate unwanted files: +;; +;; * `file-cache-add-directory': Adds the files in a directory to the +;; cache. You can also specify a regular expression to match the files +;; which should be added. +;; +;; * `file-cache-add-directory-list': Same as above, but acts on a list +;; of directories. You can use `load-path', `exec-path' and the like. +;; +;; * `file-cache-add-directory-using-find': Uses the `find' command to +;; add a directory tree to the cache. +;; +;; * `file-cache-add-directory-using-locate': Uses the `locate' command to +;; add files matching a pattern to the cache. +;; +;; Use the function `file-cache-clear-cache' to remove all items from the +;; cache. There are a number of `file-cache-delete' functions provided +;; as well, but in general it is probably better to not worry too much +;; about extra files in the cache. +;; +;; The most convenient way to initialize the cache is with an +;; `eval-after-load' function, as noted in the INSTALLATION section. +;; +;; FINDING FILES USING THE CACHE: +;; +;; You can use the file-cache with any function that expects a filename as +;; an argument. For example: +;; +;; 1) Invoke a function which expects a filename as an argument: +;; M-x find-file +;; +;; 2) Begin typing a file name. +;; +;; 3) Invoke `file-cache-minibuffer-complete' (bound by default to +;; C-TAB) to complete on the filename using the cache. +;; +;; 4) When you have found a unique completion, the minibuffer contents +;; will change to the full name of that file. +;; +;; If there are a number of directories which contain the completion, +;; invoking `file-cache-minibuffer-complete' repeatedly will cycle through +;; them. +;; +;; 5) You can then edit the minibuffer contents, or press RETURN. +;; +;; It is much easier to simply try it than trying to explain it :) +;; +;;; INSTALLATION +;; +;; Insert the following into your .emacs: +;; +;; (autoload 'file-cache-minibuffer-complete "filecache" nil t) +;; +;; For maximum utility, you should probably define an `eval-after-load' +;; form which loads your favorite files: +;; +;; (eval-after-load +;; "filecache" +;; '(progn +;; (message "Loading file cache...") +;; (file-cache-add-directory-using-find "~/projects") +;; (file-cache-add-directory-list load-path) +;; (file-cache-add-directory "~/") +;; (file-cache-add-file-list (list "~/foo/bar" "~/baz/bar")) +;; )) +;; +;; If you clear and reload the cache frequently, it is probably easiest +;; to put your initializations in a function: +;; +;; (eval-after-load +;; "filecache" +;; '(my-file-cache-initialize)) +;; +;; (defun my-file-cache-initialize () +;; (interactive) +;; (message "Loading file cache...") +;; (file-cache-add-directory-using-find "~/projects") +;; (file-cache-add-directory-list load-path) +;; (file-cache-add-directory "~/") +;; (file-cache-add-file-list (list "~/foo/bar" "~/baz/bar")) +;; )) +;; +;; Of course, you can still add files to the cache afterwards, via +;; Lisp functions. +;; +;; RELATED WORK: +;; +;; This package is a distant relative of Noah Friedman's fff utilities. +;; Our goal is pretty similar, but the implementation strategies are +;; different. +;; +;;; Change log: +;; $Log: filecache.el,v $ +;; Revision 1.13 1997/02/07 22:27:51 pbreton +;; Keybindings use autoload cookies instead of variable +;; +;; Revision 1.12 1997/02/07 22:02:29 pbreton +;; Added small changes suggested by RMS: +;; Revamped the doc strings +;; Added keybindings (using `file-cache-default-minibuffer-key' variable) +;; +;; Revision 1.11 1997/02/01 16:44:47 pbreton +;; Changed `file-cache-directory-name' function. Instead of using a +;; completing-read, it cycles through the directory list. +;; +;; Eliminated bug where file-cache-file-name was called twice per completion. +;; +;; Revision 1.10 1997/01/26 05:44:24 pbreton +;; Added file-cache-delete functions +;; Added file-cache-completions-buffer variable +;; Added file-cache-completions-keymap variable +;; Changed file-cache-completion-setup-function to use +;; file-cache-completions-keymap +;; Added file-cache-choose-completion and file-cache-mouse-choose-completion. +;; These rely on a patch to 'simple.el' +;; Added file-cache-debug-read-from-minibuffer function +;; +;; Revision 1.9 1997/01/17 17:54:24 pbreton +;; File names are no longer case-insensitive; this was tolerable on NT but +;; not on Unix. Instead, file-cache-minibuffer-complete checks to see if the +;; last command was itself, and if the same string is in the minibuffer. If so, +;; this string is used for completion. +;; +;; Added some functions to delete from the file-cache +;; +;; Completing-read of directories requires temporary binding of +;; enable-recursive-minibuffers variable. +;; +;; Revision 1.8 1997/01/17 14:01:08 pbreton +;; Changed file-cache-minibuffer-complete so that it operates in the +;; minibuffer instead of as a recursive minibuffer call. +;; +;; File-cache-alist now expects a filename and a list of directories (there +;; should be at least one). If the list has only one element, that element +;; is used; if it has multiple directories, the user is prompted to choose +;; one. +;; +;; File names in the cache are now canonicalized to lowercase, to resolve a +;; problem which occurs when the cache has files like README and readme. +;; +;; Removed a lot of the extra completion functions which weren't used. +;; +;; Revision 1.7 1996/12/29 15:48:28 pbreton +;; Added functions: +;; `file-cache-minibuffer-complete-using-suffix' +;; `file-cache-minibuffer-complete-with-directory-filter' +;; `file-cache-minibuffer-complete-with-filename-filter' +;; Added documentation for these functions +;; +;; Revision 1.6 1996/12/24 20:27:56 pbreton +;; Added predicate functions to `file-cache-minibuffer-complete' +;; +;; Revision 1.5 1996/12/14 18:05:11 pbreton +;; Fixed uniquify bug by using `member' instead of `memq' +;; Made file-cache-add-* prompts more descriptive +;; More documentation +;; +;; Revision 1.4 1996/12/13 14:42:37 pbreton +;; Removed `file-cache-top-directory' variable +;; Changed file-cache-initialize to file-cache-add-from-file-cache-buffer +;; Regexp to match files in file-cache-buffer is now a variable +;; +;; Revision 1.3 1996/12/12 06:01:27 peter +;; Added `file-cache-add-file' and `file-cache-add-file-list' functions +;; +;; Revision 1.2 1996/12/12 05:47:49 peter +;; Fixed uniquifying bug +;; Added directory functions +;; `file-cache-find-file' now uses file-cache-file-name +;; `file-cache-minibuffer-complete' handles string completion correctly. +;; It also prepends `file-cache-minibuffer-prompt' to the normal prompt +;; +;; Revision 1.1 1996/11/26 12:12:43 peter +;; Initial revision +;; +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; User-modifiable variables +(defvar file-cache-filter-regexps + (list "~$" "\\.o$" "\\.exe$" "\\.a$" "\\.elc$" ",v$" "\\.output$" + "\\.$" "#$") + "*List of regular expressions used as filters by the file cache. +File names which match these expressions will not be added to the cache. +Note that the functions `file-cache-add-file' and `file-cache-add-file-list' +do not use this variable.") + +(defvar file-cache-find-command "find" + "*External program used by `file-cache-add-directory-using-find'.") + +(defvar file-cache-locate-command "locate" + "*External program used by `file-cache-add-directory-using-locate'.") + +;; Minibuffer messages +(defvar file-cache-no-match-message " [File Cache: No match]" + "Message to display when there is no completion.") + +(defvar file-cache-sole-match-message " [File Cache: sole completion]" + "Message to display when there is only one completion.") + +(defvar file-cache-non-unique-message " [File Cache: complete but not unique]" + "Message to display when there is a non-unique completion.") + +(defvar file-cache-multiple-directory-message nil) + +;; Internal variables +;; This should be named *Completions* because that's what the function +;; switch-to-completions in simple.el expects +(defvar file-cache-completions-buffer "*Completions*" + "Buffer to display completions when using the file cache.") + +(defvar file-cache-buffer "*File Cache*" + "Buffer to hold the cache of file names.") + +(defvar file-cache-buffer-default-regexp "^.+$" + "Regexp to match files in `file-cache-buffer'.") + +(defvar file-cache-last-completion nil) + +(defvar file-cache-alist nil + "Internal data structure to hold cache of file names.") + +(defvar file-cache-completions-keymap nil + "Keymap for file cache completions buffer.") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Functions to add files to the cache +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun file-cache-add-directory (directory &optional regexp) + "Add DIRECTORY to the file cache. +If the optional REGEXP argument is non-nil, only files which match it will +be added to the cache." + (interactive "DAdd files from directory: ") + (let* ((dir (expand-file-name directory)) + (dir-files (directory-files dir t regexp)) + ) + ;; Filter out files we don't want to see + (mapcar + '(lambda (file) + (mapcar + '(lambda (regexp) + (if (string-match regexp file) + (setq dir-files (delq file dir-files)))) + file-cache-filter-regexps)) + dir-files) + (file-cache-add-file-list dir-files))) + +(defun file-cache-add-directory-list (directory-list &optional regexp) + "Add DIRECTORY-LIST (a list of directory names) to the file cache. +If the optional REGEXP argument is non-nil, only files which match it +will be added to the cache. Note that the REGEXP is applied to the files +in each directory, not to the directory list itself." + (interactive "XAdd files from directory list: ") + (mapcar + '(lambda (dir) (file-cache-add-directory dir regexp)) + directory-list)) + +(defun file-cache-add-file-list (file-list) + "Add FILE-LIST (a list of files names) to the file cache." + (interactive "XFile List: ") + (mapcar 'file-cache-add-file file-list)) + +;; Workhorse function +(defun file-cache-add-file (file) + "Add FILE to the file cache." + (interactive "fAdd File: ") + (let* ((file-name (file-name-nondirectory file)) + (dir-name (file-name-directory file)) + (the-entry (assoc file-name file-cache-alist)) + ) + ;; Does the entry exist already? + (if the-entry + (if (or (and (stringp (cdr the-entry)) + (string= dir-name (cdr the-entry))) + (and (listp (cdr the-entry)) + (member dir-name (cdr the-entry)))) + nil + (setcdr the-entry (append (list dir-name) (cdr the-entry))) + ) + ;; If not, add it to the cache + (setq file-cache-alist + (cons (cons file-name (list dir-name)) + file-cache-alist))) + )) + +(defun file-cache-add-directory-using-find (directory) + "Use the `find' command to add files to the file cache. +Find is run in DIRECTORY." + (interactive "DAdd files under directory: ") + (let ((dir (expand-file-name directory))) + (set-buffer (get-buffer-create file-cache-buffer)) + (erase-buffer) + (call-process file-cache-find-command nil + (get-buffer file-cache-buffer) nil + dir "-name" + (if (memq system-type + (list 'windows-nt 'ms-dos)) "'*'" "*") + "-print") + (file-cache-add-from-file-cache-buffer))) + +(defun file-cache-add-directory-using-locate (string) + "Use the `locate' command to add files to the file cache. +STRING is passed as an argument to the locate command." + (interactive "sAdd files using locate string: ") + (set-buffer (get-buffer-create file-cache-buffer)) + (erase-buffer) + (call-process file-cache-locate-command nil + (get-buffer file-cache-buffer) nil + string) + (file-cache-add-from-file-cache-buffer)) + +(defun file-cache-add-from-file-cache-buffer (&optional regexp) + "Add any entries found in the file cache buffer. +Each entry matches the regular expression `file-cache-buffer-default-regexp' +or the optional REGEXP argument." + (set-buffer file-cache-buffer) + (mapcar + (function (lambda (elt) + (goto-char (point-min)) + (delete-matching-lines elt))) + file-cache-filter-regexps) + (goto-char (point-min)) + (let ((full-filename)) + (while (re-search-forward + (or regexp file-cache-buffer-default-regexp) + (point-max) t) + (setq full-filename (buffer-substring-no-properties + (match-beginning 0) (match-end 0))) + (file-cache-add-file full-filename)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Functions to delete from the cache +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun file-cache-clear-cache () + "Clear the file cache." + (interactive) + (setq file-cache-alist nil)) + +;; This clears *all* files with the given name +(defun file-cache-delete-file (file) + "Delete FILE from the file cache." + (interactive + (list (completing-read "Delete file from cache: " file-cache-alist))) + (setq file-cache-alist + (delq (assoc file file-cache-alist) file-cache-alist))) + +(defun file-cache-delete-file-list (file-list) + "Delete FILE-LIST (a list of files) from the file cache." + (interactive "XFile List: ") + (mapcar 'file-cache-delete-file file-list)) + +(defun file-cache-delete-file-regexp (regexp) + "Delete files matching REGEXP from the file cache." + (interactive "sRegexp: ") + (let ((delete-list)) + (mapcar '(lambda (elt) + (and (string-match regexp (car elt)) + (setq delete-list (cons (car elt) delete-list)))) + file-cache-alist) + (file-cache-delete-file-list delete-list) + (message "Deleted %d files from file cache" (length delete-list)))) + +(defun file-cache-delete-directory (directory) + "Delete DIRECTORY from the file cache." + (interactive "DDelete directory from file cache: ") + (let ((dir (expand-file-name directory)) + (result 0)) + (mapcar + '(lambda (entry) + (if (file-cache-do-delete-directory dir entry) + (setq result (1+ result)))) + file-cache-alist) + (if (zerop result) + (error "No entries containing %s found in cache" directory) + (message "Deleted %d entries" result)))) + +(defun file-cache-do-delete-directory (dir entry) + (let ((directory-list (cdr entry)) + (directory (file-cache-canonical-directory dir)) + ) + (and (member directory directory-list) + (if (equal 1 (length directory-list)) + (setq file-cache-alist + (delq entry file-cache-alist)) + (setcdr entry (delete directory directory-list))) + ) + )) + +(defun file-cache-delete-directory-list (directory-list) + "Delete DIRECTORY-LIST (a list of directories) from the file cache." + (interactive "XDirectory List: ") + (mapcar 'file-cache-delete-directory directory-list)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Utility functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Returns the name of a directory for a file in the cache +(defun file-cache-directory-name (file) + (let* ((directory-list (cdr (assoc file file-cache-alist))) + (len (length directory-list)) + (directory) + (num) + ) + (if (not (listp directory-list)) + (error "Unknown type in file-cache-alist for key %s" file)) + (cond + ;; Single element + ((eq 1 len) + (setq directory (elt directory-list 0))) + ;; No elements + ((eq 0 len) + (error "No directory found for key %s" file)) + ;; Multiple elements + (t + (let* ((minibuffer-dir (file-name-directory (buffer-string))) + (dir-list (member minibuffer-dir directory-list)) + ) + (setq directory + ;; If the directory is in the list, return the next element + ;; Otherwise, return the first element + (if dir-list + (or (elt directory-list + (setq num (1+ (- len (length dir-list))))) + (elt directory-list (setq num 0))) + (elt directory-list (setq num 0)))) + ) + ) + ) + ;; If there were multiple directories, set up a minibuffer message + (setq file-cache-multiple-directory-message + (and num (format " [%d of %d]" (1+ num) len))) + directory)) + +;; Returns the name of a file in the cache +(defun file-cache-file-name (file) + (let ((directory (file-cache-directory-name file))) + (concat directory file))) + +;; Return a canonical directory for comparison purposes. +;; Such a directory ends with a forward slash. +(defun file-cache-canonical-directory (dir) + (let ((directory dir)) + (if (not (char-equal ?/ (string-to-char (substring directory -1)))) + (concat directory "/") + directory))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Minibuffer functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(defun file-cache-minibuffer-complete () + "Complete a filename in the minibuffer using a preloaded cache." + (interactive) + (let* + ( + (completion-ignore-case nil) + (case-fold-search nil) + (string (file-name-nondirectory (buffer-string))) + (completion-string (try-completion string file-cache-alist)) + (completion-list) + (len) + (file-cache-string) + ) + (cond + ;; If it's the longest match, insert it + ((stringp completion-string) + ;; If we've already inserted a unique string, see if the user + ;; wants to use that one + (if (and (string= string completion-string) + (assoc string file-cache-alist)) + (if (and (eq last-command this-command) + (string= file-cache-last-completion completion-string)) + (progn + (erase-buffer) + (insert-string (file-cache-file-name completion-string)) + (setq file-cache-last-completion nil) + ) + (file-cache-temp-minibuffer-message file-cache-non-unique-message) + (setq file-cache-last-completion string) + ) + (setq file-cache-last-completion string) + (setq completion-list (all-completions string file-cache-alist) + len (length completion-list)) + (if (> len 1) + (progn + (goto-char (point-max)) + (insert-string + (substring completion-string (length string))) + ;; Add our own setup function to the Completions Buffer + (let ((completion-setup-hook + (reverse + (append (list 'file-cache-completion-setup-function) + completion-setup-hook))) + ) + (with-output-to-temp-buffer file-cache-completions-buffer + (display-completion-list completion-list)) + ) + ) + (setq file-cache-string (file-cache-file-name completion-string)) + (if (string= file-cache-string (buffer-string)) + (file-cache-temp-minibuffer-message file-cache-sole-match-message) + (erase-buffer) + (insert-string file-cache-string) + (if file-cache-multiple-directory-message + (file-cache-temp-minibuffer-message + file-cache-multiple-directory-message))) + ))) + + ;; If it's the only match, replace the original contents + ((eq completion-string t) + (setq file-cache-string (file-cache-file-name string)) + (if (string= file-cache-string (buffer-string)) + (file-cache-temp-minibuffer-message file-cache-sole-match-message) + (erase-buffer) + (insert-string file-cache-string) + (if file-cache-multiple-directory-message + (file-cache-temp-minibuffer-message + file-cache-multiple-directory-message)) + )) + + ;; No match + ((eq completion-string nil) + (file-cache-temp-minibuffer-message file-cache-no-match-message)) + ) +)) + +;; Lifted from "complete.el" +(defun file-cache-temp-minibuffer-message (msg) + "A Lisp version of `temp_minibuffer_message' from minibuf.c." + (let ((savemax (point-max))) + (save-excursion + (goto-char (point-max)) + (insert msg)) + (let ((inhibit-quit t)) + (sit-for 2) + (delete-region savemax (point-max)) + (if quit-flag + (setq quit-flag nil + unread-command-events (list 7)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Completion functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun file-cache-completion-setup-function () + (set-buffer file-cache-completions-buffer) + + (if file-cache-completions-keymap + nil + (setq file-cache-completions-keymap + (copy-keymap completion-list-mode-map)) + (define-key file-cache-completions-keymap [mouse-2] + 'file-cache-mouse-choose-completion) + (define-key file-cache-completions-keymap "\C-m" + 'file-cache-choose-completion)) + + (use-local-map file-cache-completions-keymap) + ) + +(defun file-cache-choose-completion () + "Choose a completion in the `*Completions*' buffer." + (interactive) + (let ((completion-no-auto-exit t)) + (choose-completion) + (select-window (active-minibuffer-window)) + (file-cache-minibuffer-complete) + ) + ) + +(defun file-cache-mouse-choose-completion (event) + "Choose a completion with the mouse." + (interactive "e") + (let ((completion-no-auto-exit t)) + (mouse-choose-completion event) + (select-window (active-minibuffer-window)) + (file-cache-minibuffer-complete) + ) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Debugging functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun file-cache-debug-read-from-minibuffer (file) + "Debugging function." + (interactive + (list (completing-read "File Cache: " file-cache-alist))) + (message "%s" (assoc file file-cache-alist)) + ) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Keybindings +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload (define-key minibuffer-local-completion-map [C-tab] 'file-cache-minibuffer-complete) +;;;###autoload (define-key minibuffer-local-map [C-tab] 'file-cache-minibuffer-complete) +;;;###autoload (define-key minibuffer-local-must-match-map [C-tab] 'file-cache-minibuffer-complete) + +(provide 'filecache) + +;;; filecache.el ends here