Here's new version which doesn't use electric, so the pattern editing is more natural.
;;; globalff.el --- Global find file ;; Copyright (C) 2006 Free Software Foundation, Inc. ;; This file 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. ;; This file 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, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;; Start with M-x globallff and type in any substring of any path on ;; your system to display the matching files. The displayed list is ;; updated dynamically as you type more characters or delete some. ;; ;; Needs an up-to-date locate database for file name searching. ;; ;; Since the searching is based on locate you can use any globbing ;; characters allowed by the locate command. ;; ;; You can move up/down the list with the cursor keys (I know these ;; bindings are not very Emacsian, but I happen to like them) and ;; select a file to open with Enter. ;; ;; You can quit with C-g. ;; ;;; Code: ;; ;; User configurable variables ;; (defvar globalff-databases nil "List of database files separated with colon to be used by the locate command. If nil then the system default database is used.") (defvar globalff-minimum-input-length 3 "The minimum number of characters needed to start file searching.") (defvar globalff-search-delay 0.5 "Idle time after last input event, before starting the search.") (defvar globalff-idle-timer nil "Idle timer for monitoring typed characters.") (defconst globalff-buffer "*globalff*" "Buffer used for finding files.") (defvar globalff-previous-input "" "The previous input substring used for searching.") (defvar globalff-overlay nil "Overlay used to highlight the current selection.") (defun globalff-output-filter (process string) "Avoid moving of point if the buffer is empty." (with-current-buffer globalff-buffer (let* ((empty (= (buffer-size) 0)) (moving (and (not empty) (= (point) (process-mark process))))) (save-excursion ;; Insert the text, advancing the process marker. (goto-char (process-mark process)) (insert string) (set-marker (process-mark process) (point))) (if empty (globalff-mark-current-line)) (if moving (goto-char (process-mark process)))))) (defun globalff-mark-current-line () "Mark current line with a distinctive color." (setq globalff-overlay (make-overlay (point-at-bol) (point-at-eol))) (overlay-put globalff-overlay 'face 'region)) (defun globalff-previous-line () "Move mark to the previous line." (interactive) (unless (with-current-buffer globalff-buffer (= (point-min) (line-beginning-position))) (globalff-move-mark -1))) (defun globalff-next-line () "Move mark to the next line." (interactive) (unless (with-current-buffer globalff-buffer (save-excursion (forward-line) (eobp))) (globalff-move-mark +1))) (defun globalff-move-mark (direction) (let ((old-window (selected-window))) (select-window (get-buffer-window globalff-buffer)) (when globalff-overlay (delete-overlay globalff-overlay)) (next-line direction) (globalff-mark-current-line) (select-window old-window))) (defun globalff-process-sentinel (process event) "Prevent printing of process status messages into the output buffer." ) (defun globalff-check-input () "Check input string and start/stop search if necessary." (let ((input (minibuffer-contents))) (unless (equal input globalff-previous-input) (setq globalff-previous-input input) (globalff-kill-process) (with-current-buffer globalff-buffer (erase-buffer)) (setq globalff-overlay nil) (unless (or (equal input "") (< (length input) globalff-minimum-input-length)) (let ((process (start-process "globalff-process" globalff-buffer "locate" (if globalff-databases (concat "--database=" globalff-databases) ;; -i is used as a placeholder ;; since I don't know how to ;; skip an argument "-i") "-i" input))) (set-process-filter process 'globalff-output-filter) (set-process-sentinel process 'globalff-process-sentinel)))))) (defun globalff-kill-process () "Kill find process." (if (eq 'run (process-status globalff-buffer)) (delete-process globalff-buffer))) (defun globalff () "Start global find file." (interactive) (let ((winconfig (current-window-configuration))) (pop-to-buffer globalff-buffer) (erase-buffer) (setq globalff-overlay nil) (setq globalff-previous-input "") (setq globalff-idle-timer (run-with-idle-timer globalff-search-delay t 'globalff-check-input)) (define-key minibuffer-local-map (kbd "<down>") 'globalff-next-line) (define-key minibuffer-local-map (kbd "<up>") 'globalff-previous-line) (with-current-buffer globalff-buffer (setq cursor-type nil)) (unwind-protect (read-string "substring: ") (define-key minibuffer-local-map (kbd "<down>") 'next-history-element) (define-key minibuffer-local-map (kbd "<up>") 'previous-history-element) (globalff-kill-process) (cancel-timer globalff-idle-timer) (with-current-buffer globalff-buffer (setq cursor-type t)) (set-window-configuration winconfig))) (unless (= (buffer-size (get-buffer globalff-buffer)) 0) (assert globalff-overlay) (find-file (with-current-buffer globalff-buffer (buffer-substring-no-properties (overlay-start globalff-overlay) (overlay-end globalff-overlay)))))) (provide 'globalff) ;;; globalff.el ends here _______________________________________________ gnu-emacs-sources mailing list gnu-emacs-sources@gnu.org http://lists.gnu.org/mailman/listinfo/gnu-emacs-sources