.
[bpt/emacs.git] / lisp / find-file.el
index fe255f9..ebed0b7 100644 (file)
@@ -1,25 +1,27 @@
 ;;; find-file.el --- find a file corresponding to this one given a pattern
 
-;; Author:         Henry Guillaume <henry@qbd.com.au>
+;; Author: Henry Guillaume <henri@tibco.com, henry@c032.aone.net.au>
+;; Maintainer: FSF
 ;; Keywords: c, matching, tools
 
 ;; Copyright (C) 1994, 1995 Free Software Foundation, Inc.
 
-;;; This file is part of GNU Emacs.
+;; This file is part of GNU Emacs.
 
-;;; GNU Emacs 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.
+;; GNU Emacs 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.
 
-;;; GNU Emacs 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.
+;; GNU Emacs 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.
+;; 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:
 
 ;; The *load-hooks allow you to place point where you want it in the other
 ;; file. 
 
+;;; Change Log:
+;;
 ;; FEEDBACK:
 ;; Please send me bug reports, bug fixes, and extensions, so that I can
 ;; merge them into the master source.
 ;; the development of this package:
 ;;     Rolf Ebert in particular, Fritz Knabe, Heddy Boubaker, Sebastian Kremer,
 ;;     Vasco Lopes Paulo, Mark A. Plaksin, Robert Lang, Trevor West, Kevin 
-;;     Pereira & Benedict Lofstedt.
+;;     Pereira, Benedict Lofstedt & Justin Vallon.
 
-;; Code:
+;;; Code:
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; User definable variables:
 
-(defvar ff-pre-find-hooks nil
-  "*List of functions to be called before the search for the file starts.")
-
-(defvar ff-pre-load-hooks nil
-  "*List of functions to be called before the other file is loaded.")
-
-(defvar ff-post-load-hooks nil
-  "*List of functions to be called after the other file is loaded.")
-
-(defvar ff-not-found-hooks nil
-  "*List of functions to be called if the other file could not be found.")
-
-(defvar ff-file-created-hooks nil
-  "*List of functions to be called if the other file needs to be created.")
-
-(defvar ff-case-fold-search nil
+(defgroup ff nil
+  "Find a file corresponding to this one given a pattern."
+  :prefix "ff-"
+  :group 'find-file)
+
+(defcustom ff-pre-find-hooks nil
+  "*List of functions to be called before the search for the file starts."
+  :type 'hook
+  :group 'ff)
+
+(defcustom ff-pre-load-hooks nil
+  "*List of functions to be called before the other file is loaded."
+  :type 'hook
+  :group 'ff)
+
+(defcustom ff-post-load-hooks nil
+  "*List of functions to be called after the other file is loaded."
+  :type 'hook
+  :group 'ff)
+
+(defcustom ff-not-found-hooks nil
+  "*List of functions to be called if the other file could not be found."
+  :type 'hook
+  :group 'ff)
+
+(defcustom ff-file-created-hooks nil
+  "*List of functions to be called if the other file needs to be created."
+  :type 'hook
+  :group 'ff)
+
+(defcustom ff-case-fold-search nil
   "*Non-nil means ignore cases in matches (see `case-fold-search').
-If you have extensions in different cases, you will want this to be nil.")
+If you have extensions in different cases, you will want this to be nil."
+  :type 'boolean
+  :group 'ff)
 
-(defvar ff-always-in-other-window nil
+(defcustom ff-always-in-other-window nil
   "*If non-nil, find the corresponding file in another window by default.
-To override this, give an argument to `ff-find-other-file'.")
+To override this, give an argument to `ff-find-other-file'."
+  :type 'boolean
+  :group 'ff)
 
-(defvar ff-ignore-include nil
-  "*If non-nil, ignore `#include' lines.")
+(defcustom ff-ignore-include nil
+  "*If non-nil, ignore `#include' lines."
+  :type 'boolean
+  :group 'ff)
 
-(defvar ff-always-try-to-create t
-  "*If non-nil, always attempt to create the other file if it was not found.")
+(defcustom ff-always-try-to-create t
+  "*If non-nil, always attempt to create the other file if it was not found."
+  :type 'boolean
+  :group 'ff)
 
-(defvar ff-quiet-mode nil
-  "*If non-nil, trace which directories are being searched.")
+(defcustom ff-quiet-mode nil
+  "*If non-nil, trace which directories are being searched."
+  :type 'boolean
+  :group 'ff)
 
 (defvar ff-special-constructs 
   '(
@@ -169,23 +198,27 @@ To override this, give an argument to `ff-find-other-file'.")
     ("^with[ \t]+\\([a-zA-Z0-9_\\.]+\\)" .
      (lambda ()
        (setq fname (buffer-substring (match-beginning 1) (match-end 1)))
+       (require 'ada-mode)
        (setq fname (concat (ada-make-filename-from-adaname fname)
-                           ada-spec-suffix))))
+                          ada-spec-suffix))))
     )
   "*A list of regular expressions specifying how to recognise special 
 constructs such as include files etc, and an associated method for 
 extracting the filename from that construct.")
 
-(defvar ff-other-file-alist 'cc-other-file-alist
+(defcustom ff-other-file-alist 'cc-other-file-alist
   "*Alist of extensions to find given the current file's extension.
 
 This list should contain the most used extensions before the others,
 since the search algorithm searches sequentially through each
 directory specified in `ff-search-directories'.  If a file is not found,
 a new one is created with the first matching extension (`.cc' yields `.hh').
-This alist should be set by the major mode.")
+This alist should be set by the major mode."
+  :type '(choice (repeat (list regexp (choice (repeat string) function)))
+                symbol)
+  :group 'ff)
 
-(defvar ff-search-directories 'cc-search-directories
+(defcustom ff-search-directories 'cc-search-directories
   "*List of directories to search for a specific file.
 
 Set by default to `cc-search-directories', expanded at run-time.
@@ -197,7 +230,7 @@ may not exist.
 
 A typical format is 
 
-    '(\".\" \"/usr/include/*\" \"$PROJECT/*/include\")
+    '(\".\" \"/usr/include\" \"$PROJECT/*/include\")
 
 Environment variables can be inserted between slashes (`/').
 They will be replaced by their definition. If a variable does
@@ -205,13 +238,17 @@ not exist, it is replaced (silently) with an empty string.
 
 The stars are *not* wildcards: they are searched for together with
 the preceding slash.  The star represents all the subdirectories except
-`..', and each of these subdirectories will be searched in turn.")
+`..', and each of these subdirectories will be searched in turn."
+  :type '(choice (repeat directory) symbol)
+  :group 'ff)
 
-(defvar cc-search-directories
-  '("." "/usr/include/*" "/usr/local/include/*")
-  "*See the description of the `ff-search-directories' variable.")
+(defcustom cc-search-directories
+  '("." "/usr/include" "/usr/local/include/*")
+  "*See the description of the `ff-search-directories' variable."
+  :type '(repeat directory)
+  :group 'ff)
 
-(defvar cc-other-file-alist
+(defcustom cc-other-file-alist
   '(
     ("\\.cc$"  (".hh" ".h"))
     ("\\.hh$"  (".cc" ".C"))
@@ -233,38 +270,19 @@ the preceding slash.  The star represents all the subdirectories except
 This list should contain the most used extensions before the others,
 since the search algorithm searches sequentially through each directory
 specified in `ff-search-directories'.  If a file is not found, a new one
-is created with the first matching extension (`.cc' yields `.hh').")
-
-(defvar ada-search-directories
-  '("." "/usr/adainclude" "/usr/local/adainclude")
-  "*See the description for the `ff-search-directories' variable.")
+is created with the first matching extension (`.cc' yields `.hh')."
+  :type '(repeat (list regexp (choice (repeat string) function)))
+  :group 'ff)
 
-(defvar ada-other-file-alist
-  '(
-    ("\\.ads$" (".adb")) ;; Ada specs and bodies
-    ("\\.adb$" (".ads")) ;; GNAT filename conventions
-    )
-  "*Alist of extensions to find given the current file's extension.
-
-This list should contain the most used extensions before the others,
-since the search algorithm searches sequentially through each directory
-specified in `ada-search-directories'.  If a file is not found, a new one
-is created with the first matching extension (`.adb' yields `.ads').
-")
-
-;;;### autoload
-(autoload 'ada-make-filename-from-adaname "ada-mode"
-  "Determine the filename of a package/procedure from its own Ada name.")
-(defvar ada-spec-suffix ".ads"  
-  "*Suffix of Ada specification files.")
-(make-variable-buffer-local 'ada-spec-suffix)
-
-(defvar modula2-other-file-alist
+(defcustom modula2-other-file-alist
   '(
     ("\\.mi$" (".md")) ;; Modula-2 module definition
     ("\\.md$" (".mi")) ;; and implementation.
     )
-  "*See the description for the `ff-search-directories' variable.")
+  "*See the description for the `ff-search-directories' variable."
+  :type '(repeat (list regexp (choice (repeat string) function)))
+  :group 'ff)
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; No user definable variables beyond this point!
@@ -359,13 +377,6 @@ Variables of interest include:
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Support functions
 
-(defun ff-emacs-19 ()
-  (string-match "^19\\.[0-9]+\\.[0-9]+$" emacs-version))
-
-(defun ff-xemacs ()
-  (or (string-match "Lucid"  emacs-version)
-      (string-match "XEmacs" emacs-version)))
-
 (defun ff-find-the-other-file (&optional in-other-window)
   "Find the header or source file corresponding to the current file.
 Being on a `#include' line pulls in that file, but see the help on
@@ -501,7 +512,7 @@ If optional IN-OTHER-WINDOW is non-nil, find the file in another window."
             (ff-find-file pathname in-other-window t)))
 
          (t                        ;; don't create the file, just whinge
-          (message "no file found for %s" fname))))
+          (message "No file found for %s" fname))))
 
        (t                          ;; matching file found
         nil))))
@@ -522,8 +533,8 @@ Arguments: (search-dirs fname-stub &optional suffix-list in-other-window)
      ((not filename)
       nil)
 
-     ((bufferp (get-buffer filename))
-      (ff-switch-to-buffer filename other-window)
+     ((bufferp (get-file-buffer filename))
+      (ff-switch-to-buffer (get-file-buffer filename) other-window)
       filename)
                
      ((file-exists-p filename)
@@ -565,17 +576,17 @@ Arguments: (search-dirs fname-stub &optional suffix-list)
       (setq filename (concat fname-stub this-suffix))
 
       (if (not ff-quiet-mode)
-          (message "finding buffer %s..." filename))
+          (message "Finding buffer %s..." filename))
 
-      (if (bufferp (get-buffer filename))
-          (setq found filename))
+      (if (bufferp (get-file-buffer filename))
+          (setq found (buffer-file-name (get-file-buffer filename))))
 
       (setq blist (buffer-list))
       (setq buf (buffer-name (car blist)))
       (while (and blist (not found))
 
         (if (string-match (concat filename "<[0-9]+>") buf)
-            (setq found buf))
+            (setq found (buffer-file-name (car blist))))
 
         (setq blist (cdr blist))
         (setq buf (buffer-name (car blist))))
@@ -607,7 +618,7 @@ Arguments: (search-dirs fname-stub &optional suffix-list)
               (setq file (concat dir "/" filename))
               
               (if (not ff-quiet-mode)
-                  (message "finding %s..." file))
+                  (message "Finding %s..." file))
 
               (if (file-exists-p file)
                   (setq found file))
@@ -649,7 +660,7 @@ Arguments: (search-dirs fname-stub &optional suffix-list)
     found))
 
 (defun ff-string-match (regexp string &optional start)
-  "Like string-match (which see), but set `case-fold-search' temporarily.
+  "Like `string-match', but set `case-fold-search' temporarily.
 The value used comes from `ff-case-fold-search'."
   (let ((case-fold-search ff-case-fold-search))
     (if regexp
@@ -673,7 +684,7 @@ The value used comes from `ff-case-fold-search'."
 
 (defun ff-treat-as-special ()
   "Returns the file to look for if the construct was special, else nil.
-The construct is defined in the variable `ff-special-constructs' (which see)."
+The construct is defined in the variable `ff-special-constructs'."
   (let* (fname
          (list ff-special-constructs)
          (elem (car list))
@@ -741,65 +752,37 @@ called before `ff-post-load-hooks'."
       (run-hooks 'ff-post-load-hooks)))
 
 (defun ff-find-file (file &optional in-other-window new-file)
-  "Like `find-file' (which see), but may put the file in another window."
+  "Like `find-file', but may show the file in another window."
   (ff-switch-file 'find-file 
                   'find-file-other-window 
                   file in-other-window new-file))
 
-(defun ff-switch-to-buffer (file &optional in-other-window)
-  "Like `switch-to-buffer' (which see), but may put the buffer in another window."
+(defun ff-switch-to-buffer (buffer-or-name &optional in-other-window)
+  "Like `switch-to-buffer', but may show the buffer in another window."
 
   (ff-switch-file 'switch-to-buffer 
                   'switch-to-buffer-other-window 
-                  file in-other-window nil))
-
-(cond 
- ((ff-emacs-19)
-  (defun ff-goto-click (event)
-    (set-buffer (window-buffer (posn-window (event-end event))))
-    (goto-char (posn-point (event-end event))))
-
-  ;;;###autoload
-  (defun ff-mouse-find-other-file (event)
-    "Visit the file you click on."
-    (interactive "e")
-    (save-excursion
-      (ff-goto-click event)
-      (ff-find-other-file nil)))
+                  buffer-or-name in-other-window nil))
 
-  ;;;###autoload
-  (defun ff-mouse-find-other-file-other-window (event)
-    "Visit the file you click on."
-    (interactive "e")
-    (save-excursion
-      (ff-goto-click event)
-      (ff-find-other-file t)))
-
-  ;;;###autoload
-  (defun locate-file (fname dirs &optional suffix-list ignore-perms)
-    "Defines XEmacs look-alike locate-file for GNU Emacs-19."
-    (interactive)
-    (ff-get-file dirs fname suffix-list)) 
-  )
-
- ((ff-xemacs)
-
-  ;;;###autoload
-  (defun ff-mouse-find-other-file (event)
-    "Visit the file you click on."
-    (interactive "@e")
-    (save-excursion
-      (mouse-set-point event)
-      (ff-find-other-file nil)))
+(defun ff-goto-click (event)
+  (set-buffer (window-buffer (posn-window (event-end event))))
+  (goto-char (posn-point (event-end event))))
 
-  ;;;###autoload
-  (defun ff-mouse-find-other-file-other-window (event)
-    "Visit the file you click on."
-    (interactive "@e")
-    (save-excursion
-      (mouse-set-point event)
-      (ff-find-other-file t))) 
-  ))
+;;;###autoload
+(defun ff-mouse-find-other-file (event)
+  "Visit the file you click on."
+  (interactive "e")
+  (save-excursion
+    (ff-goto-click event)
+    (ff-find-other-file nil)))
+
+;;;###autoload
+(defun ff-mouse-find-other-file-other-window (event)
+  "Visit the file you click on."
+  (interactive "e")
+  (save-excursion
+    (ff-goto-click event)
+    (ff-find-other-file t)))
 
 (provide 'find-file)
 
@@ -881,8 +864,7 @@ and the name of the file passed in."
 
 (defvar ff-function-name nil "Name of the function we are in.")
 
-(defvar ada-procedure-start-regexp)
-(defvar ada-package-start-regexp)
+(eval-when-compile (require 'ada-mode))
 
 ;; bind with (setq ff-pre-load-hooks 'ff-which-function-are-we-in)
 ;;